Loading cmds/statsd/src/StatsLogProcessor.cpp +17 −0 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ */ #include "Log.h" #include "statslog.h" #include "StatsLogProcessor.h" #include "metrics/CountMetricProducer.h" Loading Loading @@ -62,6 +63,22 @@ void StatsLogProcessor::OnLogEvent(const LogEvent& msg) { pair.second->onLogEvent(msg); flushIfNecessary(msg.GetTimestampNs(), pair.first, pair.second); } // Hard-coded logic to update the isolated uid's in the uid-map. // The field numbers need to be currently updated by hand with stats_events.proto if (msg.GetTagId() == android::util::ISOLATED_UID_CHANGED) { status_t err = NO_ERROR, err2 = NO_ERROR, err3 = NO_ERROR; bool is_create = msg.GetBool(3, &err); auto parent_uid = int(msg.GetLong(1, &err2)); auto isolated_uid = int(msg.GetLong(2, &err3)); if (err == NO_ERROR && err2 == NO_ERROR && err3 == NO_ERROR) { if (is_create) { mUidMap->assignIsolatedUid(isolated_uid, parent_uid); } else { mUidMap->removeIsolatedUid(isolated_uid, parent_uid); } } } } void StatsLogProcessor::OnConfigUpdated(const ConfigKey& key, const StatsdConfig& config) { Loading cmds/statsd/src/packages/UidMap.cpp +25 −0 Original line number Diff line number Diff line Loading @@ -150,6 +150,31 @@ void UidMap::removeListener(sp<PackageInfoListener> producer) { mSubscribers.erase(producer); } void UidMap::assignIsolatedUid(int isolatedUid, int parentUid) { lock_guard<mutex> lock(mIsolatedMutex); mIsolatedUidMap[isolatedUid] = parentUid; } void UidMap::removeIsolatedUid(int isolatedUid, int parentUid) { lock_guard<mutex> lock(mIsolatedMutex); auto it = mIsolatedUidMap.find(isolatedUid); if (it != mIsolatedUidMap.end()) { mIsolatedUidMap.erase(it); } } int UidMap::getParentUidOrSelf(int uid) { lock_guard<mutex> lock(mIsolatedMutex); auto it = mIsolatedUidMap.find(uid); if (it != mIsolatedUidMap.end()) { return it->second; } return uid; } void UidMap::clearOutput() { mOutput.Clear(); Loading cmds/statsd/src/packages/UidMap.h +11 −0 Original line number Diff line number Diff line Loading @@ -84,6 +84,12 @@ public: // Informs uid map that a config is removed. Used for keeping mConfigKeys up to date. void OnConfigRemoved(const ConfigKey& key); void assignIsolatedUid(int isolatedUid, int parentUid); void removeIsolatedUid(int isolatedUid, int parentUid); // Returns the parent uid if it exists. Otherwise, returns the same uid that was passed-in. int getParentUidOrSelf(int uid); // Gets the output. If every config key has received the output, then the output is cleared. UidMapping getOutput(const ConfigKey& key); Loading @@ -105,11 +111,16 @@ private: // TODO: Use shared_mutex for improved read-locking if a library can be found in Android. mutable mutex mMutex; mutable mutex mIsolatedMutex; // Maps uid to application data. This must be multimap since there is a feature in Android for // multiple apps to share the same uid. std::unordered_multimap<int, AppData> mMap; // Maps isolated uid to the parent uid. Any metrics for an isolated uid will instead contribute // to the parent uid. std::unordered_map<int, int> mIsolatedUidMap; // We prepare the output proto as apps are updated, so that we can grab the current output. UidMapping mOutput; Loading cmds/statsd/src/stats_events.proto +20 −2 Original line number Diff line number Diff line Loading @@ -72,7 +72,7 @@ message StatsEvent { PhoneSignalStrengthChanged phone_signal_strength_changed = 40; SettingChanged setting_changed = 41; ActivityForegroundStateChanged activity_foreground_state_changed = 42; IsolatedUidChanged isolated_uid_changed = 43; // TODO: Reorder the numbering so that the most frequent occur events occur in the first 15. } Loading Loading @@ -695,7 +695,6 @@ message SettingChanged { optional int32 user = 7; } /* * Logs activity going to foreground or background * Loading Loading @@ -848,3 +847,22 @@ message PowerStateSubsystemSleepStatePulled { optional uint64 last_entry_timestamp_ms = 5; optional bool supported_only_in_suspend = 6; } /** * Logs creation or removal of an isolated uid. Isolated uid's are temporary uid's to sandbox risky * behavior in its own uid. However, the metrics of these isolated uid's almost always should be * attributed back to the parent (host) uid. One example is Chrome. * * Logged from: * frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java */ message IsolatedUidChanged { // The host UID. Generally, we should attribute metrics from the isolated uid to the host uid. optional int32 parent_uid = 1; optional int32 isolated_uid = 2; // 1 denotes we're creating an isolated uid and 0 denotes removal. We expect an isolated uid to // be removed before if it's used for another parent uid. optional int32 is_create = 3; } cmds/statsd/tests/UidMap_test.cpp +28 −0 Original line number Diff line number Diff line Loading @@ -13,7 +13,10 @@ // limitations under the License. #include "packages/UidMap.h" #include "StatsLogProcessor.h" #include "config/ConfigKey.h" #include "logd/LogEvent.h" #include "statslog.h" #include <gtest/gtest.h> Loading @@ -29,6 +32,31 @@ namespace statsd { const string kApp1 = "app1.sharing.1"; const string kApp2 = "app2.sharing.1"; TEST(UidMapTest, TestIsolatedUID) { sp<UidMap> m = new UidMap(); StatsLogProcessor p(m, nullptr); LogEvent addEvent(android::util::ISOLATED_UID_CHANGED, 1); android_log_event_list* list = addEvent.GetAndroidLogEventList(); *list << 100; // parent UID *list << 101; // isolated UID *list << 1; // Indicates creation. addEvent.init(); EXPECT_EQ(101, m->getParentUidOrSelf(101)); p.OnLogEvent(addEvent); EXPECT_EQ(100, m->getParentUidOrSelf(101)); LogEvent removeEvent(android::util::ISOLATED_UID_CHANGED, 1); list = removeEvent.GetAndroidLogEventList(); *list << 100; // parent UID *list << 101; // isolated UID *list << 0; // Indicates removal. removeEvent.init(); p.OnLogEvent(removeEvent); EXPECT_EQ(101, m->getParentUidOrSelf(101)); } TEST(UidMapTest, TestMatching) { UidMap m; vector<int32_t> uids; Loading Loading
cmds/statsd/src/StatsLogProcessor.cpp +17 −0 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ */ #include "Log.h" #include "statslog.h" #include "StatsLogProcessor.h" #include "metrics/CountMetricProducer.h" Loading Loading @@ -62,6 +63,22 @@ void StatsLogProcessor::OnLogEvent(const LogEvent& msg) { pair.second->onLogEvent(msg); flushIfNecessary(msg.GetTimestampNs(), pair.first, pair.second); } // Hard-coded logic to update the isolated uid's in the uid-map. // The field numbers need to be currently updated by hand with stats_events.proto if (msg.GetTagId() == android::util::ISOLATED_UID_CHANGED) { status_t err = NO_ERROR, err2 = NO_ERROR, err3 = NO_ERROR; bool is_create = msg.GetBool(3, &err); auto parent_uid = int(msg.GetLong(1, &err2)); auto isolated_uid = int(msg.GetLong(2, &err3)); if (err == NO_ERROR && err2 == NO_ERROR && err3 == NO_ERROR) { if (is_create) { mUidMap->assignIsolatedUid(isolated_uid, parent_uid); } else { mUidMap->removeIsolatedUid(isolated_uid, parent_uid); } } } } void StatsLogProcessor::OnConfigUpdated(const ConfigKey& key, const StatsdConfig& config) { Loading
cmds/statsd/src/packages/UidMap.cpp +25 −0 Original line number Diff line number Diff line Loading @@ -150,6 +150,31 @@ void UidMap::removeListener(sp<PackageInfoListener> producer) { mSubscribers.erase(producer); } void UidMap::assignIsolatedUid(int isolatedUid, int parentUid) { lock_guard<mutex> lock(mIsolatedMutex); mIsolatedUidMap[isolatedUid] = parentUid; } void UidMap::removeIsolatedUid(int isolatedUid, int parentUid) { lock_guard<mutex> lock(mIsolatedMutex); auto it = mIsolatedUidMap.find(isolatedUid); if (it != mIsolatedUidMap.end()) { mIsolatedUidMap.erase(it); } } int UidMap::getParentUidOrSelf(int uid) { lock_guard<mutex> lock(mIsolatedMutex); auto it = mIsolatedUidMap.find(uid); if (it != mIsolatedUidMap.end()) { return it->second; } return uid; } void UidMap::clearOutput() { mOutput.Clear(); Loading
cmds/statsd/src/packages/UidMap.h +11 −0 Original line number Diff line number Diff line Loading @@ -84,6 +84,12 @@ public: // Informs uid map that a config is removed. Used for keeping mConfigKeys up to date. void OnConfigRemoved(const ConfigKey& key); void assignIsolatedUid(int isolatedUid, int parentUid); void removeIsolatedUid(int isolatedUid, int parentUid); // Returns the parent uid if it exists. Otherwise, returns the same uid that was passed-in. int getParentUidOrSelf(int uid); // Gets the output. If every config key has received the output, then the output is cleared. UidMapping getOutput(const ConfigKey& key); Loading @@ -105,11 +111,16 @@ private: // TODO: Use shared_mutex for improved read-locking if a library can be found in Android. mutable mutex mMutex; mutable mutex mIsolatedMutex; // Maps uid to application data. This must be multimap since there is a feature in Android for // multiple apps to share the same uid. std::unordered_multimap<int, AppData> mMap; // Maps isolated uid to the parent uid. Any metrics for an isolated uid will instead contribute // to the parent uid. std::unordered_map<int, int> mIsolatedUidMap; // We prepare the output proto as apps are updated, so that we can grab the current output. UidMapping mOutput; Loading
cmds/statsd/src/stats_events.proto +20 −2 Original line number Diff line number Diff line Loading @@ -72,7 +72,7 @@ message StatsEvent { PhoneSignalStrengthChanged phone_signal_strength_changed = 40; SettingChanged setting_changed = 41; ActivityForegroundStateChanged activity_foreground_state_changed = 42; IsolatedUidChanged isolated_uid_changed = 43; // TODO: Reorder the numbering so that the most frequent occur events occur in the first 15. } Loading Loading @@ -695,7 +695,6 @@ message SettingChanged { optional int32 user = 7; } /* * Logs activity going to foreground or background * Loading Loading @@ -848,3 +847,22 @@ message PowerStateSubsystemSleepStatePulled { optional uint64 last_entry_timestamp_ms = 5; optional bool supported_only_in_suspend = 6; } /** * Logs creation or removal of an isolated uid. Isolated uid's are temporary uid's to sandbox risky * behavior in its own uid. However, the metrics of these isolated uid's almost always should be * attributed back to the parent (host) uid. One example is Chrome. * * Logged from: * frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java */ message IsolatedUidChanged { // The host UID. Generally, we should attribute metrics from the isolated uid to the host uid. optional int32 parent_uid = 1; optional int32 isolated_uid = 2; // 1 denotes we're creating an isolated uid and 0 denotes removal. We expect an isolated uid to // be removed before if it's used for another parent uid. optional int32 is_create = 3; }
cmds/statsd/tests/UidMap_test.cpp +28 −0 Original line number Diff line number Diff line Loading @@ -13,7 +13,10 @@ // limitations under the License. #include "packages/UidMap.h" #include "StatsLogProcessor.h" #include "config/ConfigKey.h" #include "logd/LogEvent.h" #include "statslog.h" #include <gtest/gtest.h> Loading @@ -29,6 +32,31 @@ namespace statsd { const string kApp1 = "app1.sharing.1"; const string kApp2 = "app2.sharing.1"; TEST(UidMapTest, TestIsolatedUID) { sp<UidMap> m = new UidMap(); StatsLogProcessor p(m, nullptr); LogEvent addEvent(android::util::ISOLATED_UID_CHANGED, 1); android_log_event_list* list = addEvent.GetAndroidLogEventList(); *list << 100; // parent UID *list << 101; // isolated UID *list << 1; // Indicates creation. addEvent.init(); EXPECT_EQ(101, m->getParentUidOrSelf(101)); p.OnLogEvent(addEvent); EXPECT_EQ(100, m->getParentUidOrSelf(101)); LogEvent removeEvent(android::util::ISOLATED_UID_CHANGED, 1); list = removeEvent.GetAndroidLogEventList(); *list << 100; // parent UID *list << 101; // isolated UID *list << 0; // Indicates removal. removeEvent.init(); p.OnLogEvent(removeEvent); EXPECT_EQ(101, m->getParentUidOrSelf(101)); } TEST(UidMapTest, TestMatching) { UidMap m; vector<int32_t> uids; Loading