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
This commit is contained in:
@@ -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 @@ void StatsLogProcessor::onAnomalyAlarmFired(
|
||||
}
|
||||
}
|
||||
|
||||
// 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));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ private:
|
||||
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;
|
||||
|
||||
@@ -695,7 +695,7 @@ void StatsService::Startup() {
|
||||
mConfigManager->Startup();
|
||||
}
|
||||
|
||||
void StatsService::OnLogEvent(const LogEvent& event) {
|
||||
void StatsService::OnLogEvent(LogEvent* event) {
|
||||
mProcessor->OnLogEvent(event);
|
||||
}
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@ public:
|
||||
/**
|
||||
* 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.
|
||||
|
||||
@@ -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 ATTRIBUTION_FIELD_NUM_IN_ATOM_PROTO = 1;
|
||||
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) {
|
||||
|
||||
@@ -27,7 +27,6 @@ namespace android {
|
||||
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);
|
||||
|
||||
@@ -184,6 +184,7 @@ void setPositionForLeaf(Field *field, int index) {
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
void findFields(
|
||||
const FieldValueMap& fieldValueMap,
|
||||
const FieldMatcher& matcher,
|
||||
@@ -287,9 +288,18 @@ void findFields(
|
||||
}
|
||||
}
|
||||
|
||||
} // 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 @@ bool hasLeafNode(const FieldMatcher& matcher) {
|
||||
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
|
||||
|
||||
@@ -85,6 +85,9 @@ void findFields(
|
||||
// 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
|
||||
|
||||
@@ -397,6 +397,14 @@ DimensionsValue LogEvent::GetSimpleAtomDimensionsValueProto(size_t atomField) c
|
||||
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 << ")";
|
||||
|
||||
@@ -132,6 +132,11 @@ public:
|
||||
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:
|
||||
|
||||
@@ -33,7 +33,7 @@ public:
|
||||
LogListener();
|
||||
virtual ~LogListener();
|
||||
|
||||
virtual void OnLogEvent(const LogEvent& msg) = 0;
|
||||
virtual void OnLogEvent(LogEvent* msg) = 0;
|
||||
};
|
||||
|
||||
} // namespace statsd
|
||||
|
||||
@@ -110,7 +110,7 @@ int LogReader::connect_and_read() {
|
||||
LogEvent event(msg);
|
||||
|
||||
// Call the listener
|
||||
mListener->OnLogEvent(event);
|
||||
mListener->OnLogEvent(&event);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -93,11 +93,6 @@ bool combinationMatch(const vector<int>& children, const LogicalOperation& opera
|
||||
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,
|
||||
|
||||
@@ -269,7 +269,7 @@ void UidMap::removeIsolatedUid(int isolatedUid, int parentUid) {
|
||||
}
|
||||
}
|
||||
|
||||
int UidMap::getParentUidOrSelf(int uid) {
|
||||
int UidMap::getHostUidOrSelf(int uid) const {
|
||||
lock_guard<mutex> lock(mIsolatedMutex);
|
||||
|
||||
auto it = mIsolatedUidMap.find(uid);
|
||||
|
||||
@@ -90,8 +90,8 @@ public:
|
||||
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);
|
||||
|
||||
@@ -45,18 +45,18 @@ TEST(UidMapTest, TestIsolatedUID) {
|
||||
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) {
|
||||
|
||||
@@ -106,6 +106,10 @@ TEST(AttributionE2eTest, TestAttributionMatchAndSlice) {
|
||||
{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 @@ TEST(AttributionE2eTest, TestAttributionMatchAndSlice) {
|
||||
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(
|
||||
@@ -164,6 +176,14 @@ TEST(AttributionE2eTest, TestAttributionMatchAndSlice) {
|
||||
EXPECT_EQ(data.bucket_info(1).end_bucket_nanos(), bucketStartTimeNs + 2 * bucketSizeNs);
|
||||
|
||||
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);
|
||||
|
||||
@@ -188,7 +188,7 @@ TEST(MetricConditionLinkE2eTest, TestMultiplePredicatesAndLinks) {
|
||||
sortLogEventsByTimestamp(&events);
|
||||
|
||||
for (const auto& event : events) {
|
||||
processor->OnLogEvent(*event);
|
||||
processor->OnLogEvent(event.get());
|
||||
}
|
||||
ConfigMetricsReportList reports;
|
||||
processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs - 1, &reports);
|
||||
|
||||
@@ -107,7 +107,7 @@ TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensions) {
|
||||
sortLogEventsByTimestamp(&events);
|
||||
|
||||
for (const auto& event : events) {
|
||||
processor->OnLogEvent(*event);
|
||||
processor->OnLogEvent(event.get());
|
||||
}
|
||||
|
||||
ConfigMetricsReportList reports;
|
||||
|
||||
@@ -292,6 +292,17 @@ std::unique_ptr<LogEvent> CreateAppCrashEvent(const int uid, uint64_t timestampN
|
||||
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();
|
||||
|
||||
@@ -111,6 +111,10 @@ std::unique_ptr<LogEvent> CreateReleaseWakelockEvent(
|
||||
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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user