Map isolated uid to host uid when processing log event in statsD.
Test: added test case for isolated uid in Attribution e2e test.
Change-Id: I63d16ebee3e611b1ef0c910e5154cf27766cb330
diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp
index a9e0f23..1cfec32 100644
--- a/cmds/statsd/src/StatsLogProcessor.cpp
+++ b/cmds/statsd/src/StatsLogProcessor.cpp
@@ -25,6 +25,8 @@
#include "guardrail/StatsdStats.h"
#include "metrics/CountMetricProducer.h"
#include "external/StatsPullerManager.h"
+#include "dimension.h"
+#include "field_util.h"
#include "stats_util.h"
#include "storage/StorageManager.h"
@@ -88,30 +90,56 @@
}
}
-// TODO: what if statsd service restarts? How do we know what logs are already processed before?
-void StatsLogProcessor::OnLogEvent(const LogEvent& msg) {
- std::lock_guard<std::mutex> lock(mMetricsMutex);
-
- StatsdStats::getInstance().noteAtomLogged(msg.GetTagId(), msg.GetTimestampNs() / NS_PER_SEC);
- // pass the event to metrics managers.
- for (auto& pair : mMetricsManagers) {
- pair.second->onLogEvent(msg);
- flushIfNecessaryLocked(msg.GetTimestampNs(), pair.first, *(pair.second));
+void StatsLogProcessor::mapIsolatedUidToHostUidIfNecessaryLocked(LogEvent* event) const {
+ std::vector<Field> uidFields;
+ findFields(
+ event->getFieldValueMap(),
+ buildAttributionUidFieldMatcher(event->GetTagId(), Position::ANY),
+ &uidFields);
+ for (size_t i = 0; i < uidFields.size(); ++i) {
+ DimensionsValue* value = event->findFieldValueOrNull(uidFields[i]);
+ if (value != nullptr && value->value_case() == DimensionsValue::ValueCase::kValueInt) {
+ const int uid = mUidMap->getHostUidOrSelf(value->value_int());
+ value->set_value_int(uid);
+ }
}
+}
+
+void StatsLogProcessor::onIsolatedUidChangedEventLocked(const LogEvent& event) {
+ status_t err = NO_ERROR, err2 = NO_ERROR, err3 = NO_ERROR;
+ bool is_create = event.GetBool(3, &err);
+ auto parent_uid = int(event.GetLong(1, &err2));
+ auto isolated_uid = int(event.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);
+ }
+ } else {
+ ALOGE("Failed to parse uid in the isolated uid change event.");
+ }
+}
+
+// TODO: what if statsd service restarts? How do we know what logs are already processed before?
+void StatsLogProcessor::OnLogEvent(LogEvent* event) {
+ std::lock_guard<std::mutex> lock(mMetricsMutex);
+ StatsdStats::getInstance().noteAtomLogged(
+ event->GetTagId(), event->GetTimestampNs() / NS_PER_SEC);
+
// Hard-coded logic to update the isolated uid's in the uid-map.
// The field numbers need to be currently updated by hand with atoms.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);
- }
- }
+ if (event->GetTagId() == android::util::ISOLATED_UID_CHANGED) {
+ onIsolatedUidChangedEventLocked(*event);
+ } else {
+ // Map the isolated uid to host uid if necessary.
+ mapIsolatedUidToHostUidIfNecessaryLocked(event);
+ }
+
+ // pass the event to metrics managers.
+ for (auto& pair : mMetricsManagers) {
+ pair.second->onLogEvent(*event);
+ flushIfNecessaryLocked(event->GetTimestampNs(), pair.first, *(pair.second));
}
}
diff --git a/cmds/statsd/src/StatsLogProcessor.h b/cmds/statsd/src/StatsLogProcessor.h
index adc9161..09e10a1 100644
--- a/cmds/statsd/src/StatsLogProcessor.h
+++ b/cmds/statsd/src/StatsLogProcessor.h
@@ -38,7 +38,7 @@
const std::function<void(const ConfigKey&)>& sendBroadcast);
virtual ~StatsLogProcessor();
- void OnLogEvent(const LogEvent& event);
+ void OnLogEvent(LogEvent* event);
void OnConfigUpdated(const ConfigKey& key, const StatsdConfig& config);
void OnConfigRemoved(const ConfigKey& key);
@@ -46,7 +46,8 @@
size_t GetMetricsSize(const ConfigKey& key) const;
void onDumpReport(const ConfigKey& key, vector<uint8_t>* outData);
- void onDumpReport(const ConfigKey& key, const uint64_t& dumpTimeStampNs, ConfigMetricsReportList* report);
+ void onDumpReport(const ConfigKey& key, const uint64_t& dumpTimeStampNs,
+ ConfigMetricsReportList* report);
/* Tells MetricsManager that the alarms in anomalySet have fired. Modifies anomalySet. */
void onAnomalyAlarmFired(
@@ -79,6 +80,12 @@
void flushIfNecessaryLocked(uint64_t timestampNs, const ConfigKey& key,
MetricsManager& metricsManager);
+ // Maps the isolated uid in the log event to host uid if the log event contains uid fields.
+ void mapIsolatedUidToHostUidIfNecessaryLocked(LogEvent* event) const;
+
+ // Handler over the isolated uid change event.
+ void onIsolatedUidChangedEventLocked(const LogEvent& event);
+
// Function used to send a broadcast so that receiver for the config key can call getData
// to retrieve the stored data.
std::function<void(const ConfigKey& key)> mSendBroadcast;
diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp
index 45f1ea1..0ed1c1f 100644
--- a/cmds/statsd/src/StatsService.cpp
+++ b/cmds/statsd/src/StatsService.cpp
@@ -695,7 +695,7 @@
mConfigManager->Startup();
}
-void StatsService::OnLogEvent(const LogEvent& event) {
+void StatsService::OnLogEvent(LogEvent* event) {
mProcessor->OnLogEvent(event);
}
diff --git a/cmds/statsd/src/StatsService.h b/cmds/statsd/src/StatsService.h
index c0424f3..8d29970 100644
--- a/cmds/statsd/src/StatsService.h
+++ b/cmds/statsd/src/StatsService.h
@@ -72,7 +72,7 @@
/**
* Called by LogReader when there's a log event to process.
*/
- virtual void OnLogEvent(const LogEvent& event);
+ virtual void OnLogEvent(LogEvent* event);
/**
* Binder call for clients to request data for this configuration key.
diff --git a/cmds/statsd/src/dimension.cpp b/cmds/statsd/src/dimension.cpp
index 45b3586..09499b6 100644
--- a/cmds/statsd/src/dimension.cpp
+++ b/cmds/statsd/src/dimension.cpp
@@ -19,7 +19,6 @@
#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
#include "frameworks/base/cmds/statsd/src/statsd_internal.pb.h"
#include "dimension.h"
-#include "field_util.h"
namespace android {
@@ -220,33 +219,35 @@
constexpr int UID_FIELD_NUM_IN_ATTRIBUTION_NODE_PROTO = 1;
constexpr int TAG_FIELD_NUM_IN_ATTRIBUTION_NODE_PROTO = 2;
-void buildAttributionUidFieldMatcher(const int tagId, const Position position,
- FieldMatcher *matcher) {
- matcher->set_field(tagId);
- matcher->add_child()->set_field(ATTRIBUTION_FIELD_NUM_IN_ATOM_PROTO);
- FieldMatcher* child = matcher->mutable_child(0)->add_child();
- child->set_field(UID_FIELD_NUM_IN_ATTRIBUTION_NODE_PROTO);
-}
-
-void buildAttributionTagFieldMatcher(const int tagId, const Position position,
- FieldMatcher *matcher) {
- matcher->set_field(tagId);
- FieldMatcher* child = matcher->add_child();
+FieldMatcher buildAttributionUidFieldMatcher(const int tagId, const Position position) {
+ FieldMatcher matcher;
+ matcher.set_field(tagId);
+ auto child = matcher.add_child();
child->set_field(ATTRIBUTION_FIELD_NUM_IN_ATOM_PROTO);
child->set_position(position);
- child = child->add_child();
- child->set_field(TAG_FIELD_NUM_IN_ATTRIBUTION_NODE_PROTO);
+ child->add_child()->set_field(UID_FIELD_NUM_IN_ATTRIBUTION_NODE_PROTO);
+ return matcher;
}
-void buildAttributionFieldMatcher(const int tagId, const Position position,
- FieldMatcher *matcher) {
- matcher->set_field(tagId);
- FieldMatcher* child = matcher->add_child();
+FieldMatcher buildAttributionTagFieldMatcher(const int tagId, const Position position) {
+ FieldMatcher matcher;
+ matcher.set_field(tagId);
+ FieldMatcher* child = matcher.add_child();
child->set_field(ATTRIBUTION_FIELD_NUM_IN_ATOM_PROTO);
child->set_position(position);
- child = child->add_child();
- child->set_field(UID_FIELD_NUM_IN_ATTRIBUTION_NODE_PROTO);
- child->set_field(TAG_FIELD_NUM_IN_ATTRIBUTION_NODE_PROTO);
+ child->add_child()->set_field(TAG_FIELD_NUM_IN_ATTRIBUTION_NODE_PROTO);
+ return matcher;
+}
+
+FieldMatcher buildAttributionFieldMatcher(const int tagId, const Position position) {
+ FieldMatcher matcher;
+ matcher.set_field(tagId);
+ FieldMatcher* child = matcher.add_child();
+ child->set_field(ATTRIBUTION_FIELD_NUM_IN_ATOM_PROTO);
+ child->set_position(position);
+ child->add_child()->set_field(UID_FIELD_NUM_IN_ATTRIBUTION_NODE_PROTO);
+ child->add_child()->set_field(TAG_FIELD_NUM_IN_ATTRIBUTION_NODE_PROTO);
+ return matcher;
}
void DimensionsValueToString(const DimensionsValue& value, std::string *flattened) {
diff --git a/cmds/statsd/src/dimension.h b/cmds/statsd/src/dimension.h
index 5bb64a9..845c138 100644
--- a/cmds/statsd/src/dimension.h
+++ b/cmds/statsd/src/dimension.h
@@ -27,7 +27,6 @@
namespace os {
namespace statsd {
-
// Returns the leaf node from the DimensionsValue proto. It assume that the input has only one
// leaf node at most.
const DimensionsValue* getSingleLeafValue(const DimensionsValue* value);
diff --git a/cmds/statsd/src/field_util.cpp b/cmds/statsd/src/field_util.cpp
index d10e167..4ff4f74 100644
--- a/cmds/statsd/src/field_util.cpp
+++ b/cmds/statsd/src/field_util.cpp
@@ -184,6 +184,7 @@
}
}
+namespace {
void findFields(
const FieldValueMap& fieldValueMap,
const FieldMatcher& matcher,
@@ -287,9 +288,18 @@
}
}
+} // namespace
+
+void findFields(
+ const FieldValueMap& fieldValueMap,
+ const FieldMatcher& matcher,
+ std::vector<Field>* rootFields) {
+ return findFields(fieldValueMap, matcher, buildSimpleAtomField(matcher.field()), rootFields);
+}
+
void filterFields(const FieldMatcher& matcher, FieldValueMap* fieldValueMap) {
std::vector<Field> rootFields;
- findFields(*fieldValueMap, matcher, buildSimpleAtomField(matcher.field()), &rootFields);
+ findFields(*fieldValueMap, matcher, &rootFields);
std::set<Field, FieldCmp> rootFieldSet(rootFields.begin(), rootFields.end());
auto it = fieldValueMap->begin();
while (it != fieldValueMap->end()) {
@@ -313,6 +323,11 @@
return true;
}
+bool IsAttributionUidField(const Field& field) {
+ return field.child_size() == 1 && field.child(0).field() == 1
+ && field.child(0).child_size() == 1 && field.child(0).child(0).field() == 1;
+}
+
} // namespace statsd
} // namespace os
} // namespace android
diff --git a/cmds/statsd/src/field_util.h b/cmds/statsd/src/field_util.h
index 3e7d54c..a4dfddd 100644
--- a/cmds/statsd/src/field_util.h
+++ b/cmds/statsd/src/field_util.h
@@ -85,6 +85,9 @@
// Filter out the fields not in the field matcher.
void filterFields(const FieldMatcher& matcher, FieldValueMap* fieldValueMap);
+// Returns if the field is attribution node uid field.
+bool IsAttributionUidField(const Field& field);
+
} // namespace statsd
} // namespace os
} // namespace android
diff --git a/cmds/statsd/src/logd/LogEvent.cpp b/cmds/statsd/src/logd/LogEvent.cpp
index 49a6e33..6782f3f 100644
--- a/cmds/statsd/src/logd/LogEvent.cpp
+++ b/cmds/statsd/src/logd/LogEvent.cpp
@@ -397,6 +397,14 @@
return dimensionsValue;
}
+DimensionsValue* LogEvent::findFieldValueOrNull(const Field& field) {
+ auto it = mFieldValueMap.find(field);
+ if (it == mFieldValueMap.end()) {
+ return nullptr;
+ }
+ return &it->second;
+}
+
string LogEvent::ToString() const {
ostringstream result;
result << "{ " << mTimestampNs << " (" << mTagId << ")";
diff --git a/cmds/statsd/src/logd/LogEvent.h b/cmds/statsd/src/logd/LogEvent.h
index 8f3dedf..fdfa32e 100644
--- a/cmds/statsd/src/logd/LogEvent.h
+++ b/cmds/statsd/src/logd/LogEvent.h
@@ -132,6 +132,11 @@
return mFieldValueMap.size();
}
+ /**
+ * Returns the mutable DimensionsValue proto for the specific the field.
+ */
+ DimensionsValue* findFieldValueOrNull(const Field& field);
+
inline const FieldValueMap& getFieldValueMap() const { return mFieldValueMap; }
private:
diff --git a/cmds/statsd/src/logd/LogListener.h b/cmds/statsd/src/logd/LogListener.h
index 9641226..69ca571 100644
--- a/cmds/statsd/src/logd/LogListener.h
+++ b/cmds/statsd/src/logd/LogListener.h
@@ -33,7 +33,7 @@
LogListener();
virtual ~LogListener();
- virtual void OnLogEvent(const LogEvent& msg) = 0;
+ virtual void OnLogEvent(LogEvent* msg) = 0;
};
} // namespace statsd
diff --git a/cmds/statsd/src/logd/LogReader.cpp b/cmds/statsd/src/logd/LogReader.cpp
index c441a5e..7636268 100644
--- a/cmds/statsd/src/logd/LogReader.cpp
+++ b/cmds/statsd/src/logd/LogReader.cpp
@@ -110,7 +110,7 @@
LogEvent event(msg);
// Call the listener
- mListener->OnLogEvent(event);
+ mListener->OnLogEvent(&event);
}
}
diff --git a/cmds/statsd/src/matchers/matcher_util.cpp b/cmds/statsd/src/matchers/matcher_util.cpp
index 46d9b92..48f62e7 100644
--- a/cmds/statsd/src/matchers/matcher_util.cpp
+++ b/cmds/statsd/src/matchers/matcher_util.cpp
@@ -93,11 +93,6 @@
return matched;
}
-bool IsAttributionUidField(const Field& field) {
- return field.child_size() == 1 && field.child(0).field() == 1
- && field.child(0).child_size() == 1 && field.child(0).child(0).field() == 1;
-}
-
bool matchesNonRepeatedField(
const UidMap& uidMap,
const FieldValueMap& fieldMap,
diff --git a/cmds/statsd/src/packages/UidMap.cpp b/cmds/statsd/src/packages/UidMap.cpp
index 517d21d..b0c3197 100644
--- a/cmds/statsd/src/packages/UidMap.cpp
+++ b/cmds/statsd/src/packages/UidMap.cpp
@@ -269,7 +269,7 @@
}
}
-int UidMap::getParentUidOrSelf(int uid) {
+int UidMap::getHostUidOrSelf(int uid) const {
lock_guard<mutex> lock(mIsolatedMutex);
auto it = mIsolatedUidMap.find(uid);
diff --git a/cmds/statsd/src/packages/UidMap.h b/cmds/statsd/src/packages/UidMap.h
index 07e13e0..4e37977 100644
--- a/cmds/statsd/src/packages/UidMap.h
+++ b/cmds/statsd/src/packages/UidMap.h
@@ -90,8 +90,8 @@
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);
+ // Returns the host uid if it exists. Otherwise, returns the same uid that was passed-in.
+ int getHostUidOrSelf(int uid) const;
// Gets the output. If every config key has received the output, then the output is cleared.
UidMapping getOutput(const ConfigKey& key);
diff --git a/cmds/statsd/tests/UidMap_test.cpp b/cmds/statsd/tests/UidMap_test.cpp
index 945af27..5292f24 100644
--- a/cmds/statsd/tests/UidMap_test.cpp
+++ b/cmds/statsd/tests/UidMap_test.cpp
@@ -45,18 +45,18 @@
addEvent.write(1); // Indicates creation.
addEvent.init();
- EXPECT_EQ(101, m->getParentUidOrSelf(101));
+ EXPECT_EQ(101, m->getHostUidOrSelf(101));
- p.OnLogEvent(addEvent);
- EXPECT_EQ(100, m->getParentUidOrSelf(101));
+ p.OnLogEvent(&addEvent);
+ EXPECT_EQ(100, m->getHostUidOrSelf(101));
LogEvent removeEvent(android::util::ISOLATED_UID_CHANGED, 1);
removeEvent.write(100); // parent UID
removeEvent.write(101); // isolated UID
removeEvent.write(0); // Indicates removal.
removeEvent.init();
- p.OnLogEvent(removeEvent);
- EXPECT_EQ(101, m->getParentUidOrSelf(101));
+ p.OnLogEvent(&removeEvent);
+ EXPECT_EQ(101, m->getHostUidOrSelf(101));
}
TEST(UidMapTest, TestMatching) {
diff --git a/cmds/statsd/tests/e2e/Attribution_e2e_test.cpp b/cmds/statsd/tests/e2e/Attribution_e2e_test.cpp
index e28dd31..39c9549 100644
--- a/cmds/statsd/tests/e2e/Attribution_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/Attribution_e2e_test.cpp
@@ -106,6 +106,10 @@
{CreateAttribution(111, "App1"), CreateAttribution(333, "App3")};
std::vector<AttributionNode> attributions8 = {CreateAttribution(111, "App1")};
+ // GMS core node with isolated uid.
+ const int isolatedUid = 666;
+ std::vector<AttributionNode> attributions9 =
+ {CreateAttribution(isolatedUid, "GMSCoreModule3")};
std::vector<std::unique_ptr<LogEvent>> events;
// Events 1~4 are in the 1st bucket.
@@ -124,22 +128,30 @@
events.push_back(CreateAcquireWakelockEvent(
attributions6, "wl2", bucketStartTimeNs + 2 * bucketSizeNs + 100));
events.push_back(CreateAcquireWakelockEvent(
- attributions7, "wl2", bucketStartTimeNs + 3 * bucketSizeNs - 1));
+ attributions7, "wl2", bucketStartTimeNs + 3 * bucketSizeNs - 2));
events.push_back(CreateAcquireWakelockEvent(
attributions8, "wl2", bucketStartTimeNs + 3 * bucketSizeNs));
+ events.push_back(CreateAcquireWakelockEvent(
+ attributions9, "wl2", bucketStartTimeNs + 3 * bucketSizeNs + 1));
+ events.push_back(CreateAcquireWakelockEvent(
+ attributions9, "wl2", bucketStartTimeNs + 3 * bucketSizeNs + 100));
+ events.push_back(CreateIsolatedUidChangedEvent(
+ isolatedUid, 222, true/* is_create*/, bucketStartTimeNs + 3 * bucketSizeNs - 1));
+ events.push_back(CreateIsolatedUidChangedEvent(
+ isolatedUid, 222, false/* is_create*/, bucketStartTimeNs + 3 * bucketSizeNs + 10));
sortLogEventsByTimestamp(&events);
for (const auto& event : events) {
- processor->OnLogEvent(*event);
+ processor->OnLogEvent(event.get());
}
ConfigMetricsReportList reports;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 3 * bucketSizeNs + 1, &reports);
+ processor->onDumpReport(cfgKey, bucketStartTimeNs + 4 * bucketSizeNs + 1, &reports);
EXPECT_EQ(reports.reports_size(), 1);
EXPECT_EQ(reports.reports(0).metrics_size(), 1);
StatsLogReport::CountMetricDataWrapper countMetrics;
sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
- EXPECT_EQ(countMetrics.data_size(), 3);
+ EXPECT_EQ(countMetrics.data_size(), 4);
auto data = countMetrics.data(0);
ValidateAttributionUidAndTagDimension(
@@ -165,6 +177,14 @@
data = countMetrics.data(2);
ValidateAttributionUidAndTagDimension(
+ data.dimension(), android::util::WAKELOCK_STATE_CHANGED, 222, "GMSCoreModule3");
+ EXPECT_EQ(data.bucket_info_size(), 1);
+ EXPECT_EQ(data.bucket_info(0).count(), 1);
+ EXPECT_EQ(data.bucket_info(0).start_bucket_nanos(), bucketStartTimeNs + 3 * bucketSizeNs);
+ EXPECT_EQ(data.bucket_info(0).end_bucket_nanos(), bucketStartTimeNs + 4 * bucketSizeNs);
+
+ data = countMetrics.data(3);
+ ValidateAttributionUidAndTagDimension(
data.dimension(), android::util::WAKELOCK_STATE_CHANGED, 444, "GMSCoreModule2");
EXPECT_EQ(data.bucket_info_size(), 1);
EXPECT_EQ(data.bucket_info(0).count(), 1);
diff --git a/cmds/statsd/tests/e2e/MetricConditionLink_e2e_test.cpp b/cmds/statsd/tests/e2e/MetricConditionLink_e2e_test.cpp
index a81bbb9..cdc4467 100644
--- a/cmds/statsd/tests/e2e/MetricConditionLink_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/MetricConditionLink_e2e_test.cpp
@@ -188,7 +188,7 @@
sortLogEventsByTimestamp(&events);
for (const auto& event : events) {
- processor->OnLogEvent(*event);
+ processor->OnLogEvent(event.get());
}
ConfigMetricsReportList reports;
processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs - 1, &reports);
diff --git a/cmds/statsd/tests/e2e/WakelockDuration_e2e_test.cpp b/cmds/statsd/tests/e2e/WakelockDuration_e2e_test.cpp
index 47e8a72..2783356 100644
--- a/cmds/statsd/tests/e2e/WakelockDuration_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/WakelockDuration_e2e_test.cpp
@@ -107,7 +107,7 @@
sortLogEventsByTimestamp(&events);
for (const auto& event : events) {
- processor->OnLogEvent(*event);
+ processor->OnLogEvent(event.get());
}
ConfigMetricsReportList reports;
diff --git a/cmds/statsd/tests/statsd_test_util.cpp b/cmds/statsd/tests/statsd_test_util.cpp
index f9ac6d6d..e788235 100644
--- a/cmds/statsd/tests/statsd_test_util.cpp
+++ b/cmds/statsd/tests/statsd_test_util.cpp
@@ -292,6 +292,17 @@
uid, ProcessLifeCycleStateChanged::PROCESS_CRASHED, timestampNs);
}
+std::unique_ptr<LogEvent> CreateIsolatedUidChangedEvent(
+ int isolatedUid, int hostUid, bool is_create, uint64_t timestampNs) {
+ auto logEvent = std::make_unique<LogEvent>(
+ android::util::ISOLATED_UID_CHANGED, timestampNs);
+ logEvent->write(hostUid);
+ logEvent->write(isolatedUid);
+ logEvent->write(is_create);
+ logEvent->init();
+ return logEvent;
+}
+
sp<StatsLogProcessor> CreateStatsLogProcessor(const long timeBaseSec, const StatsdConfig& config,
const ConfigKey& key) {
sp<UidMap> uidMap = new UidMap();
diff --git a/cmds/statsd/tests/statsd_test_util.h b/cmds/statsd/tests/statsd_test_util.h
index f1ce358..1bbbd9a 100644
--- a/cmds/statsd/tests/statsd_test_util.h
+++ b/cmds/statsd/tests/statsd_test_util.h
@@ -111,6 +111,10 @@
const std::vector<AttributionNode>& attributions,
const string& wakelockName, uint64_t timestampNs);
+// Create log event for releasing wakelock.
+std::unique_ptr<LogEvent> CreateIsolatedUidChangedEvent(
+ int isolatedUid, int hostUid, bool is_create, uint64_t timestampNs);
+
// Helper function to create an AttributionNode proto.
AttributionNode CreateAttribution(const int& uid, const string& tag);