Loading cmds/statsd/src/StatsLogProcessor.cpp +7 −6 Original line number Diff line number Diff line Loading @@ -101,6 +101,7 @@ StatsLogProcessor::StatsLogProcessor(const sp<UidMap>& uidMap, mLargestTimestampSeen(0), mLastTimestampSeen(0) { mPullerManager->ForceClearPullerCache(); StateManager::getInstance().updateLogSources(uidMap); } StatsLogProcessor::~StatsLogProcessor() { Loading Loading @@ -419,6 +420,9 @@ void StatsLogProcessor::OnLogEvent(LogEvent* event, int64_t elapsedRealtimeNs) { // The field numbers need to be currently updated by hand with atoms.proto if (atomId == android::os::statsd::util::ISOLATED_UID_CHANGED) { onIsolatedUidChangedEventLocked(*event); } else { // Map the isolated uid to host uid if necessary. mapIsolatedUidToHostUidIfNecessaryLocked(event); } StateManager::getInstance().onLogEvent(*event); Loading @@ -433,12 +437,6 @@ void StatsLogProcessor::OnLogEvent(LogEvent* event, int64_t elapsedRealtimeNs) { mLastPullerCacheClearTimeSec = curTimeSec; } if (atomId != android::os::statsd::util::ISOLATED_UID_CHANGED) { // Map the isolated uid to host uid if necessary. mapIsolatedUidToHostUidIfNecessaryLocked(event); } std::unordered_set<int> uidsWithActiveConfigsChanged; std::unordered_map<int, std::vector<int64_t>> activeConfigsPerUid; // pass the event to metrics managers. Loading Loading @@ -1054,6 +1052,7 @@ void StatsLogProcessor::notifyAppUpgrade(const int64_t& eventTimeNs, const strin const int uid, const int64_t version) { std::lock_guard<std::mutex> lock(mMetricsMutex); VLOG("Received app upgrade"); StateManager::getInstance().notifyAppChanged(apk, mUidMap); for (const auto& it : mMetricsManagers) { it.second->notifyAppUpgrade(eventTimeNs, apk, uid, version); } Loading @@ -1063,6 +1062,7 @@ void StatsLogProcessor::notifyAppRemoved(const int64_t& eventTimeNs, const strin const int uid) { std::lock_guard<std::mutex> lock(mMetricsMutex); VLOG("Received app removed"); StateManager::getInstance().notifyAppChanged(apk, mUidMap); for (const auto& it : mMetricsManagers) { it.second->notifyAppRemoved(eventTimeNs, apk, uid); } Loading @@ -1071,6 +1071,7 @@ void StatsLogProcessor::notifyAppRemoved(const int64_t& eventTimeNs, const strin void StatsLogProcessor::onUidMapReceived(const int64_t& eventTimeNs) { std::lock_guard<std::mutex> lock(mMetricsMutex); VLOG("Received uid map"); StateManager::getInstance().updateLogSources(mUidMap); for (const auto& it : mMetricsManagers) { it.second->onUidMapReceived(eventTimeNs); } Loading cmds/statsd/src/state/StateManager.cpp +30 −2 Original line number Diff line number Diff line Loading @@ -19,10 +19,18 @@ #include "StateManager.h" #include <private/android_filesystem_config.h> namespace android { namespace os { namespace statsd { StateManager::StateManager() : mAllowedPkg({ "com.android.systemui", }) { } StateManager& StateManager::getInstance() { static StateManager sStateManager; return sStateManager; Loading @@ -33,10 +41,16 @@ void StateManager::clear() { } void StateManager::onLogEvent(const LogEvent& event) { // Only process state events from uids in AID_* and packages that are whitelisted in // mAllowedPkg. // Whitelisted AIDs are AID_ROOT and all AIDs in [1000, 2000) if (event.GetUid() == AID_ROOT || (event.GetUid() >= 1000 && event.GetUid() < 2000) || mAllowedLogSources.find(event.GetUid()) != mAllowedLogSources.end()) { if (mStateTrackers.find(event.GetTagId()) != mStateTrackers.end()) { mStateTrackers[event.GetTagId()]->onLogEvent(event); } } } void StateManager::registerListener(const int32_t atomId, wp<StateListener> listener) { // Check if state tracker already exists. Loading Loading @@ -79,6 +93,20 @@ bool StateManager::getStateValue(const int32_t atomId, const HashableDimensionKe return false; } void StateManager::updateLogSources(const sp<UidMap>& uidMap) { mAllowedLogSources.clear(); for (const auto& pkg : mAllowedPkg) { auto uids = uidMap->getAppUid(pkg); mAllowedLogSources.insert(uids.begin(), uids.end()); } } void StateManager::notifyAppChanged(const string& apk, const sp<UidMap>& uidMap) { if (mAllowedPkg.find(apk) != mAllowedPkg.end()) { updateLogSources(uidMap); } } } // namespace statsd } // namespace os } // namespace android cmds/statsd/src/state/StateManager.h +18 −1 Original line number Diff line number Diff line Loading @@ -18,7 +18,12 @@ #include <inttypes.h> #include <utils/RefBase.h> #include <set> #include <string> #include <unordered_map> #include "HashableDimensionKey.h" #include "packages/UidMap.h" #include "state/StateListener.h" #include "state/StateTracker.h" Loading @@ -32,7 +37,7 @@ namespace statsd { */ class StateManager : public virtual RefBase { public: StateManager(){}; StateManager(); ~StateManager(){}; Loading Loading @@ -62,6 +67,11 @@ public: bool getStateValue(const int32_t atomId, const HashableDimensionKey& queryKey, FieldValue* output) const; // Updates mAllowedLogSources with the latest uids for the packages that are allowed to log. void updateLogSources(const sp<UidMap>& uidMap); void notifyAppChanged(const string& apk, const sp<UidMap>& uidMap); inline int getStateTrackersCount() const { return mStateTrackers.size(); } Loading @@ -79,6 +89,13 @@ private: // Maps state atom ids to StateTrackers std::unordered_map<int32_t, sp<StateTracker>> mStateTrackers; // The package names that can log state events. const std::set<std::string> mAllowedPkg; // The combined uid sources (after translating pkg name to uid). // State events from uids that are not in the list will be ignored to avoid state pollution. std::set<int32_t> mAllowedLogSources; }; } // namespace statsd Loading cmds/statsd/tests/state/StateTracker_test.cpp +50 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ #include "state/StateTracker.h" #include <gtest/gtest.h> #include <private/android_filesystem_config.h> #include "state/StateListener.h" #include "state/StateManager.h" Loading Loading @@ -114,6 +115,55 @@ TEST(StateManagerTest, TestStateManagerGetInstance) { EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount()); } TEST(StateManagerTest, TestOnLogEvent) { sp<MockUidMap> uidMap = makeMockUidMapForPackage("com.android.systemui", {10111}); sp<TestStateListener> listener1 = new TestStateListener(); StateManager mgr; mgr.updateLogSources(uidMap); // Add StateTracker by registering a listener. mgr.registerListener(util::SCREEN_STATE_CHANGED, listener1); // log event using AID_ROOT std::unique_ptr<LogEvent> event = CreateScreenStateChangedEvent( timestampNs, android::view::DisplayStateEnum::DISPLAY_STATE_ON); mgr.onLogEvent(*event); // check StateTracker was updated by querying for state HashableDimensionKey queryKey = DEFAULT_DIMENSION_KEY; EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON, getStateInt(mgr, util::SCREEN_STATE_CHANGED, queryKey)); // log event using mocked uid event = CreateScreenStateChangedEvent( timestampNs, android::view::DisplayStateEnum::DISPLAY_STATE_OFF, 10111); mgr.onLogEvent(*event); // check StateTracker was updated by querying for state queryKey = DEFAULT_DIMENSION_KEY; EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_OFF, getStateInt(mgr, util::SCREEN_STATE_CHANGED, queryKey)); // log event using non-whitelisted uid event = CreateScreenStateChangedEvent(timestampNs, android::view::DisplayStateEnum::DISPLAY_STATE_ON, 10112); mgr.onLogEvent(*event); // check StateTracker was NOT updated by querying for state queryKey = DEFAULT_DIMENSION_KEY; EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_OFF, getStateInt(mgr, util::SCREEN_STATE_CHANGED, queryKey)); // log event using AID_SYSTEM event = CreateScreenStateChangedEvent( timestampNs, android::view::DisplayStateEnum::DISPLAY_STATE_ON, AID_SYSTEM); mgr.onLogEvent(*event); // check StateTracker was updated by querying for state queryKey = DEFAULT_DIMENSION_KEY; EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON, getStateInt(mgr, util::SCREEN_STATE_CHANGED, queryKey)); } /** * Test registering listeners to StateTrackers * Loading cmds/statsd/tests/statsd_test_util.cpp +12 −3 Original line number Diff line number Diff line Loading @@ -635,8 +635,17 @@ sp<MockUidMap> makeMockUidMapForOneHost(int hostUid, const vector<int>& isolated return uidMap; } std::unique_ptr<LogEvent> CreateScreenStateChangedEvent( uint64_t timestampNs, const android::view::DisplayStateEnum state) { sp<MockUidMap> makeMockUidMapForPackage(const string& pkg, const set<int32_t>& uids) { sp<MockUidMap> uidMap = new StrictMock<MockUidMap>(); EXPECT_CALL(*uidMap, getAppUid(_)).Times(AnyNumber()); EXPECT_CALL(*uidMap, getAppUid(pkg)).WillRepeatedly(Return(uids)); return uidMap; } std::unique_ptr<LogEvent> CreateScreenStateChangedEvent(uint64_t timestampNs, const android::view::DisplayStateEnum state, int loggerUid) { AStatsEvent* statsEvent = AStatsEvent_obtain(); AStatsEvent_setAtomId(statsEvent, util::SCREEN_STATE_CHANGED); AStatsEvent_overwriteTimestamp(statsEvent, timestampNs); Loading @@ -644,7 +653,7 @@ std::unique_ptr<LogEvent> CreateScreenStateChangedEvent( AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_EXCLUSIVE_STATE, true); AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_STATE_NESTED, false); std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0); std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(loggerUid, /*pid=*/0); parseStatsEventToLogEvent(statsEvent, logEvent.get()); return logEvent; } Loading Loading
cmds/statsd/src/StatsLogProcessor.cpp +7 −6 Original line number Diff line number Diff line Loading @@ -101,6 +101,7 @@ StatsLogProcessor::StatsLogProcessor(const sp<UidMap>& uidMap, mLargestTimestampSeen(0), mLastTimestampSeen(0) { mPullerManager->ForceClearPullerCache(); StateManager::getInstance().updateLogSources(uidMap); } StatsLogProcessor::~StatsLogProcessor() { Loading Loading @@ -419,6 +420,9 @@ void StatsLogProcessor::OnLogEvent(LogEvent* event, int64_t elapsedRealtimeNs) { // The field numbers need to be currently updated by hand with atoms.proto if (atomId == android::os::statsd::util::ISOLATED_UID_CHANGED) { onIsolatedUidChangedEventLocked(*event); } else { // Map the isolated uid to host uid if necessary. mapIsolatedUidToHostUidIfNecessaryLocked(event); } StateManager::getInstance().onLogEvent(*event); Loading @@ -433,12 +437,6 @@ void StatsLogProcessor::OnLogEvent(LogEvent* event, int64_t elapsedRealtimeNs) { mLastPullerCacheClearTimeSec = curTimeSec; } if (atomId != android::os::statsd::util::ISOLATED_UID_CHANGED) { // Map the isolated uid to host uid if necessary. mapIsolatedUidToHostUidIfNecessaryLocked(event); } std::unordered_set<int> uidsWithActiveConfigsChanged; std::unordered_map<int, std::vector<int64_t>> activeConfigsPerUid; // pass the event to metrics managers. Loading Loading @@ -1054,6 +1052,7 @@ void StatsLogProcessor::notifyAppUpgrade(const int64_t& eventTimeNs, const strin const int uid, const int64_t version) { std::lock_guard<std::mutex> lock(mMetricsMutex); VLOG("Received app upgrade"); StateManager::getInstance().notifyAppChanged(apk, mUidMap); for (const auto& it : mMetricsManagers) { it.second->notifyAppUpgrade(eventTimeNs, apk, uid, version); } Loading @@ -1063,6 +1062,7 @@ void StatsLogProcessor::notifyAppRemoved(const int64_t& eventTimeNs, const strin const int uid) { std::lock_guard<std::mutex> lock(mMetricsMutex); VLOG("Received app removed"); StateManager::getInstance().notifyAppChanged(apk, mUidMap); for (const auto& it : mMetricsManagers) { it.second->notifyAppRemoved(eventTimeNs, apk, uid); } Loading @@ -1071,6 +1071,7 @@ void StatsLogProcessor::notifyAppRemoved(const int64_t& eventTimeNs, const strin void StatsLogProcessor::onUidMapReceived(const int64_t& eventTimeNs) { std::lock_guard<std::mutex> lock(mMetricsMutex); VLOG("Received uid map"); StateManager::getInstance().updateLogSources(mUidMap); for (const auto& it : mMetricsManagers) { it.second->onUidMapReceived(eventTimeNs); } Loading
cmds/statsd/src/state/StateManager.cpp +30 −2 Original line number Diff line number Diff line Loading @@ -19,10 +19,18 @@ #include "StateManager.h" #include <private/android_filesystem_config.h> namespace android { namespace os { namespace statsd { StateManager::StateManager() : mAllowedPkg({ "com.android.systemui", }) { } StateManager& StateManager::getInstance() { static StateManager sStateManager; return sStateManager; Loading @@ -33,10 +41,16 @@ void StateManager::clear() { } void StateManager::onLogEvent(const LogEvent& event) { // Only process state events from uids in AID_* and packages that are whitelisted in // mAllowedPkg. // Whitelisted AIDs are AID_ROOT and all AIDs in [1000, 2000) if (event.GetUid() == AID_ROOT || (event.GetUid() >= 1000 && event.GetUid() < 2000) || mAllowedLogSources.find(event.GetUid()) != mAllowedLogSources.end()) { if (mStateTrackers.find(event.GetTagId()) != mStateTrackers.end()) { mStateTrackers[event.GetTagId()]->onLogEvent(event); } } } void StateManager::registerListener(const int32_t atomId, wp<StateListener> listener) { // Check if state tracker already exists. Loading Loading @@ -79,6 +93,20 @@ bool StateManager::getStateValue(const int32_t atomId, const HashableDimensionKe return false; } void StateManager::updateLogSources(const sp<UidMap>& uidMap) { mAllowedLogSources.clear(); for (const auto& pkg : mAllowedPkg) { auto uids = uidMap->getAppUid(pkg); mAllowedLogSources.insert(uids.begin(), uids.end()); } } void StateManager::notifyAppChanged(const string& apk, const sp<UidMap>& uidMap) { if (mAllowedPkg.find(apk) != mAllowedPkg.end()) { updateLogSources(uidMap); } } } // namespace statsd } // namespace os } // namespace android
cmds/statsd/src/state/StateManager.h +18 −1 Original line number Diff line number Diff line Loading @@ -18,7 +18,12 @@ #include <inttypes.h> #include <utils/RefBase.h> #include <set> #include <string> #include <unordered_map> #include "HashableDimensionKey.h" #include "packages/UidMap.h" #include "state/StateListener.h" #include "state/StateTracker.h" Loading @@ -32,7 +37,7 @@ namespace statsd { */ class StateManager : public virtual RefBase { public: StateManager(){}; StateManager(); ~StateManager(){}; Loading Loading @@ -62,6 +67,11 @@ public: bool getStateValue(const int32_t atomId, const HashableDimensionKey& queryKey, FieldValue* output) const; // Updates mAllowedLogSources with the latest uids for the packages that are allowed to log. void updateLogSources(const sp<UidMap>& uidMap); void notifyAppChanged(const string& apk, const sp<UidMap>& uidMap); inline int getStateTrackersCount() const { return mStateTrackers.size(); } Loading @@ -79,6 +89,13 @@ private: // Maps state atom ids to StateTrackers std::unordered_map<int32_t, sp<StateTracker>> mStateTrackers; // The package names that can log state events. const std::set<std::string> mAllowedPkg; // The combined uid sources (after translating pkg name to uid). // State events from uids that are not in the list will be ignored to avoid state pollution. std::set<int32_t> mAllowedLogSources; }; } // namespace statsd Loading
cmds/statsd/tests/state/StateTracker_test.cpp +50 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ #include "state/StateTracker.h" #include <gtest/gtest.h> #include <private/android_filesystem_config.h> #include "state/StateListener.h" #include "state/StateManager.h" Loading Loading @@ -114,6 +115,55 @@ TEST(StateManagerTest, TestStateManagerGetInstance) { EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount()); } TEST(StateManagerTest, TestOnLogEvent) { sp<MockUidMap> uidMap = makeMockUidMapForPackage("com.android.systemui", {10111}); sp<TestStateListener> listener1 = new TestStateListener(); StateManager mgr; mgr.updateLogSources(uidMap); // Add StateTracker by registering a listener. mgr.registerListener(util::SCREEN_STATE_CHANGED, listener1); // log event using AID_ROOT std::unique_ptr<LogEvent> event = CreateScreenStateChangedEvent( timestampNs, android::view::DisplayStateEnum::DISPLAY_STATE_ON); mgr.onLogEvent(*event); // check StateTracker was updated by querying for state HashableDimensionKey queryKey = DEFAULT_DIMENSION_KEY; EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON, getStateInt(mgr, util::SCREEN_STATE_CHANGED, queryKey)); // log event using mocked uid event = CreateScreenStateChangedEvent( timestampNs, android::view::DisplayStateEnum::DISPLAY_STATE_OFF, 10111); mgr.onLogEvent(*event); // check StateTracker was updated by querying for state queryKey = DEFAULT_DIMENSION_KEY; EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_OFF, getStateInt(mgr, util::SCREEN_STATE_CHANGED, queryKey)); // log event using non-whitelisted uid event = CreateScreenStateChangedEvent(timestampNs, android::view::DisplayStateEnum::DISPLAY_STATE_ON, 10112); mgr.onLogEvent(*event); // check StateTracker was NOT updated by querying for state queryKey = DEFAULT_DIMENSION_KEY; EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_OFF, getStateInt(mgr, util::SCREEN_STATE_CHANGED, queryKey)); // log event using AID_SYSTEM event = CreateScreenStateChangedEvent( timestampNs, android::view::DisplayStateEnum::DISPLAY_STATE_ON, AID_SYSTEM); mgr.onLogEvent(*event); // check StateTracker was updated by querying for state queryKey = DEFAULT_DIMENSION_KEY; EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON, getStateInt(mgr, util::SCREEN_STATE_CHANGED, queryKey)); } /** * Test registering listeners to StateTrackers * Loading
cmds/statsd/tests/statsd_test_util.cpp +12 −3 Original line number Diff line number Diff line Loading @@ -635,8 +635,17 @@ sp<MockUidMap> makeMockUidMapForOneHost(int hostUid, const vector<int>& isolated return uidMap; } std::unique_ptr<LogEvent> CreateScreenStateChangedEvent( uint64_t timestampNs, const android::view::DisplayStateEnum state) { sp<MockUidMap> makeMockUidMapForPackage(const string& pkg, const set<int32_t>& uids) { sp<MockUidMap> uidMap = new StrictMock<MockUidMap>(); EXPECT_CALL(*uidMap, getAppUid(_)).Times(AnyNumber()); EXPECT_CALL(*uidMap, getAppUid(pkg)).WillRepeatedly(Return(uids)); return uidMap; } std::unique_ptr<LogEvent> CreateScreenStateChangedEvent(uint64_t timestampNs, const android::view::DisplayStateEnum state, int loggerUid) { AStatsEvent* statsEvent = AStatsEvent_obtain(); AStatsEvent_setAtomId(statsEvent, util::SCREEN_STATE_CHANGED); AStatsEvent_overwriteTimestamp(statsEvent, timestampNs); Loading @@ -644,7 +653,7 @@ std::unique_ptr<LogEvent> CreateScreenStateChangedEvent( AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_EXCLUSIVE_STATE, true); AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_STATE_NESTED, false); std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0); std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(loggerUid, /*pid=*/0); parseStatsEventToLogEvent(statsEvent, logEvent.get()); return logEvent; } Loading