Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d40053eb authored by Yangster-mac's avatar Yangster-mac
Browse files

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
parent d6808dc0
Loading
Loading
Loading
Loading
+47 −19
Original line number Diff line number Diff line
@@ -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);
        }
    // 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) {
    }
}

void StatsLogProcessor::onIsolatedUidChangedEventLocked(const LogEvent& event) {
    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));
    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 (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));
    }
}

+9 −2
Original line number Diff line number Diff line
@@ -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;
+1 −1
Original line number Diff line number Diff line
@@ -695,7 +695,7 @@ void StatsService::Startup() {
    mConfigManager->Startup();
}

void StatsService::OnLogEvent(const LogEvent& event) {
void StatsService::OnLogEvent(LogEvent* event) {
    mProcessor->OnLogEvent(event);
}

+1 −1
Original line number Diff line number Diff line
@@ -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.
+21 −20
Original line number Diff line number Diff line
@@ -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);
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->add_child()->set_field(UID_FIELD_NUM_IN_ATTRIBUTION_NODE_PROTO);
    return matcher;
}

void buildAttributionTagFieldMatcher(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(TAG_FIELD_NUM_IN_ATTRIBUTION_NODE_PROTO);
    child->add_child()->set_field(TAG_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 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 = 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(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) {
Loading