From 9fc9edf95a308f5884bf541cac81ce1f41aba0ba Mon Sep 17 00:00:00 2001 From: Joe Onorato Date: Sun, 15 Oct 2017 20:08:52 -0700 Subject: [PATCH] Clean up how we handle configurations, and other assorted cleanup - Add a ConfigManager class that tracks the configurations that have been passed to us. Configurations are now tracked by tuples of (uid,tag), where the tag is an app-defined string, in case a single uid has multiple configurations. - Move all of the initialization into StatsService. - Get rid of the ability to have multiple LogListeners. Raw events are now pushed directly into StatsService, which can distribute them to the interested parties (and will eventually be able to do the proper locking). - Add Log.h, which sets our LOG_TAG correctly. - Move some of the related files that I expect will grow some into their own subdirectories. Test: statsd_test Test: adb shell cmd stats config ... Test: adb shell dumpsys stats Change-Id: I79487603003d8a842d5bd319741f1ecbf72063d1 --- cmds/statsd/Android.mk | 32 ++- cmds/statsd/src/Log.h | 30 ++ cmds/statsd/src/LogEntryPrinter.cpp | 76 ------ cmds/statsd/src/StatsLogProcessor.cpp | 35 ++- cmds/statsd/src/StatsLogProcessor.h | 20 +- cmds/statsd/src/StatsService.cpp | 258 +++++++++++++----- cmds/statsd/src/StatsService.h | 111 +++++--- .../src/{ => anomaly}/AnomalyMonitor.cpp | 17 +- .../statsd/src/{ => anomaly}/AnomalyMonitor.h | 11 +- .../{ => anomaly}/indexed_priority_queue.h | 39 ++- .../condition/CombinationConditionTracker.cpp | 16 +- cmds/statsd/src/condition/ConditionTracker.h | 17 +- .../src/condition/SimpleConditionTracker.cpp | 14 +- cmds/statsd/src/condition/condition_util.cpp | 10 +- cmds/statsd/src/config/ConfigKey.cpp | 47 ++++ cmds/statsd/src/config/ConfigKey.h | 94 +++++++ cmds/statsd/src/config/ConfigListener.cpp | 31 +++ cmds/statsd/src/config/ConfigListener.h | 54 ++++ cmds/statsd/src/config/ConfigManager.cpp | 251 +++++++++++++++++ cmds/statsd/src/config/ConfigManager.h | 102 +++++++ .../{ => external}/KernelWakelockPuller.cpp | 25 +- .../src/{ => external}/KernelWakelockPuller.h | 2 +- cmds/statsd/src/{ => external}/StatsPuller.h | 0 .../src/{ => external}/StatsPullerManager.cpp | 8 +- .../src/{ => external}/StatsPullerManager.h | 3 +- cmds/statsd/src/logd/LogListener.cpp | 41 +++ .../{LogEntryPrinter.h => logd/LogListener.h} | 41 +-- cmds/statsd/src/{ => logd}/LogReader.cpp | 23 +- cmds/statsd/src/{ => logd}/LogReader.h | 28 +- cmds/statsd/src/main.cpp | 22 +- .../CombinationLogMatchingTracker.cpp | 15 +- .../src/matchers/SimpleLogMatchingTracker.cpp | 13 +- cmds/statsd/src/matchers/matcher_util.cpp | 16 +- .../src/metrics/CountAnomalyTracker.cpp | 5 +- .../src/metrics/CountMetricProducer.cpp | 4 +- cmds/statsd/src/metrics/MetricProducer.h | 5 +- cmds/statsd/src/metrics/MetricsManager.cpp | 3 +- cmds/statsd/src/metrics/MetricsManager.h | 14 +- .../src/{ => packages}/PackageInfoListener.h | 2 +- cmds/statsd/src/{ => packages}/UidMap.cpp | 43 +-- cmds/statsd/src/{ => packages}/UidMap.h | 17 +- cmds/statsd/src/stats_util.cpp | 156 ----------- cmds/statsd/src/stats_util.h | 6 +- .../src/{ => storage}/DropboxReader.cpp | 6 +- cmds/statsd/src/{ => storage}/DropboxReader.h | 0 .../src/{ => storage}/DropboxWriter.cpp | 4 +- cmds/statsd/src/{ => storage}/DropboxWriter.h | 0 cmds/statsd/tests/AnomalyMonitor_test.cpp | 4 +- cmds/statsd/tests/ConditionTracker_test.cpp | 5 +- cmds/statsd/tests/ConfigManager_test.cpp | 156 +++++++++++ cmds/statsd/tests/LogEntryMatcher_test.cpp | 7 +- cmds/statsd/tests/LogReader_test.cpp | 2 - cmds/statsd/tests/MetricsManager_test.cpp | 13 +- cmds/statsd/tests/UidMap_test.cpp | 6 +- .../tests/indexed_priority_queue_test.cpp | 2 +- 55 files changed, 1317 insertions(+), 645 deletions(-) create mode 100644 cmds/statsd/src/Log.h delete mode 100644 cmds/statsd/src/LogEntryPrinter.cpp rename cmds/statsd/src/{ => anomaly}/AnomalyMonitor.cpp (92%) rename cmds/statsd/src/{ => anomaly}/AnomalyMonitor.h (96%) rename cmds/statsd/src/{ => anomaly}/indexed_priority_queue.h (89%) create mode 100644 cmds/statsd/src/config/ConfigKey.cpp create mode 100644 cmds/statsd/src/config/ConfigKey.h create mode 100644 cmds/statsd/src/config/ConfigListener.cpp create mode 100644 cmds/statsd/src/config/ConfigListener.h create mode 100644 cmds/statsd/src/config/ConfigManager.cpp create mode 100644 cmds/statsd/src/config/ConfigManager.h rename cmds/statsd/src/{ => external}/KernelWakelockPuller.cpp (73%) rename cmds/statsd/src/{ => external}/KernelWakelockPuller.h (97%) rename cmds/statsd/src/{ => external}/StatsPuller.h (100%) rename cmds/statsd/src/{ => external}/StatsPullerManager.cpp (93%) rename cmds/statsd/src/{ => external}/StatsPullerManager.h (97%) create mode 100644 cmds/statsd/src/logd/LogListener.cpp rename cmds/statsd/src/{LogEntryPrinter.h => logd/LogListener.h} (55%) rename cmds/statsd/src/{ => logd}/LogReader.cpp (84%) rename cmds/statsd/src/{ => logd}/LogReader.h (67%) rename cmds/statsd/src/{ => packages}/PackageInfoListener.h (96%) rename cmds/statsd/src/{ => packages}/UidMap.cpp (79%) rename cmds/statsd/src/{ => packages}/UidMap.h (96%) rename cmds/statsd/src/{ => storage}/DropboxReader.cpp (99%) rename cmds/statsd/src/{ => storage}/DropboxReader.h (100%) rename cmds/statsd/src/{ => storage}/DropboxWriter.cpp (98%) rename cmds/statsd/src/{ => storage}/DropboxWriter.h (100%) create mode 100644 cmds/statsd/tests/ConfigManager_test.cpp diff --git a/cmds/statsd/Android.mk b/cmds/statsd/Android.mk index 7412d18ca57fe..a8d3e1268b387 100644 --- a/cmds/statsd/Android.mk +++ b/cmds/statsd/Android.mk @@ -14,16 +14,23 @@ LOCAL_PATH:= $(call my-dir) - statsd_common_src := \ ../../core/java/android/os/IStatsCompanionService.aidl \ ../../core/java/android/os/IStatsManager.aidl \ src/stats_log.proto \ src/statsd_config.proto \ src/stats_events_copy.proto \ + src/anomaly/AnomalyMonitor.cpp \ src/condition/CombinationConditionTracker.cpp \ src/condition/condition_util.cpp \ src/condition/SimpleConditionTracker.cpp \ + src/config/ConfigKey.cpp \ + src/config/ConfigListener.cpp \ + src/config/ConfigManager.cpp \ + src/external/KernelWakelockPuller.cpp \ + src/external/StatsPullerManager.cpp \ + src/logd/LogListener.cpp \ + src/logd/LogReader.cpp \ src/matchers/CombinationLogMatchingTracker.cpp \ src/matchers/matcher_util.cpp \ src/matchers/SimpleLogMatchingTracker.cpp \ @@ -31,17 +38,12 @@ statsd_common_src := \ src/metrics/CountMetricProducer.cpp \ src/metrics/MetricsManager.cpp \ src/metrics/metrics_manager_util.cpp \ - src/AnomalyMonitor.cpp \ - src/DropboxReader.cpp \ - src/DropboxWriter.cpp \ - src/KernelWakelockPuller.cpp \ - src/LogEntryPrinter.cpp \ - src/LogReader.cpp \ + src/packages/UidMap.cpp \ + src/storage/DropboxReader.cpp \ + src/storage/DropboxWriter.cpp \ src/StatsLogProcessor.cpp \ - src/StatsPullerManager.cpp \ src/StatsService.cpp \ - src/stats_util.cpp \ - src/UidMap.cpp + src/stats_util.cpp statsd_common_c_includes := \ $(LOCAL_PATH)/src @@ -125,13 +127,15 @@ LOCAL_CFLAGS += \ LOCAL_SRC_FILES := \ $(statsd_common_src) \ + tests/AnomalyMonitor_test.cpp \ + tests/ConditionTracker_test.cpp \ + tests/ConfigManager_test.cpp \ tests/indexed_priority_queue_test.cpp \ + tests/LogEntryMatcher_test.cpp \ tests/LogReader_test.cpp \ tests/MetricsManager_test.cpp \ - tests/UidMap_test.cpp \ - tests/LogEntryMatcher_test.cpp \ - tests/AnomalyMonitor_test.cpp \ - tests/ConditionTracker_test.cpp + tests/UidMap_test.cpp + LOCAL_STATIC_LIBRARIES := \ libgmock diff --git a/cmds/statsd/src/Log.h b/cmds/statsd/src/Log.h new file mode 100644 index 0000000000000..785270973fd0f --- /dev/null +++ b/cmds/statsd/src/Log.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2017 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. + */ + +/* + * This file must be included at the top of the file. Other header files + * occasionally include log.h, and if LOG_TAG isn't set when that happens + * we'll get a preprocesser error when we try to define it here. + */ + +#pragma once + +#define LOG_TAG "statsd" + +#include + +#define VLOG(...) \ + if (DEBUG) ALOGD(__VA_ARGS__); diff --git a/cmds/statsd/src/LogEntryPrinter.cpp b/cmds/statsd/src/LogEntryPrinter.cpp deleted file mode 100644 index 3b6f6791d7f4e..0000000000000 --- a/cmds/statsd/src/LogEntryPrinter.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2017 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. - */ - -#include - -#include -#include -#include - -#include "matchers/matcher_util.h" - -#define PRINT_WITH_LIBLOG 0 -#define PRINT_WITH_LOG_EVENT_WRAPPER 1 - -using namespace android; - -namespace android { -namespace os { -namespace statsd { - -LogEntryPrinter::LogEntryPrinter(int out) : m_out(out) { - // Initialize the EventTagMap, which is how we know the names of the numeric event tags. - // If this fails, we can't print well, but something will print. - m_tags = android_openEventTagMap(NULL); - - // Printing format - m_format = android_log_format_new(); - android_log_setPrintFormat(m_format, FORMAT_THREADTIME); -} - -LogEntryPrinter::~LogEntryPrinter() { - if (m_tags != NULL) { - android_closeEventTagMap(m_tags); - } - android_log_format_free(m_format); -} - -void LogEntryPrinter::OnLogEvent(const log_msg& msg) { - if (PRINT_WITH_LIBLOG) { - status_t err; - AndroidLogEntry entry; - char buf[1024]; - - err = android_log_processBinaryLogBuffer(&(const_cast(&msg)->entry_v1), &entry, - m_tags, buf, sizeof(buf)); - if (err == NO_ERROR) { - android_log_printLogLine(m_format, m_out, &entry); - } else { - printf("log entry: %s\n", buf); - fflush(stdout); - } - } - - if (PRINT_WITH_LOG_EVENT_WRAPPER) { - LogEventWrapper event = parseLogEvent(msg); - printf("event: %s\n", event.toString().c_str()); - fflush(stdout); - } -} - -} // namespace statsd -} // namespace os -} // namespace android diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp index f877ef30432c0..1308ca1fb4ebf 100644 --- a/cmds/statsd/src/StatsLogProcessor.cpp +++ b/cmds/statsd/src/StatsLogProcessor.cpp @@ -14,12 +14,14 @@ * limitations under the License. */ -#include +#include "Log.h" + +#include "StatsLogProcessor.h" +#include "frameworks/base/cmds/statsd/src/stats_log.pb.h" +#include "metrics/CountMetricProducer.h" +#include "stats_util.h" -#include -#include #include -#include #include using namespace android; @@ -31,12 +33,8 @@ namespace android { namespace os { namespace statsd { -StatsLogProcessor::StatsLogProcessor(const sp &uidMap) - : m_dropbox_writer("all-logs"), m_UidMap(uidMap) -{ - // hardcoded config - // this should be called from StatsService when it receives a statsd_config - UpdateConfig(0, buildFakeConfig()); +StatsLogProcessor::StatsLogProcessor(const sp& uidMap) + : m_dropbox_writer("all-logs"), mUidMap(uidMap) { } StatsLogProcessor::~StatsLogProcessor() { @@ -54,17 +52,18 @@ void StatsLogProcessor::OnLogEvent(const log_msg& msg) { } } -void StatsLogProcessor::UpdateConfig(const int config_source, const StatsdConfig& config) { - auto it = mMetricsManagers.find(config_source); +void StatsLogProcessor::OnConfigUpdated(const ConfigKey& key, const StatsdConfig& config) { + auto it = mMetricsManagers.find(key); if (it != mMetricsManagers.end()) { it->second->finish(); } - ALOGD("Updated configuration for source %i", config_source); + ALOGD("Updated configuration for key %s", key.ToString().c_str()); unique_ptr newMetricsManager = std::make_unique(config); if (newMetricsManager->isConfigValid()) { - mMetricsManagers.insert({config_source, std::move(newMetricsManager)}); + mMetricsManagers[key] = std::move(newMetricsManager); + // Why doesn't this work? mMetricsManagers.insert({key, std::move(newMetricsManager)}); ALOGD("StatsdConfig valid"); } else { // If there is any error in the config, don't use it. @@ -72,6 +71,14 @@ void StatsLogProcessor::UpdateConfig(const int config_source, const StatsdConfig } } +void StatsLogProcessor::OnConfigRemoved(const ConfigKey& key) { + auto it = mMetricsManagers.find(key); + if (it != mMetricsManagers.end()) { + it->second->finish(); + mMetricsManagers.erase(it); + } +} + } // namespace statsd } // namespace os } // namespace android diff --git a/cmds/statsd/src/StatsLogProcessor.h b/cmds/statsd/src/StatsLogProcessor.h index 05e441caa4966..6f5dd04876e1b 100644 --- a/cmds/statsd/src/StatsLogProcessor.h +++ b/cmds/statsd/src/StatsLogProcessor.h @@ -16,12 +16,13 @@ #ifndef STATS_LOG_PROCESSOR_H #define STATS_LOG_PROCESSOR_H -#include "DropboxWriter.h" -#include "LogReader.h" -#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h" +#include "config/ConfigListener.h" +#include "logd/LogReader.h" #include "metrics/MetricsManager.h" -#include "stats_util.h" -#include "UidMap.h" +#include "packages/UidMap.h" +#include "storage/DropboxWriter.h" + +#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h" #include #include @@ -31,22 +32,23 @@ namespace android { namespace os { namespace statsd { -class StatsLogProcessor : public LogListener { +class StatsLogProcessor : public ConfigListener { public: StatsLogProcessor(const sp &uidMap); virtual ~StatsLogProcessor(); virtual void OnLogEvent(const log_msg& msg); - void UpdateConfig(const int config_source, const StatsdConfig& config); + void OnConfigUpdated(const ConfigKey& key, const StatsdConfig& config); + void OnConfigRemoved(const ConfigKey& key); private: // TODO: use EventMetrics to log the events. DropboxWriter m_dropbox_writer; - std::unordered_map> mMetricsManagers; + std::unordered_map> mMetricsManagers; - sp m_UidMap; // Reference to the UidMap to lookup app name and version for each uid. + sp mUidMap; // Reference to the UidMap to lookup app name and version for each uid. }; } // namespace statsd diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp index b496404962d5b..eff2c1cfbcec5 100644 --- a/cmds/statsd/src/StatsService.cpp +++ b/cmds/statsd/src/StatsService.cpp @@ -14,16 +14,15 @@ * limitations under the License. */ -#define LOG_TAG "statsd" #define DEBUG true +#include "Log.h" #include "StatsService.h" -#include "DropboxReader.h" +#include "storage/DropboxReader.h" #include #include #include -#include #include #include #include @@ -31,6 +30,7 @@ #include #include +#include #include using namespace android; @@ -39,24 +39,65 @@ namespace android { namespace os { namespace statsd { +// ====================================================================== +/** + * Watches for the death of the stats companion (system process). + */ +class CompanionDeathRecipient : public IBinder::DeathRecipient { +public: + CompanionDeathRecipient(const sp& anomalyMonitor); + virtual void binderDied(const wp& who); + +private: + const sp mAnomalyMonitor; +}; + +CompanionDeathRecipient::CompanionDeathRecipient(const sp& anomalyMonitor) + : mAnomalyMonitor(anomalyMonitor) { +} + +void CompanionDeathRecipient::binderDied(const wp& who) { + ALOGW("statscompanion service died"); + mAnomalyMonitor->setStatsCompanionService(nullptr); +} + +// ====================================================================== StatsService::StatsService(const sp& handlerLooper) - : mAnomalyMonitor(new AnomalyMonitor(2)),m_UidMap(new UidMap()), mStatsPullerManager() - // TODO: Change AnomalyMonitor initialization based on the config + : mStatsPullerManager(), + + mAnomalyMonitor(new AnomalyMonitor(2)) // TODO: Put this comment somewhere better { - ALOGD("stats service constructed"); + mUidMap = new UidMap(); + mConfigManager = new ConfigManager(); + mProcessor = new StatsLogProcessor(mUidMap); + + mConfigManager->AddListener(mProcessor); + + init_system_properties(); } StatsService::~StatsService() { } -status_t StatsService::setProcessor(const sp& main_processor) { - m_processor = main_processor; - ALOGD("stats service set to processor %p", m_processor.get()); - return NO_ERROR; +void StatsService::init_system_properties() { + mEngBuild = false; + const prop_info* buildType = __system_property_find("ro.build.type"); + if (buildType != NULL) { + __system_property_read_callback(buildType, init_build_type_callback, this); + } } -// Implement our own because the default binder implementation isn't -// properly handling SHELL_COMMAND_TRANSACTION +void StatsService::init_build_type_callback(void* cookie, const char* /*name*/, const char* value, + uint32_t serial) { + if (0 == strcmp("eng", value)) { + reinterpret_cast(cookie)->mEngBuild = true; + } +} + +/** + * Implement our own because the default binder implementation isn't + * properly handling SHELL_COMMAND_TRANSACTION. + */ status_t StatsService::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { status_t err; @@ -105,56 +146,159 @@ status_t StatsService::onTransact(uint32_t code, const Parcel& data, Parcel* rep } } +/** + * Write debugging data about statsd. + */ status_t StatsService::dump(int fd, const Vector& args) { FILE* out = fdopen(fd, "w"); if (out == NULL) { return NO_MEMORY; // the fd is already open } - fprintf(out, "StatsService::dump:"); - ALOGD("StatsService::dump:"); - const int N = args.size(); - for (int i = 0; i < N; i++) { - fprintf(out, " %s", String8(args[i]).string()); - ALOGD(" %s", String8(args[i]).string()); - } - fprintf(out, "\n"); + // TODO: Proto format for incident reports + dump_impl(out); fclose(out); return NO_ERROR; } +/** + * Write debugging data about statsd in text format. + */ +void StatsService::dump_impl(FILE* out) { + mConfigManager->Dump(out); +} + +/** + * Implementation of the adb shell cmd stats command. + */ status_t StatsService::command(FILE* in, FILE* out, FILE* err, Vector& args) { - if (args.size() > 0) { - if (!args[0].compare(String8("print-stats-log")) && args.size() > 1) { - return doPrintStatsLog(out, args); - } + // TODO: Permission check + + const int argCount = args.size(); + if (argCount >= 1) { + // adb shell cmd stats config ... if (!args[0].compare(String8("config"))) { - return doLoadConfig(in); + return cmd_config(in, out, err, args); } + + // adb shell cmd stats print-stats-log + if (!args[0].compare(String8("print-stats-log")) && args.size() > 1) { + return cmd_print_stats_log(out, args); + } + + // adb shell cmd stats print-stats-log if (!args[0].compare(String8("print-uid-map"))) { - return doPrintUidMap(out); + return cmd_print_uid_map(out); } } - printCmdHelp(out); + print_cmd_help(out); return NO_ERROR; } -status_t StatsService::doLoadConfig(FILE* in) { - string content; - if (!android::base::ReadFdToString(fileno(in), &content)) { - return UNKNOWN_ERROR; +void StatsService::print_cmd_help(FILE* out) { + fprintf(out, + "usage: adb shell cmd stats print-stats-log [tag_required] " + "[timestamp_nsec_optional]\n"); + fprintf(out, "\n"); + fprintf(out, "\n"); + fprintf(out, "usage: adb shell cmd stats print-uid-map \n"); + fprintf(out, "\n"); + fprintf(out, " Prints the UID, app name, version mapping.\n"); + fprintf(out, "\n"); + fprintf(out, "\n"); + fprintf(out, "usage: adb shell cmd stats config remove [UID] NAME\n"); + fprintf(out, "usage: adb shell cmd stats config update [UID] NAME\n"); + fprintf(out, "\n"); + fprintf(out, " Adds, updates or removes a configuration. The proto should be in\n"); + fprintf(out, " wire-encoded protobuf format and passed via stdin.\n"); + fprintf(out, "\n"); + fprintf(out, " UID The uid to use. It is only possible to pass the UID\n"); + fprintf(out, " parameter on eng builds. If UID is omitted the calling\n"); + fprintf(out, " uid is used.\n"); + fprintf(out, " NAME The per-uid name to use\n"); +} + +status_t StatsService::cmd_config(FILE* in, FILE* out, FILE* err, Vector& args) { + const int argCount = args.size(); + if (argCount >= 2) { + if (args[1] == "update" || args[1] == "remove") { + bool good = false; + int uid = -1; + string name; + + if (argCount == 3) { + // Automatically pick the UID + uid = IPCThreadState::self()->getCallingUid(); + // TODO: What if this isn't a binder call? Should we fail? + name.assign(args[2].c_str(), args[2].size()); + good = true; + } else if (argCount == 4) { + // If it's a userdebug or eng build, then the shell user can + // impersonate other uids. + if (mEngBuild) { + const char* s = args[2].c_str(); + if (*s != '\0') { + char* end = NULL; + uid = strtol(s, &end, 0); + if (*end == '\0') { + name.assign(args[3].c_str(), args[3].size()); + good = true; + } + } + } else { + fprintf(err, "The config can only be set for other UIDs on eng builds.\n"); + } + } + + if (!good) { + // If arg parsing failed, print the help text and return an error. + print_cmd_help(out); + return UNKNOWN_ERROR; + } + + if (args[1] == "update") { + // Read stream into buffer. + string buffer; + if (!android::base::ReadFdToString(fileno(in), &buffer)) { + fprintf(err, "Error reading stream for StatsConfig.\n"); + return UNKNOWN_ERROR; + } + + // Parse buffer. + StatsdConfig config; + if (!config.ParseFromString(buffer)) { + fprintf(err, "Error parsing proto stream for StatsConfig.\n"); + return UNKNOWN_ERROR; + } + + // Add / update the config. + mConfigManager->UpdateConfig(ConfigKey(uid, name), config); + } else { + // Remove the config. + mConfigManager->RemoveConfig(ConfigKey(uid, name)); + } + + return NO_ERROR; + } } - StatsdConfig config; - if (config.ParseFromString(content)) { - ALOGD("Config parsed from command line: %s", config.SerializeAsString().c_str()); - m_processor->UpdateConfig(0, config); - return NO_ERROR; - } else { - ALOGD("Config failed to be parsed"); - return UNKNOWN_ERROR; + print_cmd_help(out); + return UNKNOWN_ERROR; +} + +status_t StatsService::cmd_print_stats_log(FILE* out, const Vector& args) { + long msec = 0; + + if (args.size() > 2) { + msec = strtol(args[2].string(), NULL, 10); } + return DropboxReader::readStatsLogs(out, args[1].string(), msec); +} + +status_t StatsService::cmd_print_uid_map(FILE* out) { + mUidMap->printUidMap(out); + return NO_ERROR; } Status StatsService::informAllUidData(const vector& uid, const vector& version, @@ -166,7 +310,7 @@ Status StatsService::informAllUidData(const vector& uid, const vectorupdateMap(uid, version, app); + mUidMap->updateMap(uid, version, app); if (DEBUG) ALOGD("StatsService::informAllUidData succeeded"); return Status::ok(); @@ -179,7 +323,7 @@ Status StatsService::informOnePackage(const String16& app, int32_t uid, int32_t return Status::fromExceptionCode(Status::EX_SECURITY, "Only system uid can call informOnePackage"); } - m_UidMap->updateApp(app, uid, version); + mUidMap->updateApp(app, uid, version); return Status::ok(); } @@ -190,7 +334,7 @@ Status StatsService::informOnePackageRemoved(const String16& app, int32_t uid) { return Status::fromExceptionCode(Status::EX_SECURITY, "Only system uid can call informOnePackageRemoved"); } - m_UidMap->removeApp(app, uid); + mUidMap->removeApp(app, uid); return Status::ok(); } @@ -282,38 +426,18 @@ Status StatsService::statsCompanionReady() { "statscompanion unavailable despite it contacting statsd!"); } if (DEBUG) ALOGD("StatsService::statsCompanionReady linking to statsCompanion."); - IInterface::asBinder(statsCompanion)->linkToDeath(new StatsdDeathRecipient(mAnomalyMonitor)); + IInterface::asBinder(statsCompanion)->linkToDeath(new CompanionDeathRecipient(mAnomalyMonitor)); mAnomalyMonitor->setStatsCompanionService(statsCompanion); return Status::ok(); } -void StatsdDeathRecipient::binderDied(const wp& who) { - ALOGW("statscompanion service died"); - mAnmlyMntr->setStatsCompanionService(nullptr); +void StatsService::Startup() { + mConfigManager->Startup(); } -status_t StatsService::doPrintStatsLog(FILE* out, const Vector& args) { - long msec = 0; - - if (args.size() > 2) { - msec = strtol(args[2].string(), NULL, 10); - } - return DropboxReader::readStatsLogs(out, args[1].string(), msec); -} - -status_t StatsService::doPrintUidMap(FILE* out) { - m_UidMap->printUidMap(out); - return NO_ERROR; -} - -void StatsService::printCmdHelp(FILE* out) { - fprintf(out, "Usage:\n"); - fprintf(out, "\t print-stats-log [tag_required] [timestamp_nsec_optional]\n"); - fprintf(out, "\t print-uid-map Prints the UID, app name, version mapping.\n"); - fprintf(out, - "\t config\t Loads a new config from command-line (must be proto in wire-encoded " - "format).\n"); +void StatsService::OnLogEvent(const log_msg& msg) { + mProcessor->OnLogEvent(msg); } } // namespace statsd diff --git a/cmds/statsd/src/StatsService.h b/cmds/statsd/src/StatsService.h index 541f7e8be7fac..dcc73a1d47881 100644 --- a/cmds/statsd/src/StatsService.h +++ b/cmds/statsd/src/StatsService.h @@ -17,11 +17,11 @@ #ifndef STATS_SERVICE_H #define STATS_SERVICE_H -#include "AnomalyMonitor.h" #include "StatsLogProcessor.h" -#include "StatsPullerManager.h" -#include "StatsPuller.h" -#include "UidMap.h" +#include "anomaly/AnomalyMonitor.h" +#include "config/ConfigManager.h" +#include "external/StatsPullerManager.h" +#include "packages/UidMap.h" #include #include @@ -42,75 +42,114 @@ namespace android { namespace os { namespace statsd { -class StatsService : public BnStatsManager { +class StatsService : public BnStatsManager, public LogListener { public: StatsService(const sp& handlerLooper); virtual ~StatsService(); virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags); - virtual status_t dump(int fd, const Vector& args); - virtual status_t command(FILE* in, FILE* out, FILE* err, Vector& args); virtual Status systemRunning(); - - // Inform statsd that statsCompanion is ready. virtual Status statsCompanionReady(); - virtual Status informAnomalyAlarmFired(); - virtual Status informPollAlarmFired(); - virtual Status informAllUidData(const vector& uid, const vector& version, const vector& app); virtual Status informOnePackage(const String16& app, int32_t uid, int32_t version); virtual Status informOnePackageRemoved(const String16& app, int32_t uid); - virtual status_t setProcessor(const sp& main_processor); + /** + * Called right before we start processing events. + */ + void Startup(); + + /** + * Called by LogReader when there's a log event to process. + */ + virtual void OnLogEvent(const log_msg& msg); // TODO: public for testing since statsd doesn't run when system starts. Change to private // later. /** Inform statsCompanion that statsd is ready. */ virtual void sayHiToStatsCompanion(); - // TODO: Move this to a more logical file/class - // TODO: Should be private. Temporarily public for testing purposes only. - const sp mAnomalyMonitor; - - sp getUidMap() { - return m_UidMap; - } - /** Fetches and returns the StatsCompanionService. */ static sp getStatsCompanionService(); private: - sp m_UidMap; // Reference to the UID map needed for translating UID to app name/version. + /** + * Load system properties at init. + */ + void init_system_properties(); - sp m_processor; // Reference to the processor for updating configs. + /** + * Helper for loading system properties. + */ + static void init_build_type_callback(void* cookie, const char* name, const char* value, + uint32_t serial); - status_t doPrintStatsLog(FILE* out, const Vector& args); + /** + * Text output of dumpsys. + */ + void dump_impl(FILE* out); - void printCmdHelp(FILE* out); + /** + * Print usage information for the commands + */ + void print_cmd_help(FILE* out); - status_t doLoadConfig(FILE* in); + /** + * Handle the config sub-command. + */ + status_t cmd_config(FILE* in, FILE* out, FILE* err, Vector& args); + /** + * Print the event log. + */ + status_t cmd_print_stats_log(FILE* out, const Vector& args); + + /** + * Print the mapping of uids to package names. + */ + status_t cmd_print_uid_map(FILE* out); + + /** + * Update a configuration. + */ + void set_config(int uid, const string& name, const StatsdConfig& config); + + /** + * Tracks the uid <--> package name mapping. + */ + sp mUidMap; + + /** + * Fetches external metrics. + * TODO: This should be an sp<> + */ StatsPullerManager mStatsPullerManager; - status_t doPrintUidMap(FILE* out); -}; + /** + * Tracks the configurations that have been passed to statsd. + */ + sp mConfigManager; -// --- StatsdDeathRecipient --- -class StatsdDeathRecipient : public IBinder::DeathRecipient { -public: - StatsdDeathRecipient(sp anomalyMonitor) : mAnmlyMntr(anomalyMonitor) { - } + /** + * The metrics recorder. + */ + sp mProcessor; - virtual void binderDied(const wp& who); + /** + * The anomaly detector. + */ + const sp mAnomalyMonitor; -private: - const sp mAnmlyMntr; + /** + * Whether this is an eng build. + */ + bool mEngBuild; }; } // namespace statsd diff --git a/cmds/statsd/src/AnomalyMonitor.cpp b/cmds/statsd/src/anomaly/AnomalyMonitor.cpp similarity index 92% rename from cmds/statsd/src/AnomalyMonitor.cpp rename to cmds/statsd/src/anomaly/AnomalyMonitor.cpp index 4fbbc7a2267f9..7a464104fb09e 100644 --- a/cmds/statsd/src/AnomalyMonitor.cpp +++ b/cmds/statsd/src/anomaly/AnomalyMonitor.cpp @@ -14,12 +14,10 @@ * limitations under the License. */ -#define LOG_TAG "AnomalyMonitor" #define DEBUG true +#include "Log.h" -#include "AnomalyMonitor.h" - -#include +#include "anomaly/AnomalyMonitor.h" namespace android { namespace os { @@ -92,17 +90,16 @@ void AnomalyMonitor::remove(sp alarm) { // More efficient than repeatedly calling remove(mPq.top()) since it batches the // updates to the registered alarm. -unordered_set, SpHash> - AnomalyMonitor::popSoonerThan(uint32_t timestampSec) { - +unordered_set, SpHash> AnomalyMonitor::popSoonerThan( + uint32_t timestampSec) { if (DEBUG) ALOGD("Removing alarms with time <= %u", timestampSec); unordered_set, SpHash> oldAlarms; std::lock_guard lock(mLock); - for (sp t = mPq.top(); - t != nullptr && t->timestampSec <= timestampSec; t = mPq.top()) { + for (sp t = mPq.top(); t != nullptr && t->timestampSec <= timestampSec; + t = mPq.top()) { oldAlarms.insert(t); - mPq.pop(); // remove t + mPq.pop(); // remove t } // Always update registered alarm time (if anything has changed). if (!oldAlarms.empty()) { diff --git a/cmds/statsd/src/AnomalyMonitor.h b/cmds/statsd/src/anomaly/AnomalyMonitor.h similarity index 96% rename from cmds/statsd/src/AnomalyMonitor.h rename to cmds/statsd/src/anomaly/AnomalyMonitor.h index 7c6e5e8945a73..e2ac623c46702 100644 --- a/cmds/statsd/src/AnomalyMonitor.h +++ b/cmds/statsd/src/anomaly/AnomalyMonitor.h @@ -17,12 +17,13 @@ #ifndef ANOMALY_MONITOR_H #define ANOMALY_MONITOR_H +#include "anomaly/indexed_priority_queue.h" + #include -#include #include -#include #include +#include #include using namespace android; @@ -91,8 +92,8 @@ public: * Returns and removes all alarms whose timestamp <= the given timestampSec. * Always updates the registered alarm if return is non-empty. */ - unordered_set, SpHash> - popSoonerThan(uint32_t timestampSec); + unordered_set, SpHash> popSoonerThan( + uint32_t timestampSec); /** * Returns the projected alarm timestamp that is registered with @@ -144,4 +145,4 @@ private: } // namespace os } // namespace android -#endif // ANOMALY_MONITOR_H \ No newline at end of file +#endif // ANOMALY_MONITOR_H diff --git a/cmds/statsd/src/indexed_priority_queue.h b/cmds/statsd/src/anomaly/indexed_priority_queue.h similarity index 89% rename from cmds/statsd/src/indexed_priority_queue.h rename to cmds/statsd/src/anomaly/indexed_priority_queue.h index 81e8b3d023ea9..1a2e9c2a41ed1 100644 --- a/cmds/statsd/src/indexed_priority_queue.h +++ b/cmds/statsd/src/anomaly/indexed_priority_queue.h @@ -14,15 +14,10 @@ * limitations under the License. */ -#ifndef STATSD_INDEXED_PRIORITY_QUEUE_H -#define STATSD_INDEXED_PRIORITY_QUEUE_H +#pragma once -// ALOGE can be called from this file. If header loaded by another class, use their LOG_TAG instead. -#ifndef LOG_TAG -#define LOG_TAG "statsd(indexed_priority_queue)" -#endif // LOG_TAG +#include "Log.h" -#include #include #include #include @@ -132,23 +127,23 @@ void indexed_priority_queue::remove(sp a) { // The same as, but slightly more efficient than, remove(top()). template void indexed_priority_queue::pop() { - sp a = top(); - if (a == nullptr) return; - const size_t idx = 1; - if (idx == size()) { // if a is the last element + sp a = top(); + if (a == nullptr) return; + const size_t idx = 1; + if (idx == size()) { // if a is the last element + pq.pop_back(); + indices.erase(a); + return; + } + // move last element (guaranteed not to be at idx) to idx, then delete a + sp last_a = pq.back(); + pq[idx] = last_a; pq.pop_back(); + indices[last_a] = idx; indices.erase(a); - return; - } - // move last element (guaranteed not to be at idx) to idx, then delete a - sp last_a = pq.back(); - pq[idx] = last_a; - pq.pop_back(); - indices[last_a] = idx; - indices.erase(a); - // get the heap back in order (since the element at idx is not in order) - sift_down(idx); + // get the heap back in order (since the element at idx is not in order) + sift_down(idx); } template @@ -227,5 +222,3 @@ void indexed_priority_queue::swap_indices(size_t i, size_t j) { } // namespace statsd } // namespace os } // namespace android - -#endif // STATSD_INDEXED_PRIORITY_QUEUE_H diff --git a/cmds/statsd/src/condition/CombinationConditionTracker.cpp b/cmds/statsd/src/condition/CombinationConditionTracker.cpp index 6188383d4e8d2..c3a06bcbf9713 100644 --- a/cmds/statsd/src/condition/CombinationConditionTracker.cpp +++ b/cmds/statsd/src/condition/CombinationConditionTracker.cpp @@ -13,23 +13,23 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#define LOG_TAG "CombinationConditionTracker" + #define DEBUG true // STOPSHIP if true -#define VLOG(...) \ - if (DEBUG) ALOGD(__VA_ARGS__); +#include "Log.h" #include "CombinationConditionTracker.h" -#include + #include -using std::string; -using std::unique_ptr; -using std::unordered_map; -using std::vector; namespace android { namespace os { namespace statsd { +using std::string; +using std::unique_ptr; +using std::unordered_map; +using std::vector; + CombinationConditionTracker::CombinationConditionTracker(const string& name, const int index) : ConditionTracker(name, index) { VLOG("creating CombinationConditionTracker %s", mName.c_str()); diff --git a/cmds/statsd/src/condition/ConditionTracker.h b/cmds/statsd/src/condition/ConditionTracker.h index 2da8fa0e86552..9554e0a894ef6 100644 --- a/cmds/statsd/src/condition/ConditionTracker.h +++ b/cmds/statsd/src/condition/ConditionTracker.h @@ -14,17 +14,19 @@ * limitations under the License. */ -#ifndef CONDITION_TRACKER_H -#define CONDITION_TRACKER_H +#pragma once + +#include "Log.h" + +#include "condition/condition_util.h" +#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h" +#include "matchers/LogMatchingTracker.h" +#include "matchers/matcher_util.h" -#include #include #include + #include -#include "../matchers/LogMatchingTracker.h" -#include "../matchers/matcher_util.h" -#include "condition_util.h" -#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h" namespace android { namespace os { @@ -102,4 +104,3 @@ protected: } // namespace os } // namespace android -#endif // CONDITION_TRACKER_H diff --git a/cmds/statsd/src/condition/SimpleConditionTracker.cpp b/cmds/statsd/src/condition/SimpleConditionTracker.cpp index e78c0de7bdf55..694908dbb6cbe 100644 --- a/cmds/statsd/src/condition/SimpleConditionTracker.cpp +++ b/cmds/statsd/src/condition/SimpleConditionTracker.cpp @@ -14,24 +14,22 @@ * limitations under the License. */ -#define LOG_TAG "Stats_SimpleConditionTracker" #define DEBUG true // STOPSHIP if true -#define VLOG(...) \ - if (DEBUG) ALOGD(__VA_ARGS__); +#include "Log.h" #include "SimpleConditionTracker.h" -#include + #include +namespace android { +namespace os { +namespace statsd { + using std::string; using std::unique_ptr; using std::unordered_map; using std::vector; -namespace android { -namespace os { -namespace statsd { - SimpleConditionTracker::SimpleConditionTracker( const string& name, const int index, const SimpleCondition& simpleCondition, const unordered_map& trackerNameIndexMap) diff --git a/cmds/statsd/src/condition/condition_util.cpp b/cmds/statsd/src/condition/condition_util.cpp index cb07d1530daba..c7c8fcc9b361a 100644 --- a/cmds/statsd/src/condition/condition_util.cpp +++ b/cmds/statsd/src/condition/condition_util.cpp @@ -14,9 +14,10 @@ * limitations under the License. */ +#include "Log.h" + #include "condition_util.h" -#include #include #include #include @@ -27,14 +28,15 @@ #include "frameworks/base/cmds/statsd/src/statsd_config.pb.h" #include "stats_util.h" +namespace android { +namespace os { +namespace statsd { + using std::set; using std::string; using std::unordered_map; using std::vector; -namespace android { -namespace os { -namespace statsd { ConditionState evaluateCombinationCondition(const std::vector& children, const LogicalOperation& operation, diff --git a/cmds/statsd/src/config/ConfigKey.cpp b/cmds/statsd/src/config/ConfigKey.cpp new file mode 100644 index 0000000000000..a365dc0b91899 --- /dev/null +++ b/cmds/statsd/src/config/ConfigKey.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2017 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. + */ + +#include "config/ConfigKey.h" + +#include + +namespace android { +namespace os { +namespace statsd { + +using std::ostringstream; + +ConfigKey::ConfigKey() { +} + +ConfigKey::ConfigKey(const ConfigKey& that) : mName(that.mName), mUid(that.mUid) { +} + +ConfigKey::ConfigKey(int uid, const string& name) : mName(name), mUid(uid) { +} + +ConfigKey::~ConfigKey() { +} + +string ConfigKey::ToString() const { + ostringstream out; + out << '(' << mUid << ',' << mName << ')'; + return out.str(); +} + +} // namespace statsd +} // namespace os +} // namespace android diff --git a/cmds/statsd/src/config/ConfigKey.h b/cmds/statsd/src/config/ConfigKey.h new file mode 100644 index 0000000000000..bbf20fd1acf74 --- /dev/null +++ b/cmds/statsd/src/config/ConfigKey.h @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2017 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 "frameworks/base/cmds/statsd/src/statsd_config.pb.h" + +#include +#include +#include + +namespace android { +namespace os { +namespace statsd { + +using std::hash; +using std::ostream; +using std::string; + +/** + * Uniquely identifies a configuration. + */ +class ConfigKey { +public: + ConfigKey(); + explicit ConfigKey(const ConfigKey& that); + ConfigKey(int uid, const string& name); + ~ConfigKey(); + + inline int GetUid() const { + return mUid; + } + inline const string& GetName() const { + return mName; + } + + inline bool operator<(const ConfigKey& that) const { + if (mUid < that.mUid) { + return true; + } + if (mUid > that.mUid) { + return false; + } + return mName < that.mName; + }; + + inline bool operator==(const ConfigKey& that) const { + return mUid == that.mUid && mName == that.mName; + }; + + string ToString() const; + +private: + string mName; + int mUid; +}; + +inline ostream& operator<<(ostream& os, const ConfigKey& config) { + return os << config.ToString(); +} + +} // namespace statsd +} // namespace os +} // namespace android + +/** + * A hash function for ConfigKey so it can be used for unordered_map/set. + * Unfortunately this hast to go in std namespace because C++ is fun! + */ +namespace std { + +using android::os::statsd::ConfigKey; + +template <> +struct hash { + std::size_t operator()(const ConfigKey& key) const { + return (7 * key.GetUid()) ^ ((hash()(key.GetName()))); + } +}; + +} // namespace std diff --git a/cmds/statsd/src/config/ConfigListener.cpp b/cmds/statsd/src/config/ConfigListener.cpp new file mode 100644 index 0000000000000..21a3f1673fd73 --- /dev/null +++ b/cmds/statsd/src/config/ConfigListener.cpp @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2017 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. + */ + +#include "config/ConfigListener.h" + +namespace android { +namespace os { +namespace statsd { + +ConfigListener::ConfigListener() { +} + +ConfigListener::~ConfigListener() { +} + +} // namespace statsd +} // namespace os +} // namespace android diff --git a/cmds/statsd/src/config/ConfigListener.h b/cmds/statsd/src/config/ConfigListener.h new file mode 100644 index 0000000000000..a58766d2a3826 --- /dev/null +++ b/cmds/statsd/src/config/ConfigListener.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2017 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 +#include "config/ConfigKey.h" + +#include +#include + +namespace android { +namespace os { +namespace statsd { + +using android::RefBase; +using std::string; + +/** + * Callback for different subsystems inside statsd to implement to find out + * when a configuration has been added, updated or removed. + */ +class ConfigListener : public virtual RefBase { +public: + ConfigListener(); + virtual ~ConfigListener(); + + /** + * A configuration was added or updated. + */ + virtual void OnConfigUpdated(const ConfigKey& key, const StatsdConfig& config) = 0; + + /** + * A configuration was removed. + */ + virtual void OnConfigRemoved(const ConfigKey& key) = 0; +}; + +} // namespace statsd +} // namespace os +} // namespace android diff --git a/cmds/statsd/src/config/ConfigManager.cpp b/cmds/statsd/src/config/ConfigManager.cpp new file mode 100644 index 0000000000000..2a4d6e22a2edb --- /dev/null +++ b/cmds/statsd/src/config/ConfigManager.cpp @@ -0,0 +1,251 @@ +/* + * Copyright (C) 2017 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. + */ + +#include "config/ConfigManager.h" + +#include "stats_util.h" + +#include + +#include + +namespace android { +namespace os { +namespace statsd { + +static StatsdConfig build_fake_config(); + +ConfigManager::ConfigManager() { +} + +ConfigManager::~ConfigManager() { +} + +void ConfigManager::Startup() { + // TODO: Implement me -- read from storage and call onto all of the listeners. + // Instead, we'll just make a fake one. + + // this should be called from StatsService when it receives a statsd_config + UpdateConfig(ConfigKey(0, "fake"), build_fake_config()); +} + +void ConfigManager::AddListener(const sp& listener) { + mListeners.push_back(listener); +} + +void ConfigManager::UpdateConfig(const ConfigKey& key, const StatsdConfig& config) { + // Add to map + mConfigs[key] = config; + // Why doesn't this work? mConfigs.insert({key, config}); + + // Save to disk + update_saved_configs(); + + // Tell everyone + for (auto& listener : mListeners) { + listener->OnConfigUpdated(key, config); + } +} + +void ConfigManager::RemoveConfig(const ConfigKey& key) { + unordered_map::iterator it = mConfigs.find(key); + if (it != mConfigs.end()) { + // Remove from map + mConfigs.erase(it); + + // Save to disk + update_saved_configs(); + + // Tell everyone + for (auto& listener : mListeners) { + listener->OnConfigRemoved(key); + } + } + // If we didn't find it, just quietly ignore it. +} + +void ConfigManager::RemoveConfigs(int uid) { + vector removed; + + for (auto it = mConfigs.begin(); it != mConfigs.end();) { + // Remove from map + if (it->first.GetUid() == uid) { + removed.push_back(it->first); + it = mConfigs.erase(it); + } else { + it++; + } + } + + // Remove separately so if they do anything in the callback they can't mess up our iteration. + for (auto& key : removed) { + // Tell everyone + for (auto& listener : mListeners) { + listener->OnConfigRemoved(key); + } + } +} + +void ConfigManager::Dump(FILE* out) { + fprintf(out, "CONFIGURATIONS (%d)\n", (int)mConfigs.size()); + fprintf(out, " uid name\n"); + for (unordered_map::const_iterator it = mConfigs.begin(); + it != mConfigs.end(); it++) { + fprintf(out, " %6d %s\n", it->first.GetUid(), it->first.GetName().c_str()); + // TODO: Print the contents of the config too. + } +} + +void ConfigManager::update_saved_configs() { + // TODO: Implement me -- write to disk. +} + +static StatsdConfig build_fake_config() { + // HACK: Hard code a test metric for counting screen on events... + StatsdConfig config; + config.set_config_id(12345L); + + // One count metric to count screen on + CountMetric* metric = config.add_count_metric(); + metric->set_metric_id(20150717L); + metric->set_what("SCREEN_IS_ON"); + metric->mutable_bucket()->set_bucket_size_millis(30 * 1000L); + + // One count metric to count PHOTO_CHANGE_OR_CHROME_CRASH + metric = config.add_count_metric(); + metric->set_metric_id(20150718L); + metric->set_what("PHOTO_PROCESS_STATE_CHANGE"); + metric->mutable_bucket()->set_bucket_size_millis(60 * 1000L); + metric->set_condition("SCREEN_IS_ON"); + + LogEntryMatcher* eventMatcher = config.add_log_entry_matcher(); + eventMatcher->set_name("SCREEN_IS_ON"); + + SimpleLogEntryMatcher* simpleLogEntryMatcher = eventMatcher->mutable_simple_log_entry_matcher(); + simpleLogEntryMatcher->add_tag(2 /*SCREEN_STATE_CHANGE*/); + simpleLogEntryMatcher->add_key_value_matcher()->mutable_key_matcher()->set_key( + 1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/); + simpleLogEntryMatcher->mutable_key_value_matcher(0)->set_eq_int( + 2 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/); + + eventMatcher = config.add_log_entry_matcher(); + eventMatcher->set_name("SCREEN_IS_OFF"); + + simpleLogEntryMatcher = eventMatcher->mutable_simple_log_entry_matcher(); + simpleLogEntryMatcher->add_tag(2 /*SCREEN_STATE_CHANGE*/); + simpleLogEntryMatcher->add_key_value_matcher()->mutable_key_matcher()->set_key( + 1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/); + simpleLogEntryMatcher->mutable_key_value_matcher(0)->set_eq_int( + 1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_OFF*/); + + LogEntryMatcher* procEventMatcher = config.add_log_entry_matcher(); + procEventMatcher->set_name("PHOTO_CRASH"); + + SimpleLogEntryMatcher* simpleLogMatcher2 = procEventMatcher->mutable_simple_log_entry_matcher(); + simpleLogMatcher2->add_tag(1112 /*PROCESS_STATE_CHANGE*/); + KeyValueMatcher* keyValueMatcher = simpleLogMatcher2->add_key_value_matcher(); + keyValueMatcher->mutable_key_matcher()->set_key(1002 /*pkg*/); + keyValueMatcher->set_eq_string( + "com.google.android.apps.photos" /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/); + + keyValueMatcher = simpleLogMatcher2->add_key_value_matcher(); + keyValueMatcher->mutable_key_matcher()->set_key(1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/); + keyValueMatcher->set_eq_int(2); + + procEventMatcher = config.add_log_entry_matcher(); + procEventMatcher->set_name("PHOTO_START"); + + simpleLogMatcher2 = procEventMatcher->mutable_simple_log_entry_matcher(); + simpleLogMatcher2->add_tag(1112 /*PROCESS_STATE_CHANGE*/); + keyValueMatcher = simpleLogMatcher2->add_key_value_matcher(); + keyValueMatcher->mutable_key_matcher()->set_key(1002 /*pkg*/); + keyValueMatcher->set_eq_string( + "com.google.android.apps.photos" /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/); + + keyValueMatcher = simpleLogMatcher2->add_key_value_matcher(); + keyValueMatcher->mutable_key_matcher()->set_key(1 /*STATE*/); + keyValueMatcher->set_eq_int(1); + + procEventMatcher = config.add_log_entry_matcher(); + procEventMatcher->set_name("PHOTO_PROCESS_STATE_CHANGE"); + LogEntryMatcher_Combination* combinationMatcher = procEventMatcher->mutable_combination(); + combinationMatcher->set_operation(LogicalOperation::OR); + combinationMatcher->add_matcher("PHOTO_START"); + combinationMatcher->add_matcher("PHOTO_CRASH"); + + procEventMatcher = config.add_log_entry_matcher(); + procEventMatcher->set_name("CHROME_CRASH"); + + simpleLogMatcher2 = procEventMatcher->mutable_simple_log_entry_matcher(); + simpleLogMatcher2->add_tag(1112 /*PROCESS_STATE_CHANGE*/); + keyValueMatcher = simpleLogMatcher2->add_key_value_matcher(); + keyValueMatcher->mutable_key_matcher()->set_key(1002 /*pkg*/); + keyValueMatcher->set_eq_string( + "com.android.chrome" /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/); + + keyValueMatcher = simpleLogMatcher2->add_key_value_matcher(); + keyValueMatcher->mutable_key_matcher()->set_key(1 /*STATE*/); + keyValueMatcher->set_eq_int(2); + + procEventMatcher = config.add_log_entry_matcher(); + procEventMatcher->set_name("PHOTO_CHANGE_OR_CHROME_CRASH"); + combinationMatcher = procEventMatcher->mutable_combination(); + combinationMatcher->set_operation(LogicalOperation::OR); + combinationMatcher->add_matcher("PHOTO_PROCESS_STATE_CHANGE"); + combinationMatcher->add_matcher("CHROME_CRASH"); + + Condition* condition = config.add_condition(); + condition->set_name("SCREEN_IS_ON"); + SimpleCondition* simpleCondition = condition->mutable_simple_condition(); + simpleCondition->set_start("SCREEN_IS_ON"); + simpleCondition->set_stop("SCREEN_IS_OFF"); + + condition = config.add_condition(); + condition->set_name("PHOTO_STARTED"); + + simpleCondition = condition->mutable_simple_condition(); + simpleCondition->set_start("PHOTO_START"); + simpleCondition->set_stop("PHOTO_CRASH"); + + condition = config.add_condition(); + condition->set_name("SCREEN_IS_OFF"); + + simpleCondition = condition->mutable_simple_condition(); + simpleCondition->set_start("SCREEN_IS_OFF"); + simpleCondition->set_stop("SCREEN_IS_ON"); + + condition = config.add_condition(); + condition->set_name("SCREEN_IS_EITHER_ON_OFF"); + + Condition_Combination* combination = condition->mutable_combination(); + combination->set_operation(LogicalOperation::OR); + combination->add_condition("SCREEN_IS_ON"); + combination->add_condition("SCREEN_IS_OFF"); + + condition = config.add_condition(); + condition->set_name("SCREEN_IS_NEITHER_ON_OFF"); + + combination = condition->mutable_combination(); + combination->set_operation(LogicalOperation::NOR); + combination->add_condition("SCREEN_IS_ON"); + combination->add_condition("SCREEN_IS_OFF"); + + return config; +} + +} // namespace statsd +} // namespace os +} // namespace android diff --git a/cmds/statsd/src/config/ConfigManager.h b/cmds/statsd/src/config/ConfigManager.h new file mode 100644 index 0000000000000..5d73eaf3c7b6f --- /dev/null +++ b/cmds/statsd/src/config/ConfigManager.h @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2017 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 "config/ConfigListener.h" + +#include +#include + +#include + +namespace android { +namespace os { +namespace statsd { + +using android::RefBase; +using std::string; +using std::unordered_map; +using std::vector; + +/** + * Keeps track of which configurations have been set from various sources. + * + * TODO: Store the configs persistently too. + * TODO: Dump method for debugging. + */ +class ConfigManager : public virtual RefBase { +public: + ConfigManager(); + virtual ~ConfigManager(); + + /** + * Call to load the saved configs from disk. + * + * TODO: Implement me + */ + void Startup(); + + /** + * Someone else wants to know about the configs. + */ + void AddListener(const sp& listener); + + /** + * A configuration was added or updated. + * + * Reports this to listeners. + */ + void UpdateConfig(const ConfigKey& key, const StatsdConfig& data); + + /** + * A configuration was removed. + * + * Reports this to listeners. + */ + void RemoveConfig(const ConfigKey& key); + + /** + * Remove all of the configs for the given uid. + */ + void RemoveConfigs(int uid); + + /** + * Text dump of our state for debugging. + */ + void Dump(FILE* out); + +private: + /** + * Save the configs to disk. + */ + void update_saved_configs(); + + /** + * The Configs that have been set + */ + unordered_map mConfigs; + + /** + * The ConfigListeners that will be told about changes. + */ + vector> mListeners; +}; + +} // namespace statsd +} // namespace os +} // namespace android diff --git a/cmds/statsd/src/KernelWakelockPuller.cpp b/cmds/statsd/src/external/KernelWakelockPuller.cpp similarity index 73% rename from cmds/statsd/src/KernelWakelockPuller.cpp rename to cmds/statsd/src/external/KernelWakelockPuller.cpp index 1798f9dec5ef6..b9abee0d5df1d 100644 --- a/cmds/statsd/src/KernelWakelockPuller.cpp +++ b/cmds/statsd/src/external/KernelWakelockPuller.cpp @@ -14,13 +14,14 @@ * limitations under the License. */ -#include "KernelWakelockPuller.h" +#include "Log.h" + #include #include -#include #include -#include "StatsPuller.h" #include "StatsService.h" +#include "external/KernelWakelockPuller.h" +#include "external/StatsPuller.h" using namespace android; using namespace android::base; @@ -40,15 +41,15 @@ String16 KernelWakelockPuller::pull() { sp statsCompanion = StatsService::getStatsCompanionService(); String16 returned_value(""); if (statsCompanion != NULL) { - Status status = statsCompanion->pullData(KernelWakelockPuller::PULL_CODE_KERNEL_WAKELOCKS, - &returned_value); - if (!status.isOk()) { - ALOGW("error pulling kernel wakelock"); - } - ALOGD("KernelWakelockPuller::pull succeeded!"); - // TODO: remove this when we integrate into aggregation chain. - ALOGD("%s", String8(returned_value).string()); - return returned_value; + Status status = statsCompanion->pullData(KernelWakelockPuller::PULL_CODE_KERNEL_WAKELOCKS, + &returned_value); + if (!status.isOk()) { + ALOGW("error pulling kernel wakelock"); + } + ALOGD("KernelWakelockPuller::pull succeeded!"); + // TODO: remove this when we integrate into aggregation chain. + ALOGD("%s", String8(returned_value).string()); + return returned_value; } else { ALOGW("statsCompanion not found!"); return String16(); diff --git a/cmds/statsd/src/KernelWakelockPuller.h b/cmds/statsd/src/external/KernelWakelockPuller.h similarity index 97% rename from cmds/statsd/src/KernelWakelockPuller.h rename to cmds/statsd/src/external/KernelWakelockPuller.h index 1c16f87030827..1ec33762bd490 100644 --- a/cmds/statsd/src/KernelWakelockPuller.h +++ b/cmds/statsd/src/external/KernelWakelockPuller.h @@ -18,7 +18,7 @@ #define STATSD_KERNELWAKELOCKPULLER_H #include -#include "StatsPuller.h" +#include "external/StatsPuller.h" namespace android { namespace os { diff --git a/cmds/statsd/src/StatsPuller.h b/cmds/statsd/src/external/StatsPuller.h similarity index 100% rename from cmds/statsd/src/StatsPuller.h rename to cmds/statsd/src/external/StatsPuller.h diff --git a/cmds/statsd/src/StatsPullerManager.cpp b/cmds/statsd/src/external/StatsPullerManager.cpp similarity index 93% rename from cmds/statsd/src/StatsPullerManager.cpp rename to cmds/statsd/src/external/StatsPullerManager.cpp index f4cf1ceaf18ab..6e8d58bc33adb 100644 --- a/cmds/statsd/src/StatsPullerManager.cpp +++ b/cmds/statsd/src/external/StatsPullerManager.cpp @@ -14,15 +14,13 @@ * limitations under the License. */ -#define LOG_TAG "StatsPullerManager" #define DEBUG true +#include "Log.h" -#include "StatsPullerManager.h" #include -#include -#include "StatsService.h" #include "KernelWakelockPuller.h" - +#include "StatsService.h" +#include "external/StatsPullerManager.h" using namespace android; diff --git a/cmds/statsd/src/StatsPullerManager.h b/cmds/statsd/src/external/StatsPullerManager.h similarity index 97% rename from cmds/statsd/src/StatsPullerManager.h rename to cmds/statsd/src/external/StatsPullerManager.h index ab36df535ae5b..f143424e7b76c 100644 --- a/cmds/statsd/src/StatsPullerManager.h +++ b/cmds/statsd/src/external/StatsPullerManager.h @@ -19,7 +19,7 @@ #include #include -#include "StatsPuller.h" +#include "external/StatsPuller.h" namespace android { namespace os { @@ -41,7 +41,6 @@ private: std::unordered_map> mStatsPullers; }; - } // namespace statsd } // namespace os } // namespace android diff --git a/cmds/statsd/src/logd/LogListener.cpp b/cmds/statsd/src/logd/LogListener.cpp new file mode 100644 index 0000000000000..6ac7978bbac9d --- /dev/null +++ b/cmds/statsd/src/logd/LogListener.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2017 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. + */ + +#include "logd/LogReader.h" + +#include + +#include + +#include +#include + +using namespace android; +using namespace std; + +namespace android { +namespace os { +namespace statsd { + +LogListener::LogListener() { +} + +LogListener::~LogListener() { +} + +} // namespace statsd +} // namespace os +} // namespace android diff --git a/cmds/statsd/src/LogEntryPrinter.h b/cmds/statsd/src/logd/LogListener.h similarity index 55% rename from cmds/statsd/src/LogEntryPrinter.h rename to cmds/statsd/src/logd/LogListener.h index 4f79028889c9b..786a793052961 100644 --- a/cmds/statsd/src/LogEntryPrinter.h +++ b/cmds/statsd/src/logd/LogListener.h @@ -14,48 +14,29 @@ * limitations under the License. */ -#ifndef LOG_ENTRY_PRINTER_H -#define LOG_ENTRY_PRINTER_H +#pragma once -#include "LogReader.h" - -#include - -#include +#include +#include +#include namespace android { namespace os { namespace statsd { /** - * Decodes the log entry and prints it to the supplied file descriptor. + * Callback for LogReader */ -class LogEntryPrinter : public LogListener { +class LogListener : public virtual android::RefBase { public: - LogEntryPrinter(int out); - virtual ~LogEntryPrinter(); + LogListener(); + virtual ~LogListener(); - virtual void OnLogEvent(const log_msg& msg); - -private: - /** - * Where to write to. - */ - int m_out; - - /** - * Numeric to string tag name mapping. - */ - EventTagMap* m_tags; - - /** - * Pretty printing format. - */ - AndroidLogFormat* m_format; + // TODO: Rather than using log_msg, which doesn't have any real internal structure + // here, we should pull this out into our own LogEntry class. + virtual void OnLogEvent(const log_msg& msg) = 0; }; } // namespace statsd } // namespace os } // namespace android - -#endif // LOG_ENTRY_PRINTER_H diff --git a/cmds/statsd/src/LogReader.cpp b/cmds/statsd/src/logd/LogReader.cpp similarity index 84% rename from cmds/statsd/src/LogReader.cpp rename to cmds/statsd/src/logd/LogReader.cpp index c4ac33724bc72..23d3698aff0ce 100644 --- a/cmds/statsd/src/LogReader.cpp +++ b/cmds/statsd/src/logd/LogReader.cpp @@ -14,7 +14,7 @@ * limitations under the License. */ -#include "LogReader.h" +#include "logd/LogReader.h" #include @@ -33,24 +33,12 @@ namespace statsd { #define SNOOZE_INITIAL_MS 100 #define SNOOZE_MAX_MS (10 * 60 * 1000) // Ten minutes -// ================================================================================ -LogListener::LogListener() { -} - -LogListener::~LogListener() { -} - -// ================================================================================ -LogReader::LogReader() { +LogReader::LogReader(const sp& listener) : mListener(listener) { } LogReader::~LogReader() { } -void LogReader::AddListener(const sp& listener) { - m_listeners.push_back(listener); -} - void LogReader::Run() { int nextSnoozeMs = SNOOZE_INITIAL_MS; @@ -119,11 +107,8 @@ int LogReader::connect_and_read() { // Record that we read one (used above to know how to snooze). lineCount++; - // Call the listeners - for (vector >::iterator it = m_listeners.begin(); - it != m_listeners.end(); it++) { - (*it)->OnLogEvent(msg); - } + // Call the listener + mListener->OnLogEvent(msg); } } diff --git a/cmds/statsd/src/LogReader.h b/cmds/statsd/src/logd/LogReader.h similarity index 67% rename from cmds/statsd/src/LogReader.h rename to cmds/statsd/src/logd/LogReader.h index fc19585ac6f04..6ca0646eae6bb 100644 --- a/cmds/statsd/src/LogReader.h +++ b/cmds/statsd/src/logd/LogReader.h @@ -17,6 +17,8 @@ #ifndef LOGREADER_H #define LOGREADER_H +#include "logd/LogListener.h" + #include #include @@ -26,39 +28,21 @@ namespace android { namespace os { namespace statsd { -/** - * Callback for LogReader - */ -class LogListener : public virtual android::RefBase { -public: - LogListener(); - virtual ~LogListener(); - - // TODO: Rather than using log_msg, which doesn't have any real internal structure - // here, we should pull this out into our own LogEntry class. - virtual void OnLogEvent(const log_msg& msg) = 0; -}; - /** * Class to read logs from logd. */ class LogReader : public virtual android::RefBase { public: /** - * Construct the LogReader with a pointer back to the StatsService + * Construct the LogReader with the event listener. (Which is StatsService) */ - LogReader(); + LogReader(const sp& listener); /** * Destructor. */ virtual ~LogReader(); - /** - * Add a LogListener class. - */ - void AddListener(const android::sp& listener); - /** * Run the main LogReader loop */ @@ -66,9 +50,9 @@ public: private: /** - * List of listeners to call back on when we do get an event. + * Who is going to get the events when they're read. */ - std::vector > m_listeners; + sp mListener; /** * Connect to a single instance of logd, and read until there's a read error. diff --git a/cmds/statsd/src/main.cpp b/cmds/statsd/src/main.cpp index 37477dc50e4e8..a7402800630e6 100644 --- a/cmds/statsd/src/main.cpp +++ b/cmds/statsd/src/main.cpp @@ -14,20 +14,16 @@ * limitations under the License. */ -#define LOG_TAG "statsd" +#include "Log.h" -#include "LogEntryPrinter.h" -#include "LogReader.h" -#include "StatsLogProcessor.h" #include "StatsService.h" -#include "UidMap.h" +#include "logd/LogReader.h" #include #include #include #include #include -#include #include #include @@ -53,16 +49,12 @@ struct log_reader_thread_data { static void* log_reader_thread_func(void* cookie) { log_reader_thread_data* data = static_cast(cookie); - sp reader = new LogReader(); + sp reader = new LogReader(data->service); - // Put the printer one first, so it will print before the real ones. - reader->AddListener(new LogEntryPrinter(STDOUT_FILENO)); - sp main_processor = new StatsLogProcessor(data->service->getUidMap()); - data->service->setProcessor(main_processor); - reader->AddListener(main_processor); - - // TODO: Construct and add real LogListners here. + // Tell StatsService that we're ready to go. + data->service->Startup(); + // Run the read loop. Never returns. reader->Run(); ALOGW("statsd LogReader.Run() is not supposed to return."); @@ -127,6 +119,8 @@ int main(int /*argc*/, char** /*argv*/) { // TODO: This line is temporary, since statsd doesn't start up automatically (and therefore // the call in StatsService::SystemRunning() won't ever be called right now). + // TODO: Are you sure? Don't we need to reconnect to the system process if we get restarted? + // --joeo service->sayHiToStatsCompanion(); // Start the log reader thread diff --git a/cmds/statsd/src/matchers/CombinationLogMatchingTracker.cpp b/cmds/statsd/src/matchers/CombinationLogMatchingTracker.cpp index 9f9b648ae1a57..f1e0d5aed4c5b 100644 --- a/cmds/statsd/src/matchers/CombinationLogMatchingTracker.cpp +++ b/cmds/statsd/src/matchers/CombinationLogMatchingTracker.cpp @@ -14,20 +14,21 @@ * limitations under the License. */ -#include "CombinationLogMatchingTracker.h" +#include "Log.h" + +#include "CombinationLogMatchingTracker.h" +#include "matchers/matcher_util.h" + +namespace android { +namespace os { +namespace statsd { -#include -#include "matcher_util.h" using std::set; using std::string; using std::unique_ptr; using std::unordered_map; using std::vector; -namespace android { -namespace os { -namespace statsd { - CombinationLogMatchingTracker::CombinationLogMatchingTracker(const string& name, const int index) : LogMatchingTracker(name, index) { } diff --git a/cmds/statsd/src/matchers/SimpleLogMatchingTracker.cpp b/cmds/statsd/src/matchers/SimpleLogMatchingTracker.cpp index 1c83039072da1..815baf77e5a53 100644 --- a/cmds/statsd/src/matchers/SimpleLogMatchingTracker.cpp +++ b/cmds/statsd/src/matchers/SimpleLogMatchingTracker.cpp @@ -14,23 +14,22 @@ * limitations under the License. */ -#define LOG_TAG "SimpleLogMatchingTracker" #define DEBUG true // STOPSHIP if true -#define VLOG(...) \ - if (DEBUG) ALOGD(__VA_ARGS__); +#include "Log.h" #include "SimpleLogMatchingTracker.h" -#include + #include +namespace android { +namespace os { +namespace statsd { + using std::string; using std::unique_ptr; using std::unordered_map; using std::vector; -namespace android { -namespace os { -namespace statsd { SimpleLogMatchingTracker::SimpleLogMatchingTracker(const string& name, const int index, const SimpleLogEntryMatcher& matcher) diff --git a/cmds/statsd/src/matchers/matcher_util.cpp b/cmds/statsd/src/matchers/matcher_util.cpp index 3308f3aeb318c..ce0576cc082bc 100644 --- a/cmds/statsd/src/matchers/matcher_util.cpp +++ b/cmds/statsd/src/matchers/matcher_util.cpp @@ -14,19 +14,21 @@ * limitations under the License. */ -#include "matcher_util.h" -#include +#include "Log.h" + +#include "frameworks/base/cmds/statsd/src/stats_log.pb.h" +#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h" +#include "matchers/LogMatchingTracker.h" +#include "matchers/matcher_util.h" +#include "stats_util.h" + #include #include #include #include -#include -#include "LogMatchingTracker.h" -#include "frameworks/base/cmds/statsd/src/stats_log.pb.h" -#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h" -#include "stats_util.h" #include +#include using std::set; using std::string; diff --git a/cmds/statsd/src/metrics/CountAnomalyTracker.cpp b/cmds/statsd/src/metrics/CountAnomalyTracker.cpp index ebd53e0562496..e1c2b8b3a90ec 100644 --- a/cmds/statsd/src/metrics/CountAnomalyTracker.cpp +++ b/cmds/statsd/src/metrics/CountAnomalyTracker.cpp @@ -14,15 +14,14 @@ * limitations under the License. */ -#define LOG_TAG "CountAnomaly" #define DEBUG true // STOPSHIP if true +#include "Log.h" + #define VLOG(...) \ if (DEBUG) ALOGD(__VA_ARGS__); #include "CountAnomalyTracker.h" -#include - namespace android { namespace os { namespace statsd { diff --git a/cmds/statsd/src/metrics/CountMetricProducer.cpp b/cmds/statsd/src/metrics/CountMetricProducer.cpp index e98999e732238..68d0a30403b0e 100644 --- a/cmds/statsd/src/metrics/CountMetricProducer.cpp +++ b/cmds/statsd/src/metrics/CountMetricProducer.cpp @@ -14,10 +14,8 @@ * limitations under the License. */ -#define LOG_TAG "CountMetric" #define DEBUG true // STOPSHIP if true -#define VLOG(...) \ - if (DEBUG) ALOGD(__VA_ARGS__); +#include "Log.h" #include "CountMetricProducer.h" #include "CountAnomalyTracker.h" diff --git a/cmds/statsd/src/metrics/MetricProducer.h b/cmds/statsd/src/metrics/MetricProducer.h index 6c39d98281cab..7bc7f978d782a 100644 --- a/cmds/statsd/src/metrics/MetricProducer.h +++ b/cmds/statsd/src/metrics/MetricProducer.h @@ -17,10 +17,11 @@ #ifndef METRIC_PRODUCER_H #define METRIC_PRODUCER_H +#include "matchers/matcher_util.h" +#include "packages/PackageInfoListener.h" + #include #include -#include "../matchers/matcher_util.h" -#include "PackageInfoListener.h" namespace android { namespace os { diff --git a/cmds/statsd/src/metrics/MetricsManager.cpp b/cmds/statsd/src/metrics/MetricsManager.cpp index 1e65f58882331..b77daf107503d 100644 --- a/cmds/statsd/src/metrics/MetricsManager.cpp +++ b/cmds/statsd/src/metrics/MetricsManager.cpp @@ -13,13 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#define LOG_TAG "MetricManager" #define DEBUG true // STOPSHIP if true +#include "Log.h" #define VLOG(...) \ if (DEBUG) ALOGD(__VA_ARGS__); #include "MetricsManager.h" -#include #include #include "../condition/CombinationConditionTracker.h" #include "../condition/SimpleConditionTracker.h" diff --git a/cmds/statsd/src/metrics/MetricsManager.h b/cmds/statsd/src/metrics/MetricsManager.h index 70c34db6b80a0..2f3fad930bd68 100644 --- a/cmds/statsd/src/metrics/MetricsManager.h +++ b/cmds/statsd/src/metrics/MetricsManager.h @@ -14,16 +14,15 @@ * limitations under the License. */ -#ifndef METRICS_MANAGER_H -#define METRICS_MANAGER_H +#pragma once + +#include "condition/ConditionTracker.h" +#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h" +#include "matchers/LogMatchingTracker.h" +#include "metrics/MetricProducer.h" -#include #include #include -#include "../condition/ConditionTracker.h" -#include "../matchers/LogMatchingTracker.h" -#include "MetricProducer.h" -#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h" namespace android { namespace os { @@ -94,4 +93,3 @@ private: } // namespace os } // namespace android -#endif // METRICS_MANAGER_H diff --git a/cmds/statsd/src/PackageInfoListener.h b/cmds/statsd/src/packages/PackageInfoListener.h similarity index 96% rename from cmds/statsd/src/PackageInfoListener.h rename to cmds/statsd/src/packages/PackageInfoListener.h index 476c1d953cbcd..8b948dee887e6 100644 --- a/cmds/statsd/src/PackageInfoListener.h +++ b/cmds/statsd/src/packages/PackageInfoListener.h @@ -35,4 +35,4 @@ public: } // namespace os } // namespace android -#endif //STATSD_PACKAGE_INFO_LISTENER_H +#endif // STATSD_PACKAGE_INFO_LISTENER_H diff --git a/cmds/statsd/src/UidMap.cpp b/cmds/statsd/src/packages/UidMap.cpp similarity index 79% rename from cmds/statsd/src/UidMap.cpp rename to cmds/statsd/src/packages/UidMap.cpp index 76a7f3f28dee1..f4621ee15dbe7 100644 --- a/cmds/statsd/src/UidMap.cpp +++ b/cmds/statsd/src/packages/UidMap.cpp @@ -14,8 +14,10 @@ * limitations under the License. */ -#include "UidMap.h" -#include +#include "Log.h" + +#include "packages/UidMap.h" + #include using namespace android; @@ -48,18 +50,18 @@ int UidMap::getAppVersion(int uid, const string& packageName) const { return 0; } -void UidMap::updateMap(const vector &uid, const vector &versionCode, - const vector &packageName) { - lock_guard lock(mMutex); // Exclusively lock for updates. +void UidMap::updateMap(const vector& uid, const vector& versionCode, + const vector& packageName) { + lock_guard lock(mMutex); // Exclusively lock for updates. mMap.clear(); - for (unsigned long j=0; jset_app(string(String8(packageName[j]).string())); t->set_version(int(versionCode[j])); @@ -68,7 +70,7 @@ void UidMap::updateMap(const vector &uid, const vector &vers } } -void UidMap::updateApp(const String16& app_16, const int32_t& uid, const int32_t& versionCode){ +void UidMap::updateApp(const String16& app_16, const int32_t& uid, const int32_t& versionCode) { lock_guard lock(mMutex); string app = string(String8(app_16).string()); @@ -80,7 +82,7 @@ void UidMap::updateApp(const String16& app_16, const int32_t& uid, const int32_t auto log = mOutput.add_changes(); log->set_deletion(false); - //log.timestamp = TODO: choose how timestamps are computed + // log.timestamp = TODO: choose how timestamps are computed log->set_app(app); log->set_uid(uid); log->set_version(versionCode); @@ -99,15 +101,14 @@ void UidMap::updateApp(const String16& app_16, const int32_t& uid, const int32_t mMap.insert(make_pair(uid, AppData(app, int(versionCode)))); } - -void UidMap::removeApp(const String16& app_16, const int32_t& uid){ +void UidMap::removeApp(const String16& app_16, const int32_t& uid) { lock_guard lock(mMutex); string app = string(String8(app_16).string()); auto log = mOutput.add_changes(); log->set_deletion(true); - //log.timestamp = TODO: choose how timestamps are computed + // log.timestamp = TODO: choose how timestamps are computed log->set_app(app); log->set_uid(uid); @@ -123,19 +124,19 @@ void UidMap::removeApp(const String16& app_16, const int32_t& uid){ } void UidMap::addListener(sp producer) { - lock_guard lock(mMutex); // Lock for updates + lock_guard lock(mMutex); // Lock for updates mSubscribers.insert(producer); } void UidMap::removeListener(sp producer) { - lock_guard lock(mMutex); // Lock for updates + lock_guard lock(mMutex); // Lock for updates mSubscribers.erase(producer); } UidMapping UidMap::getAndClearOutput() { - lock_guard lock(mMutex); // Lock for updates + lock_guard lock(mMutex); // Lock for updates - auto ret = UidMapping(mOutput); // Copy that will be returned. + auto ret = UidMapping(mOutput); // Copy that will be returned. mOutput.Clear(); // Re-initialize the initial state for the outputs. This results in extra data being uploaded @@ -154,11 +155,11 @@ void UidMap::printUidMap(FILE* out) { lock_guard lock(mMutex); for (auto it : mMap) { - fprintf(out, "%s, v%d (%i)\n", it.second.packageName.c_str(), it.second.versionCode, it.first); + fprintf(out, "%s, v%d (%i)\n", it.second.packageName.c_str(), it.second.versionCode, + it.first); } } - } // namespace statsd } // namespace os } // namespace android diff --git a/cmds/statsd/src/UidMap.h b/cmds/statsd/src/packages/UidMap.h similarity index 96% rename from cmds/statsd/src/UidMap.h rename to cmds/statsd/src/packages/UidMap.h index 1481010a60b85..d550372f2e9f4 100644 --- a/cmds/statsd/src/UidMap.h +++ b/cmds/statsd/src/packages/UidMap.h @@ -18,17 +18,17 @@ #define STATSD_UIDMAP_H #include "frameworks/base/cmds/statsd/src/stats_log.pb.h" -#include "PackageInfoListener.h" +#include "packages/PackageInfoListener.h" #include #include #include -#include -#include #include -#include -#include #include +#include +#include +#include +#include using namespace std; @@ -40,12 +40,12 @@ struct AppData { const string packageName; int versionCode; - AppData(const string& a, const int v) : packageName(a), versionCode(v) {}; + AppData(const string& a, const int v) : packageName(a), versionCode(v){}; }; // UidMap keeps track of what the corresponding app name (APK name) and version code for every uid // at any given moment. This map must be updated by StatsCompanionService. -class UidMap : public virtual android::RefBase { +class UidMap : public virtual android::RefBase { public: /* * All three inputs must be the same size, and the jth element in each array refers to the same @@ -93,5 +93,4 @@ private: } // namespace os } // namespace android -#endif //STATSD_UIDMAP_H - +#endif // STATSD_UIDMAP_H diff --git a/cmds/statsd/src/stats_util.cpp b/cmds/statsd/src/stats_util.cpp index 978b228891b57..5157adf74607e 100644 --- a/cmds/statsd/src/stats_util.cpp +++ b/cmds/statsd/src/stats_util.cpp @@ -128,162 +128,6 @@ EventMetricData parse(log_msg msg) { return eventMetricData; } -StatsdConfig buildFakeConfig() { - // HACK: Hard code a test metric for counting screen on events... - StatsdConfig config; - config.set_config_id(12345L); - - // One count metric to count screen on - CountMetric* metric = config.add_count_metric(); - metric->set_metric_id(20150717L); - metric->set_what("SCREEN_IS_ON"); - metric->mutable_bucket()->set_bucket_size_millis(30 * 1000L); - - // One count metric to count PHOTO_CHANGE_OR_CHROME_CRASH - metric = config.add_count_metric(); - metric->set_metric_id(20150718L); - metric->set_what("PHOTO_PROCESS_STATE_CHANGE"); - metric->mutable_bucket()->set_bucket_size_millis(60 * 1000L); - metric->set_condition("SCREEN_IS_ON"); - - - LogEntryMatcher* eventMatcher = config.add_log_entry_matcher(); - eventMatcher->set_name("SCREEN_IS_ON"); - - SimpleLogEntryMatcher* simpleLogEntryMatcher = eventMatcher->mutable_simple_log_entry_matcher(); - simpleLogEntryMatcher->add_tag(2 /*SCREEN_STATE_CHANGE*/); - simpleLogEntryMatcher->add_key_value_matcher()->mutable_key_matcher()->set_key( - 1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/); - simpleLogEntryMatcher->mutable_key_value_matcher(0)->set_eq_int( - 2 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/); - - - - eventMatcher = config.add_log_entry_matcher(); - eventMatcher->set_name("SCREEN_IS_OFF"); - - simpleLogEntryMatcher = eventMatcher->mutable_simple_log_entry_matcher(); - simpleLogEntryMatcher->add_tag(2 /*SCREEN_STATE_CHANGE*/); - simpleLogEntryMatcher->add_key_value_matcher()->mutable_key_matcher()->set_key( - 1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/); - simpleLogEntryMatcher->mutable_key_value_matcher(0)->set_eq_int( - 1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_OFF*/); - - - - LogEntryMatcher* procEventMatcher = config.add_log_entry_matcher(); - procEventMatcher->set_name("PHOTO_CRASH"); - - SimpleLogEntryMatcher* simpleLogMatcher2 = procEventMatcher->mutable_simple_log_entry_matcher(); - simpleLogMatcher2->add_tag(1112 /*PROCESS_STATE_CHANGE*/); - KeyValueMatcher* keyValueMatcher = simpleLogMatcher2->add_key_value_matcher(); - keyValueMatcher->mutable_key_matcher()->set_key( - 1002 /*pkg*/); - keyValueMatcher->set_eq_string( - "com.google.android.apps.photos" /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/); - - keyValueMatcher = simpleLogMatcher2->add_key_value_matcher(); - keyValueMatcher->mutable_key_matcher()->set_key( - 1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/); - keyValueMatcher->set_eq_int(2); - - - procEventMatcher = config.add_log_entry_matcher(); - procEventMatcher->set_name("PHOTO_START"); - - simpleLogMatcher2 = procEventMatcher->mutable_simple_log_entry_matcher(); - simpleLogMatcher2->add_tag(1112 /*PROCESS_STATE_CHANGE*/); - keyValueMatcher = simpleLogMatcher2->add_key_value_matcher(); - keyValueMatcher->mutable_key_matcher()->set_key( - 1002 /*pkg*/); - keyValueMatcher->set_eq_string( - "com.google.android.apps.photos" /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/); - - keyValueMatcher = simpleLogMatcher2->add_key_value_matcher(); - keyValueMatcher->mutable_key_matcher()->set_key( - 1 /*STATE*/); - keyValueMatcher->set_eq_int(1); - - - procEventMatcher = config.add_log_entry_matcher(); - procEventMatcher->set_name("PHOTO_PROCESS_STATE_CHANGE"); - LogEntryMatcher_Combination* combinationMatcher = procEventMatcher->mutable_combination(); - combinationMatcher->set_operation(LogicalOperation::OR); - combinationMatcher->add_matcher("PHOTO_START"); - combinationMatcher->add_matcher("PHOTO_CRASH"); - - - procEventMatcher = config.add_log_entry_matcher(); - procEventMatcher->set_name("CHROME_CRASH"); - - simpleLogMatcher2 = procEventMatcher->mutable_simple_log_entry_matcher(); - simpleLogMatcher2->add_tag(1112 /*PROCESS_STATE_CHANGE*/); - keyValueMatcher = simpleLogMatcher2->add_key_value_matcher(); - keyValueMatcher->mutable_key_matcher()->set_key( - 1002 /*pkg*/); - keyValueMatcher->set_eq_string( - "com.android.chrome" /*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/); - - keyValueMatcher = simpleLogMatcher2->add_key_value_matcher(); - keyValueMatcher->mutable_key_matcher()->set_key( - 1 /*STATE*/); - keyValueMatcher->set_eq_int(2); - - - - procEventMatcher = config.add_log_entry_matcher(); - procEventMatcher->set_name("PHOTO_CHANGE_OR_CHROME_CRASH"); - combinationMatcher = procEventMatcher->mutable_combination(); - combinationMatcher->set_operation(LogicalOperation::OR); - combinationMatcher->add_matcher("PHOTO_PROCESS_STATE_CHANGE"); - combinationMatcher->add_matcher("CHROME_CRASH"); - - - - Condition* condition = config.add_condition(); - condition->set_name("SCREEN_IS_ON"); - SimpleCondition* simpleCondition = condition->mutable_simple_condition(); - simpleCondition->set_start("SCREEN_IS_ON"); - simpleCondition->set_stop("SCREEN_IS_OFF"); - - - condition = config.add_condition(); - condition->set_name("PHOTO_STARTED"); - - simpleCondition = condition->mutable_simple_condition(); - simpleCondition->set_start("PHOTO_START"); - simpleCondition->set_stop("PHOTO_CRASH"); - - - condition = config.add_condition(); - condition->set_name("SCREEN_IS_OFF"); - - simpleCondition = condition->mutable_simple_condition(); - simpleCondition->set_start("SCREEN_IS_OFF"); - simpleCondition->set_stop("SCREEN_IS_ON"); - - - condition = config.add_condition(); - condition->set_name("SCREEN_IS_EITHER_ON_OFF"); - - Condition_Combination* combination = condition->mutable_combination(); - combination->set_operation(LogicalOperation::OR); - combination->add_condition("SCREEN_IS_ON"); - combination->add_condition("SCREEN_IS_OFF"); - - - condition = config.add_condition(); - condition->set_name("SCREEN_IS_NEITHER_ON_OFF"); - - combination = condition->mutable_combination(); - combination->set_operation(LogicalOperation::NOR); - combination->add_condition("SCREEN_IS_ON"); - combination->add_condition("SCREEN_IS_OFF"); - - return config; -} - - } // namespace statsd } // namespace os } // namespace android diff --git a/cmds/statsd/src/stats_util.h b/cmds/statsd/src/stats_util.h index 25b9bba562806..38174bfae0808 100644 --- a/cmds/statsd/src/stats_util.h +++ b/cmds/statsd/src/stats_util.h @@ -16,8 +16,8 @@ #ifndef PARSE_UTIL_H #define PARSE_UTIL_H -#include "DropboxWriter.h" -#include "LogReader.h" +#include "logd/LogReader.h" +#include "storage/DropboxWriter.h" #include #include "frameworks/base/cmds/statsd/src/statsd_config.pb.h" @@ -30,8 +30,6 @@ EventMetricData parse(log_msg msg); int getTagId(log_msg msg); -StatsdConfig buildFakeConfig(); - } // namespace statsd } // namespace os } // namespace android diff --git a/cmds/statsd/src/DropboxReader.cpp b/cmds/statsd/src/storage/DropboxReader.cpp similarity index 99% rename from cmds/statsd/src/DropboxReader.cpp rename to cmds/statsd/src/storage/DropboxReader.cpp index 430e7afc7b9bc..c561959f8edd5 100644 --- a/cmds/statsd/src/DropboxReader.cpp +++ b/cmds/statsd/src/storage/DropboxReader.cpp @@ -17,14 +17,14 @@ #include #include -#include "DropboxReader.h" +#include "storage/DropboxReader.h" -using android::String16; -using android::ZipUtils; using android::base::unique_fd; using android::binder::Status; using android::os::DropBoxManager; using android::sp; +using android::String16; +using android::ZipUtils; using std::vector; namespace android { diff --git a/cmds/statsd/src/DropboxReader.h b/cmds/statsd/src/storage/DropboxReader.h similarity index 100% rename from cmds/statsd/src/DropboxReader.h rename to cmds/statsd/src/storage/DropboxReader.h diff --git a/cmds/statsd/src/DropboxWriter.cpp b/cmds/statsd/src/storage/DropboxWriter.cpp similarity index 98% rename from cmds/statsd/src/DropboxWriter.cpp rename to cmds/statsd/src/storage/DropboxWriter.cpp index b72e530e413ae..e59bdbd1eb21c 100644 --- a/cmds/statsd/src/DropboxWriter.cpp +++ b/cmds/statsd/src/storage/DropboxWriter.cpp @@ -16,12 +16,12 @@ #include -#include "DropboxWriter.h" +#include "storage/DropboxWriter.h" -using android::String16; using android::binder::Status; using android::os::DropBoxManager; using android::sp; +using android::String16; using std::vector; namespace android { diff --git a/cmds/statsd/src/DropboxWriter.h b/cmds/statsd/src/storage/DropboxWriter.h similarity index 100% rename from cmds/statsd/src/DropboxWriter.h rename to cmds/statsd/src/storage/DropboxWriter.h diff --git a/cmds/statsd/tests/AnomalyMonitor_test.cpp b/cmds/statsd/tests/AnomalyMonitor_test.cpp index d5b68118d1193..59fa16007eef3 100644 --- a/cmds/statsd/tests/AnomalyMonitor_test.cpp +++ b/cmds/statsd/tests/AnomalyMonitor_test.cpp @@ -12,9 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#define LOG_TAG "statsd_test" - -#include "../src/AnomalyMonitor.h" +#include "anomaly/AnomalyMonitor.h" #include diff --git a/cmds/statsd/tests/ConditionTracker_test.cpp b/cmds/statsd/tests/ConditionTracker_test.cpp index f8b0fd0796e71..2935ac7136ba5 100644 --- a/cmds/statsd/tests/ConditionTracker_test.cpp +++ b/cmds/statsd/tests/ConditionTracker_test.cpp @@ -12,11 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -#define LOG_TAG "statsd_test" +#include "condition/condition_util.h" +#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h" #include -#include "../src/condition/condition_util.h" -#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h" #include #include diff --git a/cmds/statsd/tests/ConfigManager_test.cpp b/cmds/statsd/tests/ConfigManager_test.cpp new file mode 100644 index 0000000000000..aa896cafffaf3 --- /dev/null +++ b/cmds/statsd/tests/ConfigManager_test.cpp @@ -0,0 +1,156 @@ +// Copyright (C) 2017 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. + +#include "src/config/ConfigManager.h" + +#include +#include + +#include +#include + +using namespace android; +using namespace android::os::statsd; +using namespace testing; +using namespace std; + +namespace android { +namespace os { +namespace statsd { + +static ostream& operator<<(ostream& os, const StatsdConfig& config) { + return os << "StatsdConfig{id=" << config.config_id() << "}"; +} + +} // namespace statsd +} // namespace os +} // namespace android + +/** + * Mock ConfigListener + */ +class MockListener : public ConfigListener { +public: + MOCK_METHOD2(OnConfigUpdated, void(const ConfigKey& key, const StatsdConfig& config)); + MOCK_METHOD1(OnConfigRemoved, void(const ConfigKey& key)); +}; + +/** + * Validate that the ConfigKey is the one we wanted. + */ +MATCHER_P2(ConfigKeyEq, uid, name, "") { + return arg.GetUid() == uid && arg.GetName() == name; +} + +/** + * Validate that the StatsdConfig is the one we wanted. + */ +MATCHER_P(StatsdConfigEq, configId, "") { + return arg.config_id() == configId; +} + +/** + * Test the addOrUpdate and remove methods + */ +TEST(ConfigManagerTest, TestAddUpdateRemove) { + sp listener = new StrictMock(); + + sp manager = new ConfigManager(); + manager->AddListener(listener); + + StatsdConfig config91; + config91.set_config_id(91); + StatsdConfig config92; + config92.set_config_id(92); + StatsdConfig config93; + config93.set_config_id(93); + StatsdConfig config94; + config94.set_config_id(94); + + { + InSequence s; + + // The built-in fake one. + // TODO: Remove this when we get rid of the fake one, and make this + // test loading one from disk somewhere. + EXPECT_CALL(*(listener.get()), + OnConfigUpdated(ConfigKeyEq(0, "fake"), StatsdConfigEq(12345))) + .RetiresOnSaturation(); + manager->Startup(); + + // Add another one + EXPECT_CALL(*(listener.get()), OnConfigUpdated(ConfigKeyEq(1, "zzz"), StatsdConfigEq(91))) + .RetiresOnSaturation(); + manager->UpdateConfig(ConfigKey(1, "zzz"), config91); + + // Update It + EXPECT_CALL(*(listener.get()), OnConfigUpdated(ConfigKeyEq(1, "zzz"), StatsdConfigEq(92))) + .RetiresOnSaturation(); + manager->UpdateConfig(ConfigKey(1, "zzz"), config92); + + // Add one with the same uid but a different name + EXPECT_CALL(*(listener.get()), OnConfigUpdated(ConfigKeyEq(1, "yyy"), StatsdConfigEq(93))) + .RetiresOnSaturation(); + manager->UpdateConfig(ConfigKey(1, "yyy"), config93); + + // Add one with the same name but a different uid + EXPECT_CALL(*(listener.get()), OnConfigUpdated(ConfigKeyEq(2, "zzz"), StatsdConfigEq(94))) + .RetiresOnSaturation(); + manager->UpdateConfig(ConfigKey(2, "zzz"), config94); + + // Remove (1,yyy) + EXPECT_CALL(*(listener.get()), OnConfigRemoved(ConfigKeyEq(1, "yyy"))) + .RetiresOnSaturation(); + manager->RemoveConfig(ConfigKey(1, "yyy")); + + // Remove (2,zzz) + EXPECT_CALL(*(listener.get()), OnConfigRemoved(ConfigKeyEq(2, "zzz"))) + .RetiresOnSaturation(); + manager->RemoveConfig(ConfigKey(2, "zzz")); + + // Remove (1,zzz) + EXPECT_CALL(*(listener.get()), OnConfigRemoved(ConfigKeyEq(1, "zzz"))) + .RetiresOnSaturation(); + manager->RemoveConfig(ConfigKey(1, "zzz")); + + // Remove (2,zzz) again and we shouldn't get the callback + manager->RemoveConfig(ConfigKey(2, "zzz")); + } +} + +/** + * Test removing all of the configs for a uid. + */ +TEST(ConfigManagerTest, TestRemoveUid) { + sp listener = new StrictMock(); + + sp manager = new ConfigManager(); + manager->AddListener(listener); + + StatsdConfig config; + + EXPECT_CALL(*(listener.get()), OnConfigUpdated(_, _)).Times(6); + EXPECT_CALL(*(listener.get()), OnConfigRemoved(ConfigKeyEq(2, "xxx"))); + EXPECT_CALL(*(listener.get()), OnConfigRemoved(ConfigKeyEq(2, "yyy"))); + EXPECT_CALL(*(listener.get()), OnConfigRemoved(ConfigKeyEq(2, "zzz"))); + + manager->Startup(); + manager->UpdateConfig(ConfigKey(1, "aaa"), config); + manager->UpdateConfig(ConfigKey(2, "xxx"), config); + manager->UpdateConfig(ConfigKey(2, "yyy"), config); + manager->UpdateConfig(ConfigKey(2, "zzz"), config); + manager->UpdateConfig(ConfigKey(3, "bbb"), config); + + manager->RemoveConfigs(2); +} diff --git a/cmds/statsd/tests/LogEntryMatcher_test.cpp b/cmds/statsd/tests/LogEntryMatcher_test.cpp index 606980178e2a6..3bc98624ff756 100644 --- a/cmds/statsd/tests/LogEntryMatcher_test.cpp +++ b/cmds/statsd/tests/LogEntryMatcher_test.cpp @@ -12,15 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License. -#define LOG_TAG "statsd_test" +#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h" +#include "matchers/matcher_util.h" +#include "stats_util.h" #include #include #include #include -#include "../src/matchers/matcher_util.h" -#include "../src/stats_util.h" -#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h" #include diff --git a/cmds/statsd/tests/LogReader_test.cpp b/cmds/statsd/tests/LogReader_test.cpp index 2002143edfc16..7ce1d6a71c859 100644 --- a/cmds/statsd/tests/LogReader_test.cpp +++ b/cmds/statsd/tests/LogReader_test.cpp @@ -12,8 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -#define LOG_TAG "statsd_test" - #include #include diff --git a/cmds/statsd/tests/MetricsManager_test.cpp b/cmds/statsd/tests/MetricsManager_test.cpp index 673c15686f710..32661dcc47525 100644 --- a/cmds/statsd/tests/MetricsManager_test.cpp +++ b/cmds/statsd/tests/MetricsManager_test.cpp @@ -12,14 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -#define LOG_TAG "statsd_test" - #include -#include "../src/condition/ConditionTracker.h" -#include "../src/matchers/LogMatchingTracker.h" -#include "../src/metrics/CountMetricProducer.h" -#include "../src/metrics/MetricProducer.h" -#include "../src/metrics/metrics_manager_util.h" + +#include "src/condition/ConditionTracker.h" +#include "src/matchers/LogMatchingTracker.h" +#include "src/metrics/CountMetricProducer.h" +#include "src/metrics/MetricProducer.h" +#include "src/metrics/metrics_manager_util.h" #include "frameworks/base/cmds/statsd/src/statsd_config.pb.h" diff --git a/cmds/statsd/tests/UidMap_test.cpp b/cmds/statsd/tests/UidMap_test.cpp index b6f14493cb360..f9a90e4ee29b1 100644 --- a/cmds/statsd/tests/UidMap_test.cpp +++ b/cmds/statsd/tests/UidMap_test.cpp @@ -12,10 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -#define LOG_TAG "statsd_test" +#include "packages/UidMap.h" #include -#include "../src/UidMap.h" + #include using namespace android; @@ -66,4 +66,4 @@ TEST(UidMapTest, TestAddAndRemove) { } #else GTEST_LOG_(INFO) << "This test does nothing.\n"; -#endif \ No newline at end of file +#endif diff --git a/cmds/statsd/tests/indexed_priority_queue_test.cpp b/cmds/statsd/tests/indexed_priority_queue_test.cpp index 74a482eace582..600b95356083f 100644 --- a/cmds/statsd/tests/indexed_priority_queue_test.cpp +++ b/cmds/statsd/tests/indexed_priority_queue_test.cpp @@ -14,7 +14,7 @@ * limitations under the License. */ -#include "../src/indexed_priority_queue.h" +#include "src/anomaly/indexed_priority_queue.h" #include