Merge "Move long-running calls to async with listeners."
diff --git a/Android.mk b/Android.mk
index ccbbb56..78d60df 100644
--- a/Android.mk
+++ b/Android.mk
@@ -26,7 +26,7 @@
 	model/ObbVolume.cpp \
 	Utils.cpp \
 	MoveTask.cpp \
-	Benchmark.cpp \
+	BenchmarkTask.cpp \
 	TrimTask.cpp \
 	KeyBuffer.cpp \
 	Keymaster.cpp \
@@ -36,9 +36,16 @@
 	secontext.cpp \
 	EncryptInplace.cpp \
 	MetadataCrypt.cpp \
+	VoldNativeService.cpp \
+
+common_aidl_files := \
 	binder/android/os/IVold.aidl \
 	binder/android/os/IVoldListener.aidl \
-	VoldNativeService.cpp \
+	binder/android/os/IVoldTaskListener.aidl \
+
+common_aidl_includes := \
+	$(LOCAL_PATH)/binder \
+	frameworks/native/aidl/binder \
 
 common_c_includes := \
 	system/extras/f2fs_utils \
@@ -101,7 +108,7 @@
 LOCAL_TIDY := $(common_local_tidy_enabled)
 LOCAL_TIDY_FLAGS := $(common_local_tidy_flags)
 LOCAL_TIDY_CHECKS := $(common_local_tidy_checks)
-LOCAL_SRC_FILES := $(common_src_files)
+LOCAL_SRC_FILES := $(common_src_files) $(common_aidl_files)
 LOCAL_C_INCLUDES := $(common_c_includes)
 LOCAL_SHARED_LIBRARIES := $(common_shared_libraries)
 LOCAL_STATIC_LIBRARIES := $(common_static_libraries)
@@ -110,7 +117,7 @@
 LOCAL_CONLYFLAGS := $(vold_conlyflags)
 LOCAL_REQUIRED_MODULES := $(required_modules)
 
-LOCAL_AIDL_INCLUDES := $(LOCAL_PATH)/binder
+LOCAL_AIDL_INCLUDES := $(common_aidl_includes)
 
 include $(BUILD_STATIC_LIBRARY)
 
@@ -124,7 +131,8 @@
 LOCAL_TIDY_CHECKS := $(common_local_tidy_checks)
 LOCAL_SRC_FILES := \
 	main.cpp \
-	$(common_src_files)
+	$(common_src_files) \
+	$(common_aidl_files) \
 
 LOCAL_INIT_RC := vold.rc
 
@@ -136,7 +144,7 @@
 LOCAL_STATIC_LIBRARIES := $(common_static_libraries)
 LOCAL_REQUIRED_MODULES := $(required_modules)
 
-LOCAL_AIDL_INCLUDES := $(LOCAL_PATH)/binder
+LOCAL_AIDL_INCLUDES := $(common_aidl_includes)
 
 include $(BUILD_EXECUTABLE)
 
@@ -150,8 +158,7 @@
 
 LOCAL_SRC_FILES := \
 	vdc.cpp \
-	binder/android/os/IVold.aidl \
-	binder/android/os/IVoldListener.aidl \
+	$(common_aidl_files) \
 
 LOCAL_MODULE := vdc
 LOCAL_SHARED_LIBRARIES := libbase libbinder libcutils libutils
@@ -159,7 +166,7 @@
 LOCAL_CONLYFLAGS := $(vold_conlyflags)
 LOCAL_INIT_RC := vdc.rc
 
-LOCAL_AIDL_INCLUDES := $(LOCAL_PATH)/binder
+LOCAL_AIDL_INCLUDES := $(common_aidl_includes)
 
 include $(BUILD_EXECUTABLE)
 
