Loading services/incremental/IncrementalService.cpp +25 −18 Original line number Diff line number Diff line Loading @@ -2272,7 +2272,7 @@ void IncrementalService::addIfsStateCallback(StorageId storageId, IfsStateCallba mIfsStateCallbacks[storageId].emplace_back(std::move(callback)); } if (wasEmpty) { addTimedJob(*mTimedQueue, kMaxStorageId, Constants::progressUpdateInterval, addTimedJob(*mTimedQueue, kAllStoragesId, Constants::progressUpdateInterval, [this]() { processIfsStateCallbacks(); }); } } Loading @@ -2288,21 +2288,27 @@ void IncrementalService::processIfsStateCallbacks() { } IfsStateCallbacks::iterator it; if (storageId == kInvalidStorageId) { // First entry, initialize the it. // First entry, initialize the |it|. it = mIfsStateCallbacks.begin(); } else { // Subsequent entries, update the storageId, and shift to the new one. it = mIfsStateCallbacks.find(storageId); // Subsequent entries, update the |storageId|, and shift to the new one (not that // it guarantees much about updated items, but at least the loop will finish). it = mIfsStateCallbacks.lower_bound(storageId); if (it == mIfsStateCallbacks.end()) { // Was removed while processing, too bad. // Nothing else left, too bad. break; } if (it->first != storageId) { local.clear(); // Was removed during processing, forget the old callbacks. } else { // Put the 'surviving' callbacks back into the map and advance the position. auto& callbacks = it->second; if (callbacks.empty()) { std::swap(callbacks, local); } else { callbacks.insert(callbacks.end(), local.begin(), local.end()); callbacks.insert(callbacks.end(), std::move_iterator(local.begin()), std::move_iterator(local.end())); local.clear(); } if (callbacks.empty()) { it = mIfsStateCallbacks.erase(it); Loading @@ -2313,6 +2319,7 @@ void IncrementalService::processIfsStateCallbacks() { ++it; } } } if (it == mIfsStateCallbacks.end()) { break; Loading @@ -2330,7 +2337,7 @@ void IncrementalService::processIfsStateCallbacks() { processIfsStateCallbacks(storageId, local); } addTimedJob(*mTimedQueue, kMaxStorageId, Constants::progressUpdateInterval, addTimedJob(*mTimedQueue, kAllStoragesId, Constants::progressUpdateInterval, [this]() { processIfsStateCallbacks(); }); } Loading services/incremental/IncrementalService.h +3 −2 Original line number Diff line number Diff line Loading @@ -95,7 +95,8 @@ public: #pragma GCC diagnostic pop static constexpr StorageId kInvalidStorageId = -1; static constexpr StorageId kMaxStorageId = std::numeric_limits<int>::max(); static constexpr StorageId kMaxStorageId = std::numeric_limits<int>::max() - 1; static constexpr StorageId kAllStoragesId = kMaxStorageId + 1; static constexpr BootClockTsUs kMaxBootClockTsUs = std::numeric_limits<BootClockTsUs>::max(); Loading Loading @@ -472,7 +473,7 @@ private: std::mutex mCallbacksLock; std::unordered_map<std::string, sp<AppOpsListener>> mCallbackRegistered; using IfsStateCallbacks = std::unordered_map<StorageId, std::vector<IfsStateCallback>>; using IfsStateCallbacks = std::map<StorageId, std::vector<IfsStateCallback>>; std::mutex mIfsStateCallbacksLock; IfsStateCallbacks mIfsStateCallbacks; Loading services/incremental/test/IncrementalServiceTest.cpp +16 −16 Original line number Diff line number Diff line Loading @@ -1735,10 +1735,10 @@ TEST_F(IncrementalServiceTest, testStartDataLoaderUnbindOnAllDone) { ASSERT_EQ(mDataLoader->status(), IDataLoaderStatusListener::DATA_LOADER_STARTED); // IfsState callback present. ASSERT_EQ(IncrementalService::kMaxStorageId, mTimedQueue->mId); ASSERT_EQ(IncrementalService::kAllStoragesId, mTimedQueue->mId); ASSERT_EQ(mTimedQueue->mAfter, stateUpdateInterval); auto callback = mTimedQueue->mWhat; mTimedQueue->clearJob(IncrementalService::kMaxStorageId); mTimedQueue->clearJob(IncrementalService::kAllStoragesId); // Not loaded yet. EXPECT_CALL(*mIncFs, isEverythingFullyLoaded(_)) Loading @@ -1751,10 +1751,10 @@ TEST_F(IncrementalServiceTest, testStartDataLoaderUnbindOnAllDone) { ASSERT_EQ(mDataLoader->status(), IDataLoaderStatusListener::DATA_LOADER_STARTED); // Still present. ASSERT_EQ(IncrementalService::kMaxStorageId, mTimedQueue->mId); ASSERT_EQ(IncrementalService::kAllStoragesId, mTimedQueue->mId); ASSERT_EQ(mTimedQueue->mAfter, stateUpdateInterval); callback = mTimedQueue->mWhat; mTimedQueue->clearJob(IncrementalService::kMaxStorageId); mTimedQueue->clearJob(IncrementalService::kAllStoragesId); // Fully loaded. EXPECT_CALL(*mIncFs, isEverythingFullyLoaded(_)).WillOnce(Return(incfs::LoadingState::Full)); Loading Loading @@ -1797,10 +1797,10 @@ TEST_F(IncrementalServiceTest, testStartDataLoaderUnbindOnAllDoneWithReadlogs) { ASSERT_EQ(mDataLoader->status(), IDataLoaderStatusListener::DATA_LOADER_STARTED); // IfsState callback present. ASSERT_EQ(IncrementalService::kMaxStorageId, mTimedQueue->mId); ASSERT_EQ(IncrementalService::kAllStoragesId, mTimedQueue->mId); ASSERT_EQ(mTimedQueue->mAfter, stateUpdateInterval); auto callback = mTimedQueue->mWhat; mTimedQueue->clearJob(IncrementalService::kMaxStorageId); mTimedQueue->clearJob(IncrementalService::kAllStoragesId); // Not loaded yet. EXPECT_CALL(*mIncFs, isEverythingFullyLoaded(_)) Loading @@ -1813,10 +1813,10 @@ TEST_F(IncrementalServiceTest, testStartDataLoaderUnbindOnAllDoneWithReadlogs) { ASSERT_EQ(mDataLoader->status(), IDataLoaderStatusListener::DATA_LOADER_STARTED); // Still present. ASSERT_EQ(IncrementalService::kMaxStorageId, mTimedQueue->mId); ASSERT_EQ(IncrementalService::kAllStoragesId, mTimedQueue->mId); ASSERT_EQ(mTimedQueue->mAfter, stateUpdateInterval); callback = mTimedQueue->mWhat; mTimedQueue->clearJob(IncrementalService::kMaxStorageId); mTimedQueue->clearJob(IncrementalService::kAllStoragesId); // Fully loaded. EXPECT_CALL(*mIncFs, isEverythingFullyLoaded(_)) Loading @@ -1832,10 +1832,10 @@ TEST_F(IncrementalServiceTest, testStartDataLoaderUnbindOnAllDoneWithReadlogs) { ASSERT_EQ(mDataLoader->status(), IDataLoaderStatusListener::DATA_LOADER_STARTED); // Still present. ASSERT_EQ(IncrementalService::kMaxStorageId, mTimedQueue->mId); ASSERT_EQ(IncrementalService::kAllStoragesId, mTimedQueue->mId); ASSERT_EQ(mTimedQueue->mAfter, stateUpdateInterval); callback = mTimedQueue->mWhat; mTimedQueue->clearJob(IncrementalService::kMaxStorageId); mTimedQueue->clearJob(IncrementalService::kAllStoragesId); // Disable readlogs and expect the unbind. EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1); Loading Loading @@ -2007,10 +2007,10 @@ TEST_F(IncrementalServiceTest, testPerUidTimeoutsSuccess) { { // Timed callback present -> 0 progress. ASSERT_EQ(IncrementalService::kMaxStorageId, mTimedQueue->mId); ASSERT_EQ(IncrementalService::kAllStoragesId, mTimedQueue->mId); ASSERT_GE(mTimedQueue->mAfter, std::chrono::seconds(1)); const auto timedCallback = mTimedQueue->mWhat; mTimedQueue->clearJob(IncrementalService::kMaxStorageId); mTimedQueue->clearJob(IncrementalService::kAllStoragesId); // Call it again. timedCallback(); Loading @@ -2018,10 +2018,10 @@ TEST_F(IncrementalServiceTest, testPerUidTimeoutsSuccess) { { // Still present -> some progress. ASSERT_EQ(IncrementalService::kMaxStorageId, mTimedQueue->mId); ASSERT_EQ(IncrementalService::kAllStoragesId, mTimedQueue->mId); ASSERT_GE(mTimedQueue->mAfter, std::chrono::seconds(1)); const auto timedCallback = mTimedQueue->mWhat; mTimedQueue->clearJob(IncrementalService::kMaxStorageId); mTimedQueue->clearJob(IncrementalService::kAllStoragesId); // Fully loaded but readlogs collection enabled. ASSERT_GE(mDataLoader->setStorageParams(true), 0); Loading @@ -2032,10 +2032,10 @@ TEST_F(IncrementalServiceTest, testPerUidTimeoutsSuccess) { { // Still present -> fully loaded + readlogs. ASSERT_EQ(IncrementalService::kMaxStorageId, mTimedQueue->mId); ASSERT_EQ(IncrementalService::kAllStoragesId, mTimedQueue->mId); ASSERT_GE(mTimedQueue->mAfter, std::chrono::seconds(1)); const auto timedCallback = mTimedQueue->mWhat; mTimedQueue->clearJob(IncrementalService::kMaxStorageId); mTimedQueue->clearJob(IncrementalService::kAllStoragesId); // Now disable readlogs. ASSERT_GE(mDataLoader->setStorageParams(false), 0); Loading Loading
services/incremental/IncrementalService.cpp +25 −18 Original line number Diff line number Diff line Loading @@ -2272,7 +2272,7 @@ void IncrementalService::addIfsStateCallback(StorageId storageId, IfsStateCallba mIfsStateCallbacks[storageId].emplace_back(std::move(callback)); } if (wasEmpty) { addTimedJob(*mTimedQueue, kMaxStorageId, Constants::progressUpdateInterval, addTimedJob(*mTimedQueue, kAllStoragesId, Constants::progressUpdateInterval, [this]() { processIfsStateCallbacks(); }); } } Loading @@ -2288,21 +2288,27 @@ void IncrementalService::processIfsStateCallbacks() { } IfsStateCallbacks::iterator it; if (storageId == kInvalidStorageId) { // First entry, initialize the it. // First entry, initialize the |it|. it = mIfsStateCallbacks.begin(); } else { // Subsequent entries, update the storageId, and shift to the new one. it = mIfsStateCallbacks.find(storageId); // Subsequent entries, update the |storageId|, and shift to the new one (not that // it guarantees much about updated items, but at least the loop will finish). it = mIfsStateCallbacks.lower_bound(storageId); if (it == mIfsStateCallbacks.end()) { // Was removed while processing, too bad. // Nothing else left, too bad. break; } if (it->first != storageId) { local.clear(); // Was removed during processing, forget the old callbacks. } else { // Put the 'surviving' callbacks back into the map and advance the position. auto& callbacks = it->second; if (callbacks.empty()) { std::swap(callbacks, local); } else { callbacks.insert(callbacks.end(), local.begin(), local.end()); callbacks.insert(callbacks.end(), std::move_iterator(local.begin()), std::move_iterator(local.end())); local.clear(); } if (callbacks.empty()) { it = mIfsStateCallbacks.erase(it); Loading @@ -2313,6 +2319,7 @@ void IncrementalService::processIfsStateCallbacks() { ++it; } } } if (it == mIfsStateCallbacks.end()) { break; Loading @@ -2330,7 +2337,7 @@ void IncrementalService::processIfsStateCallbacks() { processIfsStateCallbacks(storageId, local); } addTimedJob(*mTimedQueue, kMaxStorageId, Constants::progressUpdateInterval, addTimedJob(*mTimedQueue, kAllStoragesId, Constants::progressUpdateInterval, [this]() { processIfsStateCallbacks(); }); } Loading
services/incremental/IncrementalService.h +3 −2 Original line number Diff line number Diff line Loading @@ -95,7 +95,8 @@ public: #pragma GCC diagnostic pop static constexpr StorageId kInvalidStorageId = -1; static constexpr StorageId kMaxStorageId = std::numeric_limits<int>::max(); static constexpr StorageId kMaxStorageId = std::numeric_limits<int>::max() - 1; static constexpr StorageId kAllStoragesId = kMaxStorageId + 1; static constexpr BootClockTsUs kMaxBootClockTsUs = std::numeric_limits<BootClockTsUs>::max(); Loading Loading @@ -472,7 +473,7 @@ private: std::mutex mCallbacksLock; std::unordered_map<std::string, sp<AppOpsListener>> mCallbackRegistered; using IfsStateCallbacks = std::unordered_map<StorageId, std::vector<IfsStateCallback>>; using IfsStateCallbacks = std::map<StorageId, std::vector<IfsStateCallback>>; std::mutex mIfsStateCallbacksLock; IfsStateCallbacks mIfsStateCallbacks; Loading
services/incremental/test/IncrementalServiceTest.cpp +16 −16 Original line number Diff line number Diff line Loading @@ -1735,10 +1735,10 @@ TEST_F(IncrementalServiceTest, testStartDataLoaderUnbindOnAllDone) { ASSERT_EQ(mDataLoader->status(), IDataLoaderStatusListener::DATA_LOADER_STARTED); // IfsState callback present. ASSERT_EQ(IncrementalService::kMaxStorageId, mTimedQueue->mId); ASSERT_EQ(IncrementalService::kAllStoragesId, mTimedQueue->mId); ASSERT_EQ(mTimedQueue->mAfter, stateUpdateInterval); auto callback = mTimedQueue->mWhat; mTimedQueue->clearJob(IncrementalService::kMaxStorageId); mTimedQueue->clearJob(IncrementalService::kAllStoragesId); // Not loaded yet. EXPECT_CALL(*mIncFs, isEverythingFullyLoaded(_)) Loading @@ -1751,10 +1751,10 @@ TEST_F(IncrementalServiceTest, testStartDataLoaderUnbindOnAllDone) { ASSERT_EQ(mDataLoader->status(), IDataLoaderStatusListener::DATA_LOADER_STARTED); // Still present. ASSERT_EQ(IncrementalService::kMaxStorageId, mTimedQueue->mId); ASSERT_EQ(IncrementalService::kAllStoragesId, mTimedQueue->mId); ASSERT_EQ(mTimedQueue->mAfter, stateUpdateInterval); callback = mTimedQueue->mWhat; mTimedQueue->clearJob(IncrementalService::kMaxStorageId); mTimedQueue->clearJob(IncrementalService::kAllStoragesId); // Fully loaded. EXPECT_CALL(*mIncFs, isEverythingFullyLoaded(_)).WillOnce(Return(incfs::LoadingState::Full)); Loading Loading @@ -1797,10 +1797,10 @@ TEST_F(IncrementalServiceTest, testStartDataLoaderUnbindOnAllDoneWithReadlogs) { ASSERT_EQ(mDataLoader->status(), IDataLoaderStatusListener::DATA_LOADER_STARTED); // IfsState callback present. ASSERT_EQ(IncrementalService::kMaxStorageId, mTimedQueue->mId); ASSERT_EQ(IncrementalService::kAllStoragesId, mTimedQueue->mId); ASSERT_EQ(mTimedQueue->mAfter, stateUpdateInterval); auto callback = mTimedQueue->mWhat; mTimedQueue->clearJob(IncrementalService::kMaxStorageId); mTimedQueue->clearJob(IncrementalService::kAllStoragesId); // Not loaded yet. EXPECT_CALL(*mIncFs, isEverythingFullyLoaded(_)) Loading @@ -1813,10 +1813,10 @@ TEST_F(IncrementalServiceTest, testStartDataLoaderUnbindOnAllDoneWithReadlogs) { ASSERT_EQ(mDataLoader->status(), IDataLoaderStatusListener::DATA_LOADER_STARTED); // Still present. ASSERT_EQ(IncrementalService::kMaxStorageId, mTimedQueue->mId); ASSERT_EQ(IncrementalService::kAllStoragesId, mTimedQueue->mId); ASSERT_EQ(mTimedQueue->mAfter, stateUpdateInterval); callback = mTimedQueue->mWhat; mTimedQueue->clearJob(IncrementalService::kMaxStorageId); mTimedQueue->clearJob(IncrementalService::kAllStoragesId); // Fully loaded. EXPECT_CALL(*mIncFs, isEverythingFullyLoaded(_)) Loading @@ -1832,10 +1832,10 @@ TEST_F(IncrementalServiceTest, testStartDataLoaderUnbindOnAllDoneWithReadlogs) { ASSERT_EQ(mDataLoader->status(), IDataLoaderStatusListener::DATA_LOADER_STARTED); // Still present. ASSERT_EQ(IncrementalService::kMaxStorageId, mTimedQueue->mId); ASSERT_EQ(IncrementalService::kAllStoragesId, mTimedQueue->mId); ASSERT_EQ(mTimedQueue->mAfter, stateUpdateInterval); callback = mTimedQueue->mWhat; mTimedQueue->clearJob(IncrementalService::kMaxStorageId); mTimedQueue->clearJob(IncrementalService::kAllStoragesId); // Disable readlogs and expect the unbind. EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1); Loading Loading @@ -2007,10 +2007,10 @@ TEST_F(IncrementalServiceTest, testPerUidTimeoutsSuccess) { { // Timed callback present -> 0 progress. ASSERT_EQ(IncrementalService::kMaxStorageId, mTimedQueue->mId); ASSERT_EQ(IncrementalService::kAllStoragesId, mTimedQueue->mId); ASSERT_GE(mTimedQueue->mAfter, std::chrono::seconds(1)); const auto timedCallback = mTimedQueue->mWhat; mTimedQueue->clearJob(IncrementalService::kMaxStorageId); mTimedQueue->clearJob(IncrementalService::kAllStoragesId); // Call it again. timedCallback(); Loading @@ -2018,10 +2018,10 @@ TEST_F(IncrementalServiceTest, testPerUidTimeoutsSuccess) { { // Still present -> some progress. ASSERT_EQ(IncrementalService::kMaxStorageId, mTimedQueue->mId); ASSERT_EQ(IncrementalService::kAllStoragesId, mTimedQueue->mId); ASSERT_GE(mTimedQueue->mAfter, std::chrono::seconds(1)); const auto timedCallback = mTimedQueue->mWhat; mTimedQueue->clearJob(IncrementalService::kMaxStorageId); mTimedQueue->clearJob(IncrementalService::kAllStoragesId); // Fully loaded but readlogs collection enabled. ASSERT_GE(mDataLoader->setStorageParams(true), 0); Loading @@ -2032,10 +2032,10 @@ TEST_F(IncrementalServiceTest, testPerUidTimeoutsSuccess) { { // Still present -> fully loaded + readlogs. ASSERT_EQ(IncrementalService::kMaxStorageId, mTimedQueue->mId); ASSERT_EQ(IncrementalService::kAllStoragesId, mTimedQueue->mId); ASSERT_GE(mTimedQueue->mAfter, std::chrono::seconds(1)); const auto timedCallback = mTimedQueue->mWhat; mTimedQueue->clearJob(IncrementalService::kMaxStorageId); mTimedQueue->clearJob(IncrementalService::kAllStoragesId); // Now disable readlogs. ASSERT_GE(mDataLoader->setStorageParams(false), 0); Loading