Remove StubVolume disks upon vold reset events

StubVolumes are managed from outside Android (e.g. from Chrome OS). So,
their disk recreation on vold reset events should also be handled from
outside by 1) listening to reset events, and 2) calling
createStubVolume() for existing StubVolumes on reset events.

Bug: 175281783
Test: m
Test: (Tested in R) Manually induce a vold reset event, and confirm that
Test: 1) vold does not crash, and 2) existing volumes are successfully
Test: mounted again (by calling createStubVolume() for StubVolumes).
Change-Id: I4628eabf809037a547aeef43faedf4dfa57529a6
diff --git a/VolumeManager.cpp b/VolumeManager.cpp
index 02025b7..9311321 100644
--- a/VolumeManager.cpp
+++ b/VolumeManager.cpp
@@ -899,10 +899,21 @@
     }
     mInternalEmulatedVolumes.clear();
 
+    // Destroy and recreate all disks except that StubVolume disks are just
+    // destroyed and removed from both mDisks and mPendingDisks.
+    // StubVolumes are managed from outside Android (e.g. from Chrome OS) and
+    // their disk recreation on reset events should be handled from outside by
+    // calling createStubVolume() again.
     for (const auto& disk : mDisks) {
         disk->destroy();
-        disk->create();
+        if (!disk->isStub()) {
+            disk->create();
+        }
     }
+    const auto isStub = [](const auto& disk) { return disk->isStub(); };
+    mDisks.remove_if(isStub);
+    mPendingDisks.remove_if(isStub);
+
     updateVirtualDisk();
     mAddedUsers.clear();
     mStartedUsers.clear();
diff --git a/model/Disk.h b/model/Disk.h
index 16476dc..8c75f59 100644
--- a/model/Disk.h
+++ b/model/Disk.h
@@ -70,6 +70,8 @@
     const std::string& getLabel() const { return mLabel; }
     int getFlags() const { return mFlags; }
 
+    bool isStub() const { return (mFlags & kStubInvisible) || (mFlags & kStubVisible); }
+
     std::shared_ptr<VolumeBase> findVolume(const std::string& id);
 
     void listVolumes(VolumeBase::Type type, std::list<std::string>& list) const;
@@ -123,8 +125,6 @@
 
     int getMaxMinors();
 
-    bool isStub() { return (mFlags & kStubInvisible) || (mFlags & kStubVisible); }
-
     DISALLOW_COPY_AND_ASSIGN(Disk);
 };