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

Commit 5935d347 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Allow statsd_config be able to set destination value AUTO/EXPLICIT."

parents bca6e66c afb36062
Loading
Loading
Loading
Loading
+10 −5
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ static Status
checkIncidentPermissions(const IncidentReportArgs& args)
{
    uid_t callingUid = IPCThreadState::self()->getCallingUid();
    pid_t callingPid = IPCThreadState::self()->getCallingPid();
    if (callingUid == AID_ROOT || callingUid == AID_SHELL) {
        // root doesn't have permission.DUMP if don't do this!
        return Status::ok();
@@ -54,13 +55,13 @@ checkIncidentPermissions(const IncidentReportArgs& args)
    // checking calling permission.
    if (!checkCallingPermission(DUMP_PERMISSION)) {
        ALOGW("Calling pid %d and uid %d does not have permission: android.permission.DUMP",
                IPCThreadState::self()->getCallingPid(), callingUid);
                callingPid, callingUid);
        return Status::fromExceptionCode(Status::EX_SECURITY,
                "Calling process does not have permission: android.permission.DUMP");
    }
    if (!checkCallingPermission(USAGE_STATS_PERMISSION)) {
        ALOGW("Calling pid %d and uid %d does not have permission: android.permission.USAGE_STATS",
                IPCThreadState::self()->getCallingPid(), callingUid);
                callingPid, callingUid);
        return Status::fromExceptionCode(Status::EX_SECURITY,
                "Calling process does not have permission: android.permission.USAGE_STATS");
    }
@@ -68,13 +69,17 @@ checkIncidentPermissions(const IncidentReportArgs& args)
    // checking calling request uid permission.
    switch (args.dest()) {
        case DEST_LOCAL:
            if (callingUid != AID_SHELL || callingUid != AID_ROOT) {
            if (callingUid != AID_SHELL && callingUid != AID_ROOT) {
                ALOGW("Calling pid %d and uid %d does not have permission to get local data.",
                        callingPid, callingUid);
                return Status::fromExceptionCode(Status::EX_SECURITY,
                    "Calling process does not have permission to get local data.");
            }
        case DEST_EXPLICIT:
            if (callingUid != AID_SHELL || callingUid != AID_ROOT ||
                callingUid != AID_STATSD || callingUid != AID_SYSTEM) {
            if (callingUid != AID_SHELL && callingUid != AID_ROOT &&
                callingUid != AID_STATSD && callingUid != AID_SYSTEM) {
                ALOGW("Calling pid %d and uid %d does not have permission to get explicit data.",
                        callingPid, callingUid);
                return Status::fromExceptionCode(Status::EX_SECURITY,
                    "Calling process does not have permission to get explicit data.");
            }
+1 −0
Original line number Diff line number Diff line
@@ -65,6 +65,7 @@ statsd_common_src := \
    src/storage/StorageManager.cpp \
    src/StatsLogProcessor.cpp \
    src/StatsService.cpp \
    src/subscriber/IncidentdReporter.cpp \
    src/subscriber/SubscriberReporter.cpp \
    src/HashableDimensionKey.cpp \
    src/guardrail/MemoryLeakTrackUtil.cpp \
+14 −35
Original line number Diff line number Diff line
@@ -19,13 +19,11 @@

#include "AnomalyTracker.h"
#include "external/Perfetto.h"
#include "guardrail/StatsdStats.h"
#include "frameworks/base/libs/incident/proto/android/os/header.pb.h"
#include "guardrail/StatsdStats.h"
#include "subscriber/IncidentdReporter.h"
#include "subscriber/SubscriberReporter.h"

#include <android/os/IIncidentManager.h>
#include <android/os/IncidentReportArgs.h>
#include <binder/IServiceManager.h>
#include <statslog.h>
#include <time.h>

@@ -38,8 +36,7 @@ AnomalyTracker::AnomalyTracker(const Alert& alert, const ConfigKey& configKey)
    : mAlert(alert), mConfigKey(configKey), mNumOfPastBuckets(mAlert.num_buckets() - 1) {
    VLOG("AnomalyTracker() called");
    if (mAlert.num_buckets() <= 0) {
        ALOGE("Cannot create AnomalyTracker with %lld buckets",
              (long long)mAlert.num_buckets());
        ALOGE("Cannot create AnomalyTracker with %lld buckets", (long long)mAlert.num_buckets());
        return;
    }
    if (!mAlert.has_trigger_if_sum_gt()) {
@@ -169,8 +166,8 @@ bool AnomalyTracker::detectAnomaly(const int64_t& currentBucketNum, const Metric
        // TODO: This creates a needless 0 entry in mSumOverPastBuckets. Fix this.
        addPastBucket(key, 0, currentBucketNum - 1);
    }
    return mAlert.has_trigger_if_sum_gt()
            && getSumOverPastBuckets(key) + currentBucketValue > mAlert.trigger_if_sum_gt();
    return mAlert.has_trigger_if_sum_gt() &&
           getSumOverPastBuckets(key) + currentBucketValue > mAlert.trigger_if_sum_gt();
}

void AnomalyTracker::declareAnomaly(const uint64_t& timestampNs, const MetricDimensionKey& key) {
@@ -231,44 +228,26 @@ void AnomalyTracker::informSubscribers(const MetricDimensionKey& key) {
        return;
    }

    std::set<int> incidentdSections;

    for (const Subscription& subscription : mSubscriptions) {
        switch (subscription.subscriber_information_case()) {
            case Subscription::SubscriberInformationCase::kIncidentdDetails:
                for (int i = 0; i < subscription.incidentd_details().section_size(); i++) {
                    incidentdSections.insert(subscription.incidentd_details().section(i));
                if (!GenerateIncidentReport(subscription.incidentd_details(), mAlert, mConfigKey)) {
                    ALOGW("Failed to generate incident report.");
                }
                break;
            case Subscription::SubscriberInformationCase::kPerfettoDetails:
                CollectPerfettoTraceAndUploadToDropbox(subscription.perfetto_details());
                if (!CollectPerfettoTraceAndUploadToDropbox(subscription.perfetto_details())) {
                    ALOGW("Failed to generate prefetto traces.");
                }
                break;
            case Subscription::SubscriberInformationCase::kBroadcastSubscriberDetails:
                SubscriberReporter::getInstance()
                        .alertBroadcastSubscriber(mConfigKey, subscription, key);
                SubscriberReporter::getInstance().alertBroadcastSubscriber(mConfigKey, subscription,
                                                                           key);
                break;
            default:
                break;
        }
    }
    if (!incidentdSections.empty()) {
        sp<IIncidentManager> service = interface_cast<IIncidentManager>(
                defaultServiceManager()->getService(android::String16("incident")));
        if (service != NULL) {
            IncidentReportArgs incidentReport;
            for (const auto section : incidentdSections) {
                incidentReport.addSection(section);
            }
            android::os::IncidentHeaderProto header;
            header.set_alert_id(mAlert.id());
            header.mutable_config_key()->set_uid(mConfigKey.GetUid());
            header.mutable_config_key()->set_id(mConfigKey.GetId());
            incidentReport.addHeader(header);
            service->reportIncident(incidentReport);
        } else {
            ALOGW("Couldn't get the incident service.");
        }
    }
}

}  // namespace statsd
+12 −10
Original line number Diff line number Diff line
@@ -16,22 +16,24 @@

#pragma once

#include <memory>  // unique_ptr

#include <stdlib.h>

#include <gtest/gtest_prod.h>
#include <utils/RefBase.h>

#include "AnomalyMonitor.h"
#include "config/ConfigKey.h"
#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"  // Alert
#include "stats_util.h"  // HashableDimensionKey and DimToValMap

#include <memory> // unique_ptr
#include <stdlib.h>
#include <utils/RefBase.h>

namespace android {
namespace os {
namespace statsd {

using std::unordered_map;
using std::shared_ptr;
using std::unordered_map;

// Does NOT allow negative values.
class AnomalyTracker : public virtual RefBase {
@@ -60,8 +62,7 @@ public:

    // Detects the alert and informs the incidentd when applicable.
    void detectAndDeclareAnomaly(const uint64_t& timestampNs, const int64_t& currBucketNum,
                                 const MetricDimensionKey& key,
                                 const int64_t& currentBucketValue);
                                 const MetricDimensionKey& key, const int64_t& currentBucketValue);

    // Init the AnomalyMonitor which is shared across anomaly trackers.
    virtual void setAnomalyMonitor(const sp<AnomalyMonitor>& anomalyMonitor) {
@@ -92,7 +93,8 @@ public:

    // Declares an anomaly for each alarm in firedAlarms that belongs to this AnomalyTracker,
    // and removes it from firedAlarms. Does NOT remove the alarm from the AnomalyMonitor.
    virtual void informAlarmsFired(const uint64_t& timestampNs,
    virtual void informAlarmsFired(
            const uint64_t& timestampNs,
            unordered_set<sp<const AnomalyAlarm>, SpHash<AnomalyAlarm>>& firedAlarms) {
        return;  // The base AnomalyTracker class doesn't have alarms.
    }
+5 −6
Original line number Diff line number Diff line
@@ -53,7 +53,6 @@ void DurationAnomalyTracker::declareAnomalyIfAlarmExpired(const MetricDimensionK

void DurationAnomalyTracker::startAlarm(const MetricDimensionKey& dimensionKey,
                                        const uint64_t& timestampNs) {

    uint32_t timestampSec = static_cast<uint32_t>(timestampNs / NS_PER_SEC);
    if (isInRefractoryPeriod(timestampNs, dimensionKey)) {
        VLOG("Skipping setting anomaly alarm since it'd fall in the refractory period");
@@ -86,15 +85,15 @@ void DurationAnomalyTracker::stopAllAlarms() {
    }
}

void DurationAnomalyTracker::informAlarmsFired(const uint64_t& timestampNs,
void DurationAnomalyTracker::informAlarmsFired(
        const uint64_t& timestampNs,
        unordered_set<sp<const AnomalyAlarm>, SpHash<AnomalyAlarm>>& firedAlarms) {

    if (firedAlarms.empty() || mAlarms.empty()) return;
    // Find the intersection of firedAlarms and mAlarms.
    // The for loop is inefficient, since it loops over all keys, but that's okay since it is very
    // seldomly called. The alternative would be having AnomalyAlarms store information about the
    // DurationAnomalyTracker and key, but that's a lot of data overhead to speed up something that is
    // rarely ever called.
    // DurationAnomalyTracker and key, but that's a lot of data overhead to speed up something that
    // is rarely ever called.
    unordered_map<MetricDimensionKey, sp<const AnomalyAlarm>> matchedAlarms;
    for (const auto& kv : mAlarms) {
        if (firedAlarms.count(kv.second) > 0) {
Loading