diff --git a/VoldNativeService.cpp b/VoldNativeService.cpp index 3643c74..d648ebc 100644 --- a/VoldNativeService.cpp +++ b/VoldNativeService.cpp @@ -488,9 +488,12 @@ binder::Status VoldNativeService::destroyObb(const std::string& volId) { return translate(VolumeManager::Instance()->destroyObb(volId)); } -binder::Status VoldNativeService::createStubVolume( - const std::string& sourcePath, const std::string& mountPath, const std::string& fsType, - const std::string& fsUuid, const std::string& fsLabel, std::string* _aidl_return) { +binder::Status VoldNativeService::createStubVolume(const std::string& sourcePath, + const std::string& mountPath, + const std::string& fsType, + const std::string& fsUuid, + const std::string& fsLabel, int32_t flags, + std::string* _aidl_return) { ENFORCE_SYSTEM_OR_ROOT; CHECK_ARGUMENT_PATH(sourcePath); CHECK_ARGUMENT_PATH(mountPath); @@ -499,8 +502,8 @@ binder::Status VoldNativeService::createStubVolume( // is quite meaningless. ACQUIRE_LOCK; - return translate(VolumeManager::Instance()->createStubVolume(sourcePath, mountPath, fsType, - fsUuid, fsLabel, _aidl_return)); + return translate(VolumeManager::Instance()->createStubVolume( + sourcePath, mountPath, fsType, fsUuid, fsLabel, flags, _aidl_return)); } binder::Status VoldNativeService::destroyStubVolume(const std::string& volId) { diff --git a/VoldNativeService.h b/VoldNativeService.h index 7de2a67..a276de3 100644 --- a/VoldNativeService.h +++ b/VoldNativeService.h @@ -74,7 +74,8 @@ class VoldNativeService : public BinderService, public os::Bn binder::Status createStubVolume(const std::string& sourcePath, const std::string& mountPath, const std::string& fsType, const std::string& fsUuid, - const std::string& fsLabel, std::string* _aidl_return); + const std::string& fsLabel, int32_t flags, + std::string* _aidl_return); binder::Status destroyStubVolume(const std::string& volId); binder::Status fstrim(int32_t fstrimFlags, diff --git a/VolumeManager.cpp b/VolumeManager.cpp index 4427c9b..7be5e4f 100644 --- a/VolumeManager.cpp +++ b/VolumeManager.cpp @@ -114,7 +114,7 @@ VolumeManager* VolumeManager::Instance() { VolumeManager::VolumeManager() { mDebug = false; mNextObbId = 0; - mNextStubVolumeId = 0; + mNextStubId = 0; // For security reasons, assume that a secure keyguard is // showing until we hear otherwise mSecureKeyguardShowing = true; @@ -340,11 +340,6 @@ std::shared_ptr VolumeManager::findVolume(const std:: return vol; } } - for (const auto& vol : mStubVolumes) { - if (vol->getId() == id) { - return vol; - } - } for (const auto& vol : mObbVolumes) { if (vol->getId() == id) { return vol; @@ -767,7 +762,6 @@ int VolumeManager::shutdown() { } mInternalEmulatedVolumes.clear(); - mStubVolumes.clear(); mDisks.clear(); mPendingDisks.clear(); android::vold::sSleepOnUnmount = true; @@ -782,9 +776,6 @@ int VolumeManager::unmountAll() { for (const auto& vol : mInternalEmulatedVolumes) { vol->unmount(); } - for (const auto& stub : mStubVolumes) { - stub->unmount(); - } for (const auto& disk : mDisks) { disk->unmountAll(); } @@ -941,27 +932,30 @@ int VolumeManager::destroyObb(const std::string& volId) { int VolumeManager::createStubVolume(const std::string& sourcePath, const std::string& mountPath, const std::string& fsType, const std::string& fsUuid, - const std::string& fsLabel, std::string* outVolId) { - int id = mNextStubVolumeId++; - auto vol = std::shared_ptr( - new android::vold::StubVolume(id, sourcePath, mountPath, fsType, fsUuid, fsLabel)); - vol->create(); + const std::string& fsLabel, int32_t flags __unused, + std::string* outVolId) { + dev_t stubId = --mNextStubId; + auto vol = std::shared_ptr( + new android::vold::StubVolume(stubId, sourcePath, mountPath, fsType, fsUuid, fsLabel)); - mStubVolumes.push_back(vol); + // TODO (b/132796154): Passed each supported flags explicitly here. + // StubDisk doesn't have device node corresponds to it. So, a fake device + // number is used. The supported flags will be infered from the + // currently-unused flags parameter. + auto disk = std::shared_ptr( + new android::vold::Disk("stub", stubId, "stub", android::vold::Disk::Flags::kStub)); + disk->initializePartition(vol); + handleDiskAdded(disk); *outVolId = vol->getId(); return android::OK; } int VolumeManager::destroyStubVolume(const std::string& volId) { - auto i = mStubVolumes.begin(); - while (i != mStubVolumes.end()) { - if ((*i)->getId() == volId) { - (*i)->destroy(); - i = mStubVolumes.erase(i); - } else { - ++i; - } - } + auto tokens = android::base::Split(volId, ":"); + CHECK(tokens.size() == 2); + dev_t stubId; + CHECK(android::base::ParseUint(tokens[1], &stubId)); + handleDiskRemoved(stubId); return android::OK; } diff --git a/VolumeManager.h b/VolumeManager.h index eb48736..992b6dc 100644 --- a/VolumeManager.h +++ b/VolumeManager.h @@ -163,7 +163,7 @@ class VolumeManager { int createStubVolume(const std::string& sourcePath, const std::string& mountPath, const std::string& fsType, const std::string& fsUuid, - const std::string& fsLabel, std::string* outVolId); + const std::string& fsLabel, int32_t flags, std::string* outVolId); int destroyStubVolume(const std::string& volId); int mountAppFuse(uid_t uid, int mountId, android::base::unique_fd* device_fd); @@ -192,7 +192,6 @@ class VolumeManager { std::list> mDisks; std::list> mPendingDisks; std::list> mObbVolumes; - std::list> mStubVolumes; std::list> mInternalEmulatedVolumes; std::unordered_map mAddedUsers; @@ -205,7 +204,7 @@ class VolumeManager { std::shared_ptr mPrimary; int mNextObbId; - int mNextStubVolumeId; + int mNextStubId; bool mSecureKeyguardShowing; }; diff --git a/binder/android/os/IVold.aidl b/binder/android/os/IVold.aidl index f1e463a..d4a55c8 100644 --- a/binder/android/os/IVold.aidl +++ b/binder/android/os/IVold.aidl @@ -125,7 +125,7 @@ interface IVold { @utf8InCpp String createStubVolume(@utf8InCpp String sourcePath, @utf8InCpp String mountPath, @utf8InCpp String fsType, - @utf8InCpp String fsUuid, @utf8InCpp String fsLabel); + @utf8InCpp String fsUuid, @utf8InCpp String fsLabel, int flags); void destroyStubVolume(@utf8InCpp String volId); FileDescriptor openAppFuseFile(int uid, int mountId, int fileId, int flags); 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 @@ status_t Disk::create() { auto listener = VolumeManager::Instance()->getListener(); if (listener) listener->onDiskCreated(getId(), mFlags); + if (isStub()) { + createStubVolume(); + return OK; + } readMetadata(); readPartitions(); return OK; @@ -243,6 +247,15 @@ void Disk::createPrivateVolume(dev_t device, const std::string& partGuid) { 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 @@ status_t Disk::readPartitions() { return OK; } +void Disk::initializePartition(std::shared_ptr 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 @@ class Disk { 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 @@ class Disk { status_t readMetadata(); status_t readPartitions(); + void initializePartition(std::shared_ptr vol); status_t unmountAll(); @@ -109,11 +114,14 @@ class Disk { 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 + #include #include @@ -24,7 +26,7 @@ using android::base::StringPrintf; 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 @@ StubVolume::StubVolume(int id, const std::string& sourcePath, const std::string& 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 @@ namespace vold { */ 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();