Restrict state event logging

Restrict state event logging to AID_* and Mainline module uids.

Bug: 145706772
Test: statsd_test
Change-Id: I5dc244bd1c6c55dc0213c6e236aea93d759b675f
diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp
index 60e259b..095dd1e 100644
--- a/cmds/statsd/src/StatsLogProcessor.cpp
+++ b/cmds/statsd/src/StatsLogProcessor.cpp
@@ -101,6 +101,7 @@
       mLargestTimestampSeen(0),
       mLastTimestampSeen(0) {
     mPullerManager->ForceClearPullerCache();
+    StateManager::getInstance().updateLogSources(uidMap);
 }
 
 StatsLogProcessor::~StatsLogProcessor() {
@@ -419,6 +420,9 @@
     // 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 @@
         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.
@@ -1054,6 +1052,7 @@
                                          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);
     }
@@ -1063,6 +1062,7 @@
                                          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);
     }
@@ -1071,6 +1071,7 @@
 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);
     }
diff --git a/cmds/statsd/src/state/StateManager.cpp b/cmds/statsd/src/state/StateManager.cpp
index 5514b446..c29afeb 100644
--- a/cmds/statsd/src/state/StateManager.cpp
+++ b/cmds/statsd/src/state/StateManager.cpp
@@ -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;
@@ -33,8 +41,14 @@
 }
 
 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 @@
     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
diff --git a/cmds/statsd/src/state/StateManager.h b/cmds/statsd/src/state/StateManager.h
index 577a0f5..18c404c 100644
--- a/cmds/statsd/src/state/StateManager.h
+++ b/cmds/statsd/src/state/StateManager.h
@@ -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"
 
@@ -32,7 +37,7 @@
  */
 class StateManager : public virtual RefBase {
 public:
-    StateManager(){};
+    StateManager();
 
     ~StateManager(){};
 
@@ -62,6 +67,11 @@
     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();
     }
@@ -79,6 +89,13 @@
 
     // 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
diff --git a/cmds/statsd/tests/state/StateTracker_test.cpp b/cmds/statsd/tests/state/StateTracker_test.cpp
index 13e8f5c..8b8dd3f 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 <gtest/gtest.h>
+#include <private/android_filesystem_config.h>
 
 #include "state/StateListener.h"
 #include "state/StateManager.h"
@@ -113,6 +114,55 @@
     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
  *
diff --git a/cmds/statsd/tests/statsd_test_util.cpp b/cmds/statsd/tests/statsd_test_util.cpp
index fae56f0..f740f08 100644
--- a/cmds/statsd/tests/statsd_test_util.cpp
+++ b/cmds/statsd/tests/statsd_test_util.cpp
@@ -605,8 +605,17 @@
     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);
@@ -614,7 +623,7 @@
     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;
 }
diff --git a/cmds/statsd/tests/statsd_test_util.h b/cmds/statsd/tests/statsd_test_util.h
index dc012c5..d55d32d 100644
--- a/cmds/statsd/tests/statsd_test_util.h
+++ b/cmds/statsd/tests/statsd_test_util.h
@@ -230,9 +230,12 @@
 
 sp<MockUidMap> makeMockUidMapForOneHost(int hostUid, const vector<int>& isolatedUids);
 
+sp<MockUidMap> makeMockUidMapForPackage(const string& pkg, const set<int32_t>& uids);
+
 // Create log event for screen state changed.
-std::unique_ptr<LogEvent> CreateScreenStateChangedEvent(
-        uint64_t timestampNs, const android::view::DisplayStateEnum state);
+std::unique_ptr<LogEvent> CreateScreenStateChangedEvent(uint64_t timestampNs,
+                                                        const android::view::DisplayStateEnum state,
+                                                        int loggerUid = 0);
 
 // Create log event for screen brightness state changed.
 std::unique_ptr<LogEvent> CreateScreenBrightnessChangedEvent(uint64_t timestampNs, int level);