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

Commit c96fd618 authored by Android Build Merger (Role)'s avatar Android Build Merger (Role) Committed by Android (Google) Code Review
Browse files

Merge "Merge changes from topic "ActivationType" into qt-dev am: 266b90d8 am: ec401578"

parents e71cf276 9cb2391c
Loading
Loading
Loading
Loading
+45 −50
Original line number Diff line number Diff line
@@ -68,12 +68,8 @@ const int FIELD_ID_CURRENT_REPORT_WALL_CLOCK_NANOS = 6;
const int FIELD_ID_DUMP_REPORT_REASON = 8;
const int FIELD_ID_STRINGS = 9;

const int FIELD_ID_ACTIVE_CONFIG_LIST = 1;
const int FIELD_ID_CONFIG_ID = 1;
const int FIELD_ID_CONFIG_UID = 2;
const int FIELD_ID_ACTIVE_METRIC = 3;
const int FIELD_ID_METRIC_ID = 1;
const int FIELD_ID_TIME_TO_LIVE_NANOS = 2;
// for ActiveConfigList
const int FIELD_ID_ACTIVE_CONFIG_LIST_CONFIG = 1;

#define NS_PER_HOUR 3600 * NS_PER_SEC

@@ -613,7 +609,7 @@ void StatsLogProcessor::WriteDataToDiskLocked(const ConfigKey& key,
    mOnDiskDataConfigs.insert(key);
}

void StatsLogProcessor::WriteMetricsActivationToDisk(int64_t currentTimeNs) {
void StatsLogProcessor::SaveActiveConfigsToDisk(int64_t currentTimeNs) {
    std::lock_guard<std::mutex> lock(mMetricsMutex);

    const int64_t timeNs = getElapsedRealtimeNs();
@@ -629,28 +625,12 @@ void StatsLogProcessor::WriteMetricsActivationToDisk(int64_t currentTimeNs) {
    mLastActiveMetricsWriteNs = timeNs;

    ProtoOutputStream proto;

    for (const auto& pair : mMetricsManagers) {
        uint64_t activeConfigListToken = proto.start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
                                                     FIELD_ID_ACTIVE_CONFIG_LIST);
        proto.write(FIELD_TYPE_INT64 | FIELD_ID_CONFIG_ID, (long long)pair.first.GetId());
        proto.write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_UID, pair.first.GetUid());

        vector<MetricProducer*> activeMetrics;
        pair.second->prepForShutDown(currentTimeNs);
        pair.second->getActiveMetrics(activeMetrics);
        for (MetricProducer* metric : activeMetrics) {
            if (metric->isActive()) {
                uint64_t metricToken = proto.start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
                                                   FIELD_ID_ACTIVE_METRIC);
                proto.write(FIELD_TYPE_INT64 | FIELD_ID_METRIC_ID,
                            (long long)metric->getMetricId());
                proto.write(FIELD_TYPE_INT64 | FIELD_ID_TIME_TO_LIVE_NANOS,
                            (long long)metric->getRemainingTtlNs(currentTimeNs));
                proto.end(metricToken);
            }
        }
        proto.end(activeConfigListToken);
        const sp<MetricsManager>& metricsManager = pair.second;
        uint64_t configToken = proto.start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
                                                     FIELD_ID_ACTIVE_CONFIG_LIST_CONFIG);
        metricsManager->writeActiveConfigToProtoOutputStream(currentTimeNs, &proto);
        proto.end(configToken);
    }

    string file_name = StringPrintf("%s/active_metrics", STATS_ACTIVE_METRIC_DIR);
@@ -664,30 +644,45 @@ void StatsLogProcessor::WriteMetricsActivationToDisk(int64_t currentTimeNs) {
    proto.flush(fd.get());
}

