Wire up non-visible volumes, more states.

Adds logic to ExternalStorageProvider to scan non-visible volumes,
such as USB OTG devices.  We use internal paths when surfacing these
volumes, which also optimizes around the FUSE daemon for public
devices.  Also dumps internal state when requested.

VolumeInfo now directly contains DiskInfo, which means it's
snapshotted when sending events, avoiding teardown races.  Switch
notifications to use this DiskInfo directly.

Finish wiring up new volume state, including helper methods to make
it readable/writable state clearer.  Handle disks and volumes with
spaces in their labels.

Bug: 19993667
Change-Id: I5c75e5658a6415976811477aebafee7694bde0f4
diff --git a/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
index 4a441c7..ecd1a2f 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
@@ -60,7 +60,7 @@
             // Avoid kicking notifications when getting early metadata before
             // mounted. If already mounted, we're being kicked because of a
             // nickname or init'ed change.
-            if (vol.getState() == VolumeInfo.STATE_MOUNTED) {
+            if (vol.isMountedReadable()) {
                 onVolumeStateChangedInternal(vol, vol.getState(), vol.getState());
             }
         }
@@ -111,6 +111,7 @@
                 onVolumeChecking(vol);
                 break;
             case VolumeInfo.STATE_MOUNTED:
+            case VolumeInfo.STATE_MOUNTED_READ_ONLY:
                 onVolumeMounted(vol);
                 break;
             case VolumeInfo.STATE_FORMATTING:
@@ -136,7 +137,7 @@
     }
 
     private void onVolumeChecking(VolumeInfo vol) {
-        final DiskInfo disk = mStorageManager.findDiskById(vol.getDiskId());
+        final DiskInfo disk = vol.getDisk();
         final CharSequence title = mContext.getString(
                 R.string.ext_media_checking_notification_title, disk.getDescription());
         final CharSequence text = mContext.getString(
@@ -156,7 +157,7 @@
         // Don't annoy when user dismissed in past
         if (vol.isSnoozed()) return;
 
-        final DiskInfo disk = mStorageManager.findDiskById(vol.getDiskId());
+        final DiskInfo disk = vol.getDisk();
         final Notification notif;
         if (disk.isAdoptable() && !vol.isInited()) {
             final CharSequence title = disk.getDescription();
@@ -198,7 +199,7 @@
     }
 
     private void onVolumeEjecting(VolumeInfo vol) {
-        final DiskInfo disk = mStorageManager.findDiskById(vol.getDiskId());
+        final DiskInfo disk = vol.getDisk();
         final CharSequence title = mContext.getString(
                 R.string.ext_media_unmounting_notification_title, disk.getDescription());
         final CharSequence text = mContext.getString(
@@ -215,7 +216,7 @@
     }
 
     private void onVolumeUnmountable(VolumeInfo vol) {
-        final DiskInfo disk = mStorageManager.findDiskById(vol.getDiskId());
+        final DiskInfo disk = vol.getDisk();
         final CharSequence title = mContext.getString(
                 R.string.ext_media_unmountable_notification_title, disk.getDescription());
         final CharSequence text = mContext.getString(
@@ -236,7 +237,7 @@
             return;
         }
 
-        final DiskInfo disk = mStorageManager.findDiskById(vol.getDiskId());
+        final DiskInfo disk = vol.getDisk();
         final CharSequence title = mContext.getString(
                 R.string.ext_media_nomedia_notification_title, disk.getDescription());
         final CharSequence text = mContext.getString(
@@ -256,7 +257,7 @@
             return;
         }
 
-        final DiskInfo disk = mStorageManager.findDiskById(vol.getDiskId());
+        final DiskInfo disk = vol.getDisk();
         final CharSequence title = mContext.getString(
                 R.string.ext_media_badremoval_notification_title, disk.getDescription());
         final CharSequence text = mContext.getString(