diff --git a/Benchmark.h b/Benchmark.h
deleted file mode 100644
index 13f9009..0000000
--- a/Benchmark.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2015 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.
- */
-
-#ifndef ANDROID_VOLD_BENCHMARK_H
-#define ANDROID_VOLD_BENCHMARK_H
-
-#include <utils/Errors.h>
-#include <utils/Timers.h>
-
-#include <string>
-
-namespace android {
-namespace vold {
-
-/* Benchmark a private volume mounted at the given path */
-nsecs_t BenchmarkPrivate(const std::string& path);
-
-}  // namespace vold
-}  // namespace android
-
-#endif
diff --git a/Benchmark.cpp b/BenchmarkTask.cpp
similarity index 71%
rename from Benchmark.cpp
rename to BenchmarkTask.cpp
index bbab792..5ec249a 100644
--- a/Benchmark.cpp
+++ b/BenchmarkTask.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include "Benchmark.h"
+#include "BenchmarkTask.h"
 #include "BenchmarkGen.h"
 #include "VolumeManager.h"
 #include "ResponseCode.h"
@@ -22,6 +22,7 @@
 #include <android-base/file.h>
 #include <android-base/logging.h>
 #include <cutils/iosched_policy.h>
+#include <hardware_legacy/power.h>
 #include <private/android_filesystem_config.h>
 
 #include <sys/time.h>
