aboutsummaryrefslogtreecommitdiff
path: root/cpp/watchdog
diff options
context:
space:
mode:
authorLakshman Annadorai <lakshmana@google.com>2021-11-18 09:36:19 -0800
committerLakshman Annadorai <lakshmana@google.com>2021-11-19 21:08:47 +0000
commita0489c61600e71b8104d4ef2666866a68ed4c6a1 (patch)
tree2205af03cf60c8942574803663e7950ca9e44791 /cpp/watchdog
parent345fc0a65a00d1bdcb7131fa1fed590b0f96656e (diff)
downloadCar-a0489c61600e71b8104d4ef2666866a68ed4c6a1.tar.gz
Remove stats for deleted user on watchdog daemon side.
- CarService receives user removed broadcast when a user is deleted. Forward this signal to watchdog daemon, so the daemon can remove the I/O usage stats cached for the deleted user. Test: atest CarWatchdogServiceUnitTest libwatchdog_test Bug: 183413754 Change-Id: Ib3ceead4175e80e307f5044e41bd56b8768273a6 Merged-In: Ib3ceead4175e80e307f5044e41bd56b8768273a6 (cherry-picked from commit 0669122f9e31e34db53d62e19b6d99d02b9554c4)
Diffstat (limited to 'cpp/watchdog')
-rw-r--r--cpp/watchdog/aidl/android/automotive/watchdog/internal/UserState.aidl5
-rw-r--r--cpp/watchdog/server/src/IoOveruseMonitor.cpp36
-rw-r--r--cpp/watchdog/server/src/IoOveruseMonitor.h6
-rw-r--r--cpp/watchdog/server/src/WatchdogInternalHandler.cpp25
-rw-r--r--cpp/watchdog/server/src/WatchdogInternalHandler.h3
-rw-r--r--cpp/watchdog/server/src/WatchdogProcessService.cpp20
-rw-r--r--cpp/watchdog/server/src/WatchdogProcessService.h3
-rw-r--r--cpp/watchdog/server/tests/IoOveruseMonitorTest.cpp79
-rw-r--r--cpp/watchdog/server/tests/MockIoOveruseMonitor.h1
-rw-r--r--cpp/watchdog/server/tests/MockWatchdogProcessService.h35
-rw-r--r--cpp/watchdog/server/tests/WatchdogInternalHandlerTest.cpp28
11 files changed, 198 insertions, 43 deletions
diff --git a/cpp/watchdog/aidl/android/automotive/watchdog/internal/UserState.aidl b/cpp/watchdog/aidl/android/automotive/watchdog/internal/UserState.aidl
index 515fb41dac..95461eb966 100644
--- a/cpp/watchdog/aidl/android/automotive/watchdog/internal/UserState.aidl
+++ b/cpp/watchdog/aidl/android/automotive/watchdog/internal/UserState.aidl
@@ -32,6 +32,11 @@ enum UserState {
USER_STATE_STOPPED,
/**
+ * The user is removed.
+ */
+ USER_STATE_REMOVED,
+
+ /**
* Number of available user states.
*/
NUM_USER_STATES,
diff --git a/cpp/watchdog/server/src/IoOveruseMonitor.cpp b/cpp/watchdog/server/src/IoOveruseMonitor.cpp
index 0ebe0d494e..edf30d8acb 100644
--- a/cpp/watchdog/server/src/IoOveruseMonitor.cpp
+++ b/cpp/watchdog/server/src/IoOveruseMonitor.cpp
@@ -23,11 +23,11 @@
#include <WatchdogProperties.sysprop.h>
#include <android-base/file.h>
+#include <android-base/strings.h>
#include <android/automotive/watchdog/internal/PackageIdentifier.h>
#include <android/automotive/watchdog/internal/UidType.h>
#include <binder/IPCThreadState.h>
#include <binder/Status.h>
-#include <cutils/multiuser.h>
#include <log/log.h>
#include <processgroup/sched_policy.h>
@@ -53,8 +53,10 @@ using ::android::automotive::watchdog::internal::PackageIoOveruseStats;
using ::android::automotive::watchdog::internal::ResourceOveruseConfiguration;
using ::android::automotive::watchdog::internal::UidType;
using ::android::automotive::watchdog::internal::UserPackageIoUsageStats;
+using ::android::base::EndsWith;
using ::android::base::Error;
using ::android::base::Result;
+using ::android::base::StringPrintf;
using ::android::base::WriteStringToFd;
using ::android::binder::Status;
@@ -598,6 +600,7 @@ Result<void> IoOveruseMonitor::resetIoOveruseStats(const std::vector<std::string
std::unordered_set<std::string> uniquePackageNames;
std::copy(packageNames.begin(), packageNames.end(),
std::inserter(uniquePackageNames, uniquePackageNames.end()));
+ std::unique_lock writeLock(mRwMutex);
for (auto& [key, usage] : mUserPackageDailyIoUsageById) {
if (uniquePackageNames.find(usage.packageInfo.packageIdentifier.name) !=
uniquePackageNames.end()) {
@@ -607,6 +610,37 @@ Result<void> IoOveruseMonitor::resetIoOveruseStats(const std::vector<std::string
return {};
}
+void IoOveruseMonitor::removeStatsForUser(userid_t userId) {
+ std::unique_lock writeLock(mRwMutex);
+ for (auto it = mUserPackageDailyIoUsageById.begin();
+ it != mUserPackageDailyIoUsageById.end();) {
+ if (multiuser_get_user_id(it->second.packageInfo.packageIdentifier.uid) == userId) {
+ it = mUserPackageDailyIoUsageById.erase(it);
+ } else {
+ ++it;
+ }
+ }
+ // |mPrevBootIoUsageStatsById| keys are constructed using |uniquePackageIdStr| method. Thus, the
+ // key suffix would contain the userId. The value in this map is |IoUsageStats|, which doesn't
+ // contain the userId, so this is the only way to delete cached previous boot stats for
+ // the removed user.
+ std::string keySuffix = StringPrintf(":%" PRId32, userId);
+ for (auto it = mPrevBootIoUsageStatsById.begin(); it != mPrevBootIoUsageStatsById.end();) {
+ if (EndsWith(it->first, keySuffix)) {
+ it = mPrevBootIoUsageStatsById.erase(it);
+ } else {
+ ++it;
+ }
+ }
+ for (auto it = mLatestIoOveruseStats.begin(); it != mLatestIoOveruseStats.end();) {
+ if (multiuser_get_user_id(it->uid) == userId) {
+ it = mLatestIoOveruseStats.erase(it);
+ } else {
+ ++it;
+ }
+ }
+}
+
void IoOveruseMonitor::handleBinderDeath(const wp<IBinder>& who) {
std::unique_lock writeLock(mRwMutex);
IBinder* binder = who.unsafe_get();
diff --git a/cpp/watchdog/server/src/IoOveruseMonitor.h b/cpp/watchdog/server/src/IoOveruseMonitor.h
index 5fa91aae24..d6c261607e 100644
--- a/cpp/watchdog/server/src/IoOveruseMonitor.h
+++ b/cpp/watchdog/server/src/IoOveruseMonitor.h
@@ -31,6 +31,7 @@
#include <android/automotive/watchdog/internal/IoOveruseConfiguration.h>
#include <android/automotive/watchdog/internal/PackageInfo.h>
#include <android/automotive/watchdog/internal/PackageIoOveruseStats.h>
+#include <cutils/multiuser.h>
#include <utils/Mutex.h>
#include <time.h>
@@ -92,6 +93,9 @@ public:
virtual android::base::Result<void> resetIoOveruseStats(
const std::vector<std::string>& packageNames) = 0;
+
+ // Removes stats for the given user from the internal cache.
+ virtual void removeStatsForUser(userid_t userId) = 0;
};
class IoOveruseMonitor final : public IIoOveruseMonitor {
@@ -161,6 +165,8 @@ public:
android::base::Result<void> resetIoOveruseStats(
const std::vector<std::string>& packageName) override;
+ void removeStatsForUser(userid_t userId) override;
+
protected:
android::base::Result<void> init();
diff --git a/cpp/watchdog/server/src/WatchdogInternalHandler.cpp b/cpp/watchdog/server/src/WatchdogInternalHandler.cpp
index 2441ccf7f4..d28b322ff3 100644
--- a/cpp/watchdog/server/src/WatchdogInternalHandler.cpp
+++ b/cpp/watchdog/server/src/WatchdogInternalHandler.cpp
@@ -186,7 +186,7 @@ Status WatchdogInternalHandler::notifySystemStateChange(aawi::StateType type, in
return fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT,
StringPrintf("Invalid user state %d", userState));
}
- return mWatchdogProcessService->notifyUserStateChange(userId, userState);
+ return handleUserStateChange(userId, userState);
}
case aawi::StateType::BOOT_PHASE: {
aawi::BootPhase phase = static_cast<aawi::BootPhase>(static_cast<uint32_t>(arg1));
@@ -225,6 +225,29 @@ Status WatchdogInternalHandler::handlePowerCycleChange(PowerCycle powerCycle) {
return Status::ok();
}
+Status WatchdogInternalHandler::handleUserStateChange(userid_t userId, aawi::UserState userState) {
+ std::string stateDesc;
+ switch (userState) {
+ case aawi::UserState::USER_STATE_STARTED:
+ stateDesc = "started";
+ mWatchdogProcessService->notifyUserStateChange(userId, /*isStarted=*/true);
+ break;
+ case aawi::UserState::USER_STATE_STOPPED:
+ stateDesc = "stopped";
+ mWatchdogProcessService->notifyUserStateChange(userId, /*isStarted=*/false);
+ break;
+ case aawi::UserState::USER_STATE_REMOVED:
+ stateDesc = "removed";
+ mIoOveruseMonitor->removeStatsForUser(userId);
+ break;
+ default:
+ ALOGW("Unsupported user state: %d", userState);
+ return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT, "Unsupported user state");
+ }
+ ALOGI("Received user state change: user(%" PRId32 ") is %s", userId, stateDesc.c_str());
+ return Status::ok();
+}
+
Status WatchdogInternalHandler::updateResourceOveruseConfigurations(
const std::vector<ResourceOveruseConfiguration>& configs) {
Status status = checkSystemUser();
diff --git a/cpp/watchdog/server/src/WatchdogInternalHandler.h b/cpp/watchdog/server/src/WatchdogInternalHandler.h
index 1000c8e218..6634d5b5c8 100644
--- a/cpp/watchdog/server/src/WatchdogInternalHandler.h
+++ b/cpp/watchdog/server/src/WatchdogInternalHandler.h
@@ -105,6 +105,9 @@ private:
android::binder::Status handlePowerCycleChange(
android::automotive::watchdog::internal::PowerCycle powerCycle);
+ android::binder::Status handleUserStateChange(
+ userid_t userId, android::automotive::watchdog::internal::UserState userState);
+
android::sp<WatchdogBinderMediator> mBinderMediator;
android::sp<IWatchdogServiceHelper> mWatchdogServiceHelper;
android::sp<WatchdogProcessService> mWatchdogProcessService;
diff --git a/cpp/watchdog/server/src/WatchdogProcessService.cpp b/cpp/watchdog/server/src/WatchdogProcessService.cpp
index 891c6e24b9..3eca5ecc7d 100644
--- a/cpp/watchdog/server/src/WatchdogProcessService.cpp
+++ b/cpp/watchdog/server/src/WatchdogProcessService.cpp
@@ -289,24 +289,14 @@ void WatchdogProcessService::setEnabled(bool isEnabled) {
}
}
-Status WatchdogProcessService::notifyUserStateChange(userid_t userId, aawi::UserState state) {
+void WatchdogProcessService::notifyUserStateChange(userid_t userId, bool isStarted) {
std::string buffer;
Mutex::Autolock lock(mMutex);
- switch (state) {
- case aawi::UserState::USER_STATE_STARTED:
- mStoppedUserIds.erase(userId);
- buffer = StringPrintf("user(%d) is started", userId);
- break;
- case aawi::UserState::USER_STATE_STOPPED:
- mStoppedUserIds.insert(userId);
- buffer = StringPrintf("user(%d) is stopped", userId);
- break;
- default:
- ALOGW("Unsupported user state: %d", state);
- return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT, "Unsupported user state");
+ if (isStarted) {
+ mStoppedUserIds.erase(userId);
+ } else {
+ mStoppedUserIds.insert(userId);
}
- ALOGI("Received user state change: %s", buffer.c_str());
- return Status::ok();
}
Result<void> WatchdogProcessService::dump(int fd, const Vector<String16>& /*args*/) {
diff --git a/cpp/watchdog/server/src/WatchdogProcessService.h b/cpp/watchdog/server/src/WatchdogProcessService.h
index 46d3ef4af6..d66a4207c5 100644
--- a/cpp/watchdog/server/src/WatchdogProcessService.h
+++ b/cpp/watchdog/server/src/WatchdogProcessService.h
@@ -80,8 +80,7 @@ public:
monitor,
int32_t pid);
virtual void setEnabled(bool isEnabled);
- virtual android::binder::Status notifyUserStateChange(
- userid_t userId, android::automotive::watchdog::internal::UserState state);
+ virtual void notifyUserStateChange(userid_t userId, bool isStarted);
private:
enum ClientType {
diff --git a/cpp/watchdog/server/tests/IoOveruseMonitorTest.cpp b/cpp/watchdog/server/tests/IoOveruseMonitorTest.cpp
index c1dd4f7d56..752be7438f 100644
--- a/cpp/watchdog/server/tests/IoOveruseMonitorTest.cpp
+++ b/cpp/watchdog/server/tests/IoOveruseMonitorTest.cpp
@@ -1064,6 +1064,85 @@ TEST_F(IoOveruseMonitorTest, TestFailsUpdateResourceOveruseConfigurations) {
ASSERT_FALSE(mIoOveruseMonitor->updateResourceOveruseConfigurations({}).ok());
}
+TEST_F(IoOveruseMonitorTest, TestRemoveUser) {
+ std::vector<UserPackageIoUsageStats> todayIoUsageStats =
+ {constructUserPackageIoUsageStats(
+ /*userId=*/11, "com.android.google.package",
+ /*writtenBytes=*/constructPerStateBytes(100'000, 85'000, 120'000),
+ /*forgivenWriteBytes=*/constructPerStateBytes(70'000, 60'000, 100'000),
+ /*totalOveruses=*/3),
+ constructUserPackageIoUsageStats(
+ /*userId=*/12, "com.android.kitchensink",
+ /*writtenBytes=*/constructPerStateBytes(50'000, 40'000, 35'000),
+ /*forgivenWriteBytes=*/constructPerStateBytes(30'000, 30'000, 30'000),
+ /*totalOveruses=*/6)};
+ EXPECT_CALL(*mMockWatchdogServiceHelper, getTodayIoUsageStats(_))
+ .WillOnce(DoAll(SetArgPointee<0>(todayIoUsageStats), Return(Status::ok())));
+
+ EXPECT_CALL(*mMockUidStatsCollector, deltaStats())
+ .WillOnce(Return(
+ constructUidStats({{1001000, {/*fgWrBytes=*/70'000, /*bgWrBytes=*/20'000}},
+ {1112345, {/*fgWrBytes=*/35'000, /*bgWrBytes=*/15'000}}})));
+
+ std::vector<PackageIoOveruseStats> actualIoOveruseStats;
+ EXPECT_CALL(*mMockWatchdogServiceHelper, latestIoOveruseStats(_))
+ .WillOnce(DoAll(SaveArg<0>(&actualIoOveruseStats), Return(Status::ok())));
+
+ time_t currentTime = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
+ const auto [startTime, durationInSeconds] = calculateStartAndDuration(currentTime);
+
+ ASSERT_RESULT_OK(mIoOveruseMonitor->onPeriodicCollection(currentTime, SystemState::NORMAL_MODE,
+ mMockUidStatsCollector, nullptr));
+
+ std::vector<PackageIoOveruseStats> expectedIoOveruseStats =
+ {constructPackageIoOveruseStats(
+ /*uid*=*/1001000, /*shouldNotify=*/false, /*isKillable=*/false,
+ /*remaining=*/constructPerStateBytes(10'000, 20'000, 100'000),
+ /*written=*/constructPerStateBytes(70'000, 20'000, 0),
+ /*forgiven=*/constructPerStateBytes(0, 0, 0),
+ /*totalOveruses=*/0, startTime, durationInSeconds),
+ constructPackageIoOveruseStats(
+ /*uid*=*/1112345, /*shouldNotify=*/true, /*isKillable=*/true,
+ /*remaining=*/constructPerStateBytes(5'000, 0, 80'000),
+ /*written=*/constructPerStateBytes(135'000, 100'000, 120'000),
+ /*forgiven=*/constructPerStateBytes(70'000, 90'000, 100'000),
+ /*totalOveruses=*/4, startTime, durationInSeconds)};
+ EXPECT_THAT(actualIoOveruseStats, UnorderedElementsAreArray(expectedIoOveruseStats))
+ << "Expected: " << toString(expectedIoOveruseStats)
+ << "\nActual: " << toString(actualIoOveruseStats);
+
+ mIoOveruseMonitor->removeStatsForUser(/*userId=*/11);
+ mIoOveruseMonitor->removeStatsForUser(/*userId=*/12);
+
+ EXPECT_CALL(*mMockUidStatsCollector, deltaStats())
+ .WillOnce(Return(
+ constructUidStats({{1112345, {/*fgWrBytes=*/70'000, /*bgWrBytes=*/40'000}},
+ {1245678, {/*fgWrBytes=*/30'000, /*bgWrBytes=*/10'000}}})));
+
+ actualIoOveruseStats.clear();
+ EXPECT_CALL(*mMockWatchdogServiceHelper, latestIoOveruseStats(_))
+ .WillOnce(DoAll(SaveArg<0>(&actualIoOveruseStats), Return(Status::ok())));
+
+ ASSERT_RESULT_OK(mIoOveruseMonitor->onPeriodicCollection(currentTime, SystemState::GARAGE_MODE,
+ mMockUidStatsCollector, nullptr));
+
+ expectedIoOveruseStats = {constructPackageIoOveruseStats(
+ /*uid*=*/1112345, /*shouldNotify=*/true, /*isKillable=*/true,
+ /*remaining=*/constructPerStateBytes(70'000, 30'000, 0),
+ /*written=*/constructPerStateBytes(0, 0, 110'000),
+ /*forgiven=*/constructPerStateBytes(0, 0, 100'000),
+ /*totalOveruses=*/1, startTime, durationInSeconds),
+ constructPackageIoOveruseStats(
+ /*uid*=*/1245678, /*shouldNotify=*/true, /*isKillable=*/true,
+ /*remaining=*/constructPerStateBytes(30'000, 15'000, 0),
+ /*written=*/constructPerStateBytes(0, 0, 40'000),
+ /*forgiven=*/constructPerStateBytes(0, 0, 40'000),
+ /*totalOveruses=*/4, startTime, durationInSeconds)};
+ EXPECT_THAT(actualIoOveruseStats, UnorderedElementsAreArray(expectedIoOveruseStats))
+ << "Expected: " << toString(expectedIoOveruseStats)
+ << "\nActual: " << toString(actualIoOveruseStats);
+}
+
} // namespace watchdog
} // namespace automotive
} // namespace android
diff --git a/cpp/watchdog/server/tests/MockIoOveruseMonitor.h b/cpp/watchdog/server/tests/MockIoOveruseMonitor.h
index 294276bb48..0e3f4c4842 100644
--- a/cpp/watchdog/server/tests/MockIoOveruseMonitor.h
+++ b/cpp/watchdog/server/tests/MockIoOveruseMonitor.h
@@ -53,6 +53,7 @@ public:
(const, override));
MOCK_METHOD(android::base::Result<void>, resetIoOveruseStats, (const std::vector<std::string>&),
(override));
+ MOCK_METHOD(void, removeStatsForUser, (userid_t), (override));
};
} // namespace watchdog
diff --git a/cpp/watchdog/server/tests/MockWatchdogProcessService.h b/cpp/watchdog/server/tests/MockWatchdogProcessService.h
index 44f33770c8..304a2a4f86 100644
--- a/cpp/watchdog/server/tests/MockWatchdogProcessService.h
+++ b/cpp/watchdog/server/tests/MockWatchdogProcessService.h
@@ -40,42 +40,37 @@ namespace watchdog {
class MockWatchdogProcessService : public WatchdogProcessService {
public:
MockWatchdogProcessService() : WatchdogProcessService(nullptr) {}
- MOCK_METHOD(android::base::Result<void>, dump, (int fd, const Vector<android::String16>& args),
+ MOCK_METHOD(android::base::Result<void>, dump, (int fd, const Vector<android::String16>&),
(override));
MOCK_METHOD(android::base::Result<void>, registerWatchdogServiceHelper,
- (const android::sp<IWatchdogServiceHelper>& helper), (override));
+ (const android::sp<IWatchdogServiceHelper>&), (override));
MOCK_METHOD(android::binder::Status, registerClient,
- (const sp<ICarWatchdogClient>& client, TimeoutLength timeout), (override));
- MOCK_METHOD(android::binder::Status, unregisterClient, (const sp<ICarWatchdogClient>& client),
+ (const sp<ICarWatchdogClient>&, TimeoutLength), (override));
+ MOCK_METHOD(android::binder::Status, unregisterClient, (const sp<ICarWatchdogClient>&),
(override));
- MOCK_METHOD(android::binder::Status, registerCarWatchdogService,
- (const android::sp<IBinder>& binder), (override));
- MOCK_METHOD(void, unregisterCarWatchdogService, (const android::sp<IBinder>& binder),
+ MOCK_METHOD(android::binder::Status, registerCarWatchdogService, (const android::sp<IBinder>&),
(override));
+ MOCK_METHOD(void, unregisterCarWatchdogService, (const android::sp<IBinder>&), (override));
MOCK_METHOD(android::binder::Status, registerMonitor,
- (const sp<android::automotive::watchdog::internal::ICarWatchdogMonitor>& monitor),
+ (const sp<android::automotive::watchdog::internal::ICarWatchdogMonitor>&),
(override));
MOCK_METHOD(android::binder::Status, unregisterMonitor,
- (const sp<android::automotive::watchdog::internal::ICarWatchdogMonitor>& monitor),
+ (const sp<android::automotive::watchdog::internal::ICarWatchdogMonitor>&),
+ (override));
+ MOCK_METHOD(android::binder::Status, tellClientAlive, (const sp<ICarWatchdogClient>&, int32_t),
(override));
- MOCK_METHOD(android::binder::Status, tellClientAlive,
- (const sp<ICarWatchdogClient>& client, int32_t sessionId), (override));
MOCK_METHOD(android::binder::Status, tellCarWatchdogServiceAlive,
(const android::sp<
- android::automotive::watchdog::internal::ICarWatchdogServiceForSystem>&
- service,
- const std::vector<int32_t>& clientsNotResponding, int32_t sessionId),
+ android::automotive::watchdog::internal::ICarWatchdogServiceForSystem>&,
+ const std::vector<int32_t>&, int32_t),
(override));
MOCK_METHOD(android::binder::Status, tellDumpFinished,
- (const android::sp<android::automotive::watchdog::internal::ICarWatchdogMonitor>&
- monitor,
- int32_t pid),
+ (const android::sp<android::automotive::watchdog::internal::ICarWatchdogMonitor>&,
+ int32_t),
(override));
MOCK_METHOD(void, setEnabled, (bool), (override));
- MOCK_METHOD(android::binder::Status, notifyUserStateChange,
- (userid_t userId, android::automotive::watchdog::internal::UserState state),
- (override));
+ MOCK_METHOD(void, notifyUserStateChange, (userid_t, bool), (override));
};
} // namespace watchdog
diff --git a/cpp/watchdog/server/tests/WatchdogInternalHandlerTest.cpp b/cpp/watchdog/server/tests/WatchdogInternalHandlerTest.cpp
index a5abbc4381..3d95bc687a 100644
--- a/cpp/watchdog/server/tests/WatchdogInternalHandlerTest.cpp
+++ b/cpp/watchdog/server/tests/WatchdogInternalHandlerTest.cpp
@@ -362,12 +362,21 @@ TEST_F(WatchdogInternalHandlerTest, TestNotifyGarageModeOff) {
ASSERT_TRUE(status.isOk()) << status;
}
-TEST_F(WatchdogInternalHandlerTest, TestNotifyUserStateChange) {
+TEST_F(WatchdogInternalHandlerTest, TestNotifyUserStateChangeWithStartedUser) {
setSystemCallingUid();
aawi::StateType type = aawi::StateType::USER_STATE;
- EXPECT_CALL(*mMockWatchdogProcessService,
- notifyUserStateChange(234567, aawi::UserState::USER_STATE_STOPPED))
- .WillOnce(Return(Status::ok()));
+ EXPECT_CALL(*mMockWatchdogProcessService, notifyUserStateChange(234567, /*isStarted=*/true));
+ Status status = mWatchdogInternalHandler
+ ->notifySystemStateChange(type, 234567,
+ static_cast<int32_t>(
+ aawi::UserState::USER_STATE_STARTED));
+ ASSERT_TRUE(status.isOk()) << status;
+}
+
+TEST_F(WatchdogInternalHandlerTest, TestNotifyUserStateChangeWithStoppedUser) {
+ setSystemCallingUid();
+ aawi::StateType type = aawi::StateType::USER_STATE;
+ EXPECT_CALL(*mMockWatchdogProcessService, notifyUserStateChange(234567, /*isStarted=*/false));
Status status = mWatchdogInternalHandler
->notifySystemStateChange(type, 234567,
static_cast<int32_t>(
@@ -375,6 +384,17 @@ TEST_F(WatchdogInternalHandlerTest, TestNotifyUserStateChange) {
ASSERT_TRUE(status.isOk()) << status;
}
+TEST_F(WatchdogInternalHandlerTest, TestNotifyUserStateChangeWithRemovedUser) {
+ setSystemCallingUid();
+ aawi::StateType type = aawi::StateType::USER_STATE;
+ EXPECT_CALL(*mMockIoOveruseMonitor, removeStatsForUser(/*userId=*/234567));
+ Status status = mWatchdogInternalHandler
+ ->notifySystemStateChange(type, 234567,
+ static_cast<int32_t>(
+ aawi::UserState::USER_STATE_REMOVED));
+ ASSERT_TRUE(status.isOk()) << status;
+}
+
TEST_F(WatchdogInternalHandlerTest, TestErrorOnNotifyUserStateChangeWithInvalidArgs) {
EXPECT_CALL(*mMockWatchdogProcessService, notifyUserStateChange(_, _)).Times(0);
aawi::StateType type = aawi::StateType::USER_STATE;