Volumes know parent disks; unsupported disks.

This is cleaner and more direct than the reverse of having the disk
publish child volume membership.  Rename state constants to match
public API.  Add state representing bad removal.  Make it clear that
volume flags are related to mounting.

Send new unsupported disk event when we finish scanning an entire
disk and have no meaningful volumes.

Splice disk labels into description when known.  Only adoptable
slots are directly visible to apps.

Bug: 19993667
Change-Id: I12fda95be0d82781f70c3d85c039749052dc936b
diff --git a/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
index 818f5ee..4a441c7 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
@@ -107,8 +107,8 @@
             case VolumeInfo.STATE_UNMOUNTED:
                 onVolumeUnmounted(vol);
                 break;
-            case VolumeInfo.STATE_MOUNTING:
-                onVolumeMounting(vol);
+            case VolumeInfo.STATE_CHECKING:
+                onVolumeChecking(vol);
                 break;
             case VolumeInfo.STATE_MOUNTED:
                 onVolumeMounted(vol);
@@ -116,8 +116,8 @@
             case VolumeInfo.STATE_FORMATTING:
                 onVolumeFormatting(vol);
                 break;
-            case VolumeInfo.STATE_UNMOUNTING:
-                onVolumeUnmounting(vol);
+            case VolumeInfo.STATE_EJECTING:
+                onVolumeEjecting(vol);
                 break;
             case VolumeInfo.STATE_UNMOUNTABLE:
                 onVolumeUnmountable(vol);
@@ -125,6 +125,9 @@
             case VolumeInfo.STATE_REMOVED:
                 onVolumeRemoved(vol);
                 break;
+            case VolumeInfo.STATE_BAD_REMOVAL:
+                onVolumeBadRemoval(vol);
+                break;
         }
     }
 
@@ -132,7 +135,7 @@
         // Ignored
     }
 
-    private void onVolumeMounting(VolumeInfo vol) {
+    private void onVolumeChecking(VolumeInfo vol) {
         final DiskInfo disk = mStorageManager.findDiskById(vol.getDiskId());
         final CharSequence title = mContext.getString(
                 R.string.ext_media_checking_notification_title, disk.getDescription());
@@ -194,7 +197,7 @@
         // Ignored
     }
 
-    private void onVolumeUnmounting(VolumeInfo vol) {
+    private void onVolumeEjecting(VolumeInfo vol) {
         final DiskInfo disk = mStorageManager.findDiskById(vol.getDiskId());
         final CharSequence title = mContext.getString(
                 R.string.ext_media_unmounting_notification_title, disk.getDescription());
@@ -247,6 +250,26 @@
         mNotificationManager.notifyAsUser(vol.getId(), NOTIF_ID, notif, UserHandle.ALL);
     }
 
+    private void onVolumeBadRemoval(VolumeInfo vol) {
+        if (!vol.isPrimary()) {
+            // Ignore non-primary media
+            return;
+        }
+
+        final DiskInfo disk = mStorageManager.findDiskById(vol.getDiskId());
+        final CharSequence title = mContext.getString(
+                R.string.ext_media_badremoval_notification_title, disk.getDescription());
+        final CharSequence text = mContext.getString(
+                R.string.ext_media_badremoval_notification_message, disk.getDescription());
+
+        final Notification notif = buildNotificationBuilder(title, text)
+                .setSmallIcon(R.drawable.stat_notify_sdcard)
+                .setCategory(Notification.CATEGORY_ERROR)
+                .build();
+
+        mNotificationManager.notifyAsUser(vol.getId(), NOTIF_ID, notif, UserHandle.ALL);
+    }
+
     private Notification.Builder buildNotificationBuilder(CharSequence title, CharSequence text) {
         return new Notification.Builder(mContext)
                 .setColor(mContext.getColor(R.color.system_notification_accent_color))