Loading services/incremental/IncrementalService.cpp +64 −8 Original line number Diff line number Diff line Loading @@ -86,6 +86,9 @@ struct Constants { static constexpr auto maxBindDelay = 10000s; static constexpr auto bindDelayMultiplier = 10; static constexpr auto bindDelayJitterDivider = 10; // Max interval after system invoked the DL when readlog collection can be enabled. static constexpr auto readLogsMaxInterval = 2h; }; static const Constants& constants() { Loading Loading @@ -290,6 +293,14 @@ void IncrementalService::IncFsMount::cleanupFilesystem(std::string_view root) { ::rmdir(path::c_str(root)); } void IncrementalService::IncFsMount::setReadLogsEnabled(bool value) { if (value) { flags |= StorageFlags::ReadLogsEnabled; } else { flags &= ~StorageFlags::ReadLogsEnabled; } } IncrementalService::IncrementalService(ServiceManagerWrapper&& sm, std::string_view rootDir) : mVold(sm.getVoldService()), mDataLoaderManager(sm.getDataLoaderManager()), Loading Loading @@ -406,7 +417,7 @@ void IncrementalService::onDump(int fd) { } bool IncrementalService::needStartDataLoaderLocked(IncFsMount& ifs) { if (ifs.dataLoaderStub->params().packageName == Constants::systemPackage) { if (ifs.dataLoaderStub->isSystemDataLoader()) { return true; } Loading Loading @@ -658,7 +669,7 @@ StorageId IncrementalService::createLinkedStorage(std::string_view mountPoint, return storageId; } bool IncrementalService::startLoading(StorageId storage, bool IncrementalService::startLoading(StorageId storageId, content::pm::DataLoaderParamsParcel&& dataLoaderParams, const DataLoaderStatusListener& statusListener, StorageHealthCheckParams&& healthCheckParams, Loading @@ -666,12 +677,12 @@ bool IncrementalService::startLoading(StorageId storage, const std::vector<PerUidReadTimeouts>& perUidReadTimeouts) { // Per Uid timeouts. if (!perUidReadTimeouts.empty()) { setUidReadTimeouts(storage, perUidReadTimeouts); setUidReadTimeouts(storageId, perUidReadTimeouts); } // Re-initialize DataLoader. std::unique_lock l(mLock); const auto ifs = getIfsLocked(storage); const auto ifs = getIfsLocked(storageId); if (!ifs) { return false; } Loading @@ -686,6 +697,32 @@ bool IncrementalService::startLoading(StorageId storage, std::move(healthCheckParams), &healthListener); CHECK(dataLoaderStub); if (dataLoaderStub->isSystemDataLoader()) { // Readlogs from system dataloader (adb) can always be collected. ifs->startLoadingTs = TimePoint::max(); } else { // Assign time when installation wants the DL to start streaming. const auto startLoadingTs = mClock->now(); ifs->startLoadingTs = startLoadingTs; // Setup a callback to disable the readlogs after max interval. addTimedJob(*mTimedQueue, storageId, Constants::readLogsMaxInterval, [this, storageId, startLoadingTs]() { const auto ifs = getIfs(storageId); if (!ifs) { LOG(WARNING) << "Can't disable the readlogs, invalid storageId: " << storageId; return; } if (ifs->startLoadingTs != startLoadingTs) { LOG(INFO) << "Can't disable the readlogs, timestamp mismatch (new " "installation?): " << storageId; return; } setStorageParams(*ifs, storageId, /*enableReadLogs=*/false); }); } return dataLoaderStub->requestStart(); } Loading Loading @@ -735,11 +772,16 @@ int IncrementalService::setStorageParams(StorageId storageId, bool enableReadLog LOG(ERROR) << "setStorageParams failed, invalid storageId: " << storageId; return -EINVAL; } return setStorageParams(*ifs, storageId, enableReadLogs); } const auto& params = ifs->dataLoaderStub->params(); int IncrementalService::setStorageParams(IncFsMount& ifs, StorageId storageId, bool enableReadLogs) { const auto& params = ifs.dataLoaderStub->params(); if (enableReadLogs) { if (!ifs->readLogsAllowed()) { LOG(ERROR) << "setStorageParams failed, readlogs disabled for storageId: " << storageId; if (!ifs.readLogsAllowed()) { LOG(ERROR) << "setStorageParams failed, readlogs disallowed for storageId: " << storageId; return -EPERM; } Loading @@ -760,9 +802,19 @@ int IncrementalService::setStorageParams(StorageId storageId, bool enableReadLog << " check failed: " << status.toString8(); return fromBinderStatus(status); } // Check installation time. const auto now = mClock->now(); const auto startLoadingTs = ifs.startLoadingTs; if (startLoadingTs <= now && now - startLoadingTs > Constants::readLogsMaxInterval) { LOG(ERROR) << "setStorageParams failed, readlogs can't be enabled at this time, " "storageId: " << storageId; return -EPERM; } } if (auto status = applyStorageParams(*ifs, enableReadLogs); !status.isOk()) { if (auto status = applyStorageParams(ifs, enableReadLogs); !status.isOk()) { LOG(ERROR) << "applyStorageParams failed: " << status.toString8(); return fromBinderStatus(status); } Loading Loading @@ -2222,6 +2274,10 @@ sp<content::pm::IDataLoader> IncrementalService::DataLoaderStub::getDataLoader() return dataloader; } bool IncrementalService::DataLoaderStub::isSystemDataLoader() const { return (params().packageName == Constants::systemPackage); } bool IncrementalService::DataLoaderStub::requestCreate() { return setTargetStatus(IDataLoaderStatusListener::DATA_LOADER_CREATED); } Loading services/incremental/IncrementalService.h +5 −6 Original line number Diff line number Diff line Loading @@ -231,6 +231,7 @@ private: MountId id() const { return mId.load(std::memory_order_relaxed); } const content::pm::DataLoaderParamsParcel& params() const { return mParams; } bool isSystemDataLoader() const; void setHealthListener(StorageHealthCheckParams&& healthCheckParams, const StorageHealthListener* healthListener); long elapsedMsSinceOldestPendingRead(); Loading Loading @@ -330,6 +331,7 @@ private: StorageMap storages; BindMap bindPoints; DataLoaderStubPtr dataLoaderStub; TimePoint startLoadingTs = {}; std::atomic<int> nextStorageDirNo{0}; const IncrementalService& incrementalService; Loading @@ -348,12 +350,7 @@ private: void disallowReadLogs() { flags &= ~StorageFlags::ReadLogsAllowed; } int32_t readLogsAllowed() const { return (flags & StorageFlags::ReadLogsAllowed); } void setReadLogsEnabled(bool value) { if (value) flags |= StorageFlags::ReadLogsEnabled; else flags &= ~StorageFlags::ReadLogsEnabled; } void setReadLogsEnabled(bool value); int32_t readLogsEnabled() const { return (flags & StorageFlags::ReadLogsEnabled); } static void cleanupFilesystem(std::string_view root); Loading Loading @@ -411,6 +408,8 @@ private: IncFsMount::StorageMap::const_iterator storageIt, std::string_view path) const; int makeDirs(const IncFsMount& ifs, StorageId storageId, std::string_view path, int mode); int setStorageParams(IncFsMount& ifs, StorageId storageId, bool enableReadLogs); binder::Status applyStorageParams(IncFsMount& ifs, bool enableReadLogs); int isFileFullyLoadedFromPath(const IncFsMount& ifs, std::string_view filePath) const; Loading services/incremental/test/IncrementalServiceTest.cpp +147 −3 Original line number Diff line number Diff line Loading @@ -908,7 +908,7 @@ TEST_F(IncrementalServiceTest, testDataLoaderOnRestart) { EXPECT_CALL(*mDataLoader, start(_)).Times(6); EXPECT_CALL(*mDataLoader, destroy(_)).Times(1); EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2); EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(2); EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(3); TemporaryDir tempDir; int storageId = mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel, Loading Loading @@ -1119,7 +1119,7 @@ TEST_F(IncrementalServiceTest, testStartDataLoaderUnhealthyStorage) { EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2); EXPECT_CALL(*mLooper, addFd(MockIncFs::kPendingReadsFd, _, _, _, _)).Times(2); EXPECT_CALL(*mLooper, removeFd(MockIncFs::kPendingReadsFd)).Times(2); EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(4); EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(5); sp<NiceMock<MockStorageHealthListener>> listener{new NiceMock<MockStorageHealthListener>}; NiceMock<MockStorageHealthListener>* listenerMock = listener.get(); Loading Loading @@ -1292,6 +1292,147 @@ TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccessAndDisabled) { ASSERT_EQ(mDataLoader->setStorageParams(true), -EPERM); } TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccessAndTimedOut) { mVold->setIncFsMountOptionsSuccess(); mAppOpsManager->checkPermissionSuccess(); const auto readLogsMaxInterval = 2h; EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)); EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2); // Enabling and then disabling readlogs. EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(2); EXPECT_CALL(*mVold, setIncFsMountOptions(_, false)).Times(1); // After setIncFsMountOptions succeeded expecting to start watching. EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(1); // Not expecting callback removal. EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0); EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(1); TemporaryDir tempDir; int storageId = mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel, IncrementalService::CreateOptions::CreateNew); ASSERT_GE(storageId, 0); ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {}, {}, {})); // Disable readlogs callback present. ASSERT_EQ(storageId, mTimedQueue->mId); ASSERT_EQ(mTimedQueue->mAfter, readLogsMaxInterval); auto callback = mTimedQueue->mWhat; mTimedQueue->clearJob(storageId); ASSERT_GE(mDataLoader->setStorageParams(true), 0); // Now advance clock for 1hr. mClock->advance(1h); ASSERT_GE(mDataLoader->setStorageParams(true), 0); // Now call the timed callback, it should turn off the readlogs. callback(); // Now advance clock for 2hrs. mClock->advance(readLogsMaxInterval); ASSERT_EQ(mDataLoader->setStorageParams(true), -EPERM); } TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccessAndNoTimedOutForSystem) { mVold->setIncFsMountOptionsSuccess(); mAppOpsManager->checkPermissionSuccess(); const auto readLogsMaxInterval = 2h; EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)); EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2); // Enabling and then disabling readlogs. EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(3); EXPECT_CALL(*mVold, setIncFsMountOptions(_, false)).Times(0); // After setIncFsMountOptions succeeded expecting to start watching. EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(1); // Not expecting callback removal. EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0); EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(0); // System data loader. mDataLoaderParcel.packageName = "android"; TemporaryDir tempDir; int storageId = mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel, IncrementalService::CreateOptions::CreateNew); ASSERT_GE(storageId, 0); ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {}, {}, {})); // No readlogs callback. ASSERT_EQ(mTimedQueue->mAfter, 0ms); ASSERT_EQ(mTimedQueue->mWhat, nullptr); ASSERT_GE(mDataLoader->setStorageParams(true), 0); // Now advance clock for 1hr. mClock->advance(1h); ASSERT_GE(mDataLoader->setStorageParams(true), 0); // Now advance clock for 2hrs. mClock->advance(readLogsMaxInterval); ASSERT_EQ(mDataLoader->setStorageParams(true), 0); } TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccessAndNewInstall) { mVold->setIncFsMountOptionsSuccess(); mAppOpsManager->checkPermissionSuccess(); const auto readLogsMaxInterval = 2h; EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(2); EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2); // Enabling and then disabling readlogs. EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(3); EXPECT_CALL(*mVold, setIncFsMountOptions(_, false)).Times(1); // After setIncFsMountOptions succeeded expecting to start watching. EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(1); // Not expecting callback removal. EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0); EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(2); TemporaryDir tempDir; int storageId = mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel, IncrementalService::CreateOptions::CreateNew); ASSERT_GE(storageId, 0); auto dataLoaderParcel = mDataLoaderParcel; ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(dataLoaderParcel), {}, {}, {}, {})); // Disable readlogs callback present. ASSERT_EQ(storageId, mTimedQueue->mId); ASSERT_EQ(mTimedQueue->mAfter, readLogsMaxInterval); auto callback = mTimedQueue->mWhat; mTimedQueue->clearJob(storageId); ASSERT_GE(mDataLoader->setStorageParams(true), 0); // Now advance clock for 1.5hrs. mClock->advance(90min); ASSERT_GE(mDataLoader->setStorageParams(true), 0); // New installation. ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {}, {}, {})); // New callback present. ASSERT_EQ(storageId, mTimedQueue->mId); ASSERT_EQ(mTimedQueue->mAfter, readLogsMaxInterval); auto callback2 = mTimedQueue->mWhat; mTimedQueue->clearJob(storageId); // Old callback should not disable readlogs (setIncFsMountOptions should be called only once). callback(); // Advance clock for another 1.5hrs. mClock->advance(90min); // Still success even it's 3hrs past first install. ASSERT_GE(mDataLoader->setStorageParams(true), 0); // New one should disable. callback2(); // And timeout. mClock->advance(90min); ASSERT_EQ(mDataLoader->setStorageParams(true), -EPERM); } TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccessAndPermissionChanged) { mVold->setIncFsMountOptionsSuccess(); mAppOpsManager->checkPermissionSuccess(); Loading Loading @@ -1675,7 +1816,7 @@ TEST_F(IncrementalServiceTest, testPerUidTimeoutsTooShort) { EXPECT_CALL(*mDataLoader, start(_)).Times(1); EXPECT_CALL(*mDataLoader, destroy(_)).Times(1); EXPECT_CALL(*mIncFs, setUidReadTimeouts(_, _)).Times(0); EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(0); EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(1); EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2); TemporaryDir tempDir; int storageId = Loading @@ -1702,6 +1843,9 @@ TEST_F(IncrementalServiceTest, testPerUidTimeoutsSuccess) { // Empty storage. mIncFs->countFilledBlocksEmpty(); // Mark DataLoader as 'system' so that readlogs don't pollute the timed queue. mDataLoaderParcel.packageName = "android"; TemporaryDir tempDir; int storageId = mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel, Loading Loading
services/incremental/IncrementalService.cpp +64 −8 Original line number Diff line number Diff line Loading @@ -86,6 +86,9 @@ struct Constants { static constexpr auto maxBindDelay = 10000s; static constexpr auto bindDelayMultiplier = 10; static constexpr auto bindDelayJitterDivider = 10; // Max interval after system invoked the DL when readlog collection can be enabled. static constexpr auto readLogsMaxInterval = 2h; }; static const Constants& constants() { Loading Loading @@ -290,6 +293,14 @@ void IncrementalService::IncFsMount::cleanupFilesystem(std::string_view root) { ::rmdir(path::c_str(root)); } void IncrementalService::IncFsMount::setReadLogsEnabled(bool value) { if (value) { flags |= StorageFlags::ReadLogsEnabled; } else { flags &= ~StorageFlags::ReadLogsEnabled; } } IncrementalService::IncrementalService(ServiceManagerWrapper&& sm, std::string_view rootDir) : mVold(sm.getVoldService()), mDataLoaderManager(sm.getDataLoaderManager()), Loading Loading @@ -406,7 +417,7 @@ void IncrementalService::onDump(int fd) { } bool IncrementalService::needStartDataLoaderLocked(IncFsMount& ifs) { if (ifs.dataLoaderStub->params().packageName == Constants::systemPackage) { if (ifs.dataLoaderStub->isSystemDataLoader()) { return true; } Loading Loading @@ -658,7 +669,7 @@ StorageId IncrementalService::createLinkedStorage(std::string_view mountPoint, return storageId; } bool IncrementalService::startLoading(StorageId storage, bool IncrementalService::startLoading(StorageId storageId, content::pm::DataLoaderParamsParcel&& dataLoaderParams, const DataLoaderStatusListener& statusListener, StorageHealthCheckParams&& healthCheckParams, Loading @@ -666,12 +677,12 @@ bool IncrementalService::startLoading(StorageId storage, const std::vector<PerUidReadTimeouts>& perUidReadTimeouts) { // Per Uid timeouts. if (!perUidReadTimeouts.empty()) { setUidReadTimeouts(storage, perUidReadTimeouts); setUidReadTimeouts(storageId, perUidReadTimeouts); } // Re-initialize DataLoader. std::unique_lock l(mLock); const auto ifs = getIfsLocked(storage); const auto ifs = getIfsLocked(storageId); if (!ifs) { return false; } Loading @@ -686,6 +697,32 @@ bool IncrementalService::startLoading(StorageId storage, std::move(healthCheckParams), &healthListener); CHECK(dataLoaderStub); if (dataLoaderStub->isSystemDataLoader()) { // Readlogs from system dataloader (adb) can always be collected. ifs->startLoadingTs = TimePoint::max(); } else { // Assign time when installation wants the DL to start streaming. const auto startLoadingTs = mClock->now(); ifs->startLoadingTs = startLoadingTs; // Setup a callback to disable the readlogs after max interval. addTimedJob(*mTimedQueue, storageId, Constants::readLogsMaxInterval, [this, storageId, startLoadingTs]() { const auto ifs = getIfs(storageId); if (!ifs) { LOG(WARNING) << "Can't disable the readlogs, invalid storageId: " << storageId; return; } if (ifs->startLoadingTs != startLoadingTs) { LOG(INFO) << "Can't disable the readlogs, timestamp mismatch (new " "installation?): " << storageId; return; } setStorageParams(*ifs, storageId, /*enableReadLogs=*/false); }); } return dataLoaderStub->requestStart(); } Loading Loading @@ -735,11 +772,16 @@ int IncrementalService::setStorageParams(StorageId storageId, bool enableReadLog LOG(ERROR) << "setStorageParams failed, invalid storageId: " << storageId; return -EINVAL; } return setStorageParams(*ifs, storageId, enableReadLogs); } const auto& params = ifs->dataLoaderStub->params(); int IncrementalService::setStorageParams(IncFsMount& ifs, StorageId storageId, bool enableReadLogs) { const auto& params = ifs.dataLoaderStub->params(); if (enableReadLogs) { if (!ifs->readLogsAllowed()) { LOG(ERROR) << "setStorageParams failed, readlogs disabled for storageId: " << storageId; if (!ifs.readLogsAllowed()) { LOG(ERROR) << "setStorageParams failed, readlogs disallowed for storageId: " << storageId; return -EPERM; } Loading @@ -760,9 +802,19 @@ int IncrementalService::setStorageParams(StorageId storageId, bool enableReadLog << " check failed: " << status.toString8(); return fromBinderStatus(status); } // Check installation time. const auto now = mClock->now(); const auto startLoadingTs = ifs.startLoadingTs; if (startLoadingTs <= now && now - startLoadingTs > Constants::readLogsMaxInterval) { LOG(ERROR) << "setStorageParams failed, readlogs can't be enabled at this time, " "storageId: " << storageId; return -EPERM; } } if (auto status = applyStorageParams(*ifs, enableReadLogs); !status.isOk()) { if (auto status = applyStorageParams(ifs, enableReadLogs); !status.isOk()) { LOG(ERROR) << "applyStorageParams failed: " << status.toString8(); return fromBinderStatus(status); } Loading Loading @@ -2222,6 +2274,10 @@ sp<content::pm::IDataLoader> IncrementalService::DataLoaderStub::getDataLoader() return dataloader; } bool IncrementalService::DataLoaderStub::isSystemDataLoader() const { return (params().packageName == Constants::systemPackage); } bool IncrementalService::DataLoaderStub::requestCreate() { return setTargetStatus(IDataLoaderStatusListener::DATA_LOADER_CREATED); } Loading
services/incremental/IncrementalService.h +5 −6 Original line number Diff line number Diff line Loading @@ -231,6 +231,7 @@ private: MountId id() const { return mId.load(std::memory_order_relaxed); } const content::pm::DataLoaderParamsParcel& params() const { return mParams; } bool isSystemDataLoader() const; void setHealthListener(StorageHealthCheckParams&& healthCheckParams, const StorageHealthListener* healthListener); long elapsedMsSinceOldestPendingRead(); Loading Loading @@ -330,6 +331,7 @@ private: StorageMap storages; BindMap bindPoints; DataLoaderStubPtr dataLoaderStub; TimePoint startLoadingTs = {}; std::atomic<int> nextStorageDirNo{0}; const IncrementalService& incrementalService; Loading @@ -348,12 +350,7 @@ private: void disallowReadLogs() { flags &= ~StorageFlags::ReadLogsAllowed; } int32_t readLogsAllowed() const { return (flags & StorageFlags::ReadLogsAllowed); } void setReadLogsEnabled(bool value) { if (value) flags |= StorageFlags::ReadLogsEnabled; else flags &= ~StorageFlags::ReadLogsEnabled; } void setReadLogsEnabled(bool value); int32_t readLogsEnabled() const { return (flags & StorageFlags::ReadLogsEnabled); } static void cleanupFilesystem(std::string_view root); Loading Loading @@ -411,6 +408,8 @@ private: IncFsMount::StorageMap::const_iterator storageIt, std::string_view path) const; int makeDirs(const IncFsMount& ifs, StorageId storageId, std::string_view path, int mode); int setStorageParams(IncFsMount& ifs, StorageId storageId, bool enableReadLogs); binder::Status applyStorageParams(IncFsMount& ifs, bool enableReadLogs); int isFileFullyLoadedFromPath(const IncFsMount& ifs, std::string_view filePath) const; Loading
services/incremental/test/IncrementalServiceTest.cpp +147 −3 Original line number Diff line number Diff line Loading @@ -908,7 +908,7 @@ TEST_F(IncrementalServiceTest, testDataLoaderOnRestart) { EXPECT_CALL(*mDataLoader, start(_)).Times(6); EXPECT_CALL(*mDataLoader, destroy(_)).Times(1); EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2); EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(2); EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(3); TemporaryDir tempDir; int storageId = mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel, Loading Loading @@ -1119,7 +1119,7 @@ TEST_F(IncrementalServiceTest, testStartDataLoaderUnhealthyStorage) { EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2); EXPECT_CALL(*mLooper, addFd(MockIncFs::kPendingReadsFd, _, _, _, _)).Times(2); EXPECT_CALL(*mLooper, removeFd(MockIncFs::kPendingReadsFd)).Times(2); EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(4); EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(5); sp<NiceMock<MockStorageHealthListener>> listener{new NiceMock<MockStorageHealthListener>}; NiceMock<MockStorageHealthListener>* listenerMock = listener.get(); Loading Loading @@ -1292,6 +1292,147 @@ TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccessAndDisabled) { ASSERT_EQ(mDataLoader->setStorageParams(true), -EPERM); } TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccessAndTimedOut) { mVold->setIncFsMountOptionsSuccess(); mAppOpsManager->checkPermissionSuccess(); const auto readLogsMaxInterval = 2h; EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)); EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2); // Enabling and then disabling readlogs. EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(2); EXPECT_CALL(*mVold, setIncFsMountOptions(_, false)).Times(1); // After setIncFsMountOptions succeeded expecting to start watching. EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(1); // Not expecting callback removal. EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0); EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(1); TemporaryDir tempDir; int storageId = mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel, IncrementalService::CreateOptions::CreateNew); ASSERT_GE(storageId, 0); ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {}, {}, {})); // Disable readlogs callback present. ASSERT_EQ(storageId, mTimedQueue->mId); ASSERT_EQ(mTimedQueue->mAfter, readLogsMaxInterval); auto callback = mTimedQueue->mWhat; mTimedQueue->clearJob(storageId); ASSERT_GE(mDataLoader->setStorageParams(true), 0); // Now advance clock for 1hr. mClock->advance(1h); ASSERT_GE(mDataLoader->setStorageParams(true), 0); // Now call the timed callback, it should turn off the readlogs. callback(); // Now advance clock for 2hrs. mClock->advance(readLogsMaxInterval); ASSERT_EQ(mDataLoader->setStorageParams(true), -EPERM); } TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccessAndNoTimedOutForSystem) { mVold->setIncFsMountOptionsSuccess(); mAppOpsManager->checkPermissionSuccess(); const auto readLogsMaxInterval = 2h; EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)); EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2); // Enabling and then disabling readlogs. EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(3); EXPECT_CALL(*mVold, setIncFsMountOptions(_, false)).Times(0); // After setIncFsMountOptions succeeded expecting to start watching. EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(1); // Not expecting callback removal. EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0); EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(0); // System data loader. mDataLoaderParcel.packageName = "android"; TemporaryDir tempDir; int storageId = mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel, IncrementalService::CreateOptions::CreateNew); ASSERT_GE(storageId, 0); ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {}, {}, {})); // No readlogs callback. ASSERT_EQ(mTimedQueue->mAfter, 0ms); ASSERT_EQ(mTimedQueue->mWhat, nullptr); ASSERT_GE(mDataLoader->setStorageParams(true), 0); // Now advance clock for 1hr. mClock->advance(1h); ASSERT_GE(mDataLoader->setStorageParams(true), 0); // Now advance clock for 2hrs. mClock->advance(readLogsMaxInterval); ASSERT_EQ(mDataLoader->setStorageParams(true), 0); } TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccessAndNewInstall) { mVold->setIncFsMountOptionsSuccess(); mAppOpsManager->checkPermissionSuccess(); const auto readLogsMaxInterval = 2h; EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(2); EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2); // Enabling and then disabling readlogs. EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(3); EXPECT_CALL(*mVold, setIncFsMountOptions(_, false)).Times(1); // After setIncFsMountOptions succeeded expecting to start watching. EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(1); // Not expecting callback removal. EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0); EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(2); TemporaryDir tempDir; int storageId = mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel, IncrementalService::CreateOptions::CreateNew); ASSERT_GE(storageId, 0); auto dataLoaderParcel = mDataLoaderParcel; ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(dataLoaderParcel), {}, {}, {}, {})); // Disable readlogs callback present. ASSERT_EQ(storageId, mTimedQueue->mId); ASSERT_EQ(mTimedQueue->mAfter, readLogsMaxInterval); auto callback = mTimedQueue->mWhat; mTimedQueue->clearJob(storageId); ASSERT_GE(mDataLoader->setStorageParams(true), 0); // Now advance clock for 1.5hrs. mClock->advance(90min); ASSERT_GE(mDataLoader->setStorageParams(true), 0); // New installation. ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {}, {}, {})); // New callback present. ASSERT_EQ(storageId, mTimedQueue->mId); ASSERT_EQ(mTimedQueue->mAfter, readLogsMaxInterval); auto callback2 = mTimedQueue->mWhat; mTimedQueue->clearJob(storageId); // Old callback should not disable readlogs (setIncFsMountOptions should be called only once). callback(); // Advance clock for another 1.5hrs. mClock->advance(90min); // Still success even it's 3hrs past first install. ASSERT_GE(mDataLoader->setStorageParams(true), 0); // New one should disable. callback2(); // And timeout. mClock->advance(90min); ASSERT_EQ(mDataLoader->setStorageParams(true), -EPERM); } TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccessAndPermissionChanged) { mVold->setIncFsMountOptionsSuccess(); mAppOpsManager->checkPermissionSuccess(); Loading Loading @@ -1675,7 +1816,7 @@ TEST_F(IncrementalServiceTest, testPerUidTimeoutsTooShort) { EXPECT_CALL(*mDataLoader, start(_)).Times(1); EXPECT_CALL(*mDataLoader, destroy(_)).Times(1); EXPECT_CALL(*mIncFs, setUidReadTimeouts(_, _)).Times(0); EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(0); EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(1); EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2); TemporaryDir tempDir; int storageId = Loading @@ -1702,6 +1843,9 @@ TEST_F(IncrementalServiceTest, testPerUidTimeoutsSuccess) { // Empty storage. mIncFs->countFilledBlocksEmpty(); // Mark DataLoader as 'system' so that readlogs don't pollute the timed queue. mDataLoaderParcel.packageName = "android"; TemporaryDir tempDir; int storageId = mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel, Loading