void StatsLogProcessor::LoadMetricsActivationFromDisk() {
void StatsLogProcessor::LoadActiveConfigsFromDisk() {
    std::lock_guard<std::mutex> lock(mMetricsMutex);

    string file_name = StringPrintf("%s/active_metrics", STATS_ACTIVE_METRIC_DIR);
    int fd = open(file_name.c_str(), O_RDONLY | O_CLOEXEC);
    if (fd != -1) {
    if (-1 == fd) {
        VLOG("Attempt to read %s but failed", file_name.c_str());
        StorageManager::deleteFile(file_name.c_str());
        return;
    }
    string content;
        if (android::base::ReadFdToString(fd, &content)) {
    if (!android::base::ReadFdToString(fd, &content)) {
        ALOGE("Attempt to read %s but failed", file_name.c_str());
        close(fd);
        StorageManager::deleteFile(file_name.c_str());
        return;
    }

    close(fd);

    ActiveConfigList activeConfigList;
            if (activeConfigList.ParseFromString(content)) {
                for (int i = 0; i < activeConfigList.active_config_size(); i++) {
                    const auto& config = activeConfigList.active_config(i);
                    ConfigKey key(config.uid(), config.config_id());
    if (!activeConfigList.ParseFromString(content)) {
        ALOGE("Attempt to read %s but failed; failed to load active configs", file_name.c_str());
        StorageManager::deleteFile(file_name.c_str());
        return;
    }
    for (int i = 0; i < activeConfigList.config_size(); i++) {
        const auto& config = activeConfigList.config(i);
        ConfigKey key(config.uid(), config.id());
        auto it = mMetricsManagers.find(key);
        if (it == mMetricsManagers.end()) {
            ALOGE("No config found for config %s", key.ToString().c_str());
            continue;
        }
        VLOG("Setting active config %s", key.ToString().c_str());
                    it->second->setActiveMetrics(config, mTimeBaseNs);
                }
            }
            VLOG("Successfully loaded %d active configs.", activeConfigList.active_config_size());
        }
        close(fd);
        it->second->loadActiveConfig(config, mTimeBaseNs);
    }
    VLOG("Successfully loaded %d active configs.", activeConfigList.config_size());

    StorageManager::deleteFile(file_name.c_str());
}

+7 −4
Original line number Diff line number Diff line
@@ -89,11 +89,11 @@ public:
    void WriteDataToDisk(const DumpReportReason dumpReportReason,
                         const DumpLatency dumpLatency);

    /* Persist metric activation status onto disk. */
    void WriteMetricsActivationToDisk(int64_t currentTimeNs);
    /* Persist configs containing metrics with active activations to disk. */
    void SaveActiveConfigsToDisk(int64_t currentTimeNs);

    /* Load metric activation status from disk. */
    void LoadMetricsActivationFromDisk();
    /* Load configs containing metrics with active activations from disk. */
    void LoadActiveConfigsFromDisk();

    // Reset all configs.
    void resetConfigs();
@@ -221,6 +221,9 @@ private:
    FRIEND_TEST(StatsLogProcessorTest, TestDropWhenByteSizeTooLarge);
    FRIEND_TEST(StatsLogProcessorTest, TestActiveConfigMetricDiskWriteRead);
    FRIEND_TEST(StatsLogProcessorTest, TestActivationOnBoot);
    FRIEND_TEST(StatsLogProcessorTest, TestActivationOnBootMultipleActivations);
    FRIEND_TEST(StatsLogProcessorTest,
            TestActivationOnBootMultipleActivationsDifferentActivationTypes);

    FRIEND_TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForSumDuration1);
    FRIEND_TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForSumDuration2);
+3 −3
Original line number Diff line number Diff line
@@ -986,7 +986,7 @@ Status StatsService::informDeviceShutdown() {
    ENFORCE_UID(AID_SYSTEM);
    VLOG("StatsService::informDeviceShutdown");
    mProcessor->WriteDataToDisk(DEVICE_SHUTDOWN, FAST);
    mProcessor->WriteMetricsActivationToDisk(getElapsedRealtimeNs());
    mProcessor->SaveActiveConfigsToDisk(getElapsedRealtimeNs());
    return Status::ok();
}

