[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/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