Add disk for StubVolume

StubVolume is a volume type for ARC++ external storage. Named StubVolume
because it is managed from outside Android (not through Android kernel).

Previously, StubVolume is a diskless volume. However, as mentioned in
jsharkey@ email, a disk is needed for StubVolume to hold "kInternal"
(external storage type that is "external" from Android perspective,
but is "internal" to the device. For example shared directory from
ChromeOS to Android) and "kIndexable" (whether or not a disk should be
indexed by MediaStore).

The addition of disk means we could expose the createStubVolume API to
add a disk flags, which is also introduced in this CL.

Both kInternal and kIndexable will be introduced in separate CL.

Bug: 132796154
Test: Mount/unmount ARC++ removable device in ChromeOS.
Change-Id: I8b77fa1cf50ab38a2892272154dafdb78f079378
diff --git a/model/Disk.cpp b/model/Disk.cpp
index f8357a9..d08891a 100644
--- a/model/Disk.cpp
+++ b/model/Disk.cpp
@@ -180,6 +180,10 @@
     auto listener = VolumeManager::Instance()->getListener();
     if (listener) listener->onDiskCreated(getId(), mFlags);
 
+    if (isStub()) {
+        createStubVolume();
+        return OK;
+    }
     readMetadata();
     readPartitions();
     return OK;
@@ -243,6 +247,15 @@
     vol->create();
 }
 
+void Disk::createStubVolume() {
+    CHECK(mVolumes.size() == 1);
+    auto listener = VolumeManager::Instance()->getListener();
+    if (listener) listener->onDiskMetadataChanged(getId(), mSize, mLabel, mSysPath);
+    if (listener) listener->onDiskScanned(getId());
+    mVolumes[0]->setDiskId(getId());
+    mVolumes[0]->create();
+}
+
 void Disk::destroyAllVolumes() {
     for (const auto& vol : mVolumes) {
         vol->destroy();
@@ -443,6 +456,12 @@
     return OK;
 }
 
+void Disk::initializePartition(std::shared_ptr<StubVolume> vol) {
+    CHECK(isStub());
+    CHECK(mVolumes.empty());
+    mVolumes.push_back(vol);
+}
+
 status_t Disk::unmountAll() {
     for (const auto& vol : mVolumes) {
         vol->unmount();
diff --git a/model/Disk.h b/model/Disk.h
index d82d141..99c98fc 100644
--- a/model/Disk.h
+++ b/model/Disk.h
@@ -17,6 +17,7 @@
 #ifndef ANDROID_VOLD_DISK_H
 #define ANDROID_VOLD_DISK_H
 
+#include "StubVolume.h"
 #include "Utils.h"
 #include "VolumeBase.h"
 
@@ -52,6 +53,9 @@
         kUsb = 1 << 3,
         /* Flag that disk is EMMC internal */
         kEmmc = 1 << 4,
+        /* Flag that disk is Stub disk, i.e., disk that is managed from outside
+         * Android (e.g., ARC++). */
+        kStub = 1 << 5,
     };
 
     const std::string& getId() const { return mId; }
@@ -74,6 +78,7 @@
 
     status_t readMetadata();
     status_t readPartitions();
+    void initializePartition(std::shared_ptr<StubVolume> vol);
 
     status_t unmountAll();
 
@@ -109,11 +114,14 @@
 
     void createPublicVolume(dev_t device);
     void createPrivateVolume(dev_t device, const std::string& partGuid);
+    void createStubVolume();
 
     void destroyAllVolumes();
 
     int getMaxMinors();
 
+    bool isStub() { return mFlags & kStub; }
+
     DISALLOW_COPY_AND_ASSIGN(Disk);
 };
 
diff --git a/model/StubVolume.cpp b/model/StubVolume.cpp
index edd0861..d2cd8a8 100644
--- a/model/StubVolume.cpp
+++ b/model/StubVolume.cpp
@@ -16,6 +16,8 @@
 
 #include "StubVolume.h"
 
+#include <inttypes.h>
+
 #include <android-base/logging.h>
 #include <android-base/stringprintf.h>
 
@@ -24,7 +26,7 @@
 namespace android {
 namespace vold {
 
-StubVolume::StubVolume(int id, const std::string& sourcePath, const std::string& mountPath,
+StubVolume::StubVolume(dev_t id, const std::string& sourcePath, const std::string& mountPath,
                        const std::string& fsType, const std::string& fsUuid,
                        const std::string& fsLabel)
     : VolumeBase(Type::kStub),
@@ -33,7 +35,7 @@
       mFsType(fsType),
       mFsUuid(fsUuid),
       mFsLabel(fsLabel) {
-    setId(StringPrintf("stub:%d", id));
+    setId(StringPrintf("stub:%llu", (unsigned long long)id));
 }
 
 StubVolume::~StubVolume() {}
diff --git a/model/StubVolume.h b/model/StubVolume.h
index 538cae9..3697b53 100644
--- a/model/StubVolume.h
+++ b/model/StubVolume.h
@@ -31,7 +31,7 @@
  */
 class StubVolume : public VolumeBase {
   public:
-    StubVolume(int id, const std::string& sourcePath, const std::string& mountPath,
+    StubVolume(dev_t id, const std::string& sourcePath, const std::string& mountPath,
                const std::string& fsType, const std::string& fsUuid, const std::string& fsLabel);
     virtual ~StubVolume();