Move long-running calls to async with listeners.

Now that we're using Binder, we can have callers provide explicit
listeners for every request instead of trying to squeeze them all
into unsolicited socket events.

Move benchmarking to be async to avoid blocking other commands for
up to several minutes.  Remove post-trim benchmarking flag, since
benchmarking now requires a separate callback.  Will bring back in
a future CL.

Test: cts-tradefed run commandAndExit cts-dev -m CtsAppSecurityHostTestCases -t android.appsecurity.cts.AdoptableHostTest
Test: adb shell sm fstrim
Bug: 62201209, 13758960
Change-Id: I0f2ebf1ac3b4252ecd6b44303f2887adfdb58e86
gugelfrei
Jeff Sharkey 7 years ago
parent 0990b69d6b
commit 52f7a91934

@ -26,7 +26,7 @@ common_src_files := \
model/ObbVolume.cpp \
Utils.cpp \
MoveTask.cpp \
Benchmark.cpp \
BenchmarkTask.cpp \
TrimTask.cpp \
KeyBuffer.cpp \
Keymaster.cpp \
@ -36,9 +36,16 @@ common_src_files := \
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_CLANG := true
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_CFLAGS := $(vold_cflags)
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_FLAGS := $(common_local_tidy_flags)
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_SHARED_LIBRARIES := $(common_shared_libraries)
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_TIDY_CHECKS := $(common_local_tidy_checks)
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_CFLAGS := $(vold_cflags)
LOCAL_CONLYFLAGS := $(vold_conlyflags)
LOCAL_INIT_RC := vdc.rc
LOCAL_AIDL_INCLUDES := $(LOCAL_PATH)/binder
LOCAL_AIDL_INCLUDES := $(common_aidl_includes)
include $(BUILD_EXECUTABLE)

@ -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 @@ using android::base::WriteStringToFile;
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) {
}
BenchmarkTask::~BenchmarkTask() {
}
void BenchmarkTask::start() {
mThread = std::thread(&BenchmarkTask::run, this);
}
static nsecs_t benchmark(const std::string& path) {
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 @@ static nsecs_t benchmark(const std::string& path) {
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;
}
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;
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);
}
return benchmark(benchPath);
release_wake_lock(kWakeLock);
}
} // namespace vold

@ -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

@ -256,13 +256,14 @@ int CommandListener::VolumeCmd::runCommand(SocketClient *cli,
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 @@ int CommandListener::FstrimCmd::runCommand(SocketClient *cli,
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);
}

@ -45,9 +45,9 @@ static const char* kRmPath = "/system/bin/rm";
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 @@ void MoveTask::start() {
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 @@ static status_t pushBackContents(const std::string& path, std::vector<std::strin
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 @@ static status_t execRm(const std::string& path, int startProgress, int stepProgr
#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);

@ -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 @@ namespace vold {
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 @@ public:
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);
};

@ -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 @@ namespace vold {
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 @@ void TrimTask::start() {
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 @@ void TrimTask::run() {
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);

@ -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 @@ namespace vold {
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;

@ -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 @@ binder::Status VoldNativeService::format(const std::string& volId, const std::st
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 @@ binder::Status VoldNativeService::moveStorage(const std::string& fromVolId,
} 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 @@ binder::Status VoldNativeService::destroyObb(const std::string& volId) {
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();
}

@ -48,9 +48,11 @@ public:
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 @@ public:
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);

@ -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 @@ void VolumeManager::listVolumes(android::vold::VolumeBase::Type type,
}
}
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)) {

@ -132,8 +132,6 @@ public:
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);

@ -17,6 +17,7 @@
package android.os;
import android.os.IVoldListener;
import android.os.IVoldTaskListener;
/** {@hide} */
interface IVold {
@ -37,9 +38,10 @@ interface IVold {
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 @@ interface IVold {
@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 @@ interface IVold {
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;

@ -1,5 +1,5 @@
/*
* Copyright (C) 2015 The Android Open Source Project
* 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.
@ -14,21 +14,12 @@
* limitations under the License.
*/
#ifndef ANDROID_VOLD_BENCHMARK_H
#define ANDROID_VOLD_BENCHMARK_H
package android.os;
#include <utils/Errors.h>
#include <utils/Timers.h>
import android.os.PersistableBundle;
#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
/** {@hide} */
oneway interface IVoldTaskListener {
void onStatus(int status, in PersistableBundle extras);
void onFinished(int status, in PersistableBundle extras);
}
Loading…
Cancel
Save