@@ -1021,14 +1021,14 @@ Status StatsService::statsCompanionReady() {

void StatsService::Startup() {
    mConfigManager->Startup();
    mProcessor->LoadMetricsActivationFromDisk();
    mProcessor->LoadActiveConfigsFromDisk();
}

void StatsService::Terminate() {
    ALOGI("StatsService::Terminating");
    if (mProcessor != nullptr) {
        mProcessor->WriteDataToDisk(TERMINATION_SIGNAL_RECEIVED, FAST);
        mProcessor->WriteMetricsActivationToDisk(getElapsedRealtimeNs());
        mProcessor->SaveActiveConfigsToDisk(getElapsedRealtimeNs());
    }
}

+14 −11
Original line number Diff line number Diff line
@@ -21,23 +21,26 @@ option java_package = "com.android.os";
option java_multiple_files = true;
option java_outer_classname = "ActiveConfigProto";

message ActiveEventActivation {
    optional int32 atom_matcher_index = 1;

    // Time left in activation. When this proto is loaded after device boot,
    // the activation should be set to active for this duration.
    optional int64 remaining_ttl_nanos = 2;
}

message ActiveMetric {
    // metric id
    optional int64 metric_id = 1;
    // Remaining time to live in nano seconds. -1 for infinity.
    optional int64 time_to_live_nanos = 2;
    optional int64 id = 1;
    repeated ActiveEventActivation activation = 2;
}

message ActiveConfig {
    // config id
    optional int64 config_id = 1;
    // config uid
    optional int64 id = 1;
    optional int32 uid = 2;
    // metrics
    repeated ActiveMetric active_metric = 3;
    repeated ActiveMetric metric = 3;
}

// all configs and their metrics on device.
message ActiveConfigList {
    repeated ActiveConfig active_config = 1;
    repeated ActiveConfig config = 1;
}
+66 −40
Original line number Diff line number Diff line
@@ -18,12 +18,26 @@
#include "Log.h"
#include "MetricProducer.h"

using android::util::FIELD_COUNT_REPEATED;
using android::util::FIELD_TYPE_INT32;
using android::util::FIELD_TYPE_INT64;
using android::util::FIELD_TYPE_MESSAGE;
using android::util::ProtoOutputStream;

namespace android {
namespace os {
namespace statsd {

using std::map;

// for ActiveMetric
const int FIELD_ID_ACTIVE_METRIC_ID = 1;
const int FIELD_ID_ACTIVE_METRIC_ACTIVATION = 2;

// for ActiveEventActivation
const int FIELD_ID_ACTIVE_EVENT_ACTIVATION_ATOM_MATCHER_INDEX = 1;
const int FIELD_ID_ACTIVE_EVENT_ACTIVATION_REMAINING_TTL_NANOS = 2;

void MetricProducer::onMatchedLogEventLocked(const size_t matcherIndex, const LogEvent& event) {
    if (!mIsActive) {
        return;
@@ -74,7 +88,7 @@ bool MetricProducer::evaluateActiveStateLocked(int64_t elapsedTimestampNs) {
    bool isActive = mEventActivationMap.empty();
    for (auto& it : mEventActivationMap) {
        if (it.second->state == ActivationState::kActive &&
            elapsedTimestampNs > it.second->ttl_ns + it.second->activation_ns) {
            elapsedTimestampNs > it.second->ttl_ns + it.second->start_ns) {
            it.second->state = ActivationState::kNotActive;
        }
        if (it.second->state == ActivationState::kActive) {
@@ -95,8 +109,8 @@ void MetricProducer::flushIfExpire(int64_t elapsedTimestampNs) {
    }
}

void MetricProducer::addActivation(int activationTrackerIndex, int64_t ttl_seconds,
                                   int deactivationTrackerIndex) {
void MetricProducer::addActivation(int activationTrackerIndex, const ActivationType& activationType,
        int64_t ttl_seconds, int deactivationTrackerIndex) {
    std::lock_guard<std::mutex> lock(mMutex);
    // When a metric producer does not depend on any activation, its mIsActive is true.
    // Therefore, if this is the 1st activation, mIsActive will turn to false. Otherwise it does not
@@ -104,8 +118,8 @@ void MetricProducer::addActivation(int activationTrackerIndex, int64_t ttl_secon
    if  (mEventActivationMap.empty()) {
        mIsActive = false;
    }
    std::shared_ptr<Activation> activation = std::make_shared<Activation>();
    activation->ttl_ns = ttl_seconds * NS_PER_SEC;
    std::shared_ptr<Activation> activation =
            std::make_shared<Activation>(activationType, ttl_seconds * NS_PER_SEC);
    mEventActivationMap.emplace(activationTrackerIndex, activation);
    if (-1 != deactivationTrackerIndex) {
        mEventDeactivationMap.emplace(deactivationTrackerIndex, activation);
@@ -117,13 +131,16 @@ void MetricProducer::activateLocked(int activationTrackerIndex, int64_t elapsedT
    if (it == mEventActivationMap.end()) {
        return;
    }
    if (mActivationType == MetricActivation::ACTIVATE_ON_BOOT &&
        it->second->state == ActivationState::kNotActive) {
        it->second->state = ActivationState::kActiveOnBoot;
    auto& activation = it->second;
    if (ACTIVATE_ON_BOOT == activation->activationType) {
        if (ActivationState::kNotActive == activation->state) {
            activation->state = ActivationState::kActiveOnBoot;
        }
        // If the Activation is already active or set to kActiveOnBoot, do nothing.
        return;
    }
    it->second->activation_ns = elapsedTimestampNs;
    it->second->state = ActivationState::kActive;
    activation->start_ns = elapsedTimestampNs;
    activation->state = ActivationState::kActive;
    mIsActive = true;
}

@@ -135,46 +152,55 @@ void MetricProducer::cancelEventActivationLocked(int deactivationTrackerIndex) {
    it->second->state = ActivationState::kNotActive;
}

void MetricProducer::setActiveLocked(int64_t currentTimeNs, int64_t remainingTtlNs) {
void MetricProducer::loadActiveMetricLocked(const ActiveMetric& activeMetric,
                                            int64_t currentTimeNs) {
    if (mEventActivationMap.size() == 0) {
        return;
    }
    for (auto& pair : mEventActivationMap) {
        auto& activation = pair.second;
        if (activation->ttl_ns >= remainingTtlNs) {
            activation->activation_ns = currentTimeNs + remainingTtlNs - activation->ttl_ns;
            activation->state = kActive;
    for (int i = 0; i < activeMetric.activation_size(); i++) {
        const auto& activeEventActivation = activeMetric.activation(i);
        auto it = mEventActivationMap.find(activeEventActivation.atom_matcher_index());
        if (it == mEventActivationMap.end()) {
            ALOGE("Saved event activation not found");
            continue;
        }
        auto& activation = it->second;
        // We don't want to change the ttl for future activations, so we set the start_ns
        // such that start_ns + ttl_ns == currentTimeNs + remaining_ttl_nanos
        activation->start_ns =
            currentTimeNs + activeEventActivation.remaining_ttl_nanos() - activation->ttl_ns;
        activation->state = ActivationState::kActive;
        mIsActive = true;
            VLOG("setting new activation->time to %lld, %lld, %lld",
                 (long long)activation->activation_ns, (long long)currentTimeNs,
                 (long long)remainingTtlNs);
            return;
    }
}
    ALOGE("Required ttl is longer than all possible activations.");
}

int64_t MetricProducer::getRemainingTtlNsLocked(int64_t currentTimeNs) const {
    int64_t maxTtl = 0;
    for (const auto& activation : mEventActivationMap) {
        if (activation.second->state == kActive) {
            maxTtl = std::max(maxTtl, activation.second->ttl_ns + activation.second->activation_ns -
                                              currentTimeNs);
        }
    }
    return maxTtl;
}

void MetricProducer::prepActiveForBootIfNecessaryLocked(int64_t currentTimeNs) {
    if (mActivationType != MetricActivation::ACTIVATE_ON_BOOT) {
        return;
    }
    for (auto& activation : mEventActivationMap) {
        if (activation.second->state == kActiveOnBoot) {
            activation.second->state = kActive;
            activation.second->activation_ns = currentTimeNs;
            mIsActive = true;
void MetricProducer::writeActiveMetricToProtoOutputStream(
        int64_t currentTimeNs, ProtoOutputStream* proto) {
    proto->write(FIELD_TYPE_INT64 | FIELD_ID_ACTIVE_METRIC_ID, (long long)mMetricId);
    for (auto& it : mEventActivationMap) {
        const int atom_matcher_index = it.first;
        const std::shared_ptr<Activation>& activation = it.second;

        if (ActivationState::kNotActive == activation->state ||
                (ActivationState::kActive == activation->state &&
                 activation->start_ns + activation->ttl_ns < currentTimeNs)) {
            continue;
        }

        const uint64_t activationToken = proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
                FIELD_ID_ACTIVE_METRIC_ACTIVATION);
        proto->write(FIELD_TYPE_INT32 | FIELD_ID_ACTIVE_EVENT_ACTIVATION_ATOM_MATCHER_INDEX,
                atom_matcher_index);
        if (ActivationState::kActive == activation->state) {
            const int64_t remainingTtlNs =
                    activation->start_ns + activation->ttl_ns - currentTimeNs;
            proto->write(FIELD_TYPE_INT64 | FIELD_ID_ACTIVE_EVENT_ACTIVATION_REMAINING_TTL_NANOS,
                    (long long)remainingTtlNs);
        } else if (ActivationState::kActiveOnBoot == activation->state) {
            proto->write(FIELD_TYPE_INT64 | FIELD_ID_ACTIVE_EVENT_ACTIVATION_REMAINING_TTL_NANOS,
                    (long long)activation->ttl_ns);
        }
        proto->end(activationToken);
    }
}

Loading