Show USB flash drive in storage spinner when it's unmounted

Before this change, USB flash drive is removed from storage spinner
when it's unmounted (by option menu 'Eject'), however, USB flash
drive will show in storage spinner when Storage Settings page is
resumed again.

After this change, USB flash drive will show in storage spinner
even if it's unmounted. It will be removed until it's unplugged
from device.

Bug: 225095144
Test: manual visual
      Insert / Eject / Mount / unplug an USB flash drive and
      observe UI behavior.
Change-Id: I6b81766216c7850b018997f2de12a19d9d8675be
diff --git a/src/com/android/settings/dashboard/profileselector/ProfileSelectStorageFragment.java b/src/com/android/settings/dashboard/profileselector/ProfileSelectStorageFragment.java
index 57988c5..1473dd1 100644
--- a/src/com/android/settings/dashboard/profileselector/ProfileSelectStorageFragment.java
+++ b/src/com/android/settings/dashboard/profileselector/ProfileSelectStorageFragment.java
@@ -84,10 +84,19 @@
             }
 
             final StorageEntry changedStorageEntry = new StorageEntry(getContext(), volumeInfo);
-            switch (volumeInfo.getState()) {
+            final int volumeState = volumeInfo.getState();
+            switch (volumeState) {
+                case VolumeInfo.STATE_REMOVED:
+                case VolumeInfo.STATE_BAD_REMOVAL:
+                    // Remove removed storage from list and don't show it on spinner.
+                    if (!mStorageEntries.remove(changedStorageEntry)) {
+                        break;
+                    }
                 case VolumeInfo.STATE_MOUNTED:
                 case VolumeInfo.STATE_MOUNTED_READ_ONLY:
                 case VolumeInfo.STATE_UNMOUNTABLE:
+                case VolumeInfo.STATE_UNMOUNTED:
+                case VolumeInfo.STATE_EJECTING:
                     // Add mounted or unmountable storage in the list and show it on spinner.
                     // Unmountable storages are the storages which has a problem format and android
                     // is not able to mount it automatically.
@@ -95,25 +104,15 @@
                     mStorageEntries.removeIf(storageEntry -> {
                         return storageEntry.equals(changedStorageEntry);
                     });
-                    mStorageEntries.add(changedStorageEntry);
+                    if (volumeState != VolumeInfo.STATE_REMOVED
+                            && volumeState != VolumeInfo.STATE_BAD_REMOVAL) {
+                        mStorageEntries.add(changedStorageEntry);
+                    }
                     if (changedStorageEntry.equals(mSelectedStorageEntry)) {
                         mSelectedStorageEntry = changedStorageEntry;
                     }
                     refreshUi();
                     break;
-                case VolumeInfo.STATE_REMOVED:
-                case VolumeInfo.STATE_UNMOUNTED:
-                case VolumeInfo.STATE_BAD_REMOVAL:
-                case VolumeInfo.STATE_EJECTING:
-                    // Remove removed storage from list and don't show it on spinner.
-                    if (mStorageEntries.remove(changedStorageEntry)) {
-                        if (changedStorageEntry.equals(mSelectedStorageEntry)) {
-                            mSelectedStorageEntry =
-                                    StorageEntry.getDefaultInternalStorageEntry(getContext());
-                        }
-                        refreshUi();
-                    }
-                    break;
                 default:
                     // Do nothing.
             }
diff --git a/src/com/android/settings/deviceinfo/StorageDashboardFragment.java b/src/com/android/settings/deviceinfo/StorageDashboardFragment.java
index 77d4072..a4809c9 100644
--- a/src/com/android/settings/deviceinfo/StorageDashboardFragment.java
+++ b/src/com/android/settings/deviceinfo/StorageDashboardFragment.java
@@ -115,10 +115,19 @@
             }
 
             final StorageEntry changedStorageEntry = new StorageEntry(getContext(), volumeInfo);
-            switch (volumeInfo.getState()) {
+            final int volumeState = volumeInfo.getState();
+            switch (volumeState) {
+                case VolumeInfo.STATE_REMOVED:
+                case VolumeInfo.STATE_BAD_REMOVAL:
+                    // Remove removed storage from list and don't show it on spinner.
+                    if (!mStorageEntries.remove(changedStorageEntry)) {
+                        break;
+                    }
                 case VolumeInfo.STATE_MOUNTED:
                 case VolumeInfo.STATE_MOUNTED_READ_ONLY:
                 case VolumeInfo.STATE_UNMOUNTABLE:
+                case VolumeInfo.STATE_UNMOUNTED:
+                case VolumeInfo.STATE_EJECTING:
                     // Add mounted or unmountable storage in the list and show it on spinner.
                     // Unmountable storages are the storages which has a problem format and android
                     // is not able to mount it automatically.
@@ -126,25 +135,15 @@
                     mStorageEntries.removeIf(storageEntry -> {
                         return storageEntry.equals(changedStorageEntry);
                     });
-                    mStorageEntries.add(changedStorageEntry);
+                    if (volumeState != VolumeInfo.STATE_REMOVED
+                            && volumeState != VolumeInfo.STATE_BAD_REMOVAL) {
+                        mStorageEntries.add(changedStorageEntry);
+                    }
                     if (changedStorageEntry.equals(mSelectedStorageEntry)) {
                         mSelectedStorageEntry = changedStorageEntry;
                     }
                     refreshUi();
                     break;
-                case VolumeInfo.STATE_REMOVED:
-                case VolumeInfo.STATE_UNMOUNTED:
-                case VolumeInfo.STATE_BAD_REMOVAL:
-                case VolumeInfo.STATE_EJECTING:
-                    // Remove removed storage from list and don't show it on spinner.
-                    if (mStorageEntries.remove(changedStorageEntry)) {
-                        if (changedStorageEntry.equals(mSelectedStorageEntry)) {
-                            mSelectedStorageEntry =
-                                    StorageEntry.getDefaultInternalStorageEntry(getContext());
-                        }
-                        refreshUi();
-                    }
-                    break;
                 default:
                     // Do nothing.
             }
diff --git a/src/com/android/settings/deviceinfo/VolumeOptionMenuController.java b/src/com/android/settings/deviceinfo/VolumeOptionMenuController.java
index d4f93fa..07102a2 100644
--- a/src/com/android/settings/deviceinfo/VolumeOptionMenuController.java
+++ b/src/com/android/settings/deviceinfo/VolumeOptionMenuController.java
@@ -26,6 +26,7 @@
 import android.os.storage.DiskInfo;
 import android.os.storage.StorageManager;
 import android.os.storage.VolumeInfo;
+import android.util.Log;
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
@@ -53,6 +54,8 @@
 public class VolumeOptionMenuController implements LifecycleObserver, OnCreateOptionsMenu,
         OnPrepareOptionsMenu, OnOptionsItemSelected {
 
+    private static final String TAG = "VolumeOptionMenuController";
+
     @VisibleForTesting
     MenuItem mRename;
     @VisibleForTesting
@@ -103,6 +106,17 @@
         mFree = menu.findItem(R.id.storage_free);
         mForget = menu.findItem(R.id.storage_forget);
 
+        updateOptionsMenu();
+    }
+
+    private void updateOptionsMenu() {
+        if (mRename == null || mMount == null || mUnmount == null || mFormat == null
+                || mFormatAsPortable == null || mFormatAsInternal == null || mMigrate == null
+                || mFree == null || mForget == null) {
+            Log.d(TAG, "Menu items are not available");
+            return;
+        }
+
         mRename.setVisible(false);
         mMount.setVisible(false);
         mUnmount.setVisible(false);
@@ -253,5 +267,7 @@
 
     public void setSelectedStorageEntry(StorageEntry storageEntry) {
         mStorageEntry = storageEntry;
+
+        updateOptionsMenu();
     }
 }