diff options
author | 2020-08-20 08:40:29 -0700 | |
---|---|---|
committer | 2020-08-22 04:17:02 +0000 | |
commit | 374f7654dfb00692f6b3c2f6c68997e3ca54092a (patch) | |
tree | 209eec3efa43e43f1795f95905ae61eec575e3a7 | |
parent | 1581527cbd46ac3411fdf0c7068f40c04a9926fd (diff) |
[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
-rw-r--r-- | core/java/android/os/incremental/IIncrementalService.aidl | 5 | ||||
-rw-r--r-- | core/java/android/os/incremental/IncrementalStorage.java | 28 | ||||
-rw-r--r-- | services/incremental/BinderIncrementalService.cpp | 8 | ||||
-rw-r--r-- | services/incremental/BinderIncrementalService.h | 3 | ||||
-rw-r--r-- | services/incremental/IncrementalService.cpp | 51 | ||||
-rw-r--r-- | services/incremental/IncrementalService.h | 7 | ||||
-rw-r--r-- | services/incremental/ServiceWrappers.cpp | 45 | ||||
-rw-r--r-- | services/incremental/ServiceWrappers.h | 13 | ||||
-rw-r--r-- | services/incremental/test/IncrementalServiceTest.cpp | 197 |
9 files changed, 242 insertions, 115 deletions
diff --git a/core/java/android/os/incremental/IIncrementalService.aidl b/core/java/android/os/incremental/IIncrementalService.aidl index 61e6a05fce37..be8b9297ea6a 100644 --- a/core/java/android/os/incremental/IIncrementalService.aidl +++ b/core/java/android/os/incremental/IIncrementalService.aidl @@ -90,9 +90,10 @@ interface IIncrementalService { 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 ca6114f29b9c..b8dbfbb9d109 100644 --- a/core/java/android/os/incremental/IncrementalStorage.java +++ b/core/java/android/os/incremental/IncrementalStorage.java @@ -304,29 +304,21 @@ public final class IncrementalStorage { } /** - * 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. - */ - 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. + * @return progress value between [0, 1]. */ - 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 0ae10b6dc3b5..41945a276fde 100644 --- a/services/incremental/BinderIncrementalService.cpp +++ b/services/incremental/BinderIncrementalService.cpp @@ -237,11 +237,9 @@ binder::Status BinderIncrementalService::unlink(int32_t storageId, const std::st 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 10154946d3ee..8b40350468ce 100644 --- a/services/incremental/BinderIncrementalService.h +++ b/services/incremental/BinderIncrementalService.h @@ -66,8 +66,7 @@ public: 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 f7082a9a1a0c..ba6ae9262aea 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 @@ IncrementalService::IncrementalService(ServiceManagerWrapper&& sm, std::string_v 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 @@ IncrementalService::IncrementalService(ServiceManagerWrapper&& sm, std::string_v 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 @@ void IncrementalService::onDump(int fd) { } 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 @@ bool IncrementalService::waitForNativeBinariesExtraction(StorageId storage) { 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 @@ void IncrementalService::DataLoaderStub::updateHealthStatus(bool baseline) { // 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 a6cc94639c8a..cd6bfedb8a9e 100644 --- a/services/incremental/IncrementalService.h +++ b/services/incremental/IncrementalService.h @@ -132,9 +132,7 @@ public: 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 @@ private: 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 @@ private: 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 99a35adb5074..1ed46c49c5e1 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 @@ public: 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 @@ private: 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 @@ std::unique_ptr<TimedQueueWrapper> RealServiceManager::getTimedQueue() { 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 8cd726fdc0f1..82a170470fee 100644 --- a/services/incremental/ServiceWrappers.h +++ b/services/incremental/ServiceWrappers.h @@ -91,6 +91,8 @@ public: 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 @@ public: 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 @@ public: 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 @@ public: 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 @@ public: 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 1ae9e256c9f4..44cef49a716c 100644 --- a/services/incremental/test/IncrementalServiceTest.cpp +++ b/services/incremental/test/IncrementalServiceTest.cpp @@ -54,8 +54,10 @@ public: 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 @@ public: } 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 @@ public: 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 @@ public: 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 @@ public: 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 @@ public: 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 @@ private: 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 @@ public: 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 @@ public: 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 @@ public: .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 @@ protected: 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, testCreateStoragePrepareDataLoaderFails) { } 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, testDeleteStorageSuccess) { } 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, testDataLoaderDestroyed) { } 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, testStartDataLoaderCreate) { } 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, testStartDataLoaderPendingStart) { } 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, testStartDataLoaderCreateUnavailable) { } 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, testStartDataLoaderRecreateOnPendingReads) { } 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, testStartDataLoaderUnhealthyStorage) { } 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, testSetIncFsMountOptionsSuccess) { } 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, testSetIncFsMountOptionsSuccessAndDisabled) { } 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, testSetIncFsMountOptionsSuccessAndPermissionChang } 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, testSetIncFsMountOptionsCheckPermissionFails) { } 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, testSetIncFsMountOptionsFails) { } 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, testMakeDirectory) { } 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 @@ TEST_F(IncrementalServiceTest, testMakeDirectories) { 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 |