diff options
| author | 2018-01-31 19:14:25 -0800 | |
|---|---|---|
| committer | 2018-02-06 11:15:09 -0800 | |
| commit | afb36062d5e6d36700147226b5776b4ca8abf922 (patch) | |
| tree | d1fee6604d94f47a433da34bb15b5ca6dfc61d1c | |
| parent | d1b99d2544ced280b63ed615c52b6eae74cb328e (diff) | |
Allow statsd_config be able to set destination value AUTO/EXPLICIT.
Also move incidentd integration to its own files.
clang-format -style=file -i src/anomaly/* and src/subscribers/Incidentd*
Bug: 70239380
Test: manual
Change-Id: I7bfe14d704d9e86d925365a8a21ffed726723e60
| -rw-r--r-- | cmds/incidentd/src/IncidentService.cpp | 15 | ||||
| -rw-r--r-- | cmds/statsd/Android.mk | 1 | ||||
| -rw-r--r-- | cmds/statsd/src/anomaly/AnomalyTracker.cpp | 53 | ||||
| -rw-r--r-- | cmds/statsd/src/anomaly/AnomalyTracker.h | 22 | ||||
| -rw-r--r-- | cmds/statsd/src/anomaly/DurationAnomalyTracker.cpp | 11 | ||||
| -rw-r--r-- | cmds/statsd/src/anomaly/DurationAnomalyTracker.h | 3 | ||||
| -rw-r--r-- | cmds/statsd/src/statsd_config.proto | 6 | ||||
| -rw-r--r-- | cmds/statsd/src/subscriber/IncidentdReporter.cpp | 78 | ||||
| -rw-r--r-- | cmds/statsd/src/subscriber/IncidentdReporter.h | 34 |
9 files changed, 163 insertions, 60 deletions
diff --git a/cmds/incidentd/src/IncidentService.cpp b/cmds/incidentd/src/IncidentService.cpp index 1d5ab59f9ba8..654036ec6ab7 100644 --- a/cmds/incidentd/src/IncidentService.cpp +++ b/cmds/incidentd/src/IncidentService.cpp @@ -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."); } diff --git a/cmds/statsd/Android.mk b/cmds/statsd/Android.mk index b0019ac90708..b46c5c1b6372 100644 --- a/cmds/statsd/Android.mk +++ b/cmds/statsd/Android.mk @@ -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 \ diff --git a/cmds/statsd/src/anomaly/AnomalyTracker.cpp b/cmds/statsd/src/anomaly/AnomalyTracker.cpp index c84a5b4509b0..7c5e45e100a5 100644 --- a/cmds/statsd/src/anomaly/AnomalyTracker.cpp +++ b/cmds/statsd/src/anomaly/AnomalyTracker.cpp @@ -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> @@ -35,20 +33,17 @@ namespace statsd { // TODO: Get rid of bucketNumbers, and return to the original circular array method. AnomalyTracker::AnomalyTracker(const Alert& alert, const ConfigKey& configKey) - : mAlert(alert), - mConfigKey(configKey), - mNumOfPastBuckets(mAlert.num_buckets() - 1) { + : 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()) { ALOGE("Cannot create AnomalyTracker without threshold"); return; } - resetStorage(); // initialization + resetStorage(); // initialization } AnomalyTracker::~AnomalyTracker() { @@ -171,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) { @@ -188,7 +183,7 @@ void AnomalyTracker::declareAnomaly(const uint64_t& timestampNs, const MetricDim if (!mSubscriptions.empty()) { if (mAlert.has_id()) { - ALOGI("An anomaly (%llu) has occurred! Informing subscribers.",mAlert.id()); + ALOGI("An anomaly (%llu) has occurred! Informing subscribers.", mAlert.id()); informSubscribers(key); } else { ALOGI("An anomaly (with no id) has occurred! Not informing any subscribers."); @@ -233,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 diff --git a/cmds/statsd/src/anomaly/AnomalyTracker.h b/cmds/statsd/src/anomaly/AnomalyTracker.h index f01a97f86cf6..3be959d14109 100644 --- a/cmds/statsd/src/anomaly/AnomalyTracker.h +++ b/cmds/statsd/src/anomaly/AnomalyTracker.h @@ -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,12 +62,11 @@ 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) { - return; // Base AnomalyTracker class has no need for the AnomalyMonitor. + return; // Base AnomalyTracker class has no need for the AnomalyMonitor. } // Helper function to return the sum value of past buckets at given dimension. @@ -92,9 +93,10 @@ 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. + return; // The base AnomalyTracker class doesn't have alarms. } protected: diff --git a/cmds/statsd/src/anomaly/DurationAnomalyTracker.cpp b/cmds/statsd/src/anomaly/DurationAnomalyTracker.cpp index bbee9fa5358c..e459f7681f26 100644 --- a/cmds/statsd/src/anomaly/DurationAnomalyTracker.cpp +++ b/cmds/statsd/src/anomaly/DurationAnomalyTracker.cpp @@ -52,8 +52,7 @@ void DurationAnomalyTracker::declareAnomalyIfAlarmExpired(const MetricDimensionK } void DurationAnomalyTracker::startAlarm(const MetricDimensionKey& dimensionKey, - const uint64_t& timestampNs) { - + 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) { diff --git a/cmds/statsd/src/anomaly/DurationAnomalyTracker.h b/cmds/statsd/src/anomaly/DurationAnomalyTracker.h index 052fdf576289..ba687dacf519 100644 --- a/cmds/statsd/src/anomaly/DurationAnomalyTracker.h +++ b/cmds/statsd/src/anomaly/DurationAnomalyTracker.h @@ -53,7 +53,8 @@ public: // and removes it from firedAlarms. // Note that this will generally be called from a different thread from the other functions; // the caller is responsible for thread safety. - void informAlarmsFired(const uint64_t& timestampNs, + void informAlarmsFired( + const uint64_t& timestampNs, unordered_set<sp<const AnomalyAlarm>, SpHash<AnomalyAlarm>>& firedAlarms) override; protected: diff --git a/cmds/statsd/src/statsd_config.proto b/cmds/statsd/src/statsd_config.proto index 3eaf7a17a3e2..5a326a47eb24 100644 --- a/cmds/statsd/src/statsd_config.proto +++ b/cmds/statsd/src/statsd_config.proto @@ -275,6 +275,12 @@ message Alarm { message IncidentdDetails { repeated int32 section = 1; + + enum Destination { + AUTOMATIC = 0; + EXPLICIT = 1; + } + optional Destination dest = 2; } message PerfettoDetails { diff --git a/cmds/statsd/src/subscriber/IncidentdReporter.cpp b/cmds/statsd/src/subscriber/IncidentdReporter.cpp new file mode 100644 index 000000000000..d9a8fc894804 --- /dev/null +++ b/cmds/statsd/src/subscriber/IncidentdReporter.cpp @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#define DEBUG true +#include "Log.h" + +#include "IncidentdReporter.h" +#include "frameworks/base/libs/incident/proto/android/os/header.pb.h" + +#include <android/os/IIncidentManager.h> +#include <android/os/IncidentReportArgs.h> +#include <binder/IBinder.h> +#include <binder/IServiceManager.h> + +namespace android { +namespace os { +namespace statsd { + +bool GenerateIncidentReport(const IncidentdDetails& config, const Alert& alert, + const ConfigKey& configKey) { + if (config.section_size() == 0) { + VLOG("The alert %lld contains zero section in config(%d,%lld)", alert.id(), + configKey.GetUid(), (long long) configKey.GetId()); + return false; + } + + IncidentReportArgs incidentReport; + + android::os::IncidentHeaderProto header; + header.set_alert_id(alert.id()); + header.mutable_config_key()->set_uid(configKey.GetUid()); + header.mutable_config_key()->set_id(configKey.GetId()); + incidentReport.addHeader(header); + + for (int i = 0; i < config.section_size(); i++) { + incidentReport.addSection(config.section(i)); + } + + uint8_t dest; + switch (config.dest()) { + case IncidentdDetails_Destination_AUTOMATIC: + dest = android::os::DEST_AUTOMATIC; + break; + case IncidentdDetails_Destination_EXPLICIT: + dest = android::os::DEST_EXPLICIT; + break; + default: + dest = android::os::DEST_AUTOMATIC; + } + incidentReport.setDest(dest); + + sp<IIncidentManager> service = interface_cast<IIncidentManager>( + defaultServiceManager()->getService(android::String16("incident"))); + if (service == nullptr) { + ALOGW("Failed to fetch incident service."); + return false; + } + VLOG("Calling incidentd %p", service.get()); + binder::Status s = service->reportIncident(incidentReport); + VLOG("Report incident status: %s", s.toString8().string()); + return s.isOk(); +} + +} // namespace statsd +} // namespace os +} // namespace android diff --git a/cmds/statsd/src/subscriber/IncidentdReporter.h b/cmds/statsd/src/subscriber/IncidentdReporter.h new file mode 100644 index 000000000000..229ed778af3a --- /dev/null +++ b/cmds/statsd/src/subscriber/IncidentdReporter.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "config/ConfigKey.h" +#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h" // Alert, IncidentdDetails + +namespace android { +namespace os { +namespace statsd { + +/** + * Calls incidentd to trigger an incident report and put in dropbox for uploading. + */ +bool GenerateIncidentReport(const IncidentdDetails& config, const Alert& alert, + const ConfigKey& configKey); + +} // namespace statsd +} // namespace os +} // namespace android |