blob: 329d0295943594aeec3d9af4221a4bc5d8d34a07 [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
Philip P. Moltmann75b230b2016-04-11 15:27:58 -070019import android.annotation.NonNull;
San Mehat64e6a452010-02-04 20:53:48 -080020import android.app.Notification;
Jeff Sharkey56bd3122015-04-14 10:30:34 -070021import android.app.Notification.Action;
San Mehat64e6a452010-02-04 20:53:48 -080022import android.app.NotificationManager;
23import android.app.PendingIntent;
Jeff Sharkeyd95d3bf2015-04-14 21:39:44 -070024import android.content.BroadcastReceiver;
25import android.content.Context;
San Mehat64e6a452010-02-04 20:53:48 -080026import android.content.Intent;
Jeff Sharkeyd95d3bf2015-04-14 21:39:44 -070027import android.content.IntentFilter;
Jeff Sharkeyb36586a2015-04-27 08:42:28 -070028import android.content.pm.PackageManager;
29import android.content.pm.PackageManager.MoveCallback;
Jeff Sharkey50a05452015-04-29 11:24:52 -070030import android.os.Bundle;
Jeff Sharkeyb36586a2015-04-27 08:42:28 -070031import android.os.Handler;
Dianne Hackborn50cdf7c32012-09-23 17:08:57 -070032import android.os.UserHandle;
Jeff Sharkey56bd3122015-04-14 10:30:34 -070033import android.os.storage.DiskInfo;
San Mehatb1043402010-02-05 08:26:50 -080034import android.os.storage.StorageEventListener;
35import android.os.storage.StorageManager;
Jeff Sharkey56bd3122015-04-14 10:30:34 -070036import android.os.storage.VolumeInfo;
Jeff Sharkeyb36586a2015-04-27 08:42:28 -070037import android.os.storage.VolumeRecord;
Dmitri Plotnikov519c0882017-02-13 14:37:05 -080038import android.provider.Settings;
Jeff Sharkeyb36586a2015-04-27 08:42:28 -070039import android.text.TextUtils;
40import android.text.format.DateUtils;
John Spurlockcd686b52013-06-05 10:13:46 -040041import android.util.Log;
Jeff Sharkey50a05452015-04-29 11:24:52 -070042import android.util.SparseArray;
San Mehat64e6a452010-02-04 20:53:48 -080043
Jeff Sharkey56bd3122015-04-14 10:30:34 -070044import com.android.internal.R;
Chris Wren5e6c0ff2017-01-05 12:57:06 -050045import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
John Spurlock3e309b22013-06-25 11:01:29 -040046import com.android.systemui.SystemUI;
Dan Sandler8e032e12017-01-25 13:41:38 -050047import com.android.systemui.util.NotificationChannels;
John Spurlock3e309b22013-06-25 11:01:29 -040048
Jeff Sharkey56bd3122015-04-14 10:30:34 -070049import java.util.List;
50
John Spurlock3e309b22013-06-25 11:01:29 -040051public class StorageNotification extends SystemUI {
San Mehat64e6a452010-02-04 20:53:48 -080052 private static final String TAG = "StorageNotification";
53
Jeff Sharkeyd95d3bf2015-04-14 21:39:44 -070054 private static final String ACTION_SNOOZE_VOLUME = "com.android.systemui.action.SNOOZE_VOLUME";
Jeff Sharkeydf27d3b2015-06-16 13:51:48 -070055 private static final String ACTION_FINISH_WIZARD = "com.android.systemui.action.FINISH_WIZARD";
Jeff Sharkeyd95d3bf2015-04-14 21:39:44 -070056
Jeff Sharkey56bd3122015-04-14 10:30:34 -070057 // TODO: delay some notifications to avoid bumpy fast operations
San Mehat64e6a452010-02-04 20:53:48 -080058
Jeff Sharkey56bd3122015-04-14 10:30:34 -070059 private NotificationManager mNotificationManager;
San Mehatb1043402010-02-05 08:26:50 -080060 private StorageManager mStorageManager;
San Mehat64e6a452010-02-04 20:53:48 -080061
Jeff Sharkey50a05452015-04-29 11:24:52 -070062 private static class MoveInfo {
63 public int moveId;
64 public Bundle extras;
65 public String packageName;
66 public String label;
67 public String volumeUuid;
68 }
69
70 private final SparseArray<MoveInfo> mMoves = new SparseArray<>();
71
Jeff Sharkey56bd3122015-04-14 10:30:34 -070072 private final StorageEventListener mListener = new StorageEventListener() {
73 @Override
74 public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
Jeff Sharkeyb36586a2015-04-27 08:42:28 -070075 onVolumeStateChangedInternal(vol);
John Spurlock3e309b22013-06-25 11:01:29 -040076 }
Jeff Sharkeyd95d3bf2015-04-14 21:39:44 -070077
78 @Override
Jeff Sharkey50a05452015-04-29 11:24:52 -070079 public void onVolumeRecordChanged(VolumeRecord rec) {
Jeff Sharkeyd95d3bf2015-04-14 21:39:44 -070080 // Avoid kicking notifications when getting early metadata before
81 // mounted. If already mounted, we're being kicked because of a
82 // nickname or init'ed change.
Jeff Sharkey50a05452015-04-29 11:24:52 -070083 final VolumeInfo vol = mStorageManager.findVolumeByUuid(rec.getFsUuid());
Jeff Sharkeyb36586a2015-04-27 08:42:28 -070084 if (vol != null && vol.isMountedReadable()) {
85 onVolumeStateChangedInternal(vol);
Jeff Sharkeyd95d3bf2015-04-14 21:39:44 -070086 }
Jeff Sharkey50a05452015-04-29 11:24:52 -070087 }
Jeff Sharkeyb36586a2015-04-27 08:42:28 -070088
Jeff Sharkey50a05452015-04-29 11:24:52 -070089 @Override
90 public void onVolumeForgotten(String fsUuid) {
91 // Stop annoying the user
Chris Wren5e6c0ff2017-01-05 12:57:06 -050092 mNotificationManager.cancelAsUser(fsUuid, SystemMessage.NOTE_STORAGE_PRIVATE,
93 UserHandle.ALL);
Jeff Sharkeyb36586a2015-04-27 08:42:28 -070094 }
95
96 @Override
97 public void onDiskScanned(DiskInfo disk, int volumeCount) {
98 onDiskScannedInternal(disk, volumeCount);
Jeff Sharkeyd95d3bf2015-04-14 21:39:44 -070099 }
Philip P. Moltmann75b230b2016-04-11 15:27:58 -0700100
101 @Override
102 public void onDiskDestroyed(DiskInfo disk) {
103 onDiskDestroyedInternal(disk);
104 }
Jeff Sharkeyd95d3bf2015-04-14 21:39:44 -0700105 };
106
107 private final BroadcastReceiver mSnoozeReceiver = new BroadcastReceiver() {
108 @Override
109 public void onReceive(Context context, Intent intent) {
110 // TODO: kick this onto background thread
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700111 final String fsUuid = intent.getStringExtra(VolumeRecord.EXTRA_FS_UUID);
112 mStorageManager.setVolumeSnoozed(fsUuid, true);
113 }
114 };
115
Jeff Sharkeydf27d3b2015-06-16 13:51:48 -0700116 private final BroadcastReceiver mFinishReceiver = new BroadcastReceiver() {
117 @Override
118 public void onReceive(Context context, Intent intent) {
119 // When finishing the adoption wizard, clean up any notifications
120 // for moving primary storage
Chris Wren5e6c0ff2017-01-05 12:57:06 -0500121 mNotificationManager.cancelAsUser(null, SystemMessage.NOTE_STORAGE_MOVE,
122 UserHandle.ALL);
Jeff Sharkeydf27d3b2015-06-16 13:51:48 -0700123 }
124 };
125
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700126 private final MoveCallback mMoveCallback = new MoveCallback() {
127 @Override
Jeff Sharkey50a05452015-04-29 11:24:52 -0700128 public void onCreated(int moveId, Bundle extras) {
129 final MoveInfo move = new MoveInfo();
130 move.moveId = moveId;
131 move.extras = extras;
132 if (extras != null) {
133 move.packageName = extras.getString(Intent.EXTRA_PACKAGE_NAME);
134 move.label = extras.getString(Intent.EXTRA_TITLE);
135 move.volumeUuid = extras.getString(VolumeRecord.EXTRA_FS_UUID);
136 }
137 mMoves.put(moveId, move);
138 }
139
140 @Override
141 public void onStatusChanged(int moveId, int status, long estMillis) {
142 final MoveInfo move = mMoves.get(moveId);
143 if (move == null) {
144 Log.w(TAG, "Ignoring unknown move " + moveId);
145 return;
146 }
147
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700148 if (PackageManager.isMoveStatusFinished(status)) {
Jeff Sharkey50a05452015-04-29 11:24:52 -0700149 onMoveFinished(move, status);
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700150 } else {
Jeff Sharkey50a05452015-04-29 11:24:52 -0700151 onMoveProgress(move, status, estMillis);
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700152 }
Jeff Sharkeyd95d3bf2015-04-14 21:39:44 -0700153 }
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700154 };
San Mehat64e6a452010-02-04 20:53:48 -0800155
John Spurlock3e309b22013-06-25 11:01:29 -0400156 @Override
157 public void start() {
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700158 mNotificationManager = mContext.getSystemService(NotificationManager.class);
John Spurlock3e309b22013-06-25 11:01:29 -0400159
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700160 mStorageManager = mContext.getSystemService(StorageManager.class);
161 mStorageManager.registerListener(mListener);
Daniel Sandler5b8743f2010-11-03 09:43:46 -0400162
Jeff Sharkeyd95d3bf2015-04-14 21:39:44 -0700163 mContext.registerReceiver(mSnoozeReceiver, new IntentFilter(ACTION_SNOOZE_VOLUME),
164 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
Jeff Sharkeydf27d3b2015-06-16 13:51:48 -0700165 mContext.registerReceiver(mFinishReceiver, new IntentFilter(ACTION_FINISH_WIZARD),
166 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
Jeff Sharkeyd95d3bf2015-04-14 21:39:44 -0700167
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700168 // Kick current state into place
Jeff Sharkeyf5a6bd72015-05-19 14:42:38 -0700169 final List<DiskInfo> disks = mStorageManager.getDisks();
170 for (DiskInfo disk : disks) {
171 onDiskScannedInternal(disk, disk.volumeCount);
172 }
173
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700174 final List<VolumeInfo> vols = mStorageManager.getVolumes();
175 for (VolumeInfo vol : vols) {
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700176 onVolumeStateChangedInternal(vol);
177 }
178
179 mContext.getPackageManager().registerMoveCallback(mMoveCallback, new Handler());
180
181 updateMissingPrivateVolumes();
182 }
183
184 private void updateMissingPrivateVolumes() {
Dmitri Plotnikov519c0882017-02-13 14:37:05 -0800185 if (isTv()) {
186 // On TV, TvSettings displays a modal full-screen activity in this case.
187 return;
188 }
189
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700190 final List<VolumeRecord> recs = mStorageManager.getVolumeRecords();
191 for (VolumeRecord rec : recs) {
192 if (rec.getType() != VolumeInfo.TYPE_PRIVATE) continue;
193
194 final String fsUuid = rec.getFsUuid();
195 final VolumeInfo info = mStorageManager.findVolumeByUuid(fsUuid);
Jeff Sharkey52fc3c0f2015-06-14 20:58:54 -0700196 if ((info != null && info.isMountedWritable()) || rec.isSnoozed()) {
197 // Yay, private volume is here, or user snoozed
Chris Wren5e6c0ff2017-01-05 12:57:06 -0500198 mNotificationManager.cancelAsUser(fsUuid, SystemMessage.NOTE_STORAGE_PRIVATE,
199 UserHandle.ALL);
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700200
201 } else {
202 // Boo, annoy the user to reinsert the private volume
203 final CharSequence title = mContext.getString(R.string.ext_media_missing_title,
204 rec.getNickname());
205 final CharSequence text = mContext.getString(R.string.ext_media_missing_message);
206
Geoffrey Pitsch1dc93bc2017-01-31 16:38:11 -0500207 Notification.Builder builder =
208 new Notification.Builder(mContext, NotificationChannels.STORAGE)
209 .setSmallIcon(R.drawable.ic_sd_card_48dp)
210 .setColor(mContext.getColor(
211 R.color.system_notification_accent_color))
212 .setContentTitle(title)
213 .setContentText(text)
214 .setContentIntent(buildForgetPendingIntent(rec))
215 .setStyle(new Notification.BigTextStyle().bigText(text))
216 .setVisibility(Notification.VISIBILITY_PUBLIC)
217 .setLocalOnly(true)
218 .setCategory(Notification.CATEGORY_SYSTEM)
Dmitri Plotnikov519c0882017-02-13 14:37:05 -0800219 .setDeleteIntent(buildSnoozeIntent(fsUuid))
220 .extend(new Notification.TvExtender());
Julia Reynolds037d8082018-03-18 15:25:19 -0400221 SystemUI.overrideNotificationAppName(mContext, builder, false);
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700222
Chris Wren5e6c0ff2017-01-05 12:57:06 -0500223 mNotificationManager.notifyAsUser(fsUuid, SystemMessage.NOTE_STORAGE_PRIVATE,
224 builder.build(), UserHandle.ALL);
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700225 }
San Mehat64e6a452010-02-04 20:53:48 -0800226 }
227 }
228
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700229 private void onDiskScannedInternal(DiskInfo disk, int volumeCount) {
Jeff Sharkeyf5a6bd72015-05-19 14:42:38 -0700230 if (volumeCount == 0 && disk.size > 0) {
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700231 // No supported volumes found, give user option to format
232 final CharSequence title = mContext.getString(
Jeff Sharkey52fc3c0f2015-06-14 20:58:54 -0700233 R.string.ext_media_unsupported_notification_title, disk.getDescription());
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700234 final CharSequence text = mContext.getString(
Jeff Sharkey52fc3c0f2015-06-14 20:58:54 -0700235 R.string.ext_media_unsupported_notification_message, disk.getDescription());
San Mehat64e6a452010-02-04 20:53:48 -0800236
Geoffrey Pitsch1dc93bc2017-01-31 16:38:11 -0500237 Notification.Builder builder =
238 new Notification.Builder(mContext, NotificationChannels.STORAGE)
239 .setSmallIcon(getSmallIcon(disk, VolumeInfo.STATE_UNMOUNTABLE))
240 .setColor(mContext.getColor(R.color.system_notification_accent_color))
241 .setContentTitle(title)
242 .setContentText(text)
243 .setContentIntent(buildInitPendingIntent(disk))
244 .setStyle(new Notification.BigTextStyle().bigText(text))
245 .setVisibility(Notification.VISIBILITY_PUBLIC)
246 .setLocalOnly(true)
Dmitri Plotnikov519c0882017-02-13 14:37:05 -0800247 .setCategory(Notification.CATEGORY_ERROR)
248 .extend(new Notification.TvExtender());
Julia Reynolds037d8082018-03-18 15:25:19 -0400249 SystemUI.overrideNotificationAppName(mContext, builder, false);
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700250
Chris Wren5e6c0ff2017-01-05 12:57:06 -0500251 mNotificationManager.notifyAsUser(disk.getId(), SystemMessage.NOTE_STORAGE_DISK,
252 builder.build(), UserHandle.ALL);
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700253
254 } else {
255 // Yay, we have volumes!
Chris Wren5e6c0ff2017-01-05 12:57:06 -0500256 mNotificationManager.cancelAsUser(disk.getId(), SystemMessage.NOTE_STORAGE_DISK,
257 UserHandle.ALL);
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700258 }
259 }
260
Philip P. Moltmann75b230b2016-04-11 15:27:58 -0700261 /**
262 * Remove all notifications for a disk when it goes away.
263 *
264 * @param disk The disk that went away.
265 */
266 private void onDiskDestroyedInternal(@NonNull DiskInfo disk) {
Chris Wren5e6c0ff2017-01-05 12:57:06 -0500267 mNotificationManager.cancelAsUser(disk.getId(), SystemMessage.NOTE_STORAGE_DISK,
268 UserHandle.ALL);
Philip P. Moltmann75b230b2016-04-11 15:27:58 -0700269 }
270
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700271 private void onVolumeStateChangedInternal(VolumeInfo vol) {
272 switch (vol.getType()) {
273 case VolumeInfo.TYPE_PRIVATE:
274 onPrivateVolumeStateChangedInternal(vol);
275 break;
276 case VolumeInfo.TYPE_PUBLIC:
277 onPublicVolumeStateChangedInternal(vol);
278 break;
279 }
280 }
281
282 private void onPrivateVolumeStateChangedInternal(VolumeInfo vol) {
283 Log.d(TAG, "Notifying about private volume: " + vol.toString());
284
285 updateMissingPrivateVolumes();
286 }
287
288 private void onPublicVolumeStateChangedInternal(VolumeInfo vol) {
289 Log.d(TAG, "Notifying about public volume: " + vol.toString());
San Mehat64e6a452010-02-04 20:53:48 -0800290
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700291 final Notification notif;
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700292 switch (vol.getState()) {
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700293 case VolumeInfo.STATE_UNMOUNTED:
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700294 notif = onVolumeUnmounted(vol);
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700295 break;
Jeff Sharkey7e92ef32015-04-17 17:35:07 -0700296 case VolumeInfo.STATE_CHECKING:
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700297 notif = onVolumeChecking(vol);
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700298 break;
299 case VolumeInfo.STATE_MOUNTED:
Jeff Sharkey27de30d2015-04-18 16:20:27 -0700300 case VolumeInfo.STATE_MOUNTED_READ_ONLY:
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700301 notif = onVolumeMounted(vol);
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700302 break;
303 case VolumeInfo.STATE_FORMATTING:
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700304 notif = onVolumeFormatting(vol);
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700305 break;
Jeff Sharkey7e92ef32015-04-17 17:35:07 -0700306 case VolumeInfo.STATE_EJECTING:
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700307 notif = onVolumeEjecting(vol);
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700308 break;
309 case VolumeInfo.STATE_UNMOUNTABLE:
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700310 notif = onVolumeUnmountable(vol);
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700311 break;
312 case VolumeInfo.STATE_REMOVED:
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700313 notif = onVolumeRemoved(vol);
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700314 break;
Jeff Sharkey7e92ef32015-04-17 17:35:07 -0700315 case VolumeInfo.STATE_BAD_REMOVAL:
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700316 notif = onVolumeBadRemoval(vol);
Jeff Sharkey7e92ef32015-04-17 17:35:07 -0700317 break;
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700318 default:
319 notif = null;
320 break;
321 }
322
323 if (notif != null) {
Chris Wren5e6c0ff2017-01-05 12:57:06 -0500324 mNotificationManager.notifyAsUser(vol.getId(), SystemMessage.NOTE_STORAGE_PUBLIC,
Jeff Sharkeyf8543802018-03-28 10:31:55 -0600325 notif, UserHandle.of(vol.getMountUserId()));
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700326 } else {
Chris Wren5e6c0ff2017-01-05 12:57:06 -0500327 mNotificationManager.cancelAsUser(vol.getId(), SystemMessage.NOTE_STORAGE_PUBLIC,
Jeff Sharkeyf8543802018-03-28 10:31:55 -0600328 UserHandle.of(vol.getMountUserId()));
San Mehat64e6a452010-02-04 20:53:48 -0800329 }
330 }
331
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700332 private Notification onVolumeUnmounted(VolumeInfo vol) {
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700333 // Ignored
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700334 return null;
San Mehat64e6a452010-02-04 20:53:48 -0800335 }
336
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700337 private Notification onVolumeChecking(VolumeInfo vol) {
Jeff Sharkey27de30d2015-04-18 16:20:27 -0700338 final DiskInfo disk = vol.getDisk();
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700339 final CharSequence title = mContext.getString(
340 R.string.ext_media_checking_notification_title, disk.getDescription());
341 final CharSequence text = mContext.getString(
342 R.string.ext_media_checking_notification_message, disk.getDescription());
San Mehat64e6a452010-02-04 20:53:48 -0800343
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700344 return buildNotificationBuilder(vol, title, text)
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700345 .setCategory(Notification.CATEGORY_PROGRESS)
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700346 .setOngoing(true)
347 .build();
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700348 }
San Mehat64e6a452010-02-04 20:53:48 -0800349
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700350 private Notification onVolumeMounted(VolumeInfo vol) {
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700351 final VolumeRecord rec = mStorageManager.findRecordByUuid(vol.getFsUuid());
Jeff Sharkey27de30d2015-04-18 16:20:27 -0700352 final DiskInfo disk = vol.getDisk();
Makoto Onukib138cb22015-06-23 17:32:02 -0700353
354 // Don't annoy when user dismissed in past. (But make sure the disk is adoptable; we
355 // used to allow snoozing non-adoptable disks too.)
356 if (rec.isSnoozed() && disk.isAdoptable()) {
357 return null;
358 }
359
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700360 if (disk.isAdoptable() && !rec.isInited()) {
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700361 final CharSequence title = disk.getDescription();
362 final CharSequence text = mContext.getString(
363 R.string.ext_media_new_notification_message, disk.getDescription());
San Mehat64e6a452010-02-04 20:53:48 -0800364
Jeff Sharkey50a05452015-04-29 11:24:52 -0700365 final PendingIntent initIntent = buildInitPendingIntent(vol);
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700366 return buildNotificationBuilder(vol, title, text)
Jeff Sharkeya49d5fc2015-05-13 11:40:30 -0700367 .addAction(new Action(R.drawable.ic_settings_24dp,
368 mContext.getString(R.string.ext_media_init_action), initIntent))
369 .addAction(new Action(R.drawable.ic_eject_24dp,
370 mContext.getString(R.string.ext_media_unmount_action),
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700371 buildUnmountPendingIntent(vol)))
Jeff Sharkey50a05452015-04-29 11:24:52 -0700372 .setContentIntent(initIntent)
Jeff Sharkey52fc3c0f2015-06-14 20:58:54 -0700373 .setDeleteIntent(buildSnoozeIntent(vol.getFsUuid()))
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700374 .build();
John Spurlock209bede2013-07-17 12:23:27 -0400375
San Mehat64e6a452010-02-04 20:53:48 -0800376 } else {
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700377 final CharSequence title = disk.getDescription();
378 final CharSequence text = mContext.getString(
379 R.string.ext_media_ready_notification_message, disk.getDescription());
380
Jeff Sharkey50a05452015-04-29 11:24:52 -0700381 final PendingIntent browseIntent = buildBrowsePendingIntent(vol);
Makoto Onukib138cb22015-06-23 17:32:02 -0700382 final Notification.Builder builder = buildNotificationBuilder(vol, title, text)
Jeff Sharkeya49d5fc2015-05-13 11:40:30 -0700383 .addAction(new Action(R.drawable.ic_folder_24dp,
384 mContext.getString(R.string.ext_media_browse_action),
Jeff Sharkey50a05452015-04-29 11:24:52 -0700385 browseIntent))
Jeff Sharkeya49d5fc2015-05-13 11:40:30 -0700386 .addAction(new Action(R.drawable.ic_eject_24dp,
387 mContext.getString(R.string.ext_media_unmount_action),
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700388 buildUnmountPendingIntent(vol)))
Dmitri Plotnikovb2653e62017-04-11 11:45:00 -0700389 .setContentIntent(browseIntent)
Dan Sandler8e032e12017-01-25 13:41:38 -0500390 .setCategory(Notification.CATEGORY_SYSTEM);
Makoto Onukib138cb22015-06-23 17:32:02 -0700391 // Non-adoptable disks can't be snoozed.
392 if (disk.isAdoptable()) {
393 builder.setDeleteIntent(buildSnoozeIntent(vol.getFsUuid()));
394 }
395
396 return builder.build();
San Mehat64e6a452010-02-04 20:53:48 -0800397 }
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700398 }
399
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700400 private Notification onVolumeFormatting(VolumeInfo vol) {
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700401 // Ignored
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700402 return null;
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700403 }
404
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700405 private Notification onVolumeEjecting(VolumeInfo vol) {
Jeff Sharkey27de30d2015-04-18 16:20:27 -0700406 final DiskInfo disk = vol.getDisk();
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700407 final CharSequence title = mContext.getString(
408 R.string.ext_media_unmounting_notification_title, disk.getDescription());
409 final CharSequence text = mContext.getString(
410 R.string.ext_media_unmounting_notification_message, disk.getDescription());
411
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700412 return buildNotificationBuilder(vol, title, text)
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700413 .setCategory(Notification.CATEGORY_PROGRESS)
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700414 .setOngoing(true)
415 .build();
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700416 }
417
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700418 private Notification onVolumeUnmountable(VolumeInfo vol) {
Jeff Sharkey27de30d2015-04-18 16:20:27 -0700419 final DiskInfo disk = vol.getDisk();
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700420 final CharSequence title = mContext.getString(
421 R.string.ext_media_unmountable_notification_title, disk.getDescription());
422 final CharSequence text = mContext.getString(
423 R.string.ext_media_unmountable_notification_message, disk.getDescription());
424
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700425 return buildNotificationBuilder(vol, title, text)
Jeff Sharkey52fc3c0f2015-06-14 20:58:54 -0700426 .setContentIntent(buildInitPendingIntent(vol))
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700427 .setCategory(Notification.CATEGORY_ERROR)
428 .build();
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700429 }
430
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700431 private Notification onVolumeRemoved(VolumeInfo vol) {
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700432 if (!vol.isPrimary()) {
433 // Ignore non-primary media
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700434 return null;
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700435 }
436
Jeff Sharkey27de30d2015-04-18 16:20:27 -0700437 final DiskInfo disk = vol.getDisk();
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700438 final CharSequence title = mContext.getString(
439 R.string.ext_media_nomedia_notification_title, disk.getDescription());
440 final CharSequence text = mContext.getString(
441 R.string.ext_media_nomedia_notification_message, disk.getDescription());
442
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700443 return buildNotificationBuilder(vol, title, text)
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700444 .setCategory(Notification.CATEGORY_ERROR)
445 .build();
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700446 }
447
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700448 private Notification onVolumeBadRemoval(VolumeInfo vol) {
Jeff Sharkey7e92ef32015-04-17 17:35:07 -0700449 if (!vol.isPrimary()) {
450 // Ignore non-primary media
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700451 return null;
Jeff Sharkey7e92ef32015-04-17 17:35:07 -0700452 }
453
Jeff Sharkey27de30d2015-04-18 16:20:27 -0700454 final DiskInfo disk = vol.getDisk();
Jeff Sharkey7e92ef32015-04-17 17:35:07 -0700455 final CharSequence title = mContext.getString(
456 R.string.ext_media_badremoval_notification_title, disk.getDescription());
457 final CharSequence text = mContext.getString(
458 R.string.ext_media_badremoval_notification_message, disk.getDescription());
459
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700460 return buildNotificationBuilder(vol, title, text)
Jeff Sharkey7e92ef32015-04-17 17:35:07 -0700461 .setCategory(Notification.CATEGORY_ERROR)
462 .build();
Jeff Sharkey7e92ef32015-04-17 17:35:07 -0700463 }
464
Jeff Sharkey50a05452015-04-29 11:24:52 -0700465 private void onMoveProgress(MoveInfo move, int status, long estMillis) {
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700466 final CharSequence title;
Jeff Sharkey50a05452015-04-29 11:24:52 -0700467 if (!TextUtils.isEmpty(move.label)) {
468 title = mContext.getString(R.string.ext_media_move_specific_title, move.label);
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700469 } else {
470 title = mContext.getString(R.string.ext_media_move_title);
471 }
472
473 final CharSequence text;
474 if (estMillis < 0) {
475 text = null;
476 } else {
477 text = DateUtils.formatDuration(estMillis);
478 }
479
Jeff Sharkey50a05452015-04-29 11:24:52 -0700480 final PendingIntent intent;
481 if (move.packageName != null) {
482 intent = buildWizardMovePendingIntent(move);
483 } else {
484 intent = buildWizardMigratePendingIntent(move);
485 }
486
Geoffrey Pitsch1dc93bc2017-01-31 16:38:11 -0500487 Notification.Builder builder =
488 new Notification.Builder(mContext, NotificationChannels.STORAGE)
489 .setSmallIcon(R.drawable.ic_sd_card_48dp)
490 .setColor(mContext.getColor(R.color.system_notification_accent_color))
491 .setContentTitle(title)
492 .setContentText(text)
493 .setContentIntent(intent)
494 .setStyle(new Notification.BigTextStyle().bigText(text))
495 .setVisibility(Notification.VISIBILITY_PUBLIC)
496 .setLocalOnly(true)
497 .setCategory(Notification.CATEGORY_PROGRESS)
498 .setProgress(100, status, false)
499 .setOngoing(true);
Julia Reynolds037d8082018-03-18 15:25:19 -0400500 SystemUI.overrideNotificationAppName(mContext, builder, false);
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700501
Chris Wren5e6c0ff2017-01-05 12:57:06 -0500502 mNotificationManager.notifyAsUser(move.packageName, SystemMessage.NOTE_STORAGE_MOVE,
Adrian Roose25c18d2016-06-17 15:59:49 -0700503 builder.build(), UserHandle.ALL);
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700504 }
505
Jeff Sharkey50a05452015-04-29 11:24:52 -0700506 private void onMoveFinished(MoveInfo move, int status) {
507 if (move.packageName != null) {
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700508 // We currently ignore finished app moves; just clear the last
509 // published progress
Chris Wren5e6c0ff2017-01-05 12:57:06 -0500510 mNotificationManager.cancelAsUser(move.packageName, SystemMessage.NOTE_STORAGE_MOVE,
511 UserHandle.ALL);
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700512 return;
513 }
514
Jeff Sharkey50a05452015-04-29 11:24:52 -0700515 final VolumeInfo privateVol = mContext.getPackageManager().getPrimaryStorageCurrentVolume();
516 final String descrip = mStorageManager.getBestVolumeDescription(privateVol);
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700517
518 final CharSequence title;
519 final CharSequence text;
520 if (status == PackageManager.MOVE_SUCCEEDED) {
521 title = mContext.getString(R.string.ext_media_move_success_title);
522 text = mContext.getString(R.string.ext_media_move_success_message, descrip);
523 } else {
524 title = mContext.getString(R.string.ext_media_move_failure_title);
525 text = mContext.getString(R.string.ext_media_move_failure_message);
526 }
527
Jeff Sharkey50a05452015-04-29 11:24:52 -0700528 // Jump back into the wizard flow if we moved to a real disk
529 final PendingIntent intent;
530 if (privateVol != null && privateVol.getDisk() != null) {
531 intent = buildWizardReadyPendingIntent(privateVol.getDisk());
Jeff Sharkeyef10ee02015-07-05 14:17:27 -0700532 } else if (privateVol != null) {
Jeff Sharkey50a05452015-04-29 11:24:52 -0700533 intent = buildVolumeSettingsPendingIntent(privateVol);
Jeff Sharkeyef10ee02015-07-05 14:17:27 -0700534 } else {
535 intent = null;
Jeff Sharkey50a05452015-04-29 11:24:52 -0700536 }
537
Geoffrey Pitsch1dc93bc2017-01-31 16:38:11 -0500538 Notification.Builder builder =
539 new Notification.Builder(mContext, NotificationChannels.STORAGE)
540 .setSmallIcon(R.drawable.ic_sd_card_48dp)
541 .setColor(mContext.getColor(R.color.system_notification_accent_color))
542 .setContentTitle(title)
543 .setContentText(text)
544 .setContentIntent(intent)
545 .setStyle(new Notification.BigTextStyle().bigText(text))
546 .setVisibility(Notification.VISIBILITY_PUBLIC)
547 .setLocalOnly(true)
548 .setCategory(Notification.CATEGORY_SYSTEM)
549 .setAutoCancel(true);
Julia Reynolds037d8082018-03-18 15:25:19 -0400550 SystemUI.overrideNotificationAppName(mContext, builder, false);
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700551
Chris Wren5e6c0ff2017-01-05 12:57:06 -0500552 mNotificationManager.notifyAsUser(move.packageName, SystemMessage.NOTE_STORAGE_MOVE,
553 builder.build(), UserHandle.ALL);
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700554 }
555
556 private int getSmallIcon(DiskInfo disk, int state) {
557 if (disk.isSd()) {
558 switch (state) {
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700559 case VolumeInfo.STATE_CHECKING:
560 case VolumeInfo.STATE_EJECTING:
Jeff Sharkeya49d5fc2015-05-13 11:40:30 -0700561 return R.drawable.ic_sd_card_48dp;
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700562 default:
Jeff Sharkeya49d5fc2015-05-13 11:40:30 -0700563 return R.drawable.ic_sd_card_48dp;
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700564 }
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700565 } else if (disk.isUsb()) {
Jeff Sharkeya49d5fc2015-05-13 11:40:30 -0700566 return R.drawable.ic_usb_48dp;
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700567 } else {
Jeff Sharkeya49d5fc2015-05-13 11:40:30 -0700568 return R.drawable.ic_sd_card_48dp;
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700569 }
570 }
571
572 private Notification.Builder buildNotificationBuilder(VolumeInfo vol, CharSequence title,
573 CharSequence text) {
Geoffrey Pitsch1dc93bc2017-01-31 16:38:11 -0500574 Notification.Builder builder =
575 new Notification.Builder(mContext, NotificationChannels.STORAGE)
576 .setSmallIcon(getSmallIcon(vol.getDisk(), vol.getState()))
577 .setColor(mContext.getColor(R.color.system_notification_accent_color))
578 .setContentTitle(title)
579 .setContentText(text)
580 .setStyle(new Notification.BigTextStyle().bigText(text))
581 .setVisibility(Notification.VISIBILITY_PUBLIC)
Dmitri Plotnikov519c0882017-02-13 14:37:05 -0800582 .setLocalOnly(true)
583 .extend(new Notification.TvExtender());
Julia Reynolds037d8082018-03-18 15:25:19 -0400584 overrideNotificationAppName(mContext, builder, false);
Adrian Roose25c18d2016-06-17 15:59:49 -0700585 return builder;
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700586 }
587
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700588 private PendingIntent buildInitPendingIntent(DiskInfo disk) {
589 final Intent intent = new Intent();
Dmitri Plotnikov519c0882017-02-13 14:37:05 -0800590 if (isTv()) {
591 intent.setPackage("com.android.tv.settings");
592 intent.setAction("com.android.tv.settings.action.NEW_STORAGE");
593 } else {
594 intent.setClassName("com.android.settings",
595 "com.android.settings.deviceinfo.StorageWizardInit");
596 }
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700597 intent.putExtra(DiskInfo.EXTRA_DISK_ID, disk.getId());
598
599 final int requestKey = disk.getId().hashCode();
600 return PendingIntent.getActivityAsUser(mContext, requestKey, intent,
601 PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT);
602 }
603
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700604 private PendingIntent buildInitPendingIntent(VolumeInfo vol) {
605 final Intent intent = new Intent();
Dmitri Plotnikov519c0882017-02-13 14:37:05 -0800606 if (isTv()) {
607 intent.setPackage("com.android.tv.settings");
608 intent.setAction("com.android.tv.settings.action.NEW_STORAGE");
609 } else {
610 intent.setClassName("com.android.settings",
611 "com.android.settings.deviceinfo.StorageWizardInit");
612 }
Jeff Sharkeyd95d3bf2015-04-14 21:39:44 -0700613 intent.putExtra(VolumeInfo.EXTRA_VOLUME_ID, vol.getId());
614
615 final int requestKey = vol.getId().hashCode();
616 return PendingIntent.getActivityAsUser(mContext, requestKey, intent,
617 PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT);
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700618 }
619
620 private PendingIntent buildUnmountPendingIntent(VolumeInfo vol) {
621 final Intent intent = new Intent();
Dmitri Plotnikov519c0882017-02-13 14:37:05 -0800622 if (isTv()) {
623 intent.setPackage("com.android.tv.settings");
624 intent.setAction("com.android.tv.settings.action.UNMOUNT_STORAGE");
625 intent.putExtra(VolumeInfo.EXTRA_VOLUME_ID, vol.getId());
Jeff Sharkeyd95d3bf2015-04-14 21:39:44 -0700626
Dmitri Plotnikov519c0882017-02-13 14:37:05 -0800627 final int requestKey = vol.getId().hashCode();
628 return PendingIntent.getActivityAsUser(mContext, requestKey, intent,
629 PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT);
630 } else {
631 intent.setClassName("com.android.settings",
632 "com.android.settings.deviceinfo.StorageUnmountReceiver");
633 intent.putExtra(VolumeInfo.EXTRA_VOLUME_ID, vol.getId());
634
635 final int requestKey = vol.getId().hashCode();
636 return PendingIntent.getBroadcastAsUser(mContext, requestKey, intent,
637 PendingIntent.FLAG_CANCEL_CURRENT, UserHandle.CURRENT);
638 }
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700639 }
640
641 private PendingIntent buildBrowsePendingIntent(VolumeInfo vol) {
Jeff Sharkeyb4ee5d72018-05-22 12:01:31 -0600642 final Intent intent = vol.buildBrowseIntentForUser(vol.getMountUserId());
Jeff Sharkeyd95d3bf2015-04-14 21:39:44 -0700643
644 final int requestKey = vol.getId().hashCode();
645 return PendingIntent.getActivityAsUser(mContext, requestKey, intent,
646 PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT);
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700647 }
648
Jeff Sharkey50a05452015-04-29 11:24:52 -0700649 private PendingIntent buildVolumeSettingsPendingIntent(VolumeInfo vol) {
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700650 final Intent intent = new Intent();
Dmitri Plotnikov519c0882017-02-13 14:37:05 -0800651 if (isTv()) {
652 intent.setPackage("com.android.tv.settings");
653 intent.setAction(Settings.ACTION_INTERNAL_STORAGE_SETTINGS);
654 } else {
655 switch (vol.getType()) {
656 case VolumeInfo.TYPE_PRIVATE:
657 intent.setClassName("com.android.settings",
658 "com.android.settings.Settings$PrivateVolumeSettingsActivity");
659 break;
660 case VolumeInfo.TYPE_PUBLIC:
661 intent.setClassName("com.android.settings",
662 "com.android.settings.Settings$PublicVolumeSettingsActivity");
663 break;
664 default:
665 return null;
666 }
Jeff Sharkey50a05452015-04-29 11:24:52 -0700667 }
Jeff Sharkeyd95d3bf2015-04-14 21:39:44 -0700668 intent.putExtra(VolumeInfo.EXTRA_VOLUME_ID, vol.getId());
669
670 final int requestKey = vol.getId().hashCode();
671 return PendingIntent.getActivityAsUser(mContext, requestKey, intent,
672 PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT);
673 }
674
Jeff Sharkey52fc3c0f2015-06-14 20:58:54 -0700675 private PendingIntent buildSnoozeIntent(String fsUuid) {
Jeff Sharkeyd95d3bf2015-04-14 21:39:44 -0700676 final Intent intent = new Intent(ACTION_SNOOZE_VOLUME);
Jeff Sharkey52fc3c0f2015-06-14 20:58:54 -0700677 intent.putExtra(VolumeRecord.EXTRA_FS_UUID, fsUuid);
Jeff Sharkeyd95d3bf2015-04-14 21:39:44 -0700678
Jeff Sharkey52fc3c0f2015-06-14 20:58:54 -0700679 final int requestKey = fsUuid.hashCode();
Jeff Sharkeyd95d3bf2015-04-14 21:39:44 -0700680 return PendingIntent.getBroadcastAsUser(mContext, requestKey, intent,
681 PendingIntent.FLAG_CANCEL_CURRENT, UserHandle.CURRENT);
San Mehat64e6a452010-02-04 20:53:48 -0800682 }
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700683
684 private PendingIntent buildForgetPendingIntent(VolumeRecord rec) {
Dmitri Plotnikov519c0882017-02-13 14:37:05 -0800685 // Not used on TV
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700686 final Intent intent = new Intent();
687 intent.setClassName("com.android.settings",
688 "com.android.settings.Settings$PrivateVolumeForgetActivity");
689 intent.putExtra(VolumeRecord.EXTRA_FS_UUID, rec.getFsUuid());
690
691 final int requestKey = rec.getFsUuid().hashCode();
692 return PendingIntent.getActivityAsUser(mContext, requestKey, intent,
693 PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT);
694 }
Jeff Sharkey50a05452015-04-29 11:24:52 -0700695
696 private PendingIntent buildWizardMigratePendingIntent(MoveInfo move) {
697 final Intent intent = new Intent();
Dmitri Plotnikov519c0882017-02-13 14:37:05 -0800698 if (isTv()) {
699 intent.setPackage("com.android.tv.settings");
700 intent.setAction("com.android.tv.settings.action.MIGRATE_STORAGE");
701 } else {
702 intent.setClassName("com.android.settings",
703 "com.android.settings.deviceinfo.StorageWizardMigrateProgress");
704 }
Jeff Sharkey50a05452015-04-29 11:24:52 -0700705 intent.putExtra(PackageManager.EXTRA_MOVE_ID, move.moveId);
706
707 final VolumeInfo vol = mStorageManager.findVolumeByQualifiedUuid(move.volumeUuid);
Suprabh Shuklaaf6c4192016-04-27 14:05:54 -0700708 if (vol != null) {
709 intent.putExtra(VolumeInfo.EXTRA_VOLUME_ID, vol.getId());
710 }
Jeff Sharkey50a05452015-04-29 11:24:52 -0700711 return PendingIntent.getActivityAsUser(mContext, move.moveId, intent,
712 PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT);
713 }
714
715 private PendingIntent buildWizardMovePendingIntent(MoveInfo move) {
716 final Intent intent = new Intent();
Dmitri Plotnikov519c0882017-02-13 14:37:05 -0800717 if (isTv()) {
718 intent.setPackage("com.android.tv.settings");
719 intent.setAction("com.android.tv.settings.action.MOVE_APP");
720 } else {
721 intent.setClassName("com.android.settings",
722 "com.android.settings.deviceinfo.StorageWizardMoveProgress");
723 }
Jeff Sharkey50a05452015-04-29 11:24:52 -0700724 intent.putExtra(PackageManager.EXTRA_MOVE_ID, move.moveId);
725
726 return PendingIntent.getActivityAsUser(mContext, move.moveId, intent,
727 PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT);
728 }
729
730 private PendingIntent buildWizardReadyPendingIntent(DiskInfo disk) {
731 final Intent intent = new Intent();
Dmitri Plotnikov519c0882017-02-13 14:37:05 -0800732 if (isTv()) {
733 intent.setPackage("com.android.tv.settings");
734 intent.setAction(Settings.ACTION_INTERNAL_STORAGE_SETTINGS);
735 } else {
736 intent.setClassName("com.android.settings",
737 "com.android.settings.deviceinfo.StorageWizardReady");
738 }
Jeff Sharkey50a05452015-04-29 11:24:52 -0700739 intent.putExtra(DiskInfo.EXTRA_DISK_ID, disk.getId());
740
741 final int requestKey = disk.getId().hashCode();
742 return PendingIntent.getActivityAsUser(mContext, requestKey, intent,
743 PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT);
744 }
Dmitri Plotnikov519c0882017-02-13 14:37:05 -0800745
746 private boolean isTv() {
747 PackageManager packageManager = mContext.getPackageManager();
748 return packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK);
749 }
San Mehat64e6a452010-02-04 20:53:48 -0800750}