diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp index 60e259be95580..095dd1e9be592 100644 --- a/cmds/statsd/src/StatsLogProcessor.cpp +++ b/cmds/statsd/src/StatsLogProcessor.cpp @@ -101,6 +101,7 @@ StatsLogProcessor::StatsLogProcessor(const sp& uidMap, mLargestTimestampSeen(0), mLastTimestampSeen(0) { mPullerManager->ForceClearPullerCache(); + StateManager::getInstance().updateLogSources(uidMap); } StatsLogProcessor::~StatsLogProcessor() { @@ -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); @@ -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 uidsWithActiveConfigsChanged; std::unordered_map> activeConfigsPerUid; // pass the event to metrics managers. @@ -1054,6 +1052,7 @@ void StatsLogProcessor::notifyAppUpgrade(const int64_t& eventTimeNs, const strin const int uid, const int64_t version) { std::lock_guard lock(mMetricsMutex); VLOG("Received app upgrade"); + StateManager::getInstance().notifyAppChanged(apk, mUidMap); for (const auto& it : mMetricsManagers) { it.second->notifyAppUpgrade(eventTimeNs, apk, uid, version); } @@ -1063,6 +1062,7 @@ void StatsLogProcessor::notifyAppRemoved(const int64_t& eventTimeNs, const strin const int uid) { std::lock_guard lock(mMetricsMutex); VLOG("Received app removed"); + StateManager::getInstance().notifyAppChanged(apk, mUidMap); for (const auto& it : mMetricsManagers) { it.second->notifyAppRemoved(eventTimeNs, apk, uid); } @@ -1071,6 +1071,7 @@ void StatsLogProcessor::notifyAppRemoved(const int64_t& eventTimeNs, const strin void StatsLogProcessor::onUidMapReceived(const int64_t& eventTimeNs) { std::lock_guard lock(mMetricsMutex); VLOG("Received uid map"); + StateManager::getInstance().updateLogSources(mUidMap); for (const auto& it : mMetricsManagers) { it.second->onUidMapReceived(eventTimeNs); } diff --git a/cmds/statsd/src/state/StateManager.cpp b/cmds/statsd/src/state/StateManager.cpp index 5514b446b3066..c29afeb794fae 100644 --- a/cmds/statsd/src/state/StateManager.cpp +++ b/cmds/statsd/src/state/StateManager.cpp @@ -19,10 +19,18 @@ #include "StateManager.h" +#include + namespace android { namespace os { namespace statsd { +StateManager::StateManager() + : mAllowedPkg({ + "com.android.systemui", + }) { +} + StateManager& StateManager::getInstance() { static StateManager sStateManager; return sStateManager; @@ -33,8 +41,14 @@ void StateManager::clear() { } void StateManager::onLogEvent(const LogEvent& event) { - if (mStateTrackers.find(event.GetTagId()) != mStateTrackers.end()) { - mStateTrackers[event.GetTagId()]->onLogEvent(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); + } } } @@ -79,6 +93,20 @@ bool StateManager::getStateValue(const int32_t atomId, const HashableDimensionKe return false; } +void StateManager::updateLogSources(const sp& 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) { + if (mAllowedPkg.find(apk) != mAllowedPkg.end()) { + updateLogSources(uidMap); + } +} + } // namespace statsd } // namespace os } // namespace android diff --git a/cmds/statsd/src/state/StateManager.h b/cmds/statsd/src/state/StateManager.h index 577a0f51e38b8..18c404c29c4e2 100644 --- a/cmds/statsd/src/state/StateManager.h +++ b/cmds/statsd/src/state/StateManager.h @@ -18,7 +18,12 @@ #include #include +#include +#include +#include + #include "HashableDimensionKey.h" +#include "packages/UidMap.h" #include "state/StateListener.h" #include "state/StateTracker.h" @@ -32,7 +37,7 @@ namespace statsd { */ class StateManager : public virtual RefBase { public: - StateManager(){}; + StateManager(); ~StateManager(){}; @@ -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); + + void notifyAppChanged(const string& apk, const sp& uidMap); + inline int getStateTrackersCount() const { return mStateTrackers.size(); } @@ -79,6 +89,13 @@ private: // Maps state atom ids to StateTrackers std::unordered_map> mStateTrackers; + + // The package names that can log state events. + const std::set 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 mAllowedLogSources; }; } // namespace statsd diff --git a/cmds/statsd/tests/state/StateTracker_test.cpp b/cmds/statsd/tests/state/StateTracker_test.cpp index 530ac5e01f3ee..6516c1529514c 100644 --- a/cmds/statsd/tests/state/StateTracker_test.cpp +++ b/cmds/statsd/tests/state/StateTracker_test.cpp @@ -16,6 +16,7 @@ #include "state/StateTracker.h" #include +#include #include "state/StateListener.h" #include "state/StateManager.h" @@ -114,6 +115,55 @@ TEST(StateManagerTest, TestStateManagerGetInstance) { EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount()); } +TEST(StateManagerTest, TestOnLogEvent) { + sp uidMap = makeMockUidMapForPackage("com.android.systemui", {10111}); + sp 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 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 * diff --git a/cmds/statsd/tests/statsd_test_util.cpp b/cmds/statsd/tests/statsd_test_util.cpp index 582df0c1a2a3a..06e29d4b5de17 100644 --- a/cmds/statsd/tests/statsd_test_util.cpp +++ b/cmds/statsd/tests/statsd_test_util.cpp @@ -635,8 +635,17 @@ sp makeMockUidMapForOneHost(int hostUid, const vector& isolated return uidMap; } -std::unique_ptr CreateScreenStateChangedEvent( - uint64_t timestampNs, const android::view::DisplayStateEnum state) { +sp makeMockUidMapForPackage(const string& pkg, const set& uids) { + sp uidMap = new StrictMock(); + EXPECT_CALL(*uidMap, getAppUid(_)).Times(AnyNumber()); + EXPECT_CALL(*uidMap, getAppUid(pkg)).WillRepeatedly(Return(uids)); + + return uidMap; +} + +std::unique_ptr 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); @@ -644,7 +653,7 @@ std::unique_ptr CreateScreenStateChangedEvent( AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_EXCLUSIVE_STATE, true); AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_STATE_NESTED, false); - std::unique_ptr logEvent = std::make_unique(/*uid=*/0, /*pid=*/0); + std::unique_ptr logEvent = std::make_unique(loggerUid, /*pid=*/0); parseStatsEventToLogEvent(statsEvent, logEvent.get()); return logEvent; } diff --git a/cmds/statsd/tests/statsd_test_util.h b/cmds/statsd/tests/statsd_test_util.h index 6a5d5da2895cc..3dcf4ecce054f 100644 --- a/cmds/statsd/tests/statsd_test_util.h +++ b/cmds/statsd/tests/statsd_test_util.h @@ -243,9 +243,12 @@ std::shared_ptr makeAttributionLogEvent(int atomId, int64_t eventTimeN sp makeMockUidMapForOneHost(int hostUid, const vector& isolatedUids); +sp makeMockUidMapForPackage(const string& pkg, const set& uids); + // Create log event for screen state changed. -std::unique_ptr CreateScreenStateChangedEvent( - uint64_t timestampNs, const android::view::DisplayStateEnum state); +std::unique_ptr CreateScreenStateChangedEvent(uint64_t timestampNs, + const android::view::DisplayStateEnum state, + int loggerUid = 0); // Create log event for screen brightness state changed. std::unique_ptr CreateScreenBrightnessChangedEvent(uint64_t timestampNs, int level);