summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmds/statsd/src/StatsLogProcessor.cpp17
-rw-r--r--cmds/statsd/src/packages/UidMap.cpp25
-rw-r--r--cmds/statsd/src/packages/UidMap.h11
-rw-r--r--cmds/statsd/src/stats_events.proto22
-rw-r--r--cmds/statsd/tests/UidMap_test.cpp28
-rw-r--r--core/java/com/android/internal/os/BatteryStatsImpl.java9
6 files changed, 107 insertions, 5 deletions
diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp
index 8910523aeda3..f0689d2cc839 100644
--- a/cmds/statsd/src/StatsLogProcessor.cpp
+++ b/cmds/statsd/src/StatsLogProcessor.cpp
@@ -15,6 +15,7 @@
*/
#include "Log.h"
+#include "statslog.h"
#include "StatsLogProcessor.h"
#include "frameworks/base/cmds/statsd/src/stats_log.pb.h"
@@ -48,6 +49,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) {
diff --git a/cmds/statsd/src/packages/UidMap.cpp b/cmds/statsd/src/packages/UidMap.cpp
index d83c3a426685..7b276421a259 100644
--- a/cmds/statsd/src/packages/UidMap.cpp
+++ b/cmds/statsd/src/packages/UidMap.cpp
@@ -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();
diff --git a/cmds/statsd/src/packages/UidMap.h b/cmds/statsd/src/packages/UidMap.h
index bf120e04d7c8..de68fbceb7a9 100644
--- a/cmds/statsd/src/packages/UidMap.h
+++ b/cmds/statsd/src/packages/UidMap.h
@@ -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);
@@ -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;
diff --git a/cmds/statsd/src/stats_events.proto b/cmds/statsd/src/stats_events.proto
index 82d975914682..8816795ed82f 100644
--- a/cmds/statsd/src/stats_events.proto
+++ b/cmds/statsd/src/stats_events.proto
@@ -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.
}
@@ -695,7 +695,6 @@ message SettingChanged {
optional int32 user = 7;
}
-
/*
* Logs activity going to foreground or background
*
@@ -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;
+}
diff --git a/cmds/statsd/tests/UidMap_test.cpp b/cmds/statsd/tests/UidMap_test.cpp
index 671f6d4ac472..c64719ee0c85 100644
--- a/cmds/statsd/tests/UidMap_test.cpp
+++ b/cmds/statsd/tests/UidMap_test.cpp
@@ -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>
@@ -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;
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 2ec64a5ecdc4..f2483c0a71e5 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -3639,6 +3639,7 @@ public class BatteryStatsImpl extends BatteryStats {
public void addIsolatedUidLocked(int isolatedUid, int appUid) {
mIsolatedUids.put(isolatedUid, appUid);
+ StatsLog.write(StatsLog.ISOLATED_UID_CHANGED, appUid, isolatedUid, 1);
}
/**
@@ -3659,9 +3660,11 @@ public class BatteryStatsImpl extends BatteryStats {
* @see #scheduleRemoveIsolatedUidLocked(int, int)
*/
public void removeIsolatedUidLocked(int isolatedUid) {
- mIsolatedUids.delete(isolatedUid);
- mKernelUidCpuTimeReader.removeUid(isolatedUid);
- mKernelUidCpuFreqTimeReader.removeUid(isolatedUid);
+ StatsLog.write(
+ StatsLog.ISOLATED_UID_CHANGED, mIsolatedUids.get(isolatedUid, -1), isolatedUid, 0);
+ mIsolatedUids.delete(isolatedUid);
+ mKernelUidCpuTimeReader.removeUid(isolatedUid);
+ mKernelUidCpuFreqTimeReader.removeUid(isolatedUid);
}
public int mapUid(int uid) {