Merge "Restrict state event logging" into rvc-dev

This commit is contained in:
TreeHugger Robot
2020-05-29 07:50:58 +00:00
committed by Android (Google) Code Review
6 changed files with 122 additions and 14 deletions

View File

@@ -101,6 +101,7 @@ StatsLogProcessor::StatsLogProcessor(const sp<UidMap>& 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<int> uidsWithActiveConfigsChanged;
std::unordered_map<int, std::vector<int64_t>> 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<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 @@ 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);
}
@@ -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);
}

View File

@@ -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::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>& 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

View File

@@ -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 @@ 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>& uidMap);
void notifyAppChanged(const string& apk, const sp<UidMap>& uidMap);
inline int getStateTrackersCount() const {
return mStateTrackers.size();
}
@@ -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

View File

@@ -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"
@@ -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
*

View File

@@ -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);
@@ -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;
}

View File

@@ -243,9 +243,12 @@ std::shared_ptr<LogEvent> makeAttributionLogEvent(int atomId, int64_t eventTimeN
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);