diff --git a/Android.mk b/Android.mk index 49d58c2..1fc560c 100644 --- a/Android.mk +++ b/Android.mk @@ -37,6 +37,7 @@ common_src_files := \ EncryptInplace.cpp \ MetadataCrypt.cpp \ binder/android/os/IVold.aidl \ + binder/android/os/IVoldListener.aidl \ VoldNativeService.cpp \ common_c_includes := \ @@ -109,6 +110,8 @@ LOCAL_CFLAGS := $(vold_cflags) LOCAL_CONLYFLAGS := $(vold_conlyflags) LOCAL_REQUIRED_MODULES := $(required_modules) +LOCAL_AIDL_INCLUDES := $(LOCAL_PATH)/binder + include $(BUILD_STATIC_LIBRARY) include $(CLEAR_VARS) diff --git a/Utils.h b/Utils.h index 82ac440..153c320 100644 --- a/Utils.h +++ b/Utils.h @@ -19,6 +19,7 @@ #include "KeyBuffer.h" +#include #include #include #include @@ -26,16 +27,10 @@ #include #include -// DISALLOW_COPY_AND_ASSIGN disallows the copy and operator= functions. It goes in the private: -// declarations in a class. -#if !defined(DISALLOW_COPY_AND_ASSIGN) -#define DISALLOW_COPY_AND_ASSIGN(TypeName) \ - TypeName(const TypeName&) = delete; \ - void operator=(const TypeName&) = delete -#endif - struct DIR; +#define ENABLE_BINDER 1 + namespace android { namespace vold { diff --git a/VoldNativeService.cpp b/VoldNativeService.cpp index 374cb4c..f5f0838 100644 --- a/VoldNativeService.cpp +++ b/VoldNativeService.cpp @@ -201,6 +201,15 @@ status_t VoldNativeService::dump(int fd, const Vector & /* args */) { return NO_ERROR; } +binder::Status VoldNativeService::setListener( + const android::sp& listener) { + ENFORCE_UID(AID_SYSTEM); + ACQUIRE_LOCK; + + VolumeManager::Instance()->setListener(listener); + return ok(); +} + binder::Status VoldNativeService::reset() { ENFORCE_UID(AID_SYSTEM); ACQUIRE_LOCK; diff --git a/VoldNativeService.h b/VoldNativeService.h index 50244d2..b6b5d75 100644 --- a/VoldNativeService.h +++ b/VoldNativeService.h @@ -31,6 +31,8 @@ public: static char const* getServiceName() { return "vold"; } virtual status_t dump(int fd, const Vector &args) override; + binder::Status setListener(const android::sp& listener); + binder::Status reset(); binder::Status shutdown(); binder::Status mountAll(); diff --git a/VolumeManager.h b/VolumeManager.h index 7dc69f3..2751ad5 100644 --- a/VolumeManager.h +++ b/VolumeManager.h @@ -36,6 +36,8 @@ #include #include +#include "android/os/IVoldListener.h" + #include "model/Disk.h" #include "model/VolumeBase.h" @@ -96,6 +98,9 @@ public: std::mutex& getLock() { return mLock; } std::mutex& getCryptLock() { return mCryptLock; } + void setListener(android::sp listener) { mListener = listener; } + android::sp getListener() { return mListener; } + int start(); int stop(); @@ -221,6 +226,8 @@ private: std::mutex mLock; std::mutex mCryptLock; + android::sp mListener; + std::list> mDiskSources; std::list> mDisks; std::list> mObbVolumes; diff --git a/binder/android/os/IVold.aidl b/binder/android/os/IVold.aidl index e8a8f2a..0a05e6e 100644 --- a/binder/android/os/IVold.aidl +++ b/binder/android/os/IVold.aidl @@ -16,8 +16,12 @@ package android.os; +import android.os.IVoldListener; + /** {@hide} */ interface IVold { + void setListener(IVoldListener listener); + void reset(); void shutdown(); void mountAll(); @@ -116,19 +120,19 @@ interface IVold { const int REMOUNT_MODE_READ = 2; const int REMOUNT_MODE_WRITE = 3; - const int STATE_UNMOUNTED = 0; - const int STATE_CHECKING = 1; - const int STATE_MOUNTED = 2; - const int STATE_MOUNTED_READ_ONLY = 3; - const int STATE_FORMATTING = 4; - const int STATE_EJECTING = 5; - const int STATE_UNMOUNTABLE = 6; - const int STATE_REMOVED = 7; - const int STATE_BAD_REMOVAL = 8; - - const int TYPE_PUBLIC = 0; - const int TYPE_PRIVATE = 1; - const int TYPE_EMULATED = 2; - const int TYPE_ASEC = 3; - const int TYPE_OBB = 4; + const int VOLUME_STATE_UNMOUNTED = 0; + const int VOLUME_STATE_CHECKING = 1; + const int VOLUME_STATE_MOUNTED = 2; + const int VOLUME_STATE_MOUNTED_READ_ONLY = 3; + const int VOLUME_STATE_FORMATTING = 4; + const int VOLUME_STATE_EJECTING = 5; + const int VOLUME_STATE_UNMOUNTABLE = 6; + const int VOLUME_STATE_REMOVED = 7; + const int VOLUME_STATE_BAD_REMOVAL = 8; + + const int VOLUME_TYPE_PUBLIC = 0; + const int VOLUME_TYPE_PRIVATE = 1; + const int VOLUME_TYPE_EMULATED = 2; + const int VOLUME_TYPE_ASEC = 3; + const int VOLUME_TYPE_OBB = 4; } diff --git a/binder/android/os/IVoldListener.aidl b/binder/android/os/IVoldListener.aidl new file mode 100644 index 0000000..0dcfc04 --- /dev/null +++ b/binder/android/os/IVoldListener.aidl @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.os; + +/** {@hide} */ +oneway interface IVoldListener { + void onDiskCreated(@utf8InCpp String diskId, int flags); + void onDiskScanned(@utf8InCpp String diskId); + void onDiskMetadataChanged(@utf8InCpp String diskId, + long sizeBytes, @utf8InCpp String label, @utf8InCpp String sysPath); + void onDiskDestroyed(@utf8InCpp String diskId); + + void onVolumeCreated(@utf8InCpp String volId, + int type, @utf8InCpp String diskId, @utf8InCpp String partGuid); + void onVolumeStateChanged(@utf8InCpp String volId, int state); + void onVolumeMetadataChanged(@utf8InCpp String volId, + @utf8InCpp String fsType, @utf8InCpp String fsUuid, @utf8InCpp String fsLabel); + void onVolumePathChanged(@utf8InCpp String volId, + @utf8InCpp String path); + void onVolumeInternalPathChanged(@utf8InCpp String volId, + @utf8InCpp String internalPath); + void onVolumeDestroyed(@utf8InCpp String volId); +} diff --git a/model/Disk.cpp b/model/Disk.cpp index 9c22400..151937f 100644 --- a/model/Disk.cpp +++ b/model/Disk.cpp @@ -151,7 +151,12 @@ void Disk::listVolumes(VolumeBase::Type type, std::list& list) { status_t Disk::create() { CHECK(!mCreated); mCreated = true; +#if ENABLE_BINDER + auto listener = VolumeManager::Instance()->getListener(); + if (listener) listener->onDiskCreated(getId(), mFlags); +#else notifyEvent(ResponseCode::DiskCreated, StringPrintf("%d", mFlags)); +#endif readMetadata(); readPartitions(); return OK; @@ -161,7 +166,12 @@ status_t Disk::destroy() { CHECK(mCreated); destroyAllVolumes(); mCreated = false; +#if ENABLE_BINDER + auto listener = VolumeManager::Instance()->getListener(); + if (listener) listener->onDiskDestroyed(getId()); +#else notifyEvent(ResponseCode::DiskDestroyed); +#endif return OK; } @@ -281,9 +291,15 @@ status_t Disk::readMetadata() { } } +#if ENABLE_BINDER + auto listener = VolumeManager::Instance()->getListener(); + if (listener) listener->onDiskMetadataChanged(getId(), + mSize, mLabel, mSysPath); +#else notifyEvent(ResponseCode::DiskSizeChanged, StringPrintf("%" PRIu64, mSize)); notifyEvent(ResponseCode::DiskLabelChanged, mLabel); notifyEvent(ResponseCode::DiskSysPathChanged, mSysPath); +#endif return OK; } @@ -306,7 +322,12 @@ status_t Disk::readPartitions() { status_t res = ForkExecvp(cmd, output); if (res != OK) { LOG(WARNING) << "sgdisk failed to scan " << mDevPath; +#if ENABLE_BINDER + auto listener = VolumeManager::Instance()->getListener(); + if (listener) listener->onDiskScanned(getId()); +#else notifyEvent(ResponseCode::DiskScanned); +#endif mJustPartitioned = false; return res; } @@ -372,7 +393,12 @@ status_t Disk::readPartitions() { } } +#if ENABLE_BINDER + auto listener = VolumeManager::Instance()->getListener(); + if (listener) listener->onDiskScanned(getId()); +#else notifyEvent(ResponseCode::DiskScanned); +#endif mJustPartitioned = false; return OK; } diff --git a/model/PrivateVolume.cpp b/model/PrivateVolume.cpp index e66e04d..9a96082 100644 --- a/model/PrivateVolume.cpp +++ b/model/PrivateVolume.cpp @@ -55,9 +55,14 @@ PrivateVolume::~PrivateVolume() { status_t PrivateVolume::readMetadata() { status_t res = ReadMetadata(mDmDevPath, mFsType, mFsUuid, mFsLabel); +#if ENABLE_BINDER + auto listener = getListener(); + if (listener) listener->onVolumeMetadataChanged(getId(), mFsType, mFsUuid, mFsLabel); +#else notifyEvent(ResponseCode::VolumeFsTypeChanged, mFsType); notifyEvent(ResponseCode::VolumeFsUuidChanged, mFsUuid); notifyEvent(ResponseCode::VolumeFsLabelChanged, mFsLabel); +#endif return res; } diff --git a/model/PublicVolume.cpp b/model/PublicVolume.cpp index f976c4a..04bafed 100644 --- a/model/PublicVolume.cpp +++ b/model/PublicVolume.cpp @@ -53,9 +53,14 @@ PublicVolume::~PublicVolume() { status_t PublicVolume::readMetadata() { status_t res = ReadMetadataUntrusted(mDevPath, mFsType, mFsUuid, mFsLabel); +#if ENABLE_BINDER + auto listener = getListener(); + if (listener) listener->onVolumeMetadataChanged(getId(), mFsType, mFsUuid, mFsLabel); +#else notifyEvent(ResponseCode::VolumeFsTypeChanged, mFsType); notifyEvent(ResponseCode::VolumeFsUuidChanged, mFsUuid); notifyEvent(ResponseCode::VolumeFsLabelChanged, mFsLabel); +#endif return res; } diff --git a/model/VolumeBase.cpp b/model/VolumeBase.cpp index 3f27d87..b2eff3b 100644 --- a/model/VolumeBase.cpp +++ b/model/VolumeBase.cpp @@ -44,7 +44,12 @@ VolumeBase::~VolumeBase() { void VolumeBase::setState(State state) { mState = state; +#if ENABLE_BINDER + auto listener = getListener(); + if (listener) listener->onVolumeStateChanged(getId(), static_cast(mState)); +#else notifyEvent(ResponseCode::VolumeStateChanged, StringPrintf("%d", mState)); +#endif } status_t VolumeBase::setDiskId(const std::string& diskId) { @@ -114,7 +119,12 @@ status_t VolumeBase::setPath(const std::string& path) { } mPath = path; +#if ENABLE_BINDER + auto listener = getListener(); + if (listener) listener->onVolumePathChanged(getId(), mPath); +#else notifyEvent(ResponseCode::VolumePathChanged, mPath); +#endif return OK; } @@ -125,7 +135,12 @@ status_t VolumeBase::setInternalPath(const std::string& internalPath) { } mInternalPath = internalPath; +#if ENABLE_BINDER + auto listener = getListener(); + if (listener) listener->onVolumeInternalPathChanged(getId(), mInternalPath); +#else notifyEvent(ResponseCode::VolumeInternalPathChanged, mInternalPath); +#endif return OK; } @@ -141,6 +156,14 @@ void VolumeBase::notifyEvent(int event, const std::string& value) { StringPrintf("%s %s", getId().c_str(), value.c_str()).c_str(), false); } +android::sp VolumeBase::getListener() { + if (mSilent) { + return nullptr; + } else { + return VolumeManager::Instance()->getListener(); + } +} + void VolumeBase::addVolume(const std::shared_ptr& volume) { mVolumes.push_back(volume); } @@ -163,8 +186,14 @@ status_t VolumeBase::create() { mCreated = true; status_t res = doCreate(); +#if ENABLE_BINDER + auto listener = getListener(); + if (listener) listener->onVolumeCreated(getId(), + static_cast(mType), mDiskId, mPartGuid); +#else notifyEvent(ResponseCode::VolumeCreated, StringPrintf("%d \"%s\" \"%s\"", mType, mDiskId.c_str(), mPartGuid.c_str())); +#endif setState(State::kUnmounted); return res; } @@ -183,7 +212,12 @@ status_t VolumeBase::destroy() { setState(State::kRemoved); } +#if ENABLE_BINDER + auto listener = getListener(); + if (listener) listener->onVolumeDestroyed(getId()); +#else notifyEvent(ResponseCode::VolumeDestroyed); +#endif status_t res = doDestroy(); mCreated = false; return res; diff --git a/model/VolumeBase.h b/model/VolumeBase.h index d417019..ac111c2 100644 --- a/model/VolumeBase.h +++ b/model/VolumeBase.h @@ -17,6 +17,7 @@ #ifndef ANDROID_VOLD_VOLUME_BASE_H #define ANDROID_VOLD_VOLUME_BASE_H +#include "android/os/IVoldListener.h" #include "Utils.h" #include @@ -117,6 +118,8 @@ protected: void notifyEvent(int msg); void notifyEvent(int msg, const std::string& value); + android::sp getListener(); + private: /* ID that uniquely references volume while alive */ std::string mId;