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

Commit 9cb2391c authored by Muhammad Qureshi's avatar Muhammad Qureshi Committed by android-build-merger
Browse files

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

am: ec401578

Change-Id: I61694ca762aed50719423905a14a33993511a630
parents 10ff0f59 ec401578
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