Move unsolicited vold events to Binder.

Create IVoldListener and move most unsolicited vold events over to
this new interface.  The remaining events will be routed through
method-specific listeners instead of a global one.

Move to upstream DISALLOW_COPY_AND_ASSIGN macro.

Test: cts-tradefed run commandAndExit cts-dev -m CtsAppSecurityHostTestCases -t android.appsecurity.cts.DirectBootHostTest
Test: cts-tradefed run commandAndExit cts-dev -m CtsAppSecurityHostTestCases -t android.appsecurity.cts.AdoptableHostTest
Test: cts-tradefed run commandAndExit cts-dev -m CtsOsTestCases -t android.os.storage.cts.StorageManagerTest
Bug: 13758960
Change-Id: Ib9293487db2d525a76b9b9c2e9ac18d98601c6cf
diff --git a/Android.mk b/Android.mk
index 49d58c2..1fc560c 100644
--- a/Android.mk
+++ b/Android.mk
@@ -37,6 +37,7 @@
 	EncryptInplace.cpp \
 	MetadataCrypt.cpp \
 	binder/android/os/IVold.aidl \
+	binder/android/os/IVoldListener.aidl \
 	VoldNativeService.cpp \
 
 common_c_includes := \
@@ -109,6 +110,8 @@
 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 <android-base/macros.h>
 #include <utils/Errors.h>
 #include <cutils/multiuser.h>
 #include <selinux/selinux.h>
@@ -26,16 +27,10 @@
 #include <vector>
 #include <string>
 
-// 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 @@
     return NO_ERROR;
 }
 
+binder::Status VoldNativeService::setListener(
+        const android::sp<android::os::IVoldListener>& 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 @@
     static char const* getServiceName() { return "vold"; }
     virtual status_t dump(int fd, const Vector<String16> &args) override;
 
+    binder::Status setListener(const android::sp<android::os::IVoldListener>& 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 <sysutils/SocketListener.h>
 #include <sysutils/NetlinkEvent.h>
 
+#include "android/os/IVoldListener.h"
+
 #include "model/Disk.h"
 #include "model/VolumeBase.h"
 
@@ -96,6 +98,9 @@
     std::mutex& getLock() { return mLock; }
     std::mutex& getCryptLock() { return mCryptLock; }
 
+    void setListener(android::sp<android::os::IVoldListener> listener) { mListener = listener; }
+    android::sp<android::os::IVoldListener> getListener() { return mListener; }
+
     int start();
     int stop();
 
@@ -221,6 +226,8 @@
     std::mutex mLock;
     std::mutex mCryptLock;
 
+    android::sp<android::os::IVoldListener> mListener;
+
     std::list<std::shared_ptr<DiskSource>> mDiskSources;
     std::list<std::shared_ptr<android::vold::Disk>> mDisks;
     std::list<std::shared_ptr<android::vold::VolumeBase>> 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 @@
     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 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 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_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 @@
 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 @@
     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 @@
     }
     }
 
+#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 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 @@
         }
     }
 
+#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 @@
 
 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 @@
 
 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 @@
 
 void VolumeBase::setState(State state) {
     mState = state;
+#if ENABLE_BINDER
+    auto listener = getListener();
+    if (listener) listener->onVolumeStateChanged(getId(), static_cast<int32_t>(mState));
+#else
     notifyEvent(ResponseCode::VolumeStateChanged, StringPrintf("%d", mState));
+#endif
 }
 
 status_t VolumeBase::setDiskId(const std::string& diskId) {
@@ -114,7 +119,12 @@
     }
 
     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 @@
     }
 
     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 @@
             StringPrintf("%s %s", getId().c_str(), value.c_str()).c_str(), false);
 }
 
+android::sp<android::os::IVoldListener> VolumeBase::getListener() {
+    if (mSilent) {
+        return nullptr;
+    } else {
+        return VolumeManager::Instance()->getListener();
+    }
+}
+
 void VolumeBase::addVolume(const std::shared_ptr<VolumeBase>& volume) {
     mVolumes.push_back(volume);
 }
@@ -163,8 +186,14 @@
 
     mCreated = true;
     status_t res = doCreate();
+#if ENABLE_BINDER
+    auto listener = getListener();
+    if (listener) listener->onVolumeCreated(getId(),
+            static_cast<int32_t>(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 @@
         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 <cutils/multiuser.h>
@@ -117,6 +118,8 @@
     void notifyEvent(int msg);
     void notifyEvent(int msg, const std::string& value);
 
+    android::sp<android::os::IVoldListener> getListener();
+
 private:
     /* ID that uniquely references volume while alive */
     std::string mId;