@@ -36,19 +37,35 @@
 namespace android {
 namespace vold {
 
-static void notifyResult(const std::string& path, int64_t create_d,
-        int64_t drop_d, int64_t run_d, int64_t destroy_d) {
-    std::string res(path +
-            + " " + BenchmarkIdent()
-            + " " + std::to_string(create_d)
-            + " " + std::to_string(drop_d)
-            + " " + std::to_string(run_d)
-            + " " + std::to_string(destroy_d));
-    VolumeManager::Instance()->getBroadcaster()->sendBroadcast(
-            ResponseCode::BenchmarkResult, res.c_str(), false);
+static const char* kWakeLock = "BenchmarkTask";
+
+BenchmarkTask::BenchmarkTask(const std::string& path,
+        const android::sp<android::os::IVoldTaskListener>& listener) :
+        mPath(path), mListener(listener) {
 }
 
-static nsecs_t benchmark(const std::string& path) {
+BenchmarkTask::~BenchmarkTask() {
+}
+
+void BenchmarkTask::start() {
+    mThread = std::thread(&BenchmarkTask::run, this);
+}
+
+static status_t runInternal(const std::string& rootPath, android::os::PersistableBundle& extras) {
+    auto path = rootPath;
+    path += "/misc";
+    if (android::vold::PrepareDir(path, 01771, AID_SYSTEM, AID_MISC)) {
+        return -1;
+    }
+    path += "/vold";
+    if (android::vold::PrepareDir(path, 0700, AID_ROOT, AID_ROOT)) {
+        return -1;
+    }
+    path += "/bench";
+    if (android::vold::PrepareDir(path, 0700, AID_ROOT, AID_ROOT)) {
+        return -1;
+    }
+
     errno = 0;
     int orig_prio = getpriority(PRIO_PROCESS, 0);
     if (errno != 0) {
@@ -127,26 +144,26 @@
     LOG(INFO) << "run took " << nanoseconds_to_milliseconds(run_d) << "ms";
     LOG(INFO) << "destroy took " << nanoseconds_to_milliseconds(destroy_d) << "ms";
 
-    notifyResult(path, create_d, drop_d, run_d, destroy_d);
+    extras.putString(String16("path"), String16(path.c_str()));
+    extras.putString(String16("ident"), String16(BenchmarkIdent().c_str()));
+    extras.putLong(String16("create"), create_d);
+    extras.putLong(String16("drop"), drop_d);
+    extras.putLong(String16("run"), run_d);
+    extras.putLong(String16("destroy"), destroy_d);
 
-    return run_d;
+    return 0;
 }
 
-nsecs_t BenchmarkPrivate(const std::string& path) {
-    std::string benchPath(path);
-    benchPath += "/misc";
-    if (android::vold::PrepareDir(benchPath, 01771, AID_SYSTEM, AID_MISC)) {
-        return -1;
+void BenchmarkTask::run() {
+    acquire_wake_lock(PARTIAL_WAKE_LOCK, kWakeLock);
+
+    android::os::PersistableBundle extras;
+    status_t res = runInternal(mPath, extras);
+    if (mListener) {
+        mListener->onFinished(res, extras);
     }
-    benchPath += "/vold";
-    if (android::vold::PrepareDir(benchPath, 0700, AID_ROOT, AID_ROOT)) {
-        return -1;
-    }
-    benchPath += "/bench";
-    if (android::vold::PrepareDir(benchPath, 0700, AID_ROOT, AID_ROOT)) {
-        return -1;
-    }
-    return benchmark(benchPath);
+
+    release_wake_lock(kWakeLock);
 }
 
 }  // namespace vold
diff --git a/BenchmarkTask.h b/BenchmarkTask.h
new file mode 100644
index 0000000..dfa3922
--- /dev/null
+++ b/BenchmarkTask.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+#ifndef ANDROID_VOLD_BENCHMARK_TASK_H
+#define ANDROID_VOLD_BENCHMARK_TASK_H
+
+#include "android/os/IVoldTaskListener.h"
+#include "Utils.h"
+
+#include <string>
+#include <thread>
+
+namespace android {
+namespace vold {
+
+class BenchmarkTask {
+public:
+    BenchmarkTask(const std::string& path,
+            const android::sp<android::os::IVoldTaskListener>& listener);
+    virtual ~BenchmarkTask();
+
+    void start();
+
+private:
+    std::string mPath;
+    android::sp<android::os::IVoldTaskListener> mListener;
+    std::thread mThread;
+
+    void run();
+
+    DISALLOW_COPY_AND_ASSIGN(BenchmarkTask);
+};
+
+}  // namespace vold
+}  // namespace android
+
+#endif
diff --git a/CommandListener.cpp b/CommandListener.cpp
index 60c0898..a402ffa 100644
--- a/CommandListener.cpp
+++ b/CommandListener.cpp
@@ -256,13 +256,14 @@
             return cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown volume", false);
         }
 
-        (new android::vold::MoveTask(fromVol, toVol))->start();
+        (new android::vold::MoveTask(fromVol, toVol, nullptr))->start();
         return sendGenericOkFail(cli, 0);
 
     } else if (cmd == "benchmark" && argc > 2) {
         // benchmark [volId]
         std::string id(argv[2]);
-        nsecs_t res = vm->benchmarkPrivate(id);
+        LOG(WARNING) << "Benchmarking has moved to Binder interface";
+        nsecs_t res = 0;
         return cli->sendMsg(ResponseCode::CommandOkay,
                 android::base::StringPrintf("%" PRId64, res).c_str(), false);
 
@@ -603,16 +604,13 @@
     std::string cmd(argv[1]);
     if (cmd == "dotrim") {
         flags = 0;
-    } else if (cmd == "dotrimbench") {
-        flags = android::vold::TrimTask::Flags::kBenchmarkAfter;
     } else if (cmd == "dodtrim") {
         flags = android::vold::TrimTask::Flags::kDeepTrim;
     } else if (cmd == "dodtrimbench") {
-        flags = android::vold::TrimTask::Flags::kDeepTrim
-                | android::vold::TrimTask::Flags::kBenchmarkAfter;
+        flags = android::vold::TrimTask::Flags::kDeepTrim;
     }
 
-    (new android::vold::TrimTask(flags))->start();
+    (new android::vold::TrimTask(flags, nullptr))->start();
     return sendGenericOkFail(cli, 0);
 }
 
diff --git a/MoveTask.cpp b/MoveTask.cpp
index c565752..8c0efac 100644
--- a/MoveTask.cpp
+++ b/MoveTask.cpp
@@ -45,9 +45,9 @@
 
 static const char* kWakeLock = "MoveTask";
 
-MoveTask::MoveTask(const std::shared_ptr<VolumeBase>& from,
-        const std::shared_ptr<VolumeBase>& to) :
-        mFrom(from), mTo(to) {
+MoveTask::MoveTask(const std::shared_ptr<VolumeBase>& from, const std::shared_ptr<VolumeBase>& to,
+        const android::sp<android::os::IVoldTaskListener>& listener) :
+        mFrom(from), mTo(to), mListener(listener) {
 }
 
 MoveTask::~MoveTask() {
@@ -57,9 +57,11 @@
     mThread = std::thread(&MoveTask::run, this);
 }
 
-static void notifyProgress(int progress) {
-    VolumeManager::Instance()->getBroadcaster()->sendBroadcast(ResponseCode::MoveStatus,
-            StringPrintf("%d", progress).c_str(), false);
+void MoveTask::notifyProgress(int progress) {
+    if (mListener) {
+        android::os::PersistableBundle extras;
+        mListener->onStatus(progress, extras);
+    }
 }
 
 static status_t pushBackContents(const std::string& path, std::vector<std::string>& cmd,
@@ -85,7 +87,7 @@
     return found ? OK : -1;
 }
 
-static status_t execRm(const std::string& path, int startProgress, int stepProgress) {
+status_t MoveTask::execRm(const std::string& path, int startProgress, int stepProgress) {
     notifyProgress(startProgress);
 
     uint64_t expectedBytes = GetTreeBytes(path);
@@ -126,7 +128,7 @@
 #endif
 }
 
-static status_t execCp(const std::string& fromPath, const std::string& toPath,
+status_t MoveTask::execCp(const std::string& fromPath, const std::string& toPath,
         int startProgress, int stepProgress) {
     notifyProgress(startProgress);
 
diff --git a/MoveTask.h b/MoveTask.h
index cb184c3..246a24d 100644
--- a/MoveTask.h
+++ b/MoveTask.h
@@ -17,6 +17,7 @@
 #ifndef ANDROID_VOLD_MOVE_TASK_H
 #define ANDROID_VOLD_MOVE_TASK_H
 
+#include "android/os/IVoldTaskListener.h"
 #include "Utils.h"
 #include "model/VolumeBase.h"
 
@@ -27,7 +28,8 @@
 
 class MoveTask {
 public:
-    MoveTask(const std::shared_ptr<VolumeBase>& from, const std::shared_ptr<VolumeBase>& to);
+    MoveTask(const std::shared_ptr<VolumeBase>& from, const std::shared_ptr<VolumeBase>& to,
+            const android::sp<android::os::IVoldTaskListener>& listener);
     virtual ~MoveTask();
 
     void start();
@@ -35,10 +37,17 @@
 private:
     std::shared_ptr<VolumeBase> mFrom;
     std::shared_ptr<VolumeBase> mTo;
+    android::sp<android::os::IVoldTaskListener> mListener;
     std::thread mThread;
 
     void run();
 
+    void notifyProgress(int progress);
+
+    status_t execRm(const std::string& path, int startProgress, int stepProgress);
+    status_t execCp(const std::string& fromPath, const std::string& toPath,
+            int startProgress, int stepProgress);
+
     DISALLOW_COPY_AND_ASSIGN(MoveTask);
 };
 
diff --git a/TrimTask.cpp b/TrimTask.cpp
index 08e6499..d37ec20 100644
--- a/TrimTask.cpp
+++ b/TrimTask.cpp
@@ -15,7 +15,6 @@
  */
 
 #include "TrimTask.h"
-#include "Benchmark.h"
 #include "Utils.h"
 #include "VolumeManager.h"
 #include "ResponseCode.h"
@@ -37,8 +36,6 @@
 /* From a would-be kernel header */
 #define FIDTRIM         _IOWR('f', 128, struct fstrim_range)    /* Deep discard trim */
 
-#define BENCHMARK_ENABLED 1
-
 using android::base::StringPrintf;
 
 namespace android {
@@ -46,7 +43,8 @@
 
 static const char* kWakeLock = "TrimTask";
 
-TrimTask::TrimTask(int flags) : mFlags(flags) {
+TrimTask::TrimTask(int flags, const android::sp<android::os::IVoldTaskListener>& listener) :
+        mFlags(flags), mListener(listener) {
     // Collect both fstab and vold volumes
     addFromFstab();
 
@@ -102,23 +100,21 @@
     mThread = std::thread(&TrimTask::run, this);
 }
 
-static void notifyResult(const std::string& path, int64_t bytes, int64_t delta) {
-    std::string res(path
-            + " " + std::to_string(bytes)
-            + " " + std::to_string(delta));
-    VolumeManager::Instance()->getBroadcaster()->sendBroadcast(
-            ResponseCode::TrimResult, res.c_str(), false);
-}
-
 void TrimTask::run() {
     acquire_wake_lock(PARTIAL_WAKE_LOCK, kWakeLock);
 
     for (const auto& path : mPaths) {
         LOG(DEBUG) << "Starting trim of " << path;
 
+        android::os::PersistableBundle extras;
+        extras.putString(String16("path"), String16(path.c_str()));
+
         int fd = open(path.c_str(), O_RDONLY | O_DIRECTORY | O_CLOEXEC | O_NOFOLLOW);
         if (fd < 0) {
             PLOG(WARNING) << "Failed to open " << path;
+            if (mListener) {
+                mListener->onStatus(-1, extras);
+            }
             continue;
         }
 
@@ -129,22 +125,25 @@
         nsecs_t start = systemTime(SYSTEM_TIME_BOOTTIME);
         if (ioctl(fd, (mFlags & Flags::kDeepTrim) ? FIDTRIM : FITRIM, &range)) {
             PLOG(WARNING) << "Trim failed on " << path;
-            notifyResult(path, -1, -1);
+            if (mListener) {
+                mListener->onStatus(-1, extras);
+            }
         } else {
-            nsecs_t delta = systemTime(SYSTEM_TIME_BOOTTIME) - start;
+            nsecs_t time = systemTime(SYSTEM_TIME_BOOTTIME) - start;
             LOG(INFO) << "Trimmed " << range.len << " bytes on " << path
-                    << " in " << nanoseconds_to_milliseconds(delta) << "ms";
-            notifyResult(path, range.len, delta);
+                    << " in " << nanoseconds_to_milliseconds(time) << "ms";
+            extras.putLong(String16("bytes"), range.len);
+            extras.putLong(String16("time"), time);
+            if (mListener) {
+                mListener->onStatus(0, extras);
+            }
         }
         close(fd);
+    }
 
-        if (mFlags & Flags::kBenchmarkAfter) {
-#if BENCHMARK_ENABLED
-            BenchmarkPrivate(path);
-#else
-            LOG(DEBUG) << "Benchmark disabled";
-#endif
-        }
+    if (mListener) {
+        android::os::PersistableBundle extras;
+        mListener->onFinished(0, extras);
     }
 
     release_wake_lock(kWakeLock);
diff --git a/TrimTask.h b/TrimTask.h
index 2ade7b5..a87728b 100644
--- a/TrimTask.h
+++ b/TrimTask.h
@@ -17,6 +17,7 @@
 #ifndef ANDROID_VOLD_TRIM_TASK_H
 #define ANDROID_VOLD_TRIM_TASK_H
 
+#include "android/os/IVoldTaskListener.h"
 #include "Utils.h"
 
 #include <thread>
@@ -27,18 +28,18 @@
 
 class TrimTask {
 public:
-    explicit TrimTask(int flags);
+    explicit TrimTask(int flags, const android::sp<android::os::IVoldTaskListener>& listener);
     virtual ~TrimTask();
 
     enum Flags {
         kDeepTrim = 1 << 0,
-        kBenchmarkAfter = 1 << 1,
     };
 
     void start();
 
 private:
     int mFlags;
+    android::sp<android::os::IVoldTaskListener> mListener;
     std::list<std::string> mPaths;
     std::thread mThread;
 
diff --git a/VoldNativeService.cpp b/VoldNativeService.cpp
index f5f0838..6c25674 100644
--- a/VoldNativeService.cpp
+++ b/VoldNativeService.cpp
@@ -16,6 +16,7 @@
 
 #include "VoldNativeService.h"
 #include "VolumeManager.h"
+#include "BenchmarkTask.h"
 #include "MoveTask.h"
 #include "Process.h"
 #include "TrimTask.h"
@@ -333,17 +334,39 @@
     return translate(vol->format(fsType));
 }
 
-binder::Status VoldNativeService::benchmark(const std::string& volId, int64_t* _aidl_return) {
+binder::Status VoldNativeService::benchmark(const std::string& volId,
+        const android::sp<android::os::IVoldTaskListener>& listener) {
     ENFORCE_UID(AID_SYSTEM);
     CHECK_ARGUMENT_ID(volId);
     ACQUIRE_LOCK;
 
-    *_aidl_return = VolumeManager::Instance()->benchmarkPrivate(volId);
+    std::string path;
+    if (volId == "private" || volId == "null") {
+        path = "/data";
+    } else {
+        auto vol = VolumeManager::Instance()->findVolume(volId);
+        if (vol == nullptr) {
+            return error("Failed to find volume " + volId);
+        }
+        if (vol->getType() != VolumeBase::Type::kPrivate) {
+            return error("Volume " + volId + " not private");
+        }
+        if (vol->getState() != VolumeBase::State::kMounted) {
+            return error("Volume " + volId + " not mounted");
+        }
+        path = vol->getPath();
+    }
+
+    if (path.empty()) {
+        return error("Volume " + volId + " missing path");
+    }
+
+    (new android::vold::BenchmarkTask(path, listener))->start();
     return ok();
 }
 
 binder::Status VoldNativeService::moveStorage(const std::string& fromVolId,
-        const std::string& toVolId) {
+        const std::string& toVolId, const android::sp<android::os::IVoldTaskListener>& listener) {
     ENFORCE_UID(AID_SYSTEM);
     CHECK_ARGUMENT_ID(fromVolId);
     CHECK_ARGUMENT_ID(toVolId);
@@ -356,7 +379,7 @@
     } else if (toVol == nullptr) {
         return error("Failed to find volume " + toVolId);
     }
-    (new android::vold::MoveTask(fromVol, toVol))->start();
+    (new android::vold::MoveTask(fromVol, toVol, listener))->start();
     return ok();
 }
 
@@ -402,11 +425,12 @@
     return translate(VolumeManager::Instance()->destroyObb(volId));
 }
 
-binder::Status VoldNativeService::fstrim(int32_t fstrimFlags) {
+binder::Status VoldNativeService::fstrim(int32_t fstrimFlags,
+        const android::sp<android::os::IVoldTaskListener>& listener) {
     ENFORCE_UID(AID_SYSTEM);
     ACQUIRE_LOCK;
 
-    (new android::vold::TrimTask(fstrimFlags))->start();
+    (new android::vold::TrimTask(fstrimFlags, listener))->start();
     return ok();
 }
 
diff --git a/VoldNativeService.h b/VoldNativeService.h
index b6b5d75..a00010b 100644
--- a/VoldNativeService.h
+++ b/VoldNativeService.h
@@ -48,9 +48,11 @@
     binder::Status mount(const std::string& volId, int32_t mountFlags, int32_t mountUserId);
     binder::Status unmount(const std::string& volId);
     binder::Status format(const std::string& volId, const std::string& fsType);
-    binder::Status benchmark(const std::string& volId, int64_t* _aidl_return);
+    binder::Status benchmark(const std::string& volId,
+            const android::sp<android::os::IVoldTaskListener>& listener);
 
-    binder::Status moveStorage(const std::string& fromVolId, const std::string& toVolId);
+    binder::Status moveStorage(const std::string& fromVolId, const std::string& toVolId,
+            const android::sp<android::os::IVoldTaskListener>& listener);
 
     binder::Status remountUid(int32_t uid, int32_t remountMode);
 
@@ -60,7 +62,8 @@
             int32_t ownerGid, std::string* _aidl_return);
     binder::Status destroyObb(const std::string& volId);
 
-    binder::Status fstrim(int32_t fstrimFlags);
+    binder::Status fstrim(int32_t fstrimFlags,
+            const android::sp<android::os::IVoldTaskListener>& listener);
 
     binder::Status mountAppFuse(int32_t uid, int32_t pid, int32_t mountId,
             android::base::unique_fd* _aidl_return);
diff --git a/VolumeManager.cpp b/VolumeManager.cpp
index 022caff..3150997 100644
--- a/VolumeManager.cpp
+++ b/VolumeManager.cpp
@@ -47,7 +47,6 @@
 
 #include <private/android_filesystem_config.h>
 
-#include "Benchmark.h"
 #include "model/EmulatedVolume.h"
 #include "model/ObbVolume.h"
 #include "VolumeManager.h"
@@ -459,25 +458,6 @@
     }
 }
 
-nsecs_t VolumeManager::benchmarkPrivate(const std::string& id) {
-    std::string path;
-    if (id == "private" || id == "null") {
-        path = "/data";
-    } else {
-        auto vol = findVolume(id);
-        if (vol != nullptr && vol->getState() == android::vold::VolumeBase::State::kMounted) {
-            path = vol->getPath();
-        }
-    }
-
-    if (path.empty()) {
-        LOG(WARNING) << "Failed to find volume for " << id;
-        return -1;
-    }
-
-    return android::vold::BenchmarkPrivate(path);
-}
-
 int VolumeManager::forgetPartition(const std::string& partGuid) {
     std::string normalizedGuid;
     if (android::vold::NormalizeHex(partGuid, normalizedGuid)) {
diff --git a/VolumeManager.h b/VolumeManager.h
index 2751ad5..a00520e 100644
--- a/VolumeManager.h
+++ b/VolumeManager.h
@@ -132,8 +132,6 @@
 
     void listVolumes(android::vold::VolumeBase::Type type, std::list<std::string>& list);
 
-    nsecs_t benchmarkPrivate(const std::string& id);
-
     int forgetPartition(const std::string& partGuid);
 
     int onUserAdded(userid_t userId, int userSerialNumber);
diff --git a/binder/android/os/IVold.aidl b/binder/android/os/IVold.aidl
index 0a05e6e..1736829 100644
--- a/binder/android/os/IVold.aidl
+++ b/binder/android/os/IVold.aidl
@@ -17,6 +17,7 @@
 package android.os;
 
 import android.os.IVoldListener;
+import android.os.IVoldTaskListener;
 
 /** {@hide} */
 interface IVold {
@@ -37,9 +38,10 @@
     void mount(@utf8InCpp String volId, int mountFlags, int mountUserId);
     void unmount(@utf8InCpp String volId);
     void format(@utf8InCpp String volId, @utf8InCpp String fsType);
-    long benchmark(@utf8InCpp String volId);
+    void benchmark(@utf8InCpp String volId, IVoldTaskListener listener);
 
-    void moveStorage(@utf8InCpp String fromVolId, @utf8InCpp String toVolId);
+    void moveStorage(@utf8InCpp String fromVolId, @utf8InCpp String toVolId,
+            IVoldTaskListener listener);
 
     void remountUid(int uid, int remountMode);
 
@@ -49,7 +51,7 @@
             @utf8InCpp String sourceKey, int ownerGid);
     void destroyObb(@utf8InCpp String volId);
 
-    void fstrim(int fstrimFlags);
+    void fstrim(int fstrimFlags, IVoldTaskListener listener);
 
     FileDescriptor mountAppFuse(int uid, int pid, int mountId);
     void unmountAppFuse(int uid, int pid, int mountId);
@@ -98,7 +100,6 @@
     const int ENCRYPTION_STATE_ERROR_CORRUPT = -4;
 
     const int FSTRIM_FLAG_DEEP_TRIM = 1;
-    const int FSTRIM_FLAG_BENCHMARK_AFTER = 2;
 
     const int MOUNT_FLAG_PRIMARY = 1;
     const int MOUNT_FLAG_VISIBLE = 2;
diff --git a/binder/android/os/IVoldTaskListener.aidl b/binder/android/os/IVoldTaskListener.aidl
new file mode 100644
index 0000000..e2bac04
--- /dev/null
+++ b/binder/android/os/IVoldTaskListener.aidl
@@ -0,0 +1,25 @@
+/*
+ * 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;
+
+import android.os.PersistableBundle;
+
+/** {@hide} */
+oneway interface IVoldTaskListener {
+    void onStatus(int status, in PersistableBundle extras);
+    void onFinished(int status, in PersistableBundle extras);
+}