164e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat/* 256bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey * Copyright (C) 2015 The Android Open Source Project 364e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat * 464e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat * Licensed under the Apache License, Version 2.0 (the "License"); 564e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat * you may not use this file except in compliance with the License. 664e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat * You may obtain a copy of the License at 764e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat * 864e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat * http://www.apache.org/licenses/LICENSE-2.0 964e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat * 1064e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat * Unless required by applicable law or agreed to in writing, software 1164e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat * distributed under the License is distributed on an "AS IS" BASIS, 1264e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1364e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat * See the License for the specific language governing permissions and 1464e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat * limitations under the License. 1564e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat */ 1664e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat 17fe4f3ae33c8da86585399b4167fd7987c8a16066Joe Onoratopackage com.android.systemui.usb; 1864e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat 1975b230b1d5abb1089173392f294f7fc5ce00e56cPhilip P. Moltmannimport android.annotation.NonNull; 2064e6a45ed45e0d096a1490408ee1cab2a4626950San Mehatimport android.app.Notification; 2156bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkeyimport android.app.Notification.Action; 22519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikovimport android.app.NotificationChannel; 2364e6a45ed45e0d096a1490408ee1cab2a4626950San Mehatimport android.app.NotificationManager; 2464e6a45ed45e0d096a1490408ee1cab2a4626950San Mehatimport android.app.PendingIntent; 25d95d3bfb2b28a4f21f3fdcd740160c9a61eb0363Jeff Sharkeyimport android.content.BroadcastReceiver; 26d95d3bfb2b28a4f21f3fdcd740160c9a61eb0363Jeff Sharkeyimport android.content.Context; 2764e6a45ed45e0d096a1490408ee1cab2a4626950San Mehatimport android.content.Intent; 28d95d3bfb2b28a4f21f3fdcd740160c9a61eb0363Jeff Sharkeyimport android.content.IntentFilter; 29b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkeyimport android.content.pm.PackageManager; 30b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkeyimport android.content.pm.PackageManager.MoveCallback; 3150a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkeyimport android.os.Bundle; 32b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkeyimport android.os.Handler; 3350cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackbornimport android.os.UserHandle; 3456bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkeyimport android.os.storage.DiskInfo; 35b104340496e3a531e26c8f428c808eca0e039f50San Mehatimport android.os.storage.StorageEventListener; 36b104340496e3a531e26c8f428c808eca0e039f50San Mehatimport android.os.storage.StorageManager; 3756bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkeyimport android.os.storage.VolumeInfo; 38b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkeyimport android.os.storage.VolumeRecord; 39519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikovimport android.provider.Settings; 40b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkeyimport android.text.TextUtils; 41b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkeyimport android.text.format.DateUtils; 42cd686b5b6d4166b510df8e32138479a9559bc117John Spurlockimport android.util.Log; 4350a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkeyimport android.util.SparseArray; 4464e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat 4556bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkeyimport com.android.internal.R; 465e6c0ffd3e91cf0c5872de3e2d99e225ad1468f4Chris Wrenimport com.android.internal.messages.nano.SystemMessageProto.SystemMessage; 473e309b2edc99cced870916a7a0fa0d27578cad6dJohn Spurlockimport com.android.systemui.SystemUI; 488e032e15e6b1b6a2f44fd3d5063ee83f45d71189Dan Sandlerimport com.android.systemui.util.NotificationChannels; 493e309b2edc99cced870916a7a0fa0d27578cad6dJohn Spurlock 5056bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkeyimport java.util.List; 5156bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey 523e309b2edc99cced870916a7a0fa0d27578cad6dJohn Spurlockpublic class StorageNotification extends SystemUI { 5364e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat private static final String TAG = "StorageNotification"; 5464e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat 55d95d3bfb2b28a4f21f3fdcd740160c9a61eb0363Jeff Sharkey private static final String ACTION_SNOOZE_VOLUME = "com.android.systemui.action.SNOOZE_VOLUME"; 56df27d3bf3049b8e0b0c8ce432468be380a6eaeebJeff Sharkey private static final String ACTION_FINISH_WIZARD = "com.android.systemui.action.FINISH_WIZARD"; 57d95d3bfb2b28a4f21f3fdcd740160c9a61eb0363Jeff Sharkey 5856bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey // TODO: delay some notifications to avoid bumpy fast operations 5956bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey 6056bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey private NotificationManager mNotificationManager; 6156bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey private StorageManager mStorageManager; 6256bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey 6350a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey private static class MoveInfo { 6450a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey public int moveId; 6550a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey public Bundle extras; 6650a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey public String packageName; 6750a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey public String label; 6850a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey public String volumeUuid; 6950a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey } 7050a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey 7150a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey private final SparseArray<MoveInfo> mMoves = new SparseArray<>(); 7250a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey 7356bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey private final StorageEventListener mListener = new StorageEventListener() { 7456bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey @Override 7556bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) { 76b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey onVolumeStateChangedInternal(vol); 773e309b2edc99cced870916a7a0fa0d27578cad6dJohn Spurlock } 78d95d3bfb2b28a4f21f3fdcd740160c9a61eb0363Jeff Sharkey 79d95d3bfb2b28a4f21f3fdcd740160c9a61eb0363Jeff Sharkey @Override 8050a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey public void onVolumeRecordChanged(VolumeRecord rec) { 81d95d3bfb2b28a4f21f3fdcd740160c9a61eb0363Jeff Sharkey // Avoid kicking notifications when getting early metadata before 82d95d3bfb2b28a4f21f3fdcd740160c9a61eb0363Jeff Sharkey // mounted. If already mounted, we're being kicked because of a 83d95d3bfb2b28a4f21f3fdcd740160c9a61eb0363Jeff Sharkey // nickname or init'ed change. 8450a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey final VolumeInfo vol = mStorageManager.findVolumeByUuid(rec.getFsUuid()); 85b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey if (vol != null && vol.isMountedReadable()) { 86b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey onVolumeStateChangedInternal(vol); 87d95d3bfb2b28a4f21f3fdcd740160c9a61eb0363Jeff Sharkey } 8850a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey } 89b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey 9050a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey @Override 9150a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey public void onVolumeForgotten(String fsUuid) { 9250a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey // Stop annoying the user 935e6c0ffd3e91cf0c5872de3e2d99e225ad1468f4Chris Wren mNotificationManager.cancelAsUser(fsUuid, SystemMessage.NOTE_STORAGE_PRIVATE, 945e6c0ffd3e91cf0c5872de3e2d99e225ad1468f4Chris Wren UserHandle.ALL); 95b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey } 96b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey 97b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey @Override 98b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey public void onDiskScanned(DiskInfo disk, int volumeCount) { 99b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey onDiskScannedInternal(disk, volumeCount); 100d95d3bfb2b28a4f21f3fdcd740160c9a61eb0363Jeff Sharkey } 10175b230b1d5abb1089173392f294f7fc5ce00e56cPhilip P. Moltmann 10275b230b1d5abb1089173392f294f7fc5ce00e56cPhilip P. Moltmann @Override 10375b230b1d5abb1089173392f294f7fc5ce00e56cPhilip P. Moltmann public void onDiskDestroyed(DiskInfo disk) { 10475b230b1d5abb1089173392f294f7fc5ce00e56cPhilip P. Moltmann onDiskDestroyedInternal(disk); 10575b230b1d5abb1089173392f294f7fc5ce00e56cPhilip P. Moltmann } 106d95d3bfb2b28a4f21f3fdcd740160c9a61eb0363Jeff Sharkey }; 107d95d3bfb2b28a4f21f3fdcd740160c9a61eb0363Jeff Sharkey 108d95d3bfb2b28a4f21f3fdcd740160c9a61eb0363Jeff Sharkey private final BroadcastReceiver mSnoozeReceiver = new BroadcastReceiver() { 109d95d3bfb2b28a4f21f3fdcd740160c9a61eb0363Jeff Sharkey @Override 110d95d3bfb2b28a4f21f3fdcd740160c9a61eb0363Jeff Sharkey public void onReceive(Context context, Intent intent) { 111d95d3bfb2b28a4f21f3fdcd740160c9a61eb0363Jeff Sharkey // TODO: kick this onto background thread 112b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey final String fsUuid = intent.getStringExtra(VolumeRecord.EXTRA_FS_UUID); 113b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey mStorageManager.setVolumeSnoozed(fsUuid, true); 114b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey } 115b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey }; 116b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey 117df27d3bf3049b8e0b0c8ce432468be380a6eaeebJeff Sharkey private final BroadcastReceiver mFinishReceiver = new BroadcastReceiver() { 118df27d3bf3049b8e0b0c8ce432468be380a6eaeebJeff Sharkey @Override 119df27d3bf3049b8e0b0c8ce432468be380a6eaeebJeff Sharkey public void onReceive(Context context, Intent intent) { 120df27d3bf3049b8e0b0c8ce432468be380a6eaeebJeff Sharkey // When finishing the adoption wizard, clean up any notifications 121df27d3bf3049b8e0b0c8ce432468be380a6eaeebJeff Sharkey // for moving primary storage 1225e6c0ffd3e91cf0c5872de3e2d99e225ad1468f4Chris Wren mNotificationManager.cancelAsUser(null, SystemMessage.NOTE_STORAGE_MOVE, 1235e6c0ffd3e91cf0c5872de3e2d99e225ad1468f4Chris Wren UserHandle.ALL); 124df27d3bf3049b8e0b0c8ce432468be380a6eaeebJeff Sharkey } 125df27d3bf3049b8e0b0c8ce432468be380a6eaeebJeff Sharkey }; 126df27d3bf3049b8e0b0c8ce432468be380a6eaeebJeff Sharkey 127b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey private final MoveCallback mMoveCallback = new MoveCallback() { 128b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey @Override 12950a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey public void onCreated(int moveId, Bundle extras) { 13050a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey final MoveInfo move = new MoveInfo(); 13150a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey move.moveId = moveId; 13250a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey move.extras = extras; 13350a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey if (extras != null) { 13450a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey move.packageName = extras.getString(Intent.EXTRA_PACKAGE_NAME); 13550a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey move.label = extras.getString(Intent.EXTRA_TITLE); 13650a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey move.volumeUuid = extras.getString(VolumeRecord.EXTRA_FS_UUID); 13750a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey } 13850a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey mMoves.put(moveId, move); 13950a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey } 14050a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey 14150a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey @Override 14250a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey public void onStatusChanged(int moveId, int status, long estMillis) { 14350a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey final MoveInfo move = mMoves.get(moveId); 14450a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey if (move == null) { 14550a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey Log.w(TAG, "Ignoring unknown move " + moveId); 14650a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey return; 14750a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey } 14850a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey 149b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey if (PackageManager.isMoveStatusFinished(status)) { 15050a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey onMoveFinished(move, status); 151b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey } else { 15250a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey onMoveProgress(move, status, estMillis); 153b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey } 154d95d3bfb2b28a4f21f3fdcd740160c9a61eb0363Jeff Sharkey } 15556bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey }; 15664e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat 1573e309b2edc99cced870916a7a0fa0d27578cad6dJohn Spurlock @Override 1583e309b2edc99cced870916a7a0fa0d27578cad6dJohn Spurlock public void start() { 15956bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey mNotificationManager = mContext.getSystemService(NotificationManager.class); 1605b8743f3d6a0ba23dce533072f92acd7ec3210e9Daniel Sandler 16156bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey mStorageManager = mContext.getSystemService(StorageManager.class); 16256bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey mStorageManager.registerListener(mListener); 16364e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat 164d95d3bfb2b28a4f21f3fdcd740160c9a61eb0363Jeff Sharkey mContext.registerReceiver(mSnoozeReceiver, new IntentFilter(ACTION_SNOOZE_VOLUME), 165d95d3bfb2b28a4f21f3fdcd740160c9a61eb0363Jeff Sharkey android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 166df27d3bf3049b8e0b0c8ce432468be380a6eaeebJeff Sharkey mContext.registerReceiver(mFinishReceiver, new IntentFilter(ACTION_FINISH_WIZARD), 167df27d3bf3049b8e0b0c8ce432468be380a6eaeebJeff Sharkey android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 168d95d3bfb2b28a4f21f3fdcd740160c9a61eb0363Jeff Sharkey 16956bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey // Kick current state into place 170f5a6bd7538a6800c2a43ace5ad67d65b1f8f697aJeff Sharkey final List<DiskInfo> disks = mStorageManager.getDisks(); 171f5a6bd7538a6800c2a43ace5ad67d65b1f8f697aJeff Sharkey for (DiskInfo disk : disks) { 172f5a6bd7538a6800c2a43ace5ad67d65b1f8f697aJeff Sharkey onDiskScannedInternal(disk, disk.volumeCount); 173f5a6bd7538a6800c2a43ace5ad67d65b1f8f697aJeff Sharkey } 174f5a6bd7538a6800c2a43ace5ad67d65b1f8f697aJeff Sharkey 17556bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey final List<VolumeInfo> vols = mStorageManager.getVolumes(); 17656bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey for (VolumeInfo vol : vols) { 177b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey onVolumeStateChangedInternal(vol); 17864e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat } 179b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey 180b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey mContext.getPackageManager().registerMoveCallback(mMoveCallback, new Handler()); 181b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey 182b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey updateMissingPrivateVolumes(); 18364e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat } 18464e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat 185b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey private void updateMissingPrivateVolumes() { 186519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov if (isTv()) { 187519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov // On TV, TvSettings displays a modal full-screen activity in this case. 188519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov return; 189519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov } 190519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov 191b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey final List<VolumeRecord> recs = mStorageManager.getVolumeRecords(); 192b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey for (VolumeRecord rec : recs) { 193b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey if (rec.getType() != VolumeInfo.TYPE_PRIVATE) continue; 194b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey 195b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey final String fsUuid = rec.getFsUuid(); 196b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey final VolumeInfo info = mStorageManager.findVolumeByUuid(fsUuid); 19752fc3c0f73a9081609c3636dd1b393a0653a9d00Jeff Sharkey if ((info != null && info.isMountedWritable()) || rec.isSnoozed()) { 19852fc3c0f73a9081609c3636dd1b393a0653a9d00Jeff Sharkey // Yay, private volume is here, or user snoozed 1995e6c0ffd3e91cf0c5872de3e2d99e225ad1468f4Chris Wren mNotificationManager.cancelAsUser(fsUuid, SystemMessage.NOTE_STORAGE_PRIVATE, 2005e6c0ffd3e91cf0c5872de3e2d99e225ad1468f4Chris Wren UserHandle.ALL); 201b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey 202b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey } else { 203b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey // Boo, annoy the user to reinsert the private volume 204b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey final CharSequence title = mContext.getString(R.string.ext_media_missing_title, 205b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey rec.getNickname()); 206b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey final CharSequence text = mContext.getString(R.string.ext_media_missing_message); 207b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey 2081dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch Notification.Builder builder = 2091dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch new Notification.Builder(mContext, NotificationChannels.STORAGE) 2101dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch .setSmallIcon(R.drawable.ic_sd_card_48dp) 2111dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch .setColor(mContext.getColor( 2121dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch R.color.system_notification_accent_color)) 2131dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch .setContentTitle(title) 2141dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch .setContentText(text) 2151dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch .setContentIntent(buildForgetPendingIntent(rec)) 2161dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch .setStyle(new Notification.BigTextStyle().bigText(text)) 2171dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch .setVisibility(Notification.VISIBILITY_PUBLIC) 2181dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch .setLocalOnly(true) 2191dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch .setCategory(Notification.CATEGORY_SYSTEM) 220519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov .setDeleteIntent(buildSnoozeIntent(fsUuid)) 221519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov .extend(new Notification.TvExtender()); 222e25c18da7d2cc3e02620dadfcb976521821bc9d8Adrian Roos SystemUI.overrideNotificationAppName(mContext, builder); 223b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey 2245e6c0ffd3e91cf0c5872de3e2d99e225ad1468f4Chris Wren mNotificationManager.notifyAsUser(fsUuid, SystemMessage.NOTE_STORAGE_PRIVATE, 2255e6c0ffd3e91cf0c5872de3e2d99e225ad1468f4Chris Wren builder.build(), UserHandle.ALL); 226b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey } 227b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey } 228b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey } 229b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey 230b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey private void onDiskScannedInternal(DiskInfo disk, int volumeCount) { 231f5a6bd7538a6800c2a43ace5ad67d65b1f8f697aJeff Sharkey if (volumeCount == 0 && disk.size > 0) { 232b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey // No supported volumes found, give user option to format 233b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey final CharSequence title = mContext.getString( 23452fc3c0f73a9081609c3636dd1b393a0653a9d00Jeff Sharkey R.string.ext_media_unsupported_notification_title, disk.getDescription()); 235b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey final CharSequence text = mContext.getString( 23652fc3c0f73a9081609c3636dd1b393a0653a9d00Jeff Sharkey R.string.ext_media_unsupported_notification_message, disk.getDescription()); 237b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey 2381dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch Notification.Builder builder = 2391dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch new Notification.Builder(mContext, NotificationChannels.STORAGE) 2401dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch .setSmallIcon(getSmallIcon(disk, VolumeInfo.STATE_UNMOUNTABLE)) 2411dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch .setColor(mContext.getColor(R.color.system_notification_accent_color)) 2421dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch .setContentTitle(title) 2431dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch .setContentText(text) 2441dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch .setContentIntent(buildInitPendingIntent(disk)) 2451dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch .setStyle(new Notification.BigTextStyle().bigText(text)) 2461dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch .setVisibility(Notification.VISIBILITY_PUBLIC) 2471dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch .setLocalOnly(true) 248519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov .setCategory(Notification.CATEGORY_ERROR) 249519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov .extend(new Notification.TvExtender()); 250e25c18da7d2cc3e02620dadfcb976521821bc9d8Adrian Roos SystemUI.overrideNotificationAppName(mContext, builder); 251b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey 2525e6c0ffd3e91cf0c5872de3e2d99e225ad1468f4Chris Wren mNotificationManager.notifyAsUser(disk.getId(), SystemMessage.NOTE_STORAGE_DISK, 2535e6c0ffd3e91cf0c5872de3e2d99e225ad1468f4Chris Wren builder.build(), UserHandle.ALL); 254b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey 255b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey } else { 256b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey // Yay, we have volumes! 2575e6c0ffd3e91cf0c5872de3e2d99e225ad1468f4Chris Wren mNotificationManager.cancelAsUser(disk.getId(), SystemMessage.NOTE_STORAGE_DISK, 2585e6c0ffd3e91cf0c5872de3e2d99e225ad1468f4Chris Wren UserHandle.ALL); 259a804d65f4aa31c7088e7f2150d96f1bf92e9c3beJohn Eckerdal } 260b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey } 261a804d65f4aa31c7088e7f2150d96f1bf92e9c3beJohn Eckerdal 26275b230b1d5abb1089173392f294f7fc5ce00e56cPhilip P. Moltmann /** 26375b230b1d5abb1089173392f294f7fc5ce00e56cPhilip P. Moltmann * Remove all notifications for a disk when it goes away. 26475b230b1d5abb1089173392f294f7fc5ce00e56cPhilip P. Moltmann * 26575b230b1d5abb1089173392f294f7fc5ce00e56cPhilip P. Moltmann * @param disk The disk that went away. 26675b230b1d5abb1089173392f294f7fc5ce00e56cPhilip P. Moltmann */ 26775b230b1d5abb1089173392f294f7fc5ce00e56cPhilip P. Moltmann private void onDiskDestroyedInternal(@NonNull DiskInfo disk) { 2685e6c0ffd3e91cf0c5872de3e2d99e225ad1468f4Chris Wren mNotificationManager.cancelAsUser(disk.getId(), SystemMessage.NOTE_STORAGE_DISK, 2695e6c0ffd3e91cf0c5872de3e2d99e225ad1468f4Chris Wren UserHandle.ALL); 27075b230b1d5abb1089173392f294f7fc5ce00e56cPhilip P. Moltmann } 27175b230b1d5abb1089173392f294f7fc5ce00e56cPhilip P. Moltmann 272b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey private void onVolumeStateChangedInternal(VolumeInfo vol) { 273b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey switch (vol.getType()) { 274b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey case VolumeInfo.TYPE_PRIVATE: 275b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey onPrivateVolumeStateChangedInternal(vol); 276b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey break; 277b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey case VolumeInfo.TYPE_PUBLIC: 278b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey onPublicVolumeStateChangedInternal(vol); 279b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey break; 280b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey } 281b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey } 282b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey 283b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey private void onPrivateVolumeStateChangedInternal(VolumeInfo vol) { 284b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey Log.d(TAG, "Notifying about private volume: " + vol.toString()); 285b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey 286b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey updateMissingPrivateVolumes(); 287b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey } 288b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey 289b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey private void onPublicVolumeStateChangedInternal(VolumeInfo vol) { 290b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey Log.d(TAG, "Notifying about public volume: " + vol.toString()); 29156bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey 292e6c04f9417cc4bff0f5f9e72f0d6d66d2aab6e80Jeff Sharkey final Notification notif; 293b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey switch (vol.getState()) { 29456bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey case VolumeInfo.STATE_UNMOUNTED: 295e6c04f9417cc4bff0f5f9e72f0d6d66d2aab6e80Jeff Sharkey notif = onVolumeUnmounted(vol); 29656bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey break; 2977e92ef3a1146102806fa0543ef12e09231c55639Jeff Sharkey case VolumeInfo.STATE_CHECKING: 298e6c04f9417cc4bff0f5f9e72f0d6d66d2aab6e80Jeff Sharkey notif = onVolumeChecking(vol); 29956bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey break; 30056bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey case VolumeInfo.STATE_MOUNTED: 30127de30d31c3e79bc429cb71aed9681c55243f18dJeff Sharkey case VolumeInfo.STATE_MOUNTED_READ_ONLY: 302e6c04f9417cc4bff0f5f9e72f0d6d66d2aab6e80Jeff Sharkey notif = onVolumeMounted(vol); 30356bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey break; 30456bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey case VolumeInfo.STATE_FORMATTING: 305e6c04f9417cc4bff0f5f9e72f0d6d66d2aab6e80Jeff Sharkey notif = onVolumeFormatting(vol); 30656bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey break; 3077e92ef3a1146102806fa0543ef12e09231c55639Jeff Sharkey case VolumeInfo.STATE_EJECTING: 308e6c04f9417cc4bff0f5f9e72f0d6d66d2aab6e80Jeff Sharkey notif = onVolumeEjecting(vol); 30956bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey break; 31056bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey case VolumeInfo.STATE_UNMOUNTABLE: 311e6c04f9417cc4bff0f5f9e72f0d6d66d2aab6e80Jeff Sharkey notif = onVolumeUnmountable(vol); 31256bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey break; 31356bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey case VolumeInfo.STATE_REMOVED: 314e6c04f9417cc4bff0f5f9e72f0d6d66d2aab6e80Jeff Sharkey notif = onVolumeRemoved(vol); 31556bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey break; 3167e92ef3a1146102806fa0543ef12e09231c55639Jeff Sharkey case VolumeInfo.STATE_BAD_REMOVAL: 317e6c04f9417cc4bff0f5f9e72f0d6d66d2aab6e80Jeff Sharkey notif = onVolumeBadRemoval(vol); 318e6c04f9417cc4bff0f5f9e72f0d6d66d2aab6e80Jeff Sharkey break; 319e6c04f9417cc4bff0f5f9e72f0d6d66d2aab6e80Jeff Sharkey default: 320e6c04f9417cc4bff0f5f9e72f0d6d66d2aab6e80Jeff Sharkey notif = null; 3217e92ef3a1146102806fa0543ef12e09231c55639Jeff Sharkey break; 32264e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat } 323e6c04f9417cc4bff0f5f9e72f0d6d66d2aab6e80Jeff Sharkey 324e6c04f9417cc4bff0f5f9e72f0d6d66d2aab6e80Jeff Sharkey if (notif != null) { 3255e6c0ffd3e91cf0c5872de3e2d99e225ad1468f4Chris Wren mNotificationManager.notifyAsUser(vol.getId(), SystemMessage.NOTE_STORAGE_PUBLIC, 3265e6c0ffd3e91cf0c5872de3e2d99e225ad1468f4Chris Wren notif, UserHandle.ALL); 327e6c04f9417cc4bff0f5f9e72f0d6d66d2aab6e80Jeff Sharkey } else { 3285e6c0ffd3e91cf0c5872de3e2d99e225ad1468f4Chris Wren mNotificationManager.cancelAsUser(vol.getId(), SystemMessage.NOTE_STORAGE_PUBLIC, 3295e6c0ffd3e91cf0c5872de3e2d99e225ad1468f4Chris Wren UserHandle.ALL); 330e6c04f9417cc4bff0f5f9e72f0d6d66d2aab6e80Jeff Sharkey } 33164e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat } 33264e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat 333e6c04f9417cc4bff0f5f9e72f0d6d66d2aab6e80Jeff Sharkey private Notification onVolumeUnmounted(VolumeInfo vol) { 33456bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey // Ignored 335e6c04f9417cc4bff0f5f9e72f0d6d66d2aab6e80Jeff Sharkey return null; 33656bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey } 33764e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat 338e6c04f9417cc4bff0f5f9e72f0d6d66d2aab6e80Jeff Sharkey private Notification onVolumeChecking(VolumeInfo vol) { 33927de30d31c3e79bc429cb71aed9681c55243f18dJeff Sharkey final DiskInfo disk = vol.getDisk(); 34056bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey final CharSequence title = mContext.getString( 34156bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey R.string.ext_media_checking_notification_title, disk.getDescription()); 34256bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey final CharSequence text = mContext.getString( 34356bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey R.string.ext_media_checking_notification_message, disk.getDescription()); 34456bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey 345e6c04f9417cc4bff0f5f9e72f0d6d66d2aab6e80Jeff Sharkey return buildNotificationBuilder(vol, title, text) 34656bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey .setCategory(Notification.CATEGORY_PROGRESS) 34756bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey .setOngoing(true) 34856bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey .build(); 34956bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey } 350209bede6b9edb9171e5bee4077b48e35004a37b4John Spurlock 351e6c04f9417cc4bff0f5f9e72f0d6d66d2aab6e80Jeff Sharkey private Notification onVolumeMounted(VolumeInfo vol) { 352b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey final VolumeRecord rec = mStorageManager.findRecordByUuid(vol.getFsUuid()); 353b138cb2c0df9e35d2f7683d529a67f8d8b64133cMakoto Onuki final DiskInfo disk = vol.getDisk(); 354b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey 355b138cb2c0df9e35d2f7683d529a67f8d8b64133cMakoto Onuki // Don't annoy when user dismissed in past. (But make sure the disk is adoptable; we 356b138cb2c0df9e35d2f7683d529a67f8d8b64133cMakoto Onuki // used to allow snoozing non-adoptable disks too.) 357b138cb2c0df9e35d2f7683d529a67f8d8b64133cMakoto Onuki if (rec.isSnoozed() && disk.isAdoptable()) { 358b138cb2c0df9e35d2f7683d529a67f8d8b64133cMakoto Onuki return null; 359b138cb2c0df9e35d2f7683d529a67f8d8b64133cMakoto Onuki } 360d95d3bfb2b28a4f21f3fdcd740160c9a61eb0363Jeff Sharkey 361b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey if (disk.isAdoptable() && !rec.isInited()) { 36256bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey final CharSequence title = disk.getDescription(); 36356bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey final CharSequence text = mContext.getString( 36456bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey R.string.ext_media_new_notification_message, disk.getDescription()); 36556bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey 36650a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey final PendingIntent initIntent = buildInitPendingIntent(vol); 367e6c04f9417cc4bff0f5f9e72f0d6d66d2aab6e80Jeff Sharkey return buildNotificationBuilder(vol, title, text) 368a49d5fc7677162689ffae85f8b95c57d83868bcfJeff Sharkey .addAction(new Action(R.drawable.ic_settings_24dp, 369a49d5fc7677162689ffae85f8b95c57d83868bcfJeff Sharkey mContext.getString(R.string.ext_media_init_action), initIntent)) 370a49d5fc7677162689ffae85f8b95c57d83868bcfJeff Sharkey .addAction(new Action(R.drawable.ic_eject_24dp, 371a49d5fc7677162689ffae85f8b95c57d83868bcfJeff Sharkey mContext.getString(R.string.ext_media_unmount_action), 37256bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey buildUnmountPendingIntent(vol))) 37350a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey .setContentIntent(initIntent) 37452fc3c0f73a9081609c3636dd1b393a0653a9d00Jeff Sharkey .setDeleteIntent(buildSnoozeIntent(vol.getFsUuid())) 37556bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey .build(); 376209bede6b9edb9171e5bee4077b48e35004a37b4John Spurlock 37764e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat } else { 37856bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey final CharSequence title = disk.getDescription(); 37956bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey final CharSequence text = mContext.getString( 38056bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey R.string.ext_media_ready_notification_message, disk.getDescription()); 38156bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey 38250a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey final PendingIntent browseIntent = buildBrowsePendingIntent(vol); 383b138cb2c0df9e35d2f7683d529a67f8d8b64133cMakoto Onuki final Notification.Builder builder = buildNotificationBuilder(vol, title, text) 384a49d5fc7677162689ffae85f8b95c57d83868bcfJeff Sharkey .addAction(new Action(R.drawable.ic_folder_24dp, 385a49d5fc7677162689ffae85f8b95c57d83868bcfJeff Sharkey mContext.getString(R.string.ext_media_browse_action), 38650a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey browseIntent)) 387a49d5fc7677162689ffae85f8b95c57d83868bcfJeff Sharkey .addAction(new Action(R.drawable.ic_eject_24dp, 388a49d5fc7677162689ffae85f8b95c57d83868bcfJeff Sharkey mContext.getString(R.string.ext_media_unmount_action), 38956bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey buildUnmountPendingIntent(vol))) 390b2653e69708eda88d796cc32489e5e2283a13508Dmitri Plotnikov .setContentIntent(browseIntent) 3918e032e15e6b1b6a2f44fd3d5063ee83f45d71189Dan Sandler .setCategory(Notification.CATEGORY_SYSTEM); 392b138cb2c0df9e35d2f7683d529a67f8d8b64133cMakoto Onuki // Non-adoptable disks can't be snoozed. 393b138cb2c0df9e35d2f7683d529a67f8d8b64133cMakoto Onuki if (disk.isAdoptable()) { 394b138cb2c0df9e35d2f7683d529a67f8d8b64133cMakoto Onuki builder.setDeleteIntent(buildSnoozeIntent(vol.getFsUuid())); 395b138cb2c0df9e35d2f7683d529a67f8d8b64133cMakoto Onuki } 396b138cb2c0df9e35d2f7683d529a67f8d8b64133cMakoto Onuki 397b138cb2c0df9e35d2f7683d529a67f8d8b64133cMakoto Onuki return builder.build(); 39864e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat } 39964e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat } 40064e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat 401e6c04f9417cc4bff0f5f9e72f0d6d66d2aab6e80Jeff Sharkey private Notification onVolumeFormatting(VolumeInfo vol) { 40256bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey // Ignored 403e6c04f9417cc4bff0f5f9e72f0d6d66d2aab6e80Jeff Sharkey return null; 40456bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey } 40564e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat 406e6c04f9417cc4bff0f5f9e72f0d6d66d2aab6e80Jeff Sharkey private Notification onVolumeEjecting(VolumeInfo vol) { 40727de30d31c3e79bc429cb71aed9681c55243f18dJeff Sharkey final DiskInfo disk = vol.getDisk(); 40856bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey final CharSequence title = mContext.getString( 40956bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey R.string.ext_media_unmounting_notification_title, disk.getDescription()); 41056bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey final CharSequence text = mContext.getString( 41156bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey R.string.ext_media_unmounting_notification_message, disk.getDescription()); 41256bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey 413e6c04f9417cc4bff0f5f9e72f0d6d66d2aab6e80Jeff Sharkey return buildNotificationBuilder(vol, title, text) 41456bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey .setCategory(Notification.CATEGORY_PROGRESS) 41556bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey .setOngoing(true) 41656bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey .build(); 41764e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat } 41864e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat 419e6c04f9417cc4bff0f5f9e72f0d6d66d2aab6e80Jeff Sharkey private Notification onVolumeUnmountable(VolumeInfo vol) { 42027de30d31c3e79bc429cb71aed9681c55243f18dJeff Sharkey final DiskInfo disk = vol.getDisk(); 42156bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey final CharSequence title = mContext.getString( 42256bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey R.string.ext_media_unmountable_notification_title, disk.getDescription()); 42356bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey final CharSequence text = mContext.getString( 42456bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey R.string.ext_media_unmountable_notification_message, disk.getDescription()); 42564e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat 426e6c04f9417cc4bff0f5f9e72f0d6d66d2aab6e80Jeff Sharkey return buildNotificationBuilder(vol, title, text) 42752fc3c0f73a9081609c3636dd1b393a0653a9d00Jeff Sharkey .setContentIntent(buildInitPendingIntent(vol)) 42856bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey .setCategory(Notification.CATEGORY_ERROR) 42956bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey .build(); 43056bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey } 43164e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat 432e6c04f9417cc4bff0f5f9e72f0d6d66d2aab6e80Jeff Sharkey private Notification onVolumeRemoved(VolumeInfo vol) { 43356bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey if (!vol.isPrimary()) { 43456bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey // Ignore non-primary media 435e6c04f9417cc4bff0f5f9e72f0d6d66d2aab6e80Jeff Sharkey return null; 43664e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat } 43764e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat 43827de30d31c3e79bc429cb71aed9681c55243f18dJeff Sharkey final DiskInfo disk = vol.getDisk(); 43956bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey final CharSequence title = mContext.getString( 44056bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey R.string.ext_media_nomedia_notification_title, disk.getDescription()); 44156bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey final CharSequence text = mContext.getString( 44256bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey R.string.ext_media_nomedia_notification_message, disk.getDescription()); 443209bede6b9edb9171e5bee4077b48e35004a37b4John Spurlock 444e6c04f9417cc4bff0f5f9e72f0d6d66d2aab6e80Jeff Sharkey return buildNotificationBuilder(vol, title, text) 4457e92ef3a1146102806fa0543ef12e09231c55639Jeff Sharkey .setCategory(Notification.CATEGORY_ERROR) 4467e92ef3a1146102806fa0543ef12e09231c55639Jeff Sharkey .build(); 4477e92ef3a1146102806fa0543ef12e09231c55639Jeff Sharkey } 4487e92ef3a1146102806fa0543ef12e09231c55639Jeff Sharkey 449e6c04f9417cc4bff0f5f9e72f0d6d66d2aab6e80Jeff Sharkey private Notification onVolumeBadRemoval(VolumeInfo vol) { 4507e92ef3a1146102806fa0543ef12e09231c55639Jeff Sharkey if (!vol.isPrimary()) { 4517e92ef3a1146102806fa0543ef12e09231c55639Jeff Sharkey // Ignore non-primary media 452e6c04f9417cc4bff0f5f9e72f0d6d66d2aab6e80Jeff Sharkey return null; 4537e92ef3a1146102806fa0543ef12e09231c55639Jeff Sharkey } 4547e92ef3a1146102806fa0543ef12e09231c55639Jeff Sharkey 45527de30d31c3e79bc429cb71aed9681c55243f18dJeff Sharkey final DiskInfo disk = vol.getDisk(); 4567e92ef3a1146102806fa0543ef12e09231c55639Jeff Sharkey final CharSequence title = mContext.getString( 4577e92ef3a1146102806fa0543ef12e09231c55639Jeff Sharkey R.string.ext_media_badremoval_notification_title, disk.getDescription()); 4587e92ef3a1146102806fa0543ef12e09231c55639Jeff Sharkey final CharSequence text = mContext.getString( 4597e92ef3a1146102806fa0543ef12e09231c55639Jeff Sharkey R.string.ext_media_badremoval_notification_message, disk.getDescription()); 4607e92ef3a1146102806fa0543ef12e09231c55639Jeff Sharkey 461e6c04f9417cc4bff0f5f9e72f0d6d66d2aab6e80Jeff Sharkey return buildNotificationBuilder(vol, title, text) 46256bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey .setCategory(Notification.CATEGORY_ERROR) 46356bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey .build(); 464e6c04f9417cc4bff0f5f9e72f0d6d66d2aab6e80Jeff Sharkey } 465209bede6b9edb9171e5bee4077b48e35004a37b4John Spurlock 46650a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey private void onMoveProgress(MoveInfo move, int status, long estMillis) { 467b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey final CharSequence title; 46850a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey if (!TextUtils.isEmpty(move.label)) { 46950a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey title = mContext.getString(R.string.ext_media_move_specific_title, move.label); 470b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey } else { 471b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey title = mContext.getString(R.string.ext_media_move_title); 472b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey } 473b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey 474b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey final CharSequence text; 475b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey if (estMillis < 0) { 476b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey text = null; 477b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey } else { 478b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey text = DateUtils.formatDuration(estMillis); 479b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey } 480b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey 48150a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey final PendingIntent intent; 48250a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey if (move.packageName != null) { 48350a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey intent = buildWizardMovePendingIntent(move); 48450a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey } else { 48550a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey intent = buildWizardMigratePendingIntent(move); 48650a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey } 48750a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey 4881dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch Notification.Builder builder = 4891dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch new Notification.Builder(mContext, NotificationChannels.STORAGE) 4901dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch .setSmallIcon(R.drawable.ic_sd_card_48dp) 4911dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch .setColor(mContext.getColor(R.color.system_notification_accent_color)) 4921dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch .setContentTitle(title) 4931dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch .setContentText(text) 4941dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch .setContentIntent(intent) 4951dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch .setStyle(new Notification.BigTextStyle().bigText(text)) 4961dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch .setVisibility(Notification.VISIBILITY_PUBLIC) 4971dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch .setLocalOnly(true) 4981dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch .setCategory(Notification.CATEGORY_PROGRESS) 4991dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch .setProgress(100, status, false) 5001dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch .setOngoing(true); 501e25c18da7d2cc3e02620dadfcb976521821bc9d8Adrian Roos SystemUI.overrideNotificationAppName(mContext, builder); 502b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey 5035e6c0ffd3e91cf0c5872de3e2d99e225ad1468f4Chris Wren mNotificationManager.notifyAsUser(move.packageName, SystemMessage.NOTE_STORAGE_MOVE, 504e25c18da7d2cc3e02620dadfcb976521821bc9d8Adrian Roos builder.build(), UserHandle.ALL); 505b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey } 506b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey 50750a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey private void onMoveFinished(MoveInfo move, int status) { 50850a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey if (move.packageName != null) { 509b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey // We currently ignore finished app moves; just clear the last 510b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey // published progress 5115e6c0ffd3e91cf0c5872de3e2d99e225ad1468f4Chris Wren mNotificationManager.cancelAsUser(move.packageName, SystemMessage.NOTE_STORAGE_MOVE, 5125e6c0ffd3e91cf0c5872de3e2d99e225ad1468f4Chris Wren UserHandle.ALL); 513b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey return; 514b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey } 515b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey 51650a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey final VolumeInfo privateVol = mContext.getPackageManager().getPrimaryStorageCurrentVolume(); 51750a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey final String descrip = mStorageManager.getBestVolumeDescription(privateVol); 518b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey 519b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey final CharSequence title; 520b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey final CharSequence text; 521b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey if (status == PackageManager.MOVE_SUCCEEDED) { 522b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey title = mContext.getString(R.string.ext_media_move_success_title); 523b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey text = mContext.getString(R.string.ext_media_move_success_message, descrip); 524b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey } else { 525b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey title = mContext.getString(R.string.ext_media_move_failure_title); 526b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey text = mContext.getString(R.string.ext_media_move_failure_message); 527b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey } 528b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey 52950a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey // Jump back into the wizard flow if we moved to a real disk 53050a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey final PendingIntent intent; 53150a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey if (privateVol != null && privateVol.getDisk() != null) { 53250a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey intent = buildWizardReadyPendingIntent(privateVol.getDisk()); 533ef10ee014594d800f5f5ca31ea93f1cab2880d05Jeff Sharkey } else if (privateVol != null) { 53450a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey intent = buildVolumeSettingsPendingIntent(privateVol); 535ef10ee014594d800f5f5ca31ea93f1cab2880d05Jeff Sharkey } else { 536ef10ee014594d800f5f5ca31ea93f1cab2880d05Jeff Sharkey intent = null; 53750a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey } 53850a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey 5391dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch Notification.Builder builder = 5401dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch new Notification.Builder(mContext, NotificationChannels.STORAGE) 5411dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch .setSmallIcon(R.drawable.ic_sd_card_48dp) 5421dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch .setColor(mContext.getColor(R.color.system_notification_accent_color)) 5431dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch .setContentTitle(title) 5441dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch .setContentText(text) 5451dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch .setContentIntent(intent) 5461dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch .setStyle(new Notification.BigTextStyle().bigText(text)) 5471dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch .setVisibility(Notification.VISIBILITY_PUBLIC) 5481dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch .setLocalOnly(true) 5491dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch .setCategory(Notification.CATEGORY_SYSTEM) 5501dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch .setAutoCancel(true); 551e25c18da7d2cc3e02620dadfcb976521821bc9d8Adrian Roos SystemUI.overrideNotificationAppName(mContext, builder); 552b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey 5535e6c0ffd3e91cf0c5872de3e2d99e225ad1468f4Chris Wren mNotificationManager.notifyAsUser(move.packageName, SystemMessage.NOTE_STORAGE_MOVE, 5545e6c0ffd3e91cf0c5872de3e2d99e225ad1468f4Chris Wren builder.build(), UserHandle.ALL); 555b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey } 556b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey 557b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey private int getSmallIcon(DiskInfo disk, int state) { 558b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey if (disk.isSd()) { 559b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey switch (state) { 560e6c04f9417cc4bff0f5f9e72f0d6d66d2aab6e80Jeff Sharkey case VolumeInfo.STATE_CHECKING: 561e6c04f9417cc4bff0f5f9e72f0d6d66d2aab6e80Jeff Sharkey case VolumeInfo.STATE_EJECTING: 562a49d5fc7677162689ffae85f8b95c57d83868bcfJeff Sharkey return R.drawable.ic_sd_card_48dp; 563e6c04f9417cc4bff0f5f9e72f0d6d66d2aab6e80Jeff Sharkey default: 564a49d5fc7677162689ffae85f8b95c57d83868bcfJeff Sharkey return R.drawable.ic_sd_card_48dp; 565e6c04f9417cc4bff0f5f9e72f0d6d66d2aab6e80Jeff Sharkey } 566b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey } else if (disk.isUsb()) { 567a49d5fc7677162689ffae85f8b95c57d83868bcfJeff Sharkey return R.drawable.ic_usb_48dp; 568e6c04f9417cc4bff0f5f9e72f0d6d66d2aab6e80Jeff Sharkey } else { 569a49d5fc7677162689ffae85f8b95c57d83868bcfJeff Sharkey return R.drawable.ic_sd_card_48dp; 570e6c04f9417cc4bff0f5f9e72f0d6d66d2aab6e80Jeff Sharkey } 57156bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey } 57256bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey 573e6c04f9417cc4bff0f5f9e72f0d6d66d2aab6e80Jeff Sharkey private Notification.Builder buildNotificationBuilder(VolumeInfo vol, CharSequence title, 574e6c04f9417cc4bff0f5f9e72f0d6d66d2aab6e80Jeff Sharkey CharSequence text) { 5751dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch Notification.Builder builder = 5761dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch new Notification.Builder(mContext, NotificationChannels.STORAGE) 5771dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch .setSmallIcon(getSmallIcon(vol.getDisk(), vol.getState())) 5781dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch .setColor(mContext.getColor(R.color.system_notification_accent_color)) 5791dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch .setContentTitle(title) 5801dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch .setContentText(text) 5811dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch .setStyle(new Notification.BigTextStyle().bigText(text)) 5821dc93bc407540561ebba1cc007073ab9c71d7a4eGeoffrey Pitsch .setVisibility(Notification.VISIBILITY_PUBLIC) 583519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov .setLocalOnly(true) 584519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov .extend(new Notification.TvExtender()); 585e25c18da7d2cc3e02620dadfcb976521821bc9d8Adrian Roos overrideNotificationAppName(mContext, builder); 586e25c18da7d2cc3e02620dadfcb976521821bc9d8Adrian Roos return builder; 58756bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey } 58856bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey 589b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey private PendingIntent buildInitPendingIntent(DiskInfo disk) { 590b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey final Intent intent = new Intent(); 591519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov if (isTv()) { 592519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov intent.setPackage("com.android.tv.settings"); 593519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov intent.setAction("com.android.tv.settings.action.NEW_STORAGE"); 594519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov } else { 595519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov intent.setClassName("com.android.settings", 596519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov "com.android.settings.deviceinfo.StorageWizardInit"); 597519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov } 598b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey intent.putExtra(DiskInfo.EXTRA_DISK_ID, disk.getId()); 599b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey 600b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey final int requestKey = disk.getId().hashCode(); 601b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey return PendingIntent.getActivityAsUser(mContext, requestKey, intent, 602b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT); 603b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey } 604b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey 60556bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey private PendingIntent buildInitPendingIntent(VolumeInfo vol) { 60656bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey final Intent intent = new Intent(); 607519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov if (isTv()) { 608519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov intent.setPackage("com.android.tv.settings"); 609519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov intent.setAction("com.android.tv.settings.action.NEW_STORAGE"); 610519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov } else { 611519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov intent.setClassName("com.android.settings", 612519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov "com.android.settings.deviceinfo.StorageWizardInit"); 613519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov } 614d95d3bfb2b28a4f21f3fdcd740160c9a61eb0363Jeff Sharkey intent.putExtra(VolumeInfo.EXTRA_VOLUME_ID, vol.getId()); 615d95d3bfb2b28a4f21f3fdcd740160c9a61eb0363Jeff Sharkey 616d95d3bfb2b28a4f21f3fdcd740160c9a61eb0363Jeff Sharkey final int requestKey = vol.getId().hashCode(); 617d95d3bfb2b28a4f21f3fdcd740160c9a61eb0363Jeff Sharkey return PendingIntent.getActivityAsUser(mContext, requestKey, intent, 618d95d3bfb2b28a4f21f3fdcd740160c9a61eb0363Jeff Sharkey PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT); 61956bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey } 62056bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey 62156bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey private PendingIntent buildUnmountPendingIntent(VolumeInfo vol) { 62256bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey final Intent intent = new Intent(); 623519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov if (isTv()) { 624519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov intent.setPackage("com.android.tv.settings"); 625519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov intent.setAction("com.android.tv.settings.action.UNMOUNT_STORAGE"); 626519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov intent.putExtra(VolumeInfo.EXTRA_VOLUME_ID, vol.getId()); 627d95d3bfb2b28a4f21f3fdcd740160c9a61eb0363Jeff Sharkey 628519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov final int requestKey = vol.getId().hashCode(); 629519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov return PendingIntent.getActivityAsUser(mContext, requestKey, intent, 630519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT); 631519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov } else { 632519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov intent.setClassName("com.android.settings", 633519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov "com.android.settings.deviceinfo.StorageUnmountReceiver"); 634519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov intent.putExtra(VolumeInfo.EXTRA_VOLUME_ID, vol.getId()); 635519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov 636519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov final int requestKey = vol.getId().hashCode(); 637519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov return PendingIntent.getBroadcastAsUser(mContext, requestKey, intent, 638519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov PendingIntent.FLAG_CANCEL_CURRENT, UserHandle.CURRENT); 639519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov } 64056bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey } 64156bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey 64256bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey private PendingIntent buildBrowsePendingIntent(VolumeInfo vol) { 64356bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey final Intent intent = vol.buildBrowseIntent(); 644d95d3bfb2b28a4f21f3fdcd740160c9a61eb0363Jeff Sharkey 645d95d3bfb2b28a4f21f3fdcd740160c9a61eb0363Jeff Sharkey final int requestKey = vol.getId().hashCode(); 646d95d3bfb2b28a4f21f3fdcd740160c9a61eb0363Jeff Sharkey return PendingIntent.getActivityAsUser(mContext, requestKey, intent, 647d95d3bfb2b28a4f21f3fdcd740160c9a61eb0363Jeff Sharkey PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT); 64856bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey } 64956bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey 65050a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey private PendingIntent buildVolumeSettingsPendingIntent(VolumeInfo vol) { 65156bd3129138b525b0f2eba52bd4fa140f23e792cJeff Sharkey final Intent intent = new Intent(); 652519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov if (isTv()) { 653519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov intent.setPackage("com.android.tv.settings"); 654519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov intent.setAction(Settings.ACTION_INTERNAL_STORAGE_SETTINGS); 655519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov } else { 656519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov switch (vol.getType()) { 657519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov case VolumeInfo.TYPE_PRIVATE: 658519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov intent.setClassName("com.android.settings", 659519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov "com.android.settings.Settings$PrivateVolumeSettingsActivity"); 660519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov break; 661519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov case VolumeInfo.TYPE_PUBLIC: 662519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov intent.setClassName("com.android.settings", 663519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov "com.android.settings.Settings$PublicVolumeSettingsActivity"); 664519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov break; 665519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov default: 666519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov return null; 667519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov } 66850a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey } 669d95d3bfb2b28a4f21f3fdcd740160c9a61eb0363Jeff Sharkey intent.putExtra(VolumeInfo.EXTRA_VOLUME_ID, vol.getId()); 670d95d3bfb2b28a4f21f3fdcd740160c9a61eb0363Jeff Sharkey 671d95d3bfb2b28a4f21f3fdcd740160c9a61eb0363Jeff Sharkey final int requestKey = vol.getId().hashCode(); 672d95d3bfb2b28a4f21f3fdcd740160c9a61eb0363Jeff Sharkey return PendingIntent.getActivityAsUser(mContext, requestKey, intent, 673d95d3bfb2b28a4f21f3fdcd740160c9a61eb0363Jeff Sharkey PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT); 674d95d3bfb2b28a4f21f3fdcd740160c9a61eb0363Jeff Sharkey } 675d95d3bfb2b28a4f21f3fdcd740160c9a61eb0363Jeff Sharkey 67652fc3c0f73a9081609c3636dd1b393a0653a9d00Jeff Sharkey private PendingIntent buildSnoozeIntent(String fsUuid) { 677d95d3bfb2b28a4f21f3fdcd740160c9a61eb0363Jeff Sharkey final Intent intent = new Intent(ACTION_SNOOZE_VOLUME); 67852fc3c0f73a9081609c3636dd1b393a0653a9d00Jeff Sharkey intent.putExtra(VolumeRecord.EXTRA_FS_UUID, fsUuid); 679d95d3bfb2b28a4f21f3fdcd740160c9a61eb0363Jeff Sharkey 68052fc3c0f73a9081609c3636dd1b393a0653a9d00Jeff Sharkey final int requestKey = fsUuid.hashCode(); 681d95d3bfb2b28a4f21f3fdcd740160c9a61eb0363Jeff Sharkey return PendingIntent.getBroadcastAsUser(mContext, requestKey, intent, 682d95d3bfb2b28a4f21f3fdcd740160c9a61eb0363Jeff Sharkey PendingIntent.FLAG_CANCEL_CURRENT, UserHandle.CURRENT); 68364e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat } 684b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey 685b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey private PendingIntent buildForgetPendingIntent(VolumeRecord rec) { 686519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov // Not used on TV 687b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey final Intent intent = new Intent(); 688b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey intent.setClassName("com.android.settings", 689b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey "com.android.settings.Settings$PrivateVolumeForgetActivity"); 690b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey intent.putExtra(VolumeRecord.EXTRA_FS_UUID, rec.getFsUuid()); 691b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey 692b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey final int requestKey = rec.getFsUuid().hashCode(); 693b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey return PendingIntent.getActivityAsUser(mContext, requestKey, intent, 694b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT); 695b36586a7c9b7718f33961406537e27bbd9b16211Jeff Sharkey } 69650a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey 69750a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey private PendingIntent buildWizardMigratePendingIntent(MoveInfo move) { 69850a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey final Intent intent = new Intent(); 699519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov if (isTv()) { 700519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov intent.setPackage("com.android.tv.settings"); 701519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov intent.setAction("com.android.tv.settings.action.MIGRATE_STORAGE"); 702519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov } else { 703519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov intent.setClassName("com.android.settings", 704519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov "com.android.settings.deviceinfo.StorageWizardMigrateProgress"); 705519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov } 70650a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey intent.putExtra(PackageManager.EXTRA_MOVE_ID, move.moveId); 70750a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey 70850a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey final VolumeInfo vol = mStorageManager.findVolumeByQualifiedUuid(move.volumeUuid); 709af6c41957462a1ef7c59bd77f4a771f097421227Suprabh Shukla if (vol != null) { 710af6c41957462a1ef7c59bd77f4a771f097421227Suprabh Shukla intent.putExtra(VolumeInfo.EXTRA_VOLUME_ID, vol.getId()); 711af6c41957462a1ef7c59bd77f4a771f097421227Suprabh Shukla } 71250a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey return PendingIntent.getActivityAsUser(mContext, move.moveId, intent, 71350a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT); 71450a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey } 71550a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey 71650a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey private PendingIntent buildWizardMovePendingIntent(MoveInfo move) { 71750a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey final Intent intent = new Intent(); 718519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov if (isTv()) { 719519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov intent.setPackage("com.android.tv.settings"); 720519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov intent.setAction("com.android.tv.settings.action.MOVE_APP"); 721519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov } else { 722519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov intent.setClassName("com.android.settings", 723519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov "com.android.settings.deviceinfo.StorageWizardMoveProgress"); 724519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov } 72550a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey intent.putExtra(PackageManager.EXTRA_MOVE_ID, move.moveId); 72650a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey 72750a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey return PendingIntent.getActivityAsUser(mContext, move.moveId, intent, 72850a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT); 72950a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey } 73050a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey 73150a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey private PendingIntent buildWizardReadyPendingIntent(DiskInfo disk) { 73250a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey final Intent intent = new Intent(); 733519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov if (isTv()) { 734519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov intent.setPackage("com.android.tv.settings"); 735519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov intent.setAction(Settings.ACTION_INTERNAL_STORAGE_SETTINGS); 736519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov } else { 737519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov intent.setClassName("com.android.settings", 738519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov "com.android.settings.deviceinfo.StorageWizardReady"); 739519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov } 74050a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey intent.putExtra(DiskInfo.EXTRA_DISK_ID, disk.getId()); 74150a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey 74250a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey final int requestKey = disk.getId().hashCode(); 74350a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey return PendingIntent.getActivityAsUser(mContext, requestKey, intent, 74450a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT); 74550a05454795c93ac483f5cb6819e74cb17be1b5bJeff Sharkey } 746519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov 747519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov private boolean isTv() { 748519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov PackageManager packageManager = mContext.getPackageManager(); 749519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov return packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK); 750519c088e65637069a4f37b7c2cfa09e9cc93ec71Dmitri Plotnikov } 75164e6a45ed45e0d096a1490408ee1cab2a4626950San Mehat} 752