blob: 6830957b96b9f6698bb50a0c9651cec3597f2868 [file] [log] [blame]
San Mehat64e6a452010-02-04 20:53:48 -08001/*
Jeff Sharkey56bd3122015-04-14 10:30:34 -07002 * Copyright (C) 2015 The Android Open Source Project
San Mehat64e6a452010-02-04 20:53:48 -08003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Joe Onoratofe4f3ae2010-06-04 11:25:26 -070017package com.android.systemui.usb;
San Mehat64e6a452010-02-04 20:53:48 -080018
San Mehat64e6a452010-02-04 20:53:48 -080019import android.app.Notification;
Jeff Sharkey56bd3122015-04-14 10:30:34 -070020import android.app.Notification.Action;
San Mehat64e6a452010-02-04 20:53:48 -080021import android.app.NotificationManager;
22import android.app.PendingIntent;
San Mehat64e6a452010-02-04 20:53:48 -080023import android.content.Intent;
Dianne Hackborn50cdf7c32012-09-23 17:08:57 -070024import android.os.UserHandle;
Jeff Sharkey56bd3122015-04-14 10:30:34 -070025import android.os.storage.DiskInfo;
San Mehatb1043402010-02-05 08:26:50 -080026import android.os.storage.StorageEventListener;
27import android.os.storage.StorageManager;
Jeff Sharkey56bd3122015-04-14 10:30:34 -070028import android.os.storage.VolumeInfo;
John Spurlockcd686b52013-06-05 10:13:46 -040029import android.util.Log;
San Mehat64e6a452010-02-04 20:53:48 -080030
Jeff Sharkey56bd3122015-04-14 10:30:34 -070031import com.android.internal.R;
John Spurlock3e309b22013-06-25 11:01:29 -040032import com.android.systemui.SystemUI;
33
Jeff Sharkey56bd3122015-04-14 10:30:34 -070034import java.util.List;
35
John Spurlock3e309b22013-06-25 11:01:29 -040036public class StorageNotification extends SystemUI {
San Mehat64e6a452010-02-04 20:53:48 -080037 private static final String TAG = "StorageNotification";
38
Jeff Sharkey56bd3122015-04-14 10:30:34 -070039 private static final int NOTIF_ID = 0x53544f52; // STOR
Daniel Sandlerc07907e2010-02-22 15:08:41 -050040
Jeff Sharkey56bd3122015-04-14 10:30:34 -070041 // TODO: delay some notifications to avoid bumpy fast operations
42 // TODO: annoy user when private media is missing
San Mehat64e6a452010-02-04 20:53:48 -080043
Jeff Sharkey56bd3122015-04-14 10:30:34 -070044 private NotificationManager mNotificationManager;
San Mehatb1043402010-02-05 08:26:50 -080045 private StorageManager mStorageManager;
San Mehat64e6a452010-02-04 20:53:48 -080046
Jeff Sharkey56bd3122015-04-14 10:30:34 -070047 private final StorageEventListener mListener = new StorageEventListener() {
48 @Override
49 public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
50 onVolumeStateChangedInternal(vol, oldState, newState);
John Spurlock3e309b22013-06-25 11:01:29 -040051 }
Jeff Sharkey56bd3122015-04-14 10:30:34 -070052 };
San Mehat64e6a452010-02-04 20:53:48 -080053
John Spurlock3e309b22013-06-25 11:01:29 -040054 @Override
55 public void start() {
Jeff Sharkey56bd3122015-04-14 10:30:34 -070056 mNotificationManager = mContext.getSystemService(NotificationManager.class);
John Spurlock3e309b22013-06-25 11:01:29 -040057
Jeff Sharkey56bd3122015-04-14 10:30:34 -070058 mStorageManager = mContext.getSystemService(StorageManager.class);
59 mStorageManager.registerListener(mListener);
Daniel Sandler5b8743f2010-11-03 09:43:46 -040060
Jeff Sharkey56bd3122015-04-14 10:30:34 -070061 // Kick current state into place
62 final List<VolumeInfo> vols = mStorageManager.getVolumes();
63 for (VolumeInfo vol : vols) {
64 onVolumeStateChangedInternal(vol, vol.state, vol.state);
San Mehat64e6a452010-02-04 20:53:48 -080065 }
66 }
67
Jeff Sharkey56bd3122015-04-14 10:30:34 -070068 public void onVolumeStateChangedInternal(VolumeInfo vol, int oldState, int newState) {
69 // We only care about public volumes
70 if (vol.type != VolumeInfo.TYPE_PUBLIC) {
San Mehat64e6a452010-02-04 20:53:48 -080071 return;
72 }
73
Jeff Sharkey56bd3122015-04-14 10:30:34 -070074 Log.d(TAG, vol.toString());
San Mehat64e6a452010-02-04 20:53:48 -080075
Jeff Sharkey56bd3122015-04-14 10:30:34 -070076 // New state means we tear down any old notifications
77 mNotificationManager.cancelAsUser(vol.id, NOTIF_ID, UserHandle.ALL);
John Spurlock209bede2013-07-17 12:23:27 -040078
Jeff Sharkey56bd3122015-04-14 10:30:34 -070079 switch (newState) {
80 case VolumeInfo.STATE_UNMOUNTED:
81 onVolumeUnmounted(vol);
82 break;
83 case VolumeInfo.STATE_MOUNTING:
84 onVolumeMounting(vol);
85 break;
86 case VolumeInfo.STATE_MOUNTED:
87 onVolumeMounted(vol);
88 break;
89 case VolumeInfo.STATE_FORMATTING:
90 onVolumeFormatting(vol);
91 break;
92 case VolumeInfo.STATE_UNMOUNTING:
93 onVolumeUnmounting(vol);
94 break;
95 case VolumeInfo.STATE_UNMOUNTABLE:
96 onVolumeUnmountable(vol);
97 break;
98 case VolumeInfo.STATE_REMOVED:
99 onVolumeRemoved(vol);
100 break;
San Mehat64e6a452010-02-04 20:53:48 -0800101 }
102 }
103
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700104 private void onVolumeUnmounted(VolumeInfo vol) {
105 // Ignored
San Mehat64e6a452010-02-04 20:53:48 -0800106 }
107
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700108 private void onVolumeMounting(VolumeInfo vol) {
109 final DiskInfo disk = mStorageManager.findDiskById(vol.diskId);
110 final CharSequence title = mContext.getString(
111 R.string.ext_media_checking_notification_title, disk.getDescription());
112 final CharSequence text = mContext.getString(
113 R.string.ext_media_checking_notification_message, disk.getDescription());
San Mehat64e6a452010-02-04 20:53:48 -0800114
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700115 final Notification notif = buildNotificationBuilder(title, text)
116 .setSmallIcon(R.drawable.stat_notify_sdcard_prepare)
117 .setCategory(Notification.CATEGORY_PROGRESS)
118 .setPriority(Notification.PRIORITY_LOW)
119 .setOngoing(true)
120 .build();
San Mehat64e6a452010-02-04 20:53:48 -0800121
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700122 mNotificationManager.notifyAsUser(vol.id, NOTIF_ID, notif, UserHandle.ALL);
123 }
San Mehat64e6a452010-02-04 20:53:48 -0800124
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700125 private void onVolumeMounted(VolumeInfo vol) {
126 final DiskInfo disk = mStorageManager.findDiskById(vol.diskId);
127 final Notification notif;
128 if (disk.isAdoptable()) {
129 final CharSequence title = disk.getDescription();
130 final CharSequence text = mContext.getString(
131 R.string.ext_media_new_notification_message, disk.getDescription());
San Mehat64e6a452010-02-04 20:53:48 -0800132
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700133 notif = buildNotificationBuilder(title, text)
134 .setSmallIcon(R.drawable.stat_notify_sdcard)
135 .addAction(new Action(0, mContext.getString(R.string.ext_media_init_action),
136 buildInitPendingIntent(vol)))
137 .addAction(new Action(0, mContext.getString(R.string.ext_media_unmount_action),
138 buildUnmountPendingIntent(vol)))
139 .setCategory(Notification.CATEGORY_SYSTEM)
140 .build();
John Spurlock209bede2013-07-17 12:23:27 -0400141
San Mehat64e6a452010-02-04 20:53:48 -0800142 } else {
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700143 final CharSequence title = disk.getDescription();
144 final CharSequence text = mContext.getString(
145 R.string.ext_media_ready_notification_message, disk.getDescription());
146
147 notif = buildNotificationBuilder(title, text)
148 .setSmallIcon(R.drawable.stat_notify_sdcard)
149 .addAction(new Action(0, mContext.getString(R.string.ext_media_browse_action),
150 buildBrowsePendingIntent(vol)))
151 .addAction(new Action(0, mContext.getString(R.string.ext_media_unmount_action),
152 buildUnmountPendingIntent(vol)))
153 .setCategory(Notification.CATEGORY_SYSTEM)
154 .setPriority(Notification.PRIORITY_LOW)
155 .build();
San Mehat64e6a452010-02-04 20:53:48 -0800156 }
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700157
158 mNotificationManager.notifyAsUser(vol.id, NOTIF_ID, notif, UserHandle.ALL);
159 }
160
161 private void onVolumeFormatting(VolumeInfo vol) {
162 // Ignored
163 }
164
165 private void onVolumeUnmounting(VolumeInfo vol) {
166 final DiskInfo disk = mStorageManager.findDiskById(vol.diskId);
167 final CharSequence title = mContext.getString(
168 R.string.ext_media_unmounting_notification_title, disk.getDescription());
169 final CharSequence text = mContext.getString(
170 R.string.ext_media_unmounting_notification_message, disk.getDescription());
171
172 final Notification notif = buildNotificationBuilder(title, text)
173 .setSmallIcon(R.drawable.stat_notify_sdcard_prepare)
174 .setCategory(Notification.CATEGORY_PROGRESS)
175 .setPriority(Notification.PRIORITY_LOW)
176 .setOngoing(true)
177 .build();
178
179 mNotificationManager.notifyAsUser(vol.id, NOTIF_ID, notif, UserHandle.ALL);
180 }
181
182 private void onVolumeUnmountable(VolumeInfo vol) {
183 final DiskInfo disk = mStorageManager.findDiskById(vol.diskId);
184 final CharSequence title = mContext.getString(
185 R.string.ext_media_unmountable_notification_title, disk.getDescription());
186 final CharSequence text = mContext.getString(
187 R.string.ext_media_unmountable_notification_message, disk.getDescription());
188
189 final Notification notif = buildNotificationBuilder(title, text)
190 .setSmallIcon(R.drawable.stat_notify_sdcard)
191 .setContentIntent(buildDetailsPendingIntent(vol))
192 .setCategory(Notification.CATEGORY_ERROR)
193 .build();
194
195 mNotificationManager.notifyAsUser(vol.id, NOTIF_ID, notif, UserHandle.ALL);
196 }
197
198 private void onVolumeRemoved(VolumeInfo vol) {
199 if (!vol.isPrimary()) {
200 // Ignore non-primary media
201 return;
202 }
203
204 final DiskInfo disk = mStorageManager.findDiskById(vol.diskId);
205 final CharSequence title = mContext.getString(
206 R.string.ext_media_nomedia_notification_title, disk.getDescription());
207 final CharSequence text = mContext.getString(
208 R.string.ext_media_nomedia_notification_message, disk.getDescription());
209
210 final Notification notif = buildNotificationBuilder(title, text)
211 .setSmallIcon(R.drawable.stat_notify_sdcard)
212 .setCategory(Notification.CATEGORY_ERROR)
213 .build();
214
215 mNotificationManager.notifyAsUser(vol.id, NOTIF_ID, notif, UserHandle.ALL);
216 }
217
218 private Notification.Builder buildNotificationBuilder(CharSequence title, CharSequence text) {
219 return new Notification.Builder(mContext)
220 .setColor(mContext.getColor(R.color.system_notification_accent_color))
221 .setContentTitle(title)
222 .setContentText(text)
223 .setStyle(new Notification.BigTextStyle().bigText(text))
224 .setVisibility(Notification.VISIBILITY_PUBLIC)
225 .setLocalOnly(true);
226 }
227
228 private PendingIntent buildInitPendingIntent(VolumeInfo vol) {
229 final Intent intent = new Intent();
230 intent.setClassName("com.android.settings",
231 "com.android.settings.deviceinfo.StorageWizardInit");
232 intent.putExtra(VolumeInfo.EXTRA_VOLUME_ID, vol.id);
233 return PendingIntent.getActivityAsUser(mContext, 0, intent, 0, null, UserHandle.CURRENT);
234 }
235
236 private PendingIntent buildUnmountPendingIntent(VolumeInfo vol) {
237 final Intent intent = new Intent();
238 intent.setClassName("com.android.settings",
239 "com.android.settings.deviceinfo.StorageUnmountReceiver");
240 intent.putExtra(VolumeInfo.EXTRA_VOLUME_ID, vol.id);
241 return PendingIntent.getBroadcastAsUser(mContext, 0, intent, 0, UserHandle.CURRENT);
242 }
243
244 private PendingIntent buildBrowsePendingIntent(VolumeInfo vol) {
245 final Intent intent = vol.buildBrowseIntent();
246 return PendingIntent.getActivityAsUser(mContext, 0, intent, 0, null, UserHandle.CURRENT);
247 }
248
249 private PendingIntent buildDetailsPendingIntent(VolumeInfo vol) {
250 final Intent intent = new Intent();
251 intent.setClassName("com.android.settings",
252 "com.android.settings.Settings$StorageVolumeSettingsActivity");
253 intent.putExtra(VolumeInfo.EXTRA_VOLUME_ID, vol.id);
254 return PendingIntent.getActivityAsUser(mContext, 0, intent, 0, null, UserHandle.CURRENT);
San Mehat64e6a452010-02-04 20:53:48 -0800255 }
256}