[IncrementalService] getLoadingProgress (v1)
This is to unblock Launcher's work on progress ring. Currently it uses
incfs getFilledBlocks(). Will switch to the new incfs progress reporting
API once it is ready.
Test: unit test
Test: adb shell dumpsys incremental
BUG: 165799231
Change-Id: Icd68124806454f888826294da36f109bca9771ac
diff --git a/core/java/android/os/incremental/IIncrementalService.aidl b/core/java/android/os/incremental/IIncrementalService.aidl
index 61e6a05..be8b929 100644
--- a/core/java/android/os/incremental/IIncrementalService.aidl
+++ b/core/java/android/os/incremental/IIncrementalService.aidl
@@ -90,9 +90,10 @@
int unlink(int storageId, in @utf8InCpp String path);
/**
- * Checks if a file's certain range is loaded. File is specified by its path.
+ * Returns overall loading progress of all the files on a storage, progress value between [0,1].
+ * Returns a negative value on error.
*/
- boolean isFileRangeLoaded(int storageId, in @utf8InCpp String path, long start, long end);
+ float getLoadingProgress(int storageId);
/**
* Reads the metadata of a file. File is specified by either its path or 16 byte id.
diff --git a/core/java/android/os/incremental/IncrementalStorage.java b/core/java/android/os/incremental/IncrementalStorage.java
index ca6114f..b8dbfbb 100644
--- a/core/java/android/os/incremental/IncrementalStorage.java
+++ b/core/java/android/os/incremental/IncrementalStorage.java
@@ -304,29 +304,21 @@
}
/**
- * Checks whether a file under the current storage directory is fully loaded.
+ * Returns the loading progress of a storage
*
- * @param path The relative path of the file.
- * @return True if the file is fully loaded.
+ * @return progress value between [0, 1].
*/
- public boolean isFileFullyLoaded(@NonNull String path) {
- return isFileRangeLoaded(path, 0, -1);
- }
-
- /**
- * Checks whether a range in a file if loaded.
- *
- * @param path The relative path of the file.
- * @param start The starting offset of the range.
- * @param end The ending offset of the range.
- * @return True if the file is fully loaded.
- */
- public boolean isFileRangeLoaded(@NonNull String path, long start, long end) {
+ public float getLoadingProgress() throws IOException {
try {
- return mService.isFileRangeLoaded(mId, path, start, end);
+ final float res = mService.getLoadingProgress(mId);
+ if (res < 0) {
+ throw new IOException(
+ "getLoadingProgress() failed at querying loading progress, errno " + -res);
+ }
+ return res;
} catch (RemoteException e) {
e.rethrowFromSystemServer();
- return false;
+ return 0;
}
}
diff --git a/services/incremental/BinderIncrementalService.cpp b/services/incremental/BinderIncrementalService.cpp
index 0ae10b6..41945a2 100644
--- a/services/incremental/BinderIncrementalService.cpp
+++ b/services/incremental/BinderIncrementalService.cpp
@@ -237,11 +237,9 @@
return ok();
}
-binder::Status BinderIncrementalService::isFileRangeLoaded(int32_t storageId,
- const std::string& path, int64_t start,
- int64_t end, bool* _aidl_return) {
- // TODO: implement
- *_aidl_return = false;
+binder::Status BinderIncrementalService::getLoadingProgress(int32_t storageId,
+ float* _aidl_return) {
+ *_aidl_return = mImpl.getLoadingProgress(storageId);
return ok();
}
diff --git a/services/incremental/BinderIncrementalService.h b/services/incremental/BinderIncrementalService.h
index 1015494..8b40350 100644
--- a/services/incremental/BinderIncrementalService.h
+++ b/services/incremental/BinderIncrementalService.h
@@ -66,8 +66,7 @@
int32_t destStorageId, const std::string& destPath,
int32_t* _aidl_return) final;
binder::Status unlink(int32_t storageId, const std::string& path, int32_t* _aidl_return) final;
- binder::Status isFileRangeLoaded(int32_t storageId, const std::string& path, int64_t start,
- int64_t end, bool* _aidl_return) final;
+ binder::Status getLoadingProgress(int32_t storageId, float* _aidl_return) final;
binder::Status getMetadataByPath(int32_t storageId, const std::string& path,
std::vector<uint8_t>* _aidl_return) final;
binder::Status getMetadataById(int32_t storageId, const std::vector<uint8_t>& id,
diff --git a/services/incremental/IncrementalService.cpp b/services/incremental/IncrementalService.cpp
index f7082a9..ba6ae92 100644
--- a/services/incremental/IncrementalService.cpp
+++ b/services/incremental/IncrementalService.cpp
@@ -37,7 +37,6 @@
#include "Metadata.pb.h"
using namespace std::literals;
-namespace fs = std::filesystem;
constexpr const char* kDataUsageStats = "android.permission.LOADER_USAGE_STATS";
constexpr const char* kOpUsage = "android:loader_usage_stats";
@@ -276,6 +275,7 @@
mJni(sm.getJni()),
mLooper(sm.getLooper()),
mTimedQueue(sm.getTimedQueue()),
+ mFs(sm.getFs()),
mIncrementalDir(rootDir) {
CHECK(mVold) << "Vold service is unavailable";
CHECK(mDataLoaderManager) << "DataLoaderManagerService is unavailable";
@@ -283,6 +283,7 @@
CHECK(mJni) << "JNI is unavailable";
CHECK(mLooper) << "Looper is unavailable";
CHECK(mTimedQueue) << "TimedQueue is unavailable";
+ CHECK(mFs) << "Fs is unavailable";
mJobQueue.reserve(16);
mJobProcessor = std::thread([this]() {
@@ -344,7 +345,8 @@
}
dprintf(fd, " storages (%d): {\n", int(mnt.storages.size()));
for (auto&& [storageId, storage] : mnt.storages) {
- dprintf(fd, " [%d] -> [%s]\n", storageId, storage.name.c_str());
+ dprintf(fd, " [%d] -> [%s] (%d %% loaded) \n", storageId, storage.name.c_str(),
+ (int)(getLoadingProgressFromPath(mnt, storage.name.c_str()) * 100));
}
dprintf(fd, " }\n");
@@ -1671,6 +1673,45 @@
return mRunning;
}
+float IncrementalService::getLoadingProgress(StorageId storage) const {
+ std::unique_lock l(mLock);
+ const auto ifs = getIfsLocked(storage);
+ if (!ifs) {
+ LOG(ERROR) << "getLoadingProgress failed, invalid storageId: " << storage;
+ return -EINVAL;
+ }
+ const auto storageInfo = ifs->storages.find(storage);
+ if (storageInfo == ifs->storages.end()) {
+ LOG(ERROR) << "getLoadingProgress failed, no storage: " << storage;
+ return -EINVAL;
+ }
+ l.unlock();
+ return getLoadingProgressFromPath(*ifs, storageInfo->second.name);
+}
+
+float IncrementalService::getLoadingProgressFromPath(const IncFsMount& ifs,
+ std::string_view storagePath) const {
+ size_t totalBlocks = 0, filledBlocks = 0;
+ const auto filePaths = mFs->listFilesRecursive(storagePath);
+ for (const auto& filePath : filePaths) {
+ const auto [filledBlocksCount, totalBlocksCount] =
+ mIncFs->countFilledBlocks(ifs.control, filePath);
+ if (filledBlocksCount < 0) {
+ LOG(ERROR) << "getLoadingProgress failed to get filled blocks count for: " << filePath
+ << " errno: " << filledBlocksCount;
+ return filledBlocksCount;
+ }
+ totalBlocks += totalBlocksCount;
+ filledBlocks += filledBlocksCount;
+ }
+
+ if (totalBlocks == 0) {
+ LOG(ERROR) << "getLoadingProgress failed to get total num of blocks";
+ return -EINVAL;
+ }
+ return (float)filledBlocks / (float)totalBlocks;
+}
+
bool IncrementalService::perfLoggingEnabled() {
static const bool enabled = base::GetBoolProperty("incremental.perflogging", false);
return enabled;
@@ -2029,11 +2070,13 @@
// Healthcheck depends on timestamp of the oldest pending read.
// To get it, we need to re-open a pendingReads FD to get a full list of reads.
- // Additionally we need to re-register for epoll with fresh FDs in case there are no reads.
+ // Additionally we need to re-register for epoll with fresh FDs in case there are no
+ // reads.
const auto now = Clock::now();
const auto kernelTsUs = getOldestPendingReadTs();
if (baseline) {
- // Updating baseline only on looper/epoll callback, i.e. on new set of pending reads.
+ // Updating baseline only on looper/epoll callback, i.e. on new set of pending
+ // reads.
mHealthBase = {now, kernelTsUs};
}
diff --git a/services/incremental/IncrementalService.h b/services/incremental/IncrementalService.h
index a6cc946..cd6bfed 100644
--- a/services/incremental/IncrementalService.h
+++ b/services/incremental/IncrementalService.h
@@ -132,9 +132,7 @@
std::string_view newPath);
int unlink(StorageId storage, std::string_view path);
- bool isRangeLoaded(StorageId storage, FileId file, std::pair<BlockIndex, BlockIndex> range) {
- return false;
- }
+ float getLoadingProgress(StorageId storage) const;
RawMetadata getMetadata(StorageId storage, std::string_view path) const;
RawMetadata getMetadata(StorageId storage, FileId node) const;
@@ -341,6 +339,8 @@
int makeDirs(const IncFsMount& ifs, StorageId storageId, std::string_view path, int mode);
binder::Status applyStorageParams(IncFsMount& ifs, bool enableReadLogs);
+ float getLoadingProgressFromPath(const IncFsMount& ifs, std::string_view path) const;
+
void registerAppOpsCallback(const std::string& packageName);
bool unregisterAppOpsCallback(const std::string& packageName);
void onAppOpChanged(const std::string& packageName);
@@ -363,6 +363,7 @@
const std::unique_ptr<JniWrapper> mJni;
const std::unique_ptr<LooperWrapper> mLooper;
const std::unique_ptr<TimedQueueWrapper> mTimedQueue;
+ const std::unique_ptr<FsWrapper> mFs;
const std::string mIncrementalDir;
mutable std::mutex mLock;
diff --git a/services/incremental/ServiceWrappers.cpp b/services/incremental/ServiceWrappers.cpp
index 99a35ad..1ed46c4 100644
--- a/services/incremental/ServiceWrappers.cpp
+++ b/services/incremental/ServiceWrappers.cpp
@@ -25,6 +25,7 @@
#include <binder/AppOpsManager.h>
#include <utils/String16.h>
+#include <filesystem>
#include <thread>
#include "IncrementalServiceValidation.h"
@@ -165,6 +166,29 @@
FileId getFileId(const Control& control, std::string_view path) const final {
return incfs::getFileId(control, path);
}
+ std::pair<IncFsBlockIndex, IncFsBlockIndex> countFilledBlocks(
+ const Control& control, std::string_view path) const final {
+ const auto fileId = incfs::getFileId(control, path);
+ const auto fd = incfs::openForSpecialOps(control, fileId);
+ int res = fd.get();
+ if (!fd.ok()) {
+ return {res, res};
+ }
+ const auto ranges = incfs::getFilledRanges(res);
+ res = ranges.first;
+ if (res) {
+ return {res, res};
+ }
+ const auto totalBlocksCount = ranges.second.internalRawRanges().endIndex;
+ int filledBlockCount = 0;
+ for (const auto& dataRange : ranges.second.dataRanges()) {
+ filledBlockCount += dataRange.size();
+ }
+ for (const auto& hashRange : ranges.second.hashRanges()) {
+ filledBlockCount += hashRange.size();
+ }
+ return {filledBlockCount, totalBlocksCount};
+ }
ErrorCode link(const Control& control, std::string_view from, std::string_view to) const final {
return incfs::link(control, from, to);
}
@@ -265,6 +289,23 @@
std::thread mThread;
};
+class RealFsWrapper : public FsWrapper {
+public:
+ RealFsWrapper() = default;
+ ~RealFsWrapper() = default;
+
+ std::vector<std::string> listFilesRecursive(std::string_view directoryPath) const final {
+ std::vector<std::string> files;
+ for (const auto& entry : std::filesystem::recursive_directory_iterator(directoryPath)) {
+ if (!entry.is_regular_file()) {
+ continue;
+ }
+ files.push_back(entry.path().c_str());
+ }
+ return files;
+ }
+};
+
RealServiceManager::RealServiceManager(sp<IServiceManager> serviceManager, JNIEnv* env)
: mServiceManager(std::move(serviceManager)), mJvm(RealJniWrapper::getJvm(env)) {}
@@ -316,6 +357,10 @@
return std::make_unique<RealTimedQueueWrapper>(mJvm);
}
+std::unique_ptr<FsWrapper> RealServiceManager::getFs() {
+ return std::make_unique<RealFsWrapper>();
+}
+
static JavaVM* getJavaVm(JNIEnv* env) {
CHECK(env);
JavaVM* jvm = nullptr;
diff --git a/services/incremental/ServiceWrappers.h b/services/incremental/ServiceWrappers.h
index 8cd726fd..82a1704 100644
--- a/services/incremental/ServiceWrappers.h
+++ b/services/incremental/ServiceWrappers.h
@@ -91,6 +91,8 @@
virtual incfs::RawMetadata getMetadata(const Control& control, FileId fileid) const = 0;
virtual incfs::RawMetadata getMetadata(const Control& control, std::string_view path) const = 0;
virtual FileId getFileId(const Control& control, std::string_view path) const = 0;
+ virtual std::pair<IncFsBlockIndex, IncFsBlockIndex> countFilledBlocks(
+ const Control& control, std::string_view path) const = 0;
virtual ErrorCode link(const Control& control, std::string_view from,
std::string_view to) const = 0;
virtual ErrorCode unlink(const Control& control, std::string_view path) const = 0;
@@ -106,7 +108,8 @@
virtual ~AppOpsManagerWrapper() = default;
virtual binder::Status checkPermission(const char* permission, const char* operation,
const char* package) const = 0;
- virtual void startWatchingMode(int32_t op, const String16& packageName, const sp<IAppOpsCallback>& callback) = 0;
+ virtual void startWatchingMode(int32_t op, const String16& packageName,
+ const sp<IAppOpsCallback>& callback) = 0;
virtual void stopWatchingMode(const sp<IAppOpsCallback>& callback) = 0;
};
@@ -134,6 +137,12 @@
virtual void stop() = 0;
};
+class FsWrapper {
+public:
+ virtual ~FsWrapper() = default;
+ virtual std::vector<std::string> listFilesRecursive(std::string_view directoryPath) const = 0;
+};
+
class ServiceManagerWrapper {
public:
virtual ~ServiceManagerWrapper() = default;
@@ -144,6 +153,7 @@
virtual std::unique_ptr<JniWrapper> getJni() = 0;
virtual std::unique_ptr<LooperWrapper> getLooper() = 0;
virtual std::unique_ptr<TimedQueueWrapper> getTimedQueue() = 0;
+ virtual std::unique_ptr<FsWrapper> getFs() = 0;
};
// --- Real stuff ---
@@ -159,6 +169,7 @@
std::unique_ptr<JniWrapper> getJni() final;
std::unique_ptr<LooperWrapper> getLooper() final;
std::unique_ptr<TimedQueueWrapper> getTimedQueue() final;
+ std::unique_ptr<FsWrapper> getFs() final;
private:
template <class INTERFACE>
diff --git a/services/incremental/test/IncrementalServiceTest.cpp b/services/incremental/test/IncrementalServiceTest.cpp
index 1ae9e25..44cef49 100644
--- a/services/incremental/test/IncrementalServiceTest.cpp
+++ b/services/incremental/test/IncrementalServiceTest.cpp
@@ -54,8 +54,10 @@
MOCK_CONST_METHOD1(unmountIncFs, binder::Status(const std::string& dir));
MOCK_CONST_METHOD2(bindMount,
binder::Status(const std::string& sourceDir, const std::string& argetDir));
- MOCK_CONST_METHOD2(setIncFsMountOptions,
- binder::Status(const ::android::os::incremental::IncrementalFileSystemControlParcel&, bool));
+ MOCK_CONST_METHOD2(
+ setIncFsMountOptions,
+ binder::Status(const ::android::os::incremental::IncrementalFileSystemControlParcel&,
+ bool));
void mountIncFsFails() {
ON_CALL(*this, mountIncFs(_, _, _, _))
@@ -80,8 +82,8 @@
}
void setIncFsMountOptionsFails() const {
ON_CALL(*this, setIncFsMountOptions(_, _))
- .WillByDefault(
- Return(binder::Status::fromExceptionCode(1, String8("failed to set options"))));
+ .WillByDefault(Return(
+ binder::Status::fromExceptionCode(1, String8("failed to set options"))));
}
void setIncFsMountOptionsSuccess() {
ON_CALL(*this, setIncFsMountOptions(_, _)).WillByDefault(Return(binder::Status::ok()));
@@ -280,8 +282,12 @@
MOCK_CONST_METHOD2(getMetadata, RawMetadata(const Control& control, FileId fileid));
MOCK_CONST_METHOD2(getMetadata, RawMetadata(const Control& control, std::string_view path));
MOCK_CONST_METHOD2(getFileId, FileId(const Control& control, std::string_view path));
+ MOCK_CONST_METHOD2(countFilledBlocks,
+ std::pair<IncFsBlockIndex, IncFsBlockIndex>(const Control& control,
+ std::string_view path));
MOCK_CONST_METHOD3(link,
- ErrorCode(const Control& control, std::string_view from, std::string_view to));
+ ErrorCode(const Control& control, std::string_view from,
+ std::string_view to));
MOCK_CONST_METHOD2(unlink, ErrorCode(const Control& control, std::string_view path));
MOCK_CONST_METHOD2(openForSpecialOps, base::unique_fd(const Control& control, FileId id));
MOCK_CONST_METHOD1(writeBlocks, ErrorCode(std::span<const DataBlock> blocks));
@@ -293,6 +299,19 @@
void makeFileFails() { ON_CALL(*this, makeFile(_, _, _, _, _)).WillByDefault(Return(-1)); }
void makeFileSuccess() { ON_CALL(*this, makeFile(_, _, _, _, _)).WillByDefault(Return(0)); }
+
+ void countFilledBlocksSuccess() {
+ ON_CALL(*this, countFilledBlocks(_, _)).WillByDefault(Return(std::make_pair(1, 2)));
+ }
+
+ void countFilledBlocksFails() {
+ ON_CALL(*this, countFilledBlocks(_, _)).WillByDefault(Return(std::make_pair(-1, -1)));
+ }
+
+ void countFilledBlocksEmpty() {
+ ON_CALL(*this, countFilledBlocks(_, _)).WillByDefault(Return(std::make_pair(0, 0)));
+ }
+
void openMountSuccess() {
ON_CALL(*this, openMount(_)).WillByDefault(Invoke(this, &MockIncFs::openMountForHealth));
}
@@ -447,6 +466,21 @@
Job mWhat;
};
+class MockFsWrapper : public FsWrapper {
+public:
+ MOCK_CONST_METHOD1(listFilesRecursive, std::vector<std::string>(std::string_view));
+ void hasNoFile() {
+ ON_CALL(*this, listFilesRecursive(_)).WillByDefault(Return(std::vector<std::string>()));
+ }
+ void hasFiles() {
+ ON_CALL(*this, listFilesRecursive(_))
+ .WillByDefault(Invoke(this, &MockFsWrapper::fakeFiles));
+ }
+ std::vector<std::string> fakeFiles(std::string_view directoryPath) {
+ return {"base.apk", "split.apk", "lib/a.so"};
+ }
+};
+
class MockStorageHealthListener : public os::incremental::BnStorageHealthListener {
public:
MOCK_METHOD2(onHealthStatus, binder::Status(int32_t storageId, int32_t status));
@@ -474,23 +508,28 @@
std::unique_ptr<MockAppOpsManager> appOpsManager,
std::unique_ptr<MockJniWrapper> jni,
std::unique_ptr<MockLooperWrapper> looper,
- std::unique_ptr<MockTimedQueueWrapper> timedQueue)
+ std::unique_ptr<MockTimedQueueWrapper> timedQueue,
+ std::unique_ptr<MockFsWrapper> fs)
: mVold(std::move(vold)),
mDataLoaderManager(std::move(dataLoaderManager)),
mIncFs(std::move(incfs)),
mAppOpsManager(std::move(appOpsManager)),
mJni(std::move(jni)),
mLooper(std::move(looper)),
- mTimedQueue(std::move(timedQueue)) {}
+ mTimedQueue(std::move(timedQueue)),
+ mFs(std::move(fs)) {}
std::unique_ptr<VoldServiceWrapper> getVoldService() final { return std::move(mVold); }
std::unique_ptr<DataLoaderManagerWrapper> getDataLoaderManager() final {
return std::move(mDataLoaderManager);
}
std::unique_ptr<IncFsWrapper> getIncFs() final { return std::move(mIncFs); }
- std::unique_ptr<AppOpsManagerWrapper> getAppOpsManager() final { return std::move(mAppOpsManager); }
+ std::unique_ptr<AppOpsManagerWrapper> getAppOpsManager() final {
+ return std::move(mAppOpsManager);
+ }
std::unique_ptr<JniWrapper> getJni() final { return std::move(mJni); }
std::unique_ptr<LooperWrapper> getLooper() final { return std::move(mLooper); }
std::unique_ptr<TimedQueueWrapper> getTimedQueue() final { return std::move(mTimedQueue); }
+ std::unique_ptr<FsWrapper> getFs() final { return std::move(mFs); }
private:
std::unique_ptr<MockVoldService> mVold;
@@ -500,6 +539,7 @@
std::unique_ptr<MockJniWrapper> mJni;
std::unique_ptr<MockLooperWrapper> mLooper;
std::unique_ptr<MockTimedQueueWrapper> mTimedQueue;
+ std::unique_ptr<MockFsWrapper> mFs;
};
// --- IncrementalServiceTest ---
@@ -523,6 +563,8 @@
mLooper = looper.get();
auto timedQueue = std::make_unique<NiceMock<MockTimedQueueWrapper>>();
mTimedQueue = timedQueue.get();
+ auto fs = std::make_unique<NiceMock<MockFsWrapper>>();
+ mFs = fs.get();
mIncrementalService =
std::make_unique<IncrementalService>(MockServiceManager(std::move(vold),
std::move(
@@ -531,12 +573,14 @@
std::move(appOps),
std::move(jni),
std::move(looper),
- std::move(timedQueue)),
+ std::move(timedQueue),
+ std::move(fs)),
mRootDir.path);
mDataLoaderParcel.packageName = "com.test";
mDataLoaderParcel.arguments = "uri";
mDataLoaderManager->unbindFromDataLoaderSuccess();
mIncrementalService->onSystemReady();
+ setupSuccess();
}
void setUpExistingMountDir(const std::string& rootDir) {
@@ -560,6 +604,14 @@
.WillByDefault(Invoke(mIncFs, &MockIncFs::getStorageMetadata));
}
+ void setupSuccess() {
+ mVold->mountIncFsSuccess();
+ mIncFs->makeFileSuccess();
+ mVold->bindMountSuccess();
+ mDataLoaderManager->bindToDataLoaderSuccess();
+ mDataLoaderManager->getDataLoaderSuccess();
+ }
+
protected:
NiceMock<MockVoldService>* mVold = nullptr;
NiceMock<MockIncFs>* mIncFs = nullptr;
@@ -568,6 +620,7 @@
NiceMock<MockJniWrapper>* mJni = nullptr;
NiceMock<MockLooperWrapper>* mLooper = nullptr;
NiceMock<MockTimedQueueWrapper>* mTimedQueue = nullptr;
+ NiceMock<MockFsWrapper>* mFs = nullptr;
NiceMock<MockDataLoader>* mDataLoader = nullptr;
std::unique_ptr<IncrementalService> mIncrementalService;
TemporaryDir mRootDir;
@@ -641,11 +694,6 @@
}
TEST_F(IncrementalServiceTest, testDeleteStorageSuccess) {
- mVold->mountIncFsSuccess();
- mIncFs->makeFileSuccess();
- mVold->bindMountSuccess();
- mDataLoaderManager->bindToDataLoaderSuccess();
- mDataLoaderManager->getDataLoaderSuccess();
EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(1);
EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
@@ -661,11 +709,6 @@
}
TEST_F(IncrementalServiceTest, testDataLoaderDestroyed) {
- mVold->mountIncFsSuccess();
- mIncFs->makeFileSuccess();
- mVold->bindMountSuccess();
- mDataLoaderManager->bindToDataLoaderSuccess();
- mDataLoaderManager->getDataLoaderSuccess();
EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(2);
EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(2);
@@ -682,12 +725,7 @@
}
TEST_F(IncrementalServiceTest, testStartDataLoaderCreate) {
- mVold->mountIncFsSuccess();
- mIncFs->makeFileSuccess();
- mVold->bindMountSuccess();
mDataLoader->initializeCreateOkNoStatus();
- mDataLoaderManager->bindToDataLoaderSuccess();
- mDataLoaderManager->getDataLoaderSuccess();
EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(1);
EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
@@ -705,12 +743,7 @@
}
TEST_F(IncrementalServiceTest, testStartDataLoaderPendingStart) {
- mVold->mountIncFsSuccess();
- mIncFs->makeFileSuccess();
- mVold->bindMountSuccess();
mDataLoader->initializeCreateOkNoStatus();
- mDataLoaderManager->bindToDataLoaderSuccess();
- mDataLoaderManager->getDataLoaderSuccess();
EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(1);
EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(2);
@@ -727,12 +760,7 @@
}
TEST_F(IncrementalServiceTest, testStartDataLoaderCreateUnavailable) {
- mVold->mountIncFsSuccess();
- mIncFs->makeFileSuccess();
- mVold->bindMountSuccess();
mDataLoader->initializeCreateOkNoStatus();
- mDataLoaderManager->bindToDataLoaderSuccess();
- mDataLoaderManager->getDataLoaderSuccess();
EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(1);
EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
@@ -748,14 +776,10 @@
}
TEST_F(IncrementalServiceTest, testStartDataLoaderRecreateOnPendingReads) {
- mVold->mountIncFsSuccess();
- mIncFs->makeFileSuccess();
- mIncFs->openMountSuccess();
mIncFs->waitForPendingReadsSuccess();
- mVold->bindMountSuccess();
+ mIncFs->openMountSuccess();
mDataLoader->initializeCreateOkNoStatus();
- mDataLoaderManager->bindToDataLoaderSuccess();
- mDataLoaderManager->getDataLoaderSuccess();
+
EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(2);
EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(2);
EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(2);
@@ -776,12 +800,8 @@
}
TEST_F(IncrementalServiceTest, testStartDataLoaderUnhealthyStorage) {
- mVold->mountIncFsSuccess();
- mIncFs->makeFileSuccess();
mIncFs->openMountSuccess();
- mVold->bindMountSuccess();
- mDataLoaderManager->bindToDataLoaderSuccess();
- mDataLoaderManager->getDataLoaderSuccess();
+
EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(1);
EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
@@ -906,13 +926,9 @@
}
TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccess) {
- mVold->mountIncFsSuccess();
- mIncFs->makeFileSuccess();
- mVold->bindMountSuccess();
mVold->setIncFsMountOptionsSuccess();
- mDataLoaderManager->bindToDataLoaderSuccess();
- mDataLoaderManager->getDataLoaderSuccess();
mAppOpsManager->checkPermissionSuccess();
+
EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
// We are calling setIncFsMountOptions(true).
@@ -930,13 +946,9 @@
}
TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccessAndDisabled) {
- mVold->mountIncFsSuccess();
- mIncFs->makeFileSuccess();
- mVold->bindMountSuccess();
mVold->setIncFsMountOptionsSuccess();
- mDataLoaderManager->bindToDataLoaderSuccess();
- mDataLoaderManager->getDataLoaderSuccess();
mAppOpsManager->checkPermissionSuccess();
+
EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
// Enabling and then disabling readlogs.
@@ -958,14 +970,10 @@
}
TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccessAndPermissionChanged) {
- mVold->mountIncFsSuccess();
- mIncFs->makeFileSuccess();
- mVold->bindMountSuccess();
mVold->setIncFsMountOptionsSuccess();
- mDataLoaderManager->bindToDataLoaderSuccess();
- mDataLoaderManager->getDataLoaderSuccess();
mAppOpsManager->checkPermissionSuccess();
mAppOpsManager->initializeStartWatchingMode();
+
EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
// We are calling setIncFsMountOptions(true).
@@ -987,12 +995,8 @@
}
TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsCheckPermissionFails) {
- mVold->mountIncFsSuccess();
- mIncFs->makeFileSuccess();
- mVold->bindMountSuccess();
- mDataLoaderManager->bindToDataLoaderSuccess();
- mDataLoaderManager->getDataLoaderSuccess();
mAppOpsManager->checkPermissionFails();
+
EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
// checkPermission fails, no calls to set opitions, start or stop WatchingMode.
@@ -1008,13 +1012,9 @@
}
TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsFails) {
- mVold->mountIncFsSuccess();
- mIncFs->makeFileSuccess();
- mVold->bindMountSuccess();
mVold->setIncFsMountOptionsFails();
- mDataLoaderManager->bindToDataLoaderSuccess();
- mDataLoaderManager->getDataLoaderSuccess();
mAppOpsManager->checkPermissionSuccess();
+
EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
// We are calling setIncFsMountOptions.
@@ -1031,11 +1031,6 @@
}
TEST_F(IncrementalServiceTest, testMakeDirectory) {
- mVold->mountIncFsSuccess();
- mIncFs->makeFileSuccess();
- mVold->bindMountSuccess();
- mDataLoaderManager->bindToDataLoaderSuccess();
- mDataLoaderManager->getDataLoaderSuccess();
TemporaryDir tempDir;
int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
IncrementalService::CreateOptions::CreateNew,
@@ -1055,11 +1050,6 @@
}
TEST_F(IncrementalServiceTest, testMakeDirectories) {
- mVold->mountIncFsSuccess();
- mIncFs->makeFileSuccess();
- mVold->bindMountSuccess();
- mDataLoaderManager->bindToDataLoaderSuccess();
- mDataLoaderManager->getDataLoaderSuccess();
TemporaryDir tempDir;
int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
IncrementalService::CreateOptions::CreateNew,
@@ -1078,4 +1068,51 @@
auto res = mIncrementalService->makeDirs(storageId, dir_path, 0555);
ASSERT_EQ(res, 0);
}
+
+TEST_F(IncrementalServiceTest, testGetLoadingProgressFailsWithNoFile) {
+ mIncFs->countFilledBlocksSuccess();
+ mFs->hasNoFile();
+
+ TemporaryDir tempDir;
+ int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
+ IncrementalService::CreateOptions::CreateNew,
+ {}, {}, {});
+ ASSERT_EQ(-EINVAL, mIncrementalService->getLoadingProgress(storageId));
+}
+
+TEST_F(IncrementalServiceTest, testGetLoadingProgressFailsWithFailedRanges) {
+ mIncFs->countFilledBlocksFails();
+ mFs->hasFiles();
+
+ TemporaryDir tempDir;
+ int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
+ IncrementalService::CreateOptions::CreateNew,
+ {}, {}, {});
+ EXPECT_CALL(*mIncFs, countFilledBlocks(_, _)).Times(1);
+ ASSERT_EQ(-1, mIncrementalService->getLoadingProgress(storageId));
+}
+
+TEST_F(IncrementalServiceTest, testGetLoadingProgressFailsWithEmptyRanges) {
+ mIncFs->countFilledBlocksEmpty();
+ mFs->hasFiles();
+
+ TemporaryDir tempDir;
+ int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
+ IncrementalService::CreateOptions::CreateNew,
+ {}, {}, {});
+ EXPECT_CALL(*mIncFs, countFilledBlocks(_, _)).Times(3);
+ ASSERT_EQ(-EINVAL, mIncrementalService->getLoadingProgress(storageId));
+}
+
+TEST_F(IncrementalServiceTest, testGetLoadingProgressSuccess) {
+ mIncFs->countFilledBlocksSuccess();
+ mFs->hasFiles();
+
+ TemporaryDir tempDir;
+ int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
+ IncrementalService::CreateOptions::CreateNew,
+ {}, {}, {});
+ EXPECT_CALL(*mIncFs, countFilledBlocks(_, _)).Times(3);
+ ASSERT_EQ(0.5, mIncrementalService->getLoadingProgress(storageId));
+}
} // namespace android::os::incremental