blob: ff5bd03740bd6782e3e6e0155c8a0284403e1004 [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;
Jeff Sharkeye3644412019-04-27 17:13:57 -060032import android.os.StrictMode;
Dianne Hackborn50cdf7c32012-09-23 17:08:57 -070033import android.os.UserHandle;
Jeff Sharkey56bd3122015-04-14 10:30:34 -070034import android.os.storage.DiskInfo;
San Mehatb1043402010-02-05 08:26:50 -080035import android.os.storage.StorageEventListener;
36import android.os.storage.StorageManager;
Jeff Sharkey56bd3122015-04-14 10:30:34 -070037import android.os.storage.VolumeInfo;
Jeff Sharkeyb36586a2015-04-27 08:42:28 -070038import android.os.storage.VolumeRecord;
Dmitri Plotnikov519c0882017-02-13 14:37:05 -080039import android.provider.Settings;
Jeff Sharkeyb36586a2015-04-27 08:42:28 -070040import android.text.TextUtils;
41import android.text.format.DateUtils;
John Spurlockcd686b52013-06-05 10:13:46 -040042import android.util.Log;
Jeff Sharkey50a05452015-04-29 11:24:52 -070043import android.util.SparseArray;
San Mehat64e6a452010-02-04 20:53:48 -080044
Jeff Sharkey56bd3122015-04-14 10:30:34 -070045import com.android.internal.R;
Chris Wren5e6c0ff2017-01-05 12:57:06 -050046import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
John Spurlock3e309b22013-06-25 11:01:29 -040047import com.android.systemui.SystemUI;
Dan Sandler8e032e12017-01-25 13:41:38 -050048import com.android.systemui.util.NotificationChannels;
John Spurlock3e309b22013-06-25 11:01:29 -040049
Jeff Sharkey56bd3122015-04-14 10:30:34 -070050import java.util.List;
51
John Spurlock3e309b22013-06-25 11:01:29 -040052public class StorageNotification extends SystemUI {
San Mehat64e6a452010-02-04 20:53:48 -080053 private static final String TAG = "StorageNotification";
54
Jeff Sharkeyd95d3bf2015-04-14 21:39:44 -070055 private static final String ACTION_SNOOZE_VOLUME = "com.android.systemui.action.SNOOZE_VOLUME";
Jeff Sharkeydf27d3b2015-06-16 13:51:48 -070056 private static final String ACTION_FINISH_WIZARD = "com.android.systemui.action.FINISH_WIZARD";
Jeff Sharkeyd95d3bf2015-04-14 21:39:44 -070057
Jeff Sharkey56bd3122015-04-14 10:30:34 -070058 // TODO: delay some notifications to avoid bumpy fast operations
San Mehat64e6a452010-02-04 20:53:48 -080059
Jeff Sharkey56bd3122015-04-14 10:30:34 -070060 private NotificationManager mNotificationManager;
San Mehatb1043402010-02-05 08:26:50 -080061 private StorageManager mStorageManager;
San Mehat64e6a452010-02-04 20:53:48 -080062
Jeff Sharkey50a05452015-04-29 11:24:52 -070063 private static class MoveInfo {
64 public int moveId;
65 public Bundle extras;
66 public String packageName;
67 public String label;
68 public String volumeUuid;
69 }
70
71 private final SparseArray<MoveInfo> mMoves = new SparseArray<>();
72
Jeff Sharkey56bd3122015-04-14 10:30:34 -070073 private final StorageEventListener mListener = new StorageEventListener() {
74 @Override
75 public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
Jeff Sharkeyb36586a2015-04-27 08:42:28 -070076 onVolumeStateChangedInternal(vol);
John Spurlock3e309b22013-06-25 11:01:29 -040077 }
Jeff Sharkeyd95d3bf2015-04-14 21:39:44 -070078
79 @Override
Jeff Sharkey50a05452015-04-29 11:24:52 -070080 public void onVolumeRecordChanged(VolumeRecord rec) {
Jeff Sharkeyd95d3bf2015-04-14 21:39:44 -070081 // Avoid kicking notifications when getting early metadata before
82 // mounted. If already mounted, we're being kicked because of a
83 // nickname or init'ed change.
Jeff Sharkey50a05452015-04-29 11:24:52 -070084 final VolumeInfo vol = mStorageManager.findVolumeByUuid(rec.getFsUuid());
Jeff Sharkeyb36586a2015-04-27 08:42:28 -070085 if (vol != null && vol.isMountedReadable()) {
86 onVolumeStateChangedInternal(vol);
Jeff Sharkeyd95d3bf2015-04-14 21:39:44 -070087 }
Jeff Sharkey50a05452015-04-29 11:24:52 -070088 }
Jeff Sharkeyb36586a2015-04-27 08:42:28 -070089
Jeff Sharkey50a05452015-04-29 11:24:52 -070090 @Override
91 public void onVolumeForgotten(String fsUuid) {
92 // Stop annoying the user
Chris Wren5e6c0ff2017-01-05 12:57:06 -050093 mNotificationManager.cancelAsUser(fsUuid, SystemMessage.NOTE_STORAGE_PRIVATE,
94 UserHandle.ALL);
Jeff Sharkeyb36586a2015-04-27 08:42:28 -070095 }
96
97 @Override
98 public void onDiskScanned(DiskInfo disk, int volumeCount) {
99 onDiskScannedInternal(disk, volumeCount);
Jeff Sharkeyd95d3bf2015-04-14 21:39:44 -0700100 }
Philip P. Moltmann75b230b2016-04-11 15:27:58 -0700101
102 @Override
103 public void onDiskDestroyed(DiskInfo disk) {
104 onDiskDestroyedInternal(disk);
105 }
Jeff Sharkeyd95d3bf2015-04-14 21:39:44 -0700106 };
107
108 private final BroadcastReceiver mSnoozeReceiver = new BroadcastReceiver() {
109 @Override
110 public void onReceive(Context context, Intent intent) {
111 // TODO: kick this onto background thread
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700112 final String fsUuid = intent.getStringExtra(VolumeRecord.EXTRA_FS_UUID);
113 mStorageManager.setVolumeSnoozed(fsUuid, true);
114 }
115 };
116
Jeff Sharkeydf27d3b2015-06-16 13:51:48 -0700117 private final BroadcastReceiver mFinishReceiver = new BroadcastReceiver() {
118 @Override
119 public void onReceive(Context context, Intent intent) {
120 // When finishing the adoption wizard, clean up any notifications
121 // for moving primary storage
Chris Wren5e6c0ff2017-01-05 12:57:06 -0500122 mNotificationManager.cancelAsUser(null, SystemMessage.NOTE_STORAGE_MOVE,
123 UserHandle.ALL);
Jeff Sharkeydf27d3b2015-06-16 13:51:48 -0700124 }
125 };
126
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700127 private final MoveCallback mMoveCallback = new MoveCallback() {
128 @Override
Jeff Sharkey50a05452015-04-29 11:24:52 -0700129 public void onCreated(int moveId, Bundle extras) {
130 final MoveInfo move = new MoveInfo();
131 move.moveId = moveId;
132 move.extras = extras;
133 if (extras != null) {
134 move.packageName = extras.getString(Intent.EXTRA_PACKAGE_NAME);
135 move.label = extras.getString(Intent.EXTRA_TITLE);
136 move.volumeUuid = extras.getString(VolumeRecord.EXTRA_FS_UUID);
137 }
138 mMoves.put(moveId, move);
139 }
140
141 @Override
142 public void onStatusChanged(int moveId, int status, long estMillis) {
143 final MoveInfo move = mMoves.get(moveId);
144 if (move == null) {
145 Log.w(TAG, "Ignoring unknown move " + moveId);
146 return;
147 }
148
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700149 if (PackageManager.isMoveStatusFinished(status)) {
Jeff Sharkey50a05452015-04-29 11:24:52 -0700150 onMoveFinished(move, status);
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700151 } else {
Jeff Sharkey50a05452015-04-29 11:24:52 -0700152 onMoveProgress(move, status, estMillis);
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700153 }
Jeff Sharkeyd95d3bf2015-04-14 21:39:44 -0700154 }
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700155 };
San Mehat64e6a452010-02-04 20:53:48 -0800156
John Spurlock3e309b22013-06-25 11:01:29 -0400157 @Override
158 public void start() {
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700159 mNotificationManager = mContext.getSystemService(NotificationManager.class);
John Spurlock3e309b22013-06-25 11:01:29 -0400160
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700161 mStorageManager = mContext.getSystemService(StorageManager.class);
162 mStorageManager.registerListener(mListener);
Daniel Sandler5b8743f2010-11-03 09:43:46 -0400163
Jeff Sharkeyd95d3bf2015-04-14 21:39:44 -0700164 mContext.registerReceiver(mSnoozeReceiver, new IntentFilter(ACTION_SNOOZE_VOLUME),
165 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
Jeff Sharkeydf27d3b2015-06-16 13:51:48 -0700166 mContext.registerReceiver(mFinishReceiver, new IntentFilter(ACTION_FINISH_WIZARD),
167 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
Jeff Sharkeyd95d3bf2015-04-14 21:39:44 -0700168
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700169 // Kick current state into place
Jeff Sharkeyf5a6bd72015-05-19 14:42:38 -0700170 final List<DiskInfo> disks = mStorageManager.getDisks();
171 for (DiskInfo disk : disks) {
172 onDiskScannedInternal(disk, disk.volumeCount);
173 }
174
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700175 final List<VolumeInfo> vols = mStorageManager.getVolumes();
176 for (VolumeInfo vol : vols) {
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700177 onVolumeStateChangedInternal(vol);
178 }
179
180 mContext.getPackageManager().registerMoveCallback(mMoveCallback, new Handler());
181
182 updateMissingPrivateVolumes();
183 }
184
185 private void updateMissingPrivateVolumes() {
Dmitri Plotnikov519c0882017-02-13 14:37:05 -0800186 if (isTv()) {
187 // On TV, TvSettings displays a modal full-screen activity in this case.
188 return;
189 }
190
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700191 final List<VolumeRecord> recs = mStorageManager.getVolumeRecords();
192 for (VolumeRecord rec : recs) {
193 if (rec.getType() != VolumeInfo.TYPE_PRIVATE) continue;
194
195 final String fsUuid = rec.getFsUuid();
196 final VolumeInfo info = mStorageManager.findVolumeByUuid(fsUuid);
Jeff Sharkey52fc3c0f2015-06-14 20:58:54 -0700197 if ((info != null && info.isMountedWritable()) || rec.isSnoozed()) {
198 // Yay, private volume is here, or user snoozed
Chris Wren5e6c0ff2017-01-05 12:57:06 -0500199 mNotificationManager.cancelAsUser(fsUuid, SystemMessage.NOTE_STORAGE_PRIVATE,
200 UserHandle.ALL);
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700201
202 } else {
203 // Boo, annoy the user to reinsert the private volume
204 final CharSequence title = mContext.getString(R.string.ext_media_missing_title,
205 rec.getNickname());
206 final CharSequence text = mContext.getString(R.string.ext_media_missing_message);
207
Geoffrey Pitsch1dc93bc2017-01-31 16:38:11 -0500208 Notification.Builder builder =
209 new Notification.Builder(mContext, NotificationChannels.STORAGE)
210 .setSmallIcon(R.drawable.ic_sd_card_48dp)
211 .setColor(mContext.getColor(
212 R.color.system_notification_accent_color))
213 .setContentTitle(title)
214 .setContentText(text)
215 .setContentIntent(buildForgetPendingIntent(rec))
216 .setStyle(new Notification.BigTextStyle().bigText(text))
217 .setVisibility(Notification.VISIBILITY_PUBLIC)
218 .setLocalOnly(true)
219 .setCategory(Notification.CATEGORY_SYSTEM)
Dmitri Plotnikov519c0882017-02-13 14:37:05 -0800220 .setDeleteIntent(buildSnoozeIntent(fsUuid))
221 .extend(new Notification.TvExtender());
Julia Reynolds037d8082018-03-18 15:25:19 -0400222 SystemUI.overrideNotificationAppName(mContext, builder, false);
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700223
Chris Wren5e6c0ff2017-01-05 12:57:06 -0500224 mNotificationManager.notifyAsUser(fsUuid, SystemMessage.NOTE_STORAGE_PRIVATE,
225 builder.build(), UserHandle.ALL);
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700226 }
San Mehat64e6a452010-02-04 20:53:48 -0800227 }
228 }
229
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700230 private void onDiskScannedInternal(DiskInfo disk, int volumeCount) {
Jeff Sharkeyf5a6bd72015-05-19 14:42:38 -0700231 if (volumeCount == 0 && disk.size > 0) {
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700232 // No supported volumes found, give user option to format
233 final CharSequence title = mContext.getString(
Jeff Sharkey52fc3c0f2015-06-14 20:58:54 -0700234 R.string.ext_media_unsupported_notification_title, disk.getDescription());
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700235 final CharSequence text = mContext.getString(
Jeff Sharkey52fc3c0f2015-06-14 20:58:54 -0700236 R.string.ext_media_unsupported_notification_message, disk.getDescription());
San Mehat64e6a452010-02-04 20:53:48 -0800237
Geoffrey Pitsch1dc93bc2017-01-31 16:38:11 -0500238 Notification.Builder builder =
239 new Notification.Builder(mContext, NotificationChannels.STORAGE)
240 .setSmallIcon(getSmallIcon(disk, VolumeInfo.STATE_UNMOUNTABLE))
241 .setColor(mContext.getColor(R.color.system_notification_accent_color))
242 .setContentTitle(title)
243 .setContentText(text)
244 .setContentIntent(buildInitPendingIntent(disk))
245 .setStyle(new Notification.BigTextStyle().bigText(text))
246 .setVisibility(Notification.VISIBILITY_PUBLIC)
247 .setLocalOnly(true)
Dmitri Plotnikov519c0882017-02-13 14:37:05 -0800248 .setCategory(Notification.CATEGORY_ERROR)
249 .extend(new Notification.TvExtender());
Julia Reynolds037d8082018-03-18 15:25:19 -0400250 SystemUI.overrideNotificationAppName(mContext, builder, false);
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700251
Chris Wren5e6c0ff2017-01-05 12:57:06 -0500252 mNotificationManager.notifyAsUser(disk.getId(), SystemMessage.NOTE_STORAGE_DISK,
253 builder.build(), UserHandle.ALL);
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700254
255 } else {
256 // Yay, we have volumes!
Chris Wren5e6c0ff2017-01-05 12:57:06 -0500257 mNotificationManager.cancelAsUser(disk.getId(), SystemMessage.NOTE_STORAGE_DISK,
258 UserHandle.ALL);
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700259 }
260 }
261
Philip P. Moltmann75b230b2016-04-11 15:27:58 -0700262 /**
263 * Remove all notifications for a disk when it goes away.
264 *
265 * @param disk The disk that went away.
266 */
267 private void onDiskDestroyedInternal(@NonNull DiskInfo disk) {
Chris Wren5e6c0ff2017-01-05 12:57:06 -0500268 mNotificationManager.cancelAsUser(disk.getId(), SystemMessage.NOTE_STORAGE_DISK,
269 UserHandle.ALL);
Philip P. Moltmann75b230b2016-04-11 15:27:58 -0700270 }
271
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700272 private void onVolumeStateChangedInternal(VolumeInfo vol) {
273 switch (vol.getType()) {
274 case VolumeInfo.TYPE_PRIVATE:
275 onPrivateVolumeStateChangedInternal(vol);
276 break;
277 case VolumeInfo.TYPE_PUBLIC:
278 onPublicVolumeStateChangedInternal(vol);
279 break;
280 }
281 }
282
283 private void onPrivateVolumeStateChangedInternal(VolumeInfo vol) {
284 Log.d(TAG, "Notifying about private volume: " + vol.toString());
285
286 updateMissingPrivateVolumes();
287 }
288
289 private void onPublicVolumeStateChangedInternal(VolumeInfo vol) {
290 Log.d(TAG, "Notifying about public volume: " + vol.toString());
San Mehat64e6a452010-02-04 20:53:48 -0800291
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700292 final Notification notif;
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700293 switch (vol.getState()) {
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700294 case VolumeInfo.STATE_UNMOUNTED:
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700295 notif = onVolumeUnmounted(vol);
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700296 break;
Jeff Sharkey7e92ef32015-04-17 17:35:07 -0700297 case VolumeInfo.STATE_CHECKING:
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700298 notif = onVolumeChecking(vol);
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700299 break;
300 case VolumeInfo.STATE_MOUNTED:
Jeff Sharkey27de30d2015-04-18 16:20:27 -0700301 case VolumeInfo.STATE_MOUNTED_READ_ONLY:
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700302 notif = onVolumeMounted(vol);
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700303 break;
304 case VolumeInfo.STATE_FORMATTING:
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700305 notif = onVolumeFormatting(vol);
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700306 break;
Jeff Sharkey7e92ef32015-04-17 17:35:07 -0700307 case VolumeInfo.STATE_EJECTING:
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700308 notif = onVolumeEjecting(vol);
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700309 break;
310 case VolumeInfo.STATE_UNMOUNTABLE:
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700311 notif = onVolumeUnmountable(vol);
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700312 break;
313 case VolumeInfo.STATE_REMOVED:
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700314 notif = onVolumeRemoved(vol);
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700315 break;
Jeff Sharkey7e92ef32015-04-17 17:35:07 -0700316 case VolumeInfo.STATE_BAD_REMOVAL:
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700317 notif = onVolumeBadRemoval(vol);
Jeff Sharkey7e92ef32015-04-17 17:35:07 -0700318 break;
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700319 default:
320 notif = null;
321 break;
322 }
323
324 if (notif != null) {
Chris Wren5e6c0ff2017-01-05 12:57:06 -0500325 mNotificationManager.notifyAsUser(vol.getId(), SystemMessage.NOTE_STORAGE_PUBLIC,
Jeff Sharkeyf8543802018-03-28 10:31:55 -0600326 notif, UserHandle.of(vol.getMountUserId()));
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700327 } else {
Chris Wren5e6c0ff2017-01-05 12:57:06 -0500328 mNotificationManager.cancelAsUser(vol.getId(), SystemMessage.NOTE_STORAGE_PUBLIC,
Jeff Sharkeyf8543802018-03-28 10:31:55 -0600329 UserHandle.of(vol.getMountUserId()));
San Mehat64e6a452010-02-04 20:53:48 -0800330 }
331 }
332
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700333 private Notification onVolumeUnmounted(VolumeInfo vol) {
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700334 // Ignored
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700335 return null;
San Mehat64e6a452010-02-04 20:53:48 -0800336 }
337
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700338 private Notification onVolumeChecking(VolumeInfo vol) {
Jeff Sharkey27de30d2015-04-18 16:20:27 -0700339 final DiskInfo disk = vol.getDisk();
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700340 final CharSequence title = mContext.getString(
341 R.string.ext_media_checking_notification_title, disk.getDescription());
342 final CharSequence text = mContext.getString(
343 R.string.ext_media_checking_notification_message, disk.getDescription());
San Mehat64e6a452010-02-04 20:53:48 -0800344
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700345 return buildNotificationBuilder(vol, title, text)
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700346 .setCategory(Notification.CATEGORY_PROGRESS)
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700347 .setOngoing(true)
348 .build();
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700349 }
San Mehat64e6a452010-02-04 20:53:48 -0800350
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700351 private Notification onVolumeMounted(VolumeInfo vol) {
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700352 final VolumeRecord rec = mStorageManager.findRecordByUuid(vol.getFsUuid());
Jeff Sharkey27de30d2015-04-18 16:20:27 -0700353 final DiskInfo disk = vol.getDisk();
Makoto Onukib138cb22015-06-23 17:32:02 -0700354
355 // Don't annoy when user dismissed in past. (But make sure the disk is adoptable; we
356 // used to allow snoozing non-adoptable disks too.)
357 if (rec.isSnoozed() && disk.isAdoptable()) {
358 return null;
359 }
360
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700361 if (disk.isAdoptable() && !rec.isInited()) {
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700362 final CharSequence title = disk.getDescription();
363 final CharSequence text = mContext.getString(
364 R.string.ext_media_new_notification_message, disk.getDescription());
San Mehat64e6a452010-02-04 20:53:48 -0800365
Jeff Sharkey50a05452015-04-29 11:24:52 -0700366 final PendingIntent initIntent = buildInitPendingIntent(vol);
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700367 return buildNotificationBuilder(vol, title, text)
Jeff Sharkeya49d5fc2015-05-13 11:40:30 -0700368 .addAction(new Action(R.drawable.ic_settings_24dp,
369 mContext.getString(R.string.ext_media_init_action), initIntent))
370 .addAction(new Action(R.drawable.ic_eject_24dp,
371 mContext.getString(R.string.ext_media_unmount_action),
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700372 buildUnmountPendingIntent(vol)))
Jeff Sharkey50a05452015-04-29 11:24:52 -0700373 .setContentIntent(initIntent)
Jeff Sharkey52fc3c0f2015-06-14 20:58:54 -0700374 .setDeleteIntent(buildSnoozeIntent(vol.getFsUuid()))
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700375 .build();
John Spurlock209bede2013-07-17 12:23:27 -0400376
San Mehat64e6a452010-02-04 20:53:48 -0800377 } else {
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700378 final CharSequence title = disk.getDescription();
379 final CharSequence text = mContext.getString(
380 R.string.ext_media_ready_notification_message, disk.getDescription());
381
Jeff Sharkey50a05452015-04-29 11:24:52 -0700382 final PendingIntent browseIntent = buildBrowsePendingIntent(vol);
Makoto Onukib138cb22015-06-23 17:32:02 -0700383 final Notification.Builder builder = buildNotificationBuilder(vol, title, text)
Jeff Sharkeya49d5fc2015-05-13 11:40:30 -0700384 .addAction(new Action(R.drawable.ic_folder_24dp,
385 mContext.getString(R.string.ext_media_browse_action),
Jeff Sharkey50a05452015-04-29 11:24:52 -0700386 browseIntent))
Jeff Sharkeya49d5fc2015-05-13 11:40:30 -0700387 .addAction(new Action(R.drawable.ic_eject_24dp,
388 mContext.getString(R.string.ext_media_unmount_action),
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700389 buildUnmountPendingIntent(vol)))
Dmitri Plotnikovb2653e62017-04-11 11:45:00 -0700390 .setContentIntent(browseIntent)
Dan Sandler8e032e12017-01-25 13:41:38 -0500391 .setCategory(Notification.CATEGORY_SYSTEM);
Makoto Onukib138cb22015-06-23 17:32:02 -0700392 // Non-adoptable disks can't be snoozed.
393 if (disk.isAdoptable()) {
394 builder.setDeleteIntent(buildSnoozeIntent(vol.getFsUuid()));
395 }
396
397 return builder.build();
San Mehat64e6a452010-02-04 20:53:48 -0800398 }
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700399 }
400
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700401 private Notification onVolumeFormatting(VolumeInfo vol) {
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700402 // Ignored
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700403 return null;
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700404 }
405
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700406 private Notification onVolumeEjecting(VolumeInfo vol) {
Jeff Sharkey27de30d2015-04-18 16:20:27 -0700407 final DiskInfo disk = vol.getDisk();
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700408 final CharSequence title = mContext.getString(
409 R.string.ext_media_unmounting_notification_title, disk.getDescription());
410 final CharSequence text = mContext.getString(
411 R.string.ext_media_unmounting_notification_message, disk.getDescription());
412
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700413 return buildNotificationBuilder(vol, title, text)
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700414 .setCategory(Notification.CATEGORY_PROGRESS)
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700415 .setOngoing(true)
416 .build();
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700417 }
418
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700419 private Notification onVolumeUnmountable(VolumeInfo vol) {
Jeff Sharkey27de30d2015-04-18 16:20:27 -0700420 final DiskInfo disk = vol.getDisk();
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700421 final CharSequence title = mContext.getString(
422 R.string.ext_media_unmountable_notification_title, disk.getDescription());
423 final CharSequence text = mContext.getString(
424 R.string.ext_media_unmountable_notification_message, disk.getDescription());
425
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700426 return buildNotificationBuilder(vol, title, text)
Jeff Sharkey52fc3c0f2015-06-14 20:58:54 -0700427 .setContentIntent(buildInitPendingIntent(vol))
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700428 .setCategory(Notification.CATEGORY_ERROR)
429 .build();
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700430 }
431
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700432 private Notification onVolumeRemoved(VolumeInfo vol) {
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700433 if (!vol.isPrimary()) {
434 // Ignore non-primary media
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700435 return null;
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700436 }
437
Jeff Sharkey27de30d2015-04-18 16:20:27 -0700438 final DiskInfo disk = vol.getDisk();
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700439 final CharSequence title = mContext.getString(
440 R.string.ext_media_nomedia_notification_title, disk.getDescription());
441 final CharSequence text = mContext.getString(
442 R.string.ext_media_nomedia_notification_message, disk.getDescription());
443
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700444 return buildNotificationBuilder(vol, title, text)
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700445 .setCategory(Notification.CATEGORY_ERROR)
446 .build();
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700447 }
448
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700449 private Notification onVolumeBadRemoval(VolumeInfo vol) {
Jeff Sharkey7e92ef32015-04-17 17:35:07 -0700450 if (!vol.isPrimary()) {
451 // Ignore non-primary media
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700452 return null;
Jeff Sharkey7e92ef32015-04-17 17:35:07 -0700453 }
454
Jeff Sharkey27de30d2015-04-18 16:20:27 -0700455 final DiskInfo disk = vol.getDisk();
Jeff Sharkey7e92ef32015-04-17 17:35:07 -0700456 final CharSequence title = mContext.getString(
457 R.string.ext_media_badremoval_notification_title, disk.getDescription());
458 final CharSequence text = mContext.getString(
459 R.string.ext_media_badremoval_notification_message, disk.getDescription());
460
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700461 return buildNotificationBuilder(vol, title, text)
Jeff Sharkey7e92ef32015-04-17 17:35:07 -0700462 .setCategory(Notification.CATEGORY_ERROR)
463 .build();
Jeff Sharkey7e92ef32015-04-17 17:35:07 -0700464 }
465
Jeff Sharkey50a05452015-04-29 11:24:52 -0700466 private void onMoveProgress(MoveInfo move, int status, long estMillis) {
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700467 final CharSequence title;
Jeff Sharkey50a05452015-04-29 11:24:52 -0700468 if (!TextUtils.isEmpty(move.label)) {
469 title = mContext.getString(R.string.ext_media_move_specific_title, move.label);
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700470 } else {
471 title = mContext.getString(R.string.ext_media_move_title);
472 }
473
474 final CharSequence text;
475 if (estMillis < 0) {
476 text = null;
477 } else {
478 text = DateUtils.formatDuration(estMillis);
479 }
480
Jeff Sharkey50a05452015-04-29 11:24:52 -0700481 final PendingIntent intent;
482 if (move.packageName != null) {
483 intent = buildWizardMovePendingIntent(move);
484 } else {
485 intent = buildWizardMigratePendingIntent(move);
486 }
487
Geoffrey Pitsch1dc93bc2017-01-31 16:38:11 -0500488 Notification.Builder builder =
489 new Notification.Builder(mContext, NotificationChannels.STORAGE)
490 .setSmallIcon(R.drawable.ic_sd_card_48dp)
491 .setColor(mContext.getColor(R.color.system_notification_accent_color))
492 .setContentTitle(title)
493 .setContentText(text)
494 .setContentIntent(intent)
495 .setStyle(new Notification.BigTextStyle().bigText(text))
496 .setVisibility(Notification.VISIBILITY_PUBLIC)
497 .setLocalOnly(true)
498 .setCategory(Notification.CATEGORY_PROGRESS)
499 .setProgress(100, status, false)
500 .setOngoing(true);
Julia Reynolds037d8082018-03-18 15:25:19 -0400501 SystemUI.overrideNotificationAppName(mContext, builder, false);
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700502
Chris Wren5e6c0ff2017-01-05 12:57:06 -0500503 mNotificationManager.notifyAsUser(move.packageName, SystemMessage.NOTE_STORAGE_MOVE,
Adrian Roose25c18d2016-06-17 15:59:49 -0700504 builder.build(), UserHandle.ALL);
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700505 }
506
Jeff Sharkey50a05452015-04-29 11:24:52 -0700507 private void onMoveFinished(MoveInfo move, int status) {
508 if (move.packageName != null) {
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700509 // We currently ignore finished app moves; just clear the last
510 // published progress
Chris Wren5e6c0ff2017-01-05 12:57:06 -0500511 mNotificationManager.cancelAsUser(move.packageName, SystemMessage.NOTE_STORAGE_MOVE,
512 UserHandle.ALL);
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700513 return;
514 }
515
Jeff Sharkey50a05452015-04-29 11:24:52 -0700516 final VolumeInfo privateVol = mContext.getPackageManager().getPrimaryStorageCurrentVolume();
517 final String descrip = mStorageManager.getBestVolumeDescription(privateVol);
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700518
519 final CharSequence title;
520 final CharSequence text;
521 if (status == PackageManager.MOVE_SUCCEEDED) {
522 title = mContext.getString(R.string.ext_media_move_success_title);
523 text = mContext.getString(R.string.ext_media_move_success_message, descrip);
524 } else {
525 title = mContext.getString(R.string.ext_media_move_failure_title);
526 text = mContext.getString(R.string.ext_media_move_failure_message);
527 }
528
Jeff Sharkey50a05452015-04-29 11:24:52 -0700529 // Jump back into the wizard flow if we moved to a real disk
530 final PendingIntent intent;
531 if (privateVol != null && privateVol.getDisk() != null) {
532 intent = buildWizardReadyPendingIntent(privateVol.getDisk());
Jeff Sharkeyef10ee02015-07-05 14:17:27 -0700533 } else if (privateVol != null) {
Jeff Sharkey50a05452015-04-29 11:24:52 -0700534 intent = buildVolumeSettingsPendingIntent(privateVol);
Jeff Sharkeyef10ee02015-07-05 14:17:27 -0700535 } else {
536 intent = null;
Jeff Sharkey50a05452015-04-29 11:24:52 -0700537 }
538
Geoffrey Pitsch1dc93bc2017-01-31 16:38:11 -0500539 Notification.Builder builder =
540 new Notification.Builder(mContext, NotificationChannels.STORAGE)
541 .setSmallIcon(R.drawable.ic_sd_card_48dp)
542 .setColor(mContext.getColor(R.color.system_notification_accent_color))
543 .setContentTitle(title)
544 .setContentText(text)
545 .setContentIntent(intent)
546 .setStyle(new Notification.BigTextStyle().bigText(text))
547 .setVisibility(Notification.VISIBILITY_PUBLIC)
548 .setLocalOnly(true)
549 .setCategory(Notification.CATEGORY_SYSTEM)
550 .setAutoCancel(true);
Julia Reynolds037d8082018-03-18 15:25:19 -0400551 SystemUI.overrideNotificationAppName(mContext, builder, false);
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700552
Chris Wren5e6c0ff2017-01-05 12:57:06 -0500553 mNotificationManager.notifyAsUser(move.packageName, SystemMessage.NOTE_STORAGE_MOVE,
554 builder.build(), UserHandle.ALL);
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700555 }
556
557 private int getSmallIcon(DiskInfo disk, int state) {
558 if (disk.isSd()) {
559 switch (state) {
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700560 case VolumeInfo.STATE_CHECKING:
561 case VolumeInfo.STATE_EJECTING:
Jeff Sharkeya49d5fc2015-05-13 11:40:30 -0700562 return R.drawable.ic_sd_card_48dp;
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700563 default:
Jeff Sharkeya49d5fc2015-05-13 11:40:30 -0700564 return R.drawable.ic_sd_card_48dp;
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700565 }
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700566 } else if (disk.isUsb()) {
Jeff Sharkeya49d5fc2015-05-13 11:40:30 -0700567 return R.drawable.ic_usb_48dp;
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700568 } else {
Jeff Sharkeya49d5fc2015-05-13 11:40:30 -0700569 return R.drawable.ic_sd_card_48dp;
Jeff Sharkeye6c04f92015-04-18 21:38:05 -0700570 }
571 }
572
573 private Notification.Builder buildNotificationBuilder(VolumeInfo vol, CharSequence title,
574 CharSequence text) {
Geoffrey Pitsch1dc93bc2017-01-31 16:38:11 -0500575 Notification.Builder builder =
576 new Notification.Builder(mContext, NotificationChannels.STORAGE)
577 .setSmallIcon(getSmallIcon(vol.getDisk(), vol.getState()))
578 .setColor(mContext.getColor(R.color.system_notification_accent_color))
579 .setContentTitle(title)
580 .setContentText(text)
581 .setStyle(new Notification.BigTextStyle().bigText(text))
582 .setVisibility(Notification.VISIBILITY_PUBLIC)
Dmitri Plotnikov519c0882017-02-13 14:37:05 -0800583 .setLocalOnly(true)
584 .extend(new Notification.TvExtender());
Julia Reynolds037d8082018-03-18 15:25:19 -0400585 overrideNotificationAppName(mContext, builder, false);
Adrian Roose25c18d2016-06-17 15:59:49 -0700586 return builder;
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700587 }
588
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700589 private PendingIntent buildInitPendingIntent(DiskInfo disk) {
590 final Intent intent = new Intent();
Dmitri Plotnikov519c0882017-02-13 14:37:05 -0800591 if (isTv()) {
592 intent.setPackage("com.android.tv.settings");
593 intent.setAction("com.android.tv.settings.action.NEW_STORAGE");
594 } else {
595 intent.setClassName("com.android.settings",
596 "com.android.settings.deviceinfo.StorageWizardInit");
597 }
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700598 intent.putExtra(DiskInfo.EXTRA_DISK_ID, disk.getId());
599
600 final int requestKey = disk.getId().hashCode();
601 return PendingIntent.getActivityAsUser(mContext, requestKey, intent,
602 PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT);
603 }
604
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700605 private PendingIntent buildInitPendingIntent(VolumeInfo vol) {
606 final Intent intent = new Intent();
Dmitri Plotnikov519c0882017-02-13 14:37:05 -0800607 if (isTv()) {
608 intent.setPackage("com.android.tv.settings");
609 intent.setAction("com.android.tv.settings.action.NEW_STORAGE");
610 } else {
611 intent.setClassName("com.android.settings",
612 "com.android.settings.deviceinfo.StorageWizardInit");
613 }
Jeff Sharkeyd95d3bf2015-04-14 21:39:44 -0700614 intent.putExtra(VolumeInfo.EXTRA_VOLUME_ID, vol.getId());
615
616 final int requestKey = vol.getId().hashCode();
617 return PendingIntent.getActivityAsUser(mContext, requestKey, intent,
618 PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT);
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700619 }
620
621 private PendingIntent buildUnmountPendingIntent(VolumeInfo vol) {
622 final Intent intent = new Intent();
Dmitri Plotnikov519c0882017-02-13 14:37:05 -0800623 if (isTv()) {
624 intent.setPackage("com.android.tv.settings");
625 intent.setAction("com.android.tv.settings.action.UNMOUNT_STORAGE");
626 intent.putExtra(VolumeInfo.EXTRA_VOLUME_ID, vol.getId());
Jeff Sharkeyd95d3bf2015-04-14 21:39:44 -0700627
Dmitri Plotnikov519c0882017-02-13 14:37:05 -0800628 final int requestKey = vol.getId().hashCode();
629 return PendingIntent.getActivityAsUser(mContext, requestKey, intent,
630 PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT);
Heemin Seog91fab5c2019-06-17 15:11:27 -0700631 } else if (isAutomotive()) {
632 intent.setClassName("com.android.car.settings",
633 "com.android.car.settings.storage.StorageUnmountReceiver");
634 intent.putExtra(VolumeInfo.EXTRA_VOLUME_ID, vol.getId());
635
636 final int requestKey = vol.getId().hashCode();
637 return PendingIntent.getBroadcastAsUser(mContext, requestKey, intent,
638 PendingIntent.FLAG_CANCEL_CURRENT, UserHandle.CURRENT);
Dmitri Plotnikov519c0882017-02-13 14:37:05 -0800639 } else {
640 intent.setClassName("com.android.settings",
641 "com.android.settings.deviceinfo.StorageUnmountReceiver");
642 intent.putExtra(VolumeInfo.EXTRA_VOLUME_ID, vol.getId());
643
644 final int requestKey = vol.getId().hashCode();
645 return PendingIntent.getBroadcastAsUser(mContext, requestKey, intent,
646 PendingIntent.FLAG_CANCEL_CURRENT, UserHandle.CURRENT);
647 }
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700648 }
649
650 private PendingIntent buildBrowsePendingIntent(VolumeInfo vol) {
Jeff Sharkeye3644412019-04-27 17:13:57 -0600651 final StrictMode.VmPolicy oldPolicy = StrictMode.allowVmViolations();
652 try {
653 final Intent intent = vol.buildBrowseIntentForUser(vol.getMountUserId());
Jeff Sharkeyd95d3bf2015-04-14 21:39:44 -0700654
Jeff Sharkeye3644412019-04-27 17:13:57 -0600655 final int requestKey = vol.getId().hashCode();
656 return PendingIntent.getActivityAsUser(mContext, requestKey, intent,
657 PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT);
658 } finally {
659 StrictMode.setVmPolicy(oldPolicy);
660 }
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700661 }
662
Jeff Sharkey50a05452015-04-29 11:24:52 -0700663 private PendingIntent buildVolumeSettingsPendingIntent(VolumeInfo vol) {
Jeff Sharkey56bd3122015-04-14 10:30:34 -0700664 final Intent intent = new Intent();
Dmitri Plotnikov519c0882017-02-13 14:37:05 -0800665 if (isTv()) {
666 intent.setPackage("com.android.tv.settings");
667 intent.setAction(Settings.ACTION_INTERNAL_STORAGE_SETTINGS);
668 } else {
669 switch (vol.getType()) {
670 case VolumeInfo.TYPE_PRIVATE:
671 intent.setClassName("com.android.settings",
672 "com.android.settings.Settings$PrivateVolumeSettingsActivity");
673 break;
674 case VolumeInfo.TYPE_PUBLIC:
675 intent.setClassName("com.android.settings",
676 "com.android.settings.Settings$PublicVolumeSettingsActivity");
677 break;
678 default:
679 return null;
680 }
Jeff Sharkey50a05452015-04-29 11:24:52 -0700681 }
Jeff Sharkeyd95d3bf2015-04-14 21:39:44 -0700682 intent.putExtra(VolumeInfo.EXTRA_VOLUME_ID, vol.getId());
683
684 final int requestKey = vol.getId().hashCode();
685 return PendingIntent.getActivityAsUser(mContext, requestKey, intent,
686 PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT);
687 }
688
Jeff Sharkey52fc3c0f2015-06-14 20:58:54 -0700689 private PendingIntent buildSnoozeIntent(String fsUuid) {
Jeff Sharkeyd95d3bf2015-04-14 21:39:44 -0700690 final Intent intent = new Intent(ACTION_SNOOZE_VOLUME);
Jeff Sharkey52fc3c0f2015-06-14 20:58:54 -0700691 intent.putExtra(VolumeRecord.EXTRA_FS_UUID, fsUuid);
Jeff Sharkeyd95d3bf2015-04-14 21:39:44 -0700692
Jeff Sharkey52fc3c0f2015-06-14 20:58:54 -0700693 final int requestKey = fsUuid.hashCode();
Jeff Sharkeyd95d3bf2015-04-14 21:39:44 -0700694 return PendingIntent.getBroadcastAsUser(mContext, requestKey, intent,
695 PendingIntent.FLAG_CANCEL_CURRENT, UserHandle.CURRENT);
San Mehat64e6a452010-02-04 20:53:48 -0800696 }
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700697
698 private PendingIntent buildForgetPendingIntent(VolumeRecord rec) {
Dmitri Plotnikov519c0882017-02-13 14:37:05 -0800699 // Not used on TV
Jeff Sharkeyb36586a2015-04-27 08:42:28 -0700700 final Intent intent = new Intent();
701 intent.setClassName("com.android.settings",
702 "com.android.settings.Settings$PrivateVolumeForgetActivity");
703 intent.putExtra(VolumeRecord.EXTRA_FS_UUID, rec.getFsUuid());
704
705 final int requestKey = rec.getFsUuid().hashCode();
706 return PendingIntent.getActivityAsUser(mContext, requestKey, intent,
707 PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT);
708 }
Jeff Sharkey50a05452015-04-29 11:24:52 -0700709
710 private PendingIntent buildWizardMigratePendingIntent(MoveInfo move) {
711 final Intent intent = new Intent();
Dmitri Plotnikov519c0882017-02-13 14:37:05 -0800712 if (isTv()) {
713 intent.setPackage("com.android.tv.settings");
714 intent.setAction("com.android.tv.settings.action.MIGRATE_STORAGE");
715 } else {
716 intent.setClassName("com.android.settings",
717 "com.android.settings.deviceinfo.StorageWizardMigrateProgress");
718 }
Jeff Sharkey50a05452015-04-29 11:24:52 -0700719 intent.putExtra(PackageManager.EXTRA_MOVE_ID, move.moveId);
720
721 final VolumeInfo vol = mStorageManager.findVolumeByQualifiedUuid(move.volumeUuid);
Suprabh Shuklaaf6c4192016-04-27 14:05:54 -0700722 if (vol != null) {
723 intent.putExtra(VolumeInfo.EXTRA_VOLUME_ID, vol.getId());
724 }
Jeff Sharkey50a05452015-04-29 11:24:52 -0700725 return PendingIntent.getActivityAsUser(mContext, move.moveId, intent,
726 PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT);
727 }
728
729 private PendingIntent buildWizardMovePendingIntent(MoveInfo move) {
730 final Intent intent = new Intent();
Dmitri Plotnikov519c0882017-02-13 14:37:05 -0800731 if (isTv()) {
732 intent.setPackage("com.android.tv.settings");
733 intent.setAction("com.android.tv.settings.action.MOVE_APP");
734 } else {
735 intent.setClassName("com.android.settings",
736 "com.android.settings.deviceinfo.StorageWizardMoveProgress");
737 }
Jeff Sharkey50a05452015-04-29 11:24:52 -0700738 intent.putExtra(PackageManager.EXTRA_MOVE_ID, move.moveId);
739
740 return PendingIntent.getActivityAsUser(mContext, move.moveId, intent,
741 PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT);
742 }
743
744 private PendingIntent buildWizardReadyPendingIntent(DiskInfo disk) {
745 final Intent intent = new Intent();
Dmitri Plotnikov519c0882017-02-13 14:37:05 -0800746 if (isTv()) {
747 intent.setPackage("com.android.tv.settings");
748 intent.setAction(Settings.ACTION_INTERNAL_STORAGE_SETTINGS);
749 } else {
750 intent.setClassName("com.android.settings",
751 "com.android.settings.deviceinfo.StorageWizardReady");
752 }
Jeff Sharkey50a05452015-04-29 11:24:52 -0700753 intent.putExtra(DiskInfo.EXTRA_DISK_ID, disk.getId());
754
755 final int requestKey = disk.getId().hashCode();
756 return PendingIntent.getActivityAsUser(mContext, requestKey, intent,
757 PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT);
758 }
Dmitri Plotnikov519c0882017-02-13 14:37:05 -0800759
Heemin Seog91fab5c2019-06-17 15:11:27 -0700760 private boolean isAutomotive() {
761 PackageManager packageManager = mContext.getPackageManager();
762 return packageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE);
763 }
764
Dmitri Plotnikov519c0882017-02-13 14:37:05 -0800765 private boolean isTv() {
766 PackageManager packageManager = mContext.getPackageManager();
767 return packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK);
768 }
San Mehat64e6a452010-02-04 20:53:48 -0800769}