From 5305e1ddc22bfe9ad941cb2550987aaba8de234c Mon Sep 17 00:00:00 2001 From: Chenjie Yu Date: Tue, 31 Oct 2017 13:49:36 -0700 Subject: [PATCH] pull resource power manager stats into statsd Test: tested on device and check output Change-Id: I65932a5527d6099e12546b6928a24f3616e54e16 --- cmds/statsd/Android.mk | 13 +- cmds/statsd/src/StatsService.cpp | 15 +- cmds/statsd/src/StatsService.h | 2 +- cmds/statsd/src/config/ConfigManager.cpp | 8 +- .../src/external/ResourcePowerManagerPuller.cpp | 165 +++++++++++++++++++++ ...kelockPuller.h => ResourcePowerManagerPuller.h} | 10 +- ...kPuller.cpp => StatsCompanionServicePuller.cpp} | 28 +++- .../src/external/StatsCompanionServicePuller.h | 33 +++++ cmds/statsd/src/external/StatsPuller.h | 3 +- cmds/statsd/src/external/StatsPullerManager.cpp | 122 +++++++-------- cmds/statsd/src/external/StatsPullerManager.h | 28 ++-- cmds/statsd/src/metrics/ValueMetricProducer.cpp | 40 ++--- cmds/statsd/src/metrics/ValueMetricProducer.h | 5 +- cmds/statsd/src/metrics/metrics_manager_util.cpp | 45 ++++-- cmds/statsd/src/stats_events.proto | 49 +++++- .../server/stats/StatsCompanionService.java | 24 ++- 16 files changed, 426 insertions(+), 164 deletions(-) create mode 100644 cmds/statsd/src/external/ResourcePowerManagerPuller.cpp rename cmds/statsd/src/external/{KernelWakelockPuller.h => ResourcePowerManagerPuller.h} (78%) rename cmds/statsd/src/external/{KernelWakelockPuller.cpp => StatsCompanionServicePuller.cpp} (63%) create mode 100644 cmds/statsd/src/external/StatsCompanionServicePuller.h diff --git a/cmds/statsd/Android.mk b/cmds/statsd/Android.mk index 54ade3563851..c5805fbb2eca 100644 --- a/cmds/statsd/Android.mk +++ b/cmds/statsd/Android.mk @@ -29,7 +29,8 @@ statsd_common_src := \ src/config/ConfigKey.cpp \ src/config/ConfigListener.cpp \ src/config/ConfigManager.cpp \ - src/external/KernelWakelockPuller.cpp \ + src/external/StatsCompanionServicePuller.cpp \ + src/external/ResourcePowerManagerPuller.cpp \ src/external/StatsPullerManager.cpp \ src/logd/LogEvent.cpp \ src/logd/LogListener.cpp \ @@ -71,7 +72,15 @@ statsd_common_shared_libraries := \ libutils \ libservices \ libandroidfw \ - libprotoutil + libprotoutil \ + libstatslog \ + libhardware \ + libhardware_legacy \ + libhidlbase \ + libhidltransport \ + libhwbinder \ + android.hardware.power@1.0 \ + android.hardware.power@1.1 # ========= # statsd diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp index edb1a0f94e2b..11c5de172721 100644 --- a/cmds/statsd/src/StatsService.cpp +++ b/cmds/statsd/src/StatsService.cpp @@ -373,12 +373,15 @@ status_t StatsService::cmd_print_uid_map(FILE* out) { status_t StatsService::cmd_print_pulled_metrics(FILE* out, const Vector& args) { int s = atoi(args[1].c_str()); - auto stats = m_stats_puller_manager.Pull(s, time(nullptr)); - for (const auto& it : stats) { - fprintf(out, "Pull from %d: %s\n", s, it->ToString().c_str()); + vector > stats; + if (mStatsPullerManager.Pull(s, &stats)) { + for (const auto& it : stats) { + fprintf(out, "Pull from %d: %s\n", s, it->ToString().c_str()); + } + fprintf(out, "Pull from %d: Received %zu elements\n", s, stats.size()); + return NO_ERROR; } - fprintf(out, "Pull from %d: Received %zu elements\n", s, stats.size()); - return NO_ERROR; + return UNKNOWN_ERROR; } Status StatsService::informAllUidData(const vector& uid, const vector& version, @@ -440,7 +443,7 @@ Status StatsService::informPollAlarmFired() { "Only system uid can call informPollAlarmFired"); } - m_stats_puller_manager.OnAlarmFired(); + mStatsPullerManager.OnAlarmFired(); if (DEBUG) ALOGD("StatsService::informPollAlarmFired succeeded"); diff --git a/cmds/statsd/src/StatsService.h b/cmds/statsd/src/StatsService.h index 3930d319ce8d..1d7e5a618cc9 100644 --- a/cmds/statsd/src/StatsService.h +++ b/cmds/statsd/src/StatsService.h @@ -157,7 +157,7 @@ private: /** * Fetches external metrics. */ - StatsPullerManager& m_stats_puller_manager = StatsPullerManager::GetInstance(); + StatsPullerManager& mStatsPullerManager = StatsPullerManager::GetInstance(); /** * Tracks the configurations that have been passed to statsd. diff --git a/cmds/statsd/src/config/ConfigManager.cpp b/cmds/statsd/src/config/ConfigManager.cpp index 88127194753f..890f44b689d6 100644 --- a/cmds/statsd/src/config/ConfigManager.cpp +++ b/cmds/statsd/src/config/ConfigManager.cpp @@ -139,7 +139,7 @@ static StatsdConfig build_fake_config() { int UID_PROCESS_STATE_TAG_ID = 27; int UID_PROCESS_STATE_UID_KEY = 1; - int KERNEL_WAKELOCK_TAG_ID = 41; + int KERNEL_WAKELOCK_TAG_ID = 1004; int KERNEL_WAKELOCK_NAME_KEY = 4; // Count Screen ON events. @@ -301,6 +301,12 @@ static StatsdConfig build_fake_config() { keyValueMatcher->mutable_key_matcher()->set_key(WAKE_LOCK_STATE_KEY); keyValueMatcher->set_eq_int(WAKE_LOCK_RELEASE_VALUE); + // pulled events + eventMatcher = config.add_log_entry_matcher(); + eventMatcher->set_name("KERNEL_WAKELOCK"); + simpleLogEntryMatcher = eventMatcher->mutable_simple_log_entry_matcher(); + simpleLogEntryMatcher->set_tag(KERNEL_WAKELOCK_TAG_ID); + // Conditions............. Condition* condition = config.add_condition(); condition->set_name("SCREEN_IS_ON"); diff --git a/cmds/statsd/src/external/ResourcePowerManagerPuller.cpp b/cmds/statsd/src/external/ResourcePowerManagerPuller.cpp new file mode 100644 index 000000000000..38953f182586 --- /dev/null +++ b/cmds/statsd/src/external/ResourcePowerManagerPuller.cpp @@ -0,0 +1,165 @@ +/* + * 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. + */ + +#define DEBUG true // STOPSHIP if true +#include "Log.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "external/ResourcePowerManagerPuller.h" +#include "external/StatsPuller.h" + +#include "logd/LogEvent.h" + +using android::hardware::hidl_vec; +using android::hardware::power::V1_0::IPower; +using android::hardware::power::V1_0::PowerStatePlatformSleepState; +using android::hardware::power::V1_0::PowerStateVoter; +using android::hardware::power::V1_0::Status; +using android::hardware::power::V1_1::PowerStateSubsystem; +using android::hardware::power::V1_1::PowerStateSubsystemSleepState; +using android::hardware::Return; +using android::hardware::Void; + +using std::make_shared; +using std::shared_ptr; + +namespace android { +namespace os { +namespace statsd { + +sp gPowerHalV1_0 = nullptr; +sp gPowerHalV1_1 = nullptr; +std::mutex gPowerHalMutex; +bool gPowerHalExists = true; + +static const int power_state_platform_sleep_state_tag = 1011; +static const int power_state_voter_tag = 1012; +static const int power_state_subsystem_state_tag = 1013; + +bool getPowerHal() { + if (gPowerHalExists && gPowerHalV1_0 == nullptr) { + gPowerHalV1_0 = android::hardware::power::V1_0::IPower::getService(); + if (gPowerHalV1_0 != nullptr) { + gPowerHalV1_1 = android::hardware::power::V1_1::IPower::castFrom(gPowerHalV1_0); + ALOGI("Loaded power HAL service"); + } else { + ALOGW("Couldn't load power HAL service"); + gPowerHalExists = false; + } + } + return gPowerHalV1_0 != nullptr; +} + +bool ResourcePowerManagerPuller::Pull(const int tagId, vector>* data) { + std::lock_guard lock(gPowerHalMutex); + + if (!getPowerHal()) { + ALOGE("Power Hal not loaded"); + return false; + } + + data->clear(); + Return ret = gPowerHalV1_0->getPlatformLowPowerStats( + [&data](hidl_vec states, Status status) { + + if (status != Status::SUCCESS) return; + + for (size_t i = 0; i < states.size(); i++) { + const PowerStatePlatformSleepState& state = states[i]; + + auto statePtr = make_shared(power_state_platform_sleep_state_tag); + auto elemList = statePtr->GetAndroidLogEventList(); + *elemList << state.name; + *elemList << state.residencyInMsecSinceBoot; + *elemList << state.totalTransitions; + *elemList << state.supportedOnlyInSuspend; + data->push_back(statePtr); + + VLOG("powerstate: %s, %lld, %lld, %d", state.name.c_str(), + (long long)state.residencyInMsecSinceBoot, + (long long)state.totalTransitions, state.supportedOnlyInSuspend ? 1 : 0); + for (auto voter : state.voters) { + auto voterPtr = make_shared(power_state_voter_tag); + auto elemList = voterPtr->GetAndroidLogEventList(); + *elemList << state.name; + *elemList << voter.name; + *elemList << voter.totalTimeInMsecVotedForSinceBoot; + *elemList << voter.totalNumberOfTimesVotedSinceBoot; + data->push_back(voterPtr); + VLOG("powerstatevoter: %s, %s, %lld, %lld", state.name.c_str(), + voter.name.c_str(), (long long)voter.totalTimeInMsecVotedForSinceBoot, + (long long)voter.totalNumberOfTimesVotedSinceBoot); + } + } + }); + if (!ret.isOk()) { + ALOGE("getLowPowerStats() failed: power HAL service not available"); + gPowerHalV1_0 = nullptr; + return false; + } + + // Trying to cast to IPower 1.1, this will succeed only for devices supporting 1.1 + sp gPowerHal_1_1 = + android::hardware::power::V1_1::IPower::castFrom(gPowerHalV1_0); + if (gPowerHal_1_1 != nullptr) { + ret = gPowerHal_1_1->getSubsystemLowPowerStats( + [&data](hidl_vec subsystems, Status status) { + + if (status != Status::SUCCESS) return; + + if (subsystems.size() > 0) { + for (size_t i = 0; i < subsystems.size(); i++) { + const PowerStateSubsystem& subsystem = subsystems[i]; + for (size_t j = 0; j < subsystem.states.size(); j++) { + const PowerStateSubsystemSleepState& state = subsystem.states[j]; + auto subsystemStatePtr = + make_shared(power_state_subsystem_state_tag); + auto elemList = subsystemStatePtr->GetAndroidLogEventList(); + *elemList << subsystem.name; + *elemList << state.name; + *elemList << state.residencyInMsecSinceBoot; + *elemList << state.totalTransitions; + *elemList << state.lastEntryTimestampMs; + *elemList << state.supportedOnlyInSuspend; + data->push_back(subsystemStatePtr); + VLOG("subsystemstate: %s, %s, %lld, %lld, %lld", + subsystem.name.c_str(), state.name.c_str(), + (long long)state.residencyInMsecSinceBoot, + (long long)state.totalTransitions, + (long long)state.lastEntryTimestampMs); + } + } + } + }); + } + return true; +} + +} // namespace statsd +} // namespace os +} // namespace android diff --git a/cmds/statsd/src/external/KernelWakelockPuller.h b/cmds/statsd/src/external/ResourcePowerManagerPuller.h similarity index 78% rename from cmds/statsd/src/external/KernelWakelockPuller.h rename to cmds/statsd/src/external/ResourcePowerManagerPuller.h index cc8059d80601..c396c12de0d7 100644 --- a/cmds/statsd/src/external/KernelWakelockPuller.h +++ b/cmds/statsd/src/external/ResourcePowerManagerPuller.h @@ -23,12 +23,12 @@ namespace android { namespace os { namespace statsd { -class KernelWakelockPuller : public StatsPuller { +/** + * Reads hal for sleep states + */ +class ResourcePowerManagerPuller : public StatsPuller { public: - // a number of stats need to be pulled from StatsCompanionService - // - const static int PULL_CODE_KERNEL_WAKELOCKS; - vector Pull() override; + bool Pull(const int tagId, vector>* data) override; }; } // namespace statsd diff --git a/cmds/statsd/src/external/KernelWakelockPuller.cpp b/cmds/statsd/src/external/StatsCompanionServicePuller.cpp similarity index 63% rename from cmds/statsd/src/external/KernelWakelockPuller.cpp rename to cmds/statsd/src/external/StatsCompanionServicePuller.cpp index 00259a83d3db..8e9639971679 100644 --- a/cmds/statsd/src/external/KernelWakelockPuller.cpp +++ b/cmds/statsd/src/external/StatsCompanionServicePuller.cpp @@ -20,37 +20,49 @@ #include #include #include -#include "KernelWakelockPuller.h" +#include "StatsCompanionServicePuller.h" #include "StatsService.h" using namespace android; using namespace android::base; using namespace android::binder; using namespace android::os; -using namespace std; +using std::make_shared; +using std::shared_ptr; +using std::vector; namespace android { namespace os { namespace statsd { -const int KernelWakelockPuller::PULL_CODE_KERNEL_WAKELOCKS = 1004; +const int kLogMsgHeaderSize = 28; // The reading and parsing are implemented in Java. It is not difficult to port over. But for now // let StatsCompanionService handle that and send the data back. -vector KernelWakelockPuller::Pull() { +bool StatsCompanionServicePuller::Pull(const int tagId, vector >* data) { sp statsCompanion = StatsService::getStatsCompanionService(); vector returned_value; if (statsCompanion != NULL) { - Status status = statsCompanion->pullData(KernelWakelockPuller::PULL_CODE_KERNEL_WAKELOCKS, - &returned_value); + Status status = statsCompanion->pullData(tagId, &returned_value); if (!status.isOk()) { ALOGW("error pulling kernel wakelock"); + return false; + } + data->clear(); + for (const StatsLogEventWrapper& it : returned_value) { + log_msg tmp; + tmp.entry_v1.len = it.bytes.size(); + // Manually set the header size to 28 bytes to match the pushed log events. + tmp.entry.hdr_size = kLogMsgHeaderSize; + // And set the received bytes starting after the 28 bytes reserved for header. + std::copy(it.bytes.begin(), it.bytes.end(), tmp.buf + kLogMsgHeaderSize); + data->push_back(make_shared(tmp)); } ALOGD("KernelWakelockPuller::pull succeeded!"); - return returned_value; + return true; } else { ALOGW("statsCompanion not found!"); - return returned_value; + return false; } } diff --git a/cmds/statsd/src/external/StatsCompanionServicePuller.h b/cmds/statsd/src/external/StatsCompanionServicePuller.h new file mode 100644 index 000000000000..3ff2274f1d65 --- /dev/null +++ b/cmds/statsd/src/external/StatsCompanionServicePuller.h @@ -0,0 +1,33 @@ +/* + * 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 "StatsPuller.h" + +namespace android { +namespace os { +namespace statsd { + +class StatsCompanionServicePuller : public StatsPuller { +public: + bool Pull(const int tagId, vector >* data) override; +}; + +} // namespace statsd +} // namespace os +} // namespace android diff --git a/cmds/statsd/src/external/StatsPuller.h b/cmds/statsd/src/external/StatsPuller.h index 774e7f093087..940ad9c788ef 100644 --- a/cmds/statsd/src/external/StatsPuller.h +++ b/cmds/statsd/src/external/StatsPuller.h @@ -19,6 +19,7 @@ #include #include #include +#include "logd/LogEvent.h" using android::os::StatsLogEventWrapper; using std::vector; @@ -31,7 +32,7 @@ class StatsPuller { public: virtual ~StatsPuller(){}; - virtual vector Pull() = 0; + virtual bool Pull(const int tagId, vector>* data) = 0; }; } // namespace statsd diff --git a/cmds/statsd/src/external/StatsPullerManager.cpp b/cmds/statsd/src/external/StatsPullerManager.cpp index f45cb1ccaa74..003b5c41a507 100644 --- a/cmds/statsd/src/external/StatsPullerManager.cpp +++ b/cmds/statsd/src/external/StatsPullerManager.cpp @@ -21,89 +21,69 @@ #include #include #include -#include "KernelWakelockPuller.h" +#include "ResourcePowerManagerPuller.h" +#include "StatsCompanionServicePuller.h" #include "StatsPullerManager.h" #include "StatsService.h" #include "logd/LogEvent.h" +#include "statslog.h" #include +using std::map; using std::string; using std::vector; +using std::make_shared; +using std::shared_ptr; namespace android { namespace os { namespace statsd { -const int kernel_wakelock = 1; -const unordered_map StatsPullerManager::kPullCodes({{"KERNEL_WAKELOCK", - kernel_wakelock}}); - StatsPullerManager::StatsPullerManager() : mCurrentPullingInterval(LONG_MAX), mPullStartTimeMs(get_pull_start_time_ms()) { - mPullers.insert({kernel_wakelock, make_unique()}); - mStatsCompanionService = get_stats_companion_service(); - if (mStatsCompanionService != nullptr) { - mStatsCompanionService->cancelPullingAlarms(); - } else { - VLOG("Failed to update pulling interval"); - } + shared_ptr statsCompanionServicePuller = make_shared(); + shared_ptr + resourcePowerManagerPuller = make_shared(); + + mPullers.insert({android::util::KERNEL_WAKELOCK_PULLED, + statsCompanionServicePuller}); + mPullers.insert({android::util::WIFI_BYTES_TRANSFERRED, + statsCompanionServicePuller}); + mPullers.insert({android::util::MOBILE_BYTES_TRANSFERRED, + statsCompanionServicePuller}); + mPullers.insert({android::util::WIFI_BYTES_TRANSFERRED_BY_FG_BG, + statsCompanionServicePuller}); + mPullers.insert({android::util::MOBILE_BYTES_TRANSFERRED_BY_FG_BG, + statsCompanionServicePuller}); + mPullers.insert({android::util::POWER_STATE_PLATFORM_SLEEP_STATE_PULLED, + resourcePowerManagerPuller}); + mPullers.insert({android::util::POWER_STATE_VOTER_PULLED, + resourcePowerManagerPuller}); + mPullers.insert({android::util::POWER_STATE_SUBSYSTEM_SLEEP_STATE_PULLED, + resourcePowerManagerPuller}); + + mStatsCompanionService = StatsService::getStatsCompanionService(); } -static const int log_msg_header_size = 28; - -vector> StatsPullerManager::Pull(int pullCode, uint64_t timestampSec) { - if (DEBUG) ALOGD("Initiating pulling %d", pullCode); - - vector> ret; - auto itr = mPullers.find(pullCode); - if (itr != mPullers.end()) { - vector outputs = itr->second->Pull(); - for (const StatsLogEventWrapper& it : outputs) { - log_msg tmp; - tmp.entry_v1.sec = timestampSec; - tmp.entry_v1.nsec = 0; - tmp.entry_v1.len = it.bytes.size(); - // Manually set the header size to 28 bytes to match the pushed log events. - tmp.entry.hdr_size = log_msg_header_size; - // And set the received bytes starting after the 28 bytes reserved for header. - copy(it.bytes.begin(), it.bytes.end(), tmp.buf + log_msg_header_size); - shared_ptr evt = make_shared(tmp); - ret.push_back(evt); - } - return ret; - } else { - ALOGD("Unknown pull code %d", pullCode); - return ret; // Return early since we don't know what to pull. - } -} + bool StatsPullerManager::Pull(int tagId, vector>* data) { + if (DEBUG) ALOGD("Initiating pulling %d", tagId); -sp StatsPullerManager::get_stats_companion_service() { - sp statsCompanion = nullptr; - // Get statscompanion service from service manager - const sp sm(defaultServiceManager()); - if (sm != nullptr) { - const String16 name("statscompanion"); - statsCompanion = interface_cast(sm->checkService(name)); - if (statsCompanion == nullptr) { - ALOGW("statscompanion service unavailable!"); - return nullptr; + if (mPullers.find(tagId) != mPullers.end()) { + return mPullers.find(tagId)->second->Pull(tagId, data); + } else { + ALOGD("Unknown tagId %d", tagId); + return false; // Return early since we don't know what to pull. + } } - } - return statsCompanion; -} StatsPullerManager& StatsPullerManager::GetInstance() { static StatsPullerManager instance; return instance; } -int StatsPullerManager::GetPullCode(string atomName) { - if (kPullCodes.find(atomName) != kPullCodes.end()) { - return kPullCodes.find(atomName)->second; - } else { - return -1; - } +bool StatsPullerManager::PullerForMatcherExists(int tagId) { + return mPullers.find(tagId) != mPullers.end(); } long StatsPullerManager::get_pull_start_time_ms() { @@ -111,9 +91,9 @@ long StatsPullerManager::get_pull_start_time_ms() { return time(nullptr) * 1000; } -void StatsPullerManager::RegisterReceiver(int pullCode, sp receiver, long intervalMs) { +void StatsPullerManager::RegisterReceiver(int tagId, sp receiver, long intervalMs) { AutoMutex _l(mReceiversLock); - vector& receivers = mReceivers[pullCode]; + vector& receivers = mReceivers[tagId]; for (auto it = receivers.begin(); it != receivers.end(); it++) { if (it->receiver.get() == receiver.get()) { VLOG("Receiver already registered of %d", (int)receivers.size()); @@ -135,20 +115,20 @@ void StatsPullerManager::RegisterReceiver(int pullCode, sp rec VLOG("Failed to update pulling interval"); } } - VLOG("Puller for pullcode %d registered of %d", pullCode, (int)receivers.size()); + VLOG("Puller for tagId %d registered of %d", tagId, (int)receivers.size()); } -void StatsPullerManager::UnRegisterReceiver(int pullCode, sp receiver) { +void StatsPullerManager::UnRegisterReceiver(int tagId, sp receiver) { AutoMutex _l(mReceiversLock); - if (mReceivers.find(pullCode) == mReceivers.end()) { - VLOG("Unknown pull code or no receivers: %d", pullCode); + if (mReceivers.find(tagId) == mReceivers.end()) { + VLOG("Unknown pull code or no receivers: %d", tagId); return; } - auto& receivers = mReceivers.find(pullCode)->second; + auto& receivers = mReceivers.find(tagId)->second; for (auto it = receivers.begin(); it != receivers.end(); it++) { if (receiver.get() == it->receiver.get()) { receivers.erase(it); - VLOG("Puller for pullcode %d unregistered of %d", pullCode, (int)receivers.size()); + VLOG("Puller for tagId %d unregistered of %d", tagId, (int)receivers.size()); return; } } @@ -176,10 +156,12 @@ void StatsPullerManager::OnAlarmFired() { } for (const auto& pullInfo : needToPull) { - const vector>& data = Pull(pullInfo.first, currentTimeMs/1000); - for(const auto& receiverInfo : pullInfo.second) { - receiverInfo->receiver->onDataPulled(data); - receiverInfo->timeInfo.second = currentTimeMs; + vector> data; + if (Pull(pullInfo.first, &data)) { + for (const auto& receiverInfo : pullInfo.second) { + receiverInfo->receiver->onDataPulled(data); + receiverInfo->timeInfo.second = currentTimeMs; + } } } } diff --git a/cmds/statsd/src/external/StatsPullerManager.h b/cmds/statsd/src/external/StatsPullerManager.h index e599b6904ed4..67580d68c6f1 100644 --- a/cmds/statsd/src/external/StatsPullerManager.h +++ b/cmds/statsd/src/external/StatsPullerManager.h @@ -37,44 +37,42 @@ class StatsPullerManager : public virtual RefBase { public: static StatsPullerManager& GetInstance(); - void RegisterReceiver(int pullCode, sp receiver, long intervalMs); + void RegisterReceiver(int tagId, sp receiver, long intervalMs); - void UnRegisterReceiver(int pullCode, sp receiver); + void UnRegisterReceiver(int tagId, sp receiver); - // We return a vector of shared_ptr since LogEvent's copy constructor is not available. - vector> Pull(const int pullCode, const uint64_t timestampSec); - - // Translate metric name to pullCodes. - // return -1 if no valid pullCode is found - int GetPullCode(std::string metricName); + // Verify if we know how to pull for this matcher + bool PullerForMatcherExists(int tagId); void OnAlarmFired(); + bool Pull(const int pullCode, vector>* data); + private: StatsPullerManager(); + // use this to update alarm sp mStatsCompanionService = nullptr; sp get_stats_companion_service(); - std::unordered_map> mPullers; - + // mapping from simple matcher tagId to puller + std::map> mPullers; - - // internal state of a bucket. typedef struct { // pull_interval_sec : last_pull_time_sec std::pair timeInfo; sp receiver; } ReceiverInfo; + // mapping from simple matcher tagId to receivers std::map> mReceivers; Mutex mReceiversLock; long mCurrentPullingInterval; - // for value metrics, it is important for the buckets to be aligned to multiple of smallest + // for pulled metrics, it is important for the buckets to be aligned to multiple of smallest // bucket size. All pulled metrics start pulling based on this time, so that they can be // correctly attributed to the correct buckets. Pulled data attach a timestamp which is the // request time. @@ -83,10 +81,8 @@ private: long get_pull_start_time_ms(); LogEvent parse_pulled_data(String16 data); - - static const std::unordered_map kPullCodes; }; } // namespace statsd } // namespace os -} // namespace android \ No newline at end of file +} // namespace android diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.cpp b/cmds/statsd/src/metrics/ValueMetricProducer.cpp index cb6166dafa3a..ca33371e033a 100644 --- a/cmds/statsd/src/metrics/ValueMetricProducer.cpp +++ b/cmds/statsd/src/metrics/ValueMetricProducer.cpp @@ -36,11 +36,11 @@ namespace statsd { // ValueMetric has a minimum bucket size of 10min so that we don't pull too frequently ValueMetricProducer::ValueMetricProducer(const ValueMetric& metric, const int conditionIndex, - const sp& wizard) + const sp& wizard, const int pullTagId) : MetricProducer((time(nullptr) / 600 * 600 * NANO_SECONDS_IN_A_SECOND), conditionIndex, wizard), mMetric(metric), - mPullCode(mStatsPullerManager.GetPullCode(mMetric.what())) { + mPullTagId(pullTagId) { // TODO: valuemetric for pushed events may need unlimited bucket length mBucketSizeNs = mMetric.bucket().bucket_size_millis() * 1000 * 1000; @@ -52,8 +52,8 @@ ValueMetricProducer::ValueMetricProducer(const ValueMetric& metric, const int co mConditionSliced = true; } - if (!metric.has_condition() && mPullCode != -1) { - mStatsPullerManager.RegisterReceiver(mPullCode, this, metric.bucket().bucket_size_millis()); + if (!metric.has_condition() && mPullTagId != -1) { + mStatsPullerManager.RegisterReceiver(mPullTagId, this, metric.bucket().bucket_size_millis()); } VLOG("value metric %lld created. bucket size %lld start_time: %lld", metric.metric_id(), @@ -120,27 +120,27 @@ StatsLogReport ValueMetricProducer::onDumpReport() { void ValueMetricProducer::onConditionChanged(const bool condition, const uint64_t eventTime) { mCondition = condition; - if (mPullCode != -1) { - vector> allData = mStatsPullerManager.Pull(mPullCode, eventTime); + if (mPullTagId != -1) { if (mCondition == true) { - mStatsPullerManager.RegisterReceiver(mPullCode, this, + mStatsPullerManager.RegisterReceiver(mPullTagId, this, mMetric.bucket().bucket_size_millis()); } else if (mCondition == ConditionState::kFalse) { - mStatsPullerManager.UnRegisterReceiver(mPullCode, this); + mStatsPullerManager.UnRegisterReceiver(mPullTagId, this); } - if (allData.size() == 0) { - return; - } - AutoMutex _l(mLock); - if (allData.size() == 0) { - return; - } - for (const auto& data : allData) { - onMatchedLogEvent(0, *data, false); + + vector> allData; + if (mStatsPullerManager.Pull(mPullTagId, &allData)) { + if (allData.size() == 0) { + return; + } + AutoMutex _l(mLock); + for (const auto& data : allData) { + onMatchedLogEvent(0, *data, false); + } + flush_if_needed(eventTime); } - flush_if_needed(eventTime); + return; } - return; } void ValueMetricProducer::onDataPulled(const std::vector>& allData) { @@ -188,7 +188,7 @@ void ValueMetricProducer::onMatchedLogEventInternal( } } } - if (mPullCode == -1) { + if (mPullTagId == -1) { flush_if_needed(eventTimeNs); } } diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.h b/cmds/statsd/src/metrics/ValueMetricProducer.h index 4f1791351f87..865398127b47 100644 --- a/cmds/statsd/src/metrics/ValueMetricProducer.h +++ b/cmds/statsd/src/metrics/ValueMetricProducer.h @@ -33,7 +33,7 @@ namespace statsd { class ValueMetricProducer : public virtual MetricProducer, public virtual PullDataReceiver { public: ValueMetricProducer(const ValueMetric& valueMetric, const int conditionIndex, - const sp& wizard); + const sp& wizard, const int pullTagId); virtual ~ValueMetricProducer(); @@ -67,7 +67,8 @@ private: Mutex mLock; - const int mPullCode; + // tagId for pulled data. -1 if this is not pulled + const int mPullTagId; // internal state of a bucket. typedef struct { diff --git a/cmds/statsd/src/metrics/metrics_manager_util.cpp b/cmds/statsd/src/metrics/metrics_manager_util.cpp index 3d4036e8d176..3ff2a773327e 100644 --- a/cmds/statsd/src/metrics/metrics_manager_util.cpp +++ b/cmds/statsd/src/metrics/metrics_manager_util.cpp @@ -192,12 +192,12 @@ bool initMetrics(const StatsdConfig& config, const unordered_map& l unordered_map>& trackerToMetricMap) { sp wizard = new ConditionWizard(allConditionTrackers); const int allMetricsCount = - config.count_metric_size() + config.duration_metric_size() + config.event_metric_size(); + config.count_metric_size() + config.duration_metric_size() + config.event_metric_size() + config.value_metric_size(); allMetricProducers.reserve(allMetricsCount); StatsPullerManager& statsPullerManager = StatsPullerManager::GetInstance(); // Build MetricProducers for each metric defined in config. - // (1) build CountMetricProducer + // build CountMetricProducer for (int i = 0; i < config.count_metric_size(); i++) { const CountMetric& metric = config.count_metric(i); if (!metric.has_what()) { @@ -224,6 +224,7 @@ bool initMetrics(const StatsdConfig& config, const unordered_map& l allMetricProducers.push_back(countProducer); } + // build DurationMetricProducer for (int i = 0; i < config.duration_metric_size(); i++) { int metricIndex = allMetricProducers.size(); const DurationMetric& metric = config.duration_metric(i); @@ -285,6 +286,7 @@ bool initMetrics(const StatsdConfig& config, const unordered_map& l allMetricProducers.push_back(durationMetric); } + // build EventMetricProducer for (int i = 0; i < config.event_metric_size(); i++) { int metricIndex = allMetricProducers.size(); const EventMetric& metric = config.event_metric(i); @@ -310,7 +312,7 @@ bool initMetrics(const StatsdConfig& config, const unordered_map& l allMetricProducers.push_back(eventMetric); } - // value metrics + // build ValueMetricProducer for (int i = 0; i < config.value_metric_size(); i++) { const ValueMetric& metric = config.value_metric(i); if (!metric.has_what()) { @@ -318,24 +320,35 @@ bool initMetrics(const StatsdConfig& config, const unordered_map& l return false; } - int pullCode = statsPullerManager.GetPullCode(metric.what()); - if (pullCode == -1) { - ALOGW("cannot find %s in pulled metrics", metric.what().c_str()); + int metricIndex = allMetricProducers.size(); + int trackerIndex; + if (!handleMetricWithLogTrackers(metric.what(), metricIndex, metric.dimension_size() > 0, + allLogEntryMatchers, logTrackerMap, trackerToMetricMap, + trackerIndex)) { return false; } - sp valueProducer; - auto condition_it = conditionTrackerMap.find(metric.condition()); - if (condition_it == conditionTrackerMap.end()) { - ALOGW("cannot find the Condition %s in the config", metric.condition().c_str()); - return false; + sp atomMatcher = allLogEntryMatchers.at(trackerIndex); + // If it is pulled atom, it should be simple matcher with one tagId. + int pullTagId = -1; + for (int tagId : atomMatcher->getTagIds()) { + if (statsPullerManager.PullerForMatcherExists(tagId)) { + if (atomMatcher->getTagIds().size() != 1) { + return false; + } + pullTagId = tagId; + } + } + + int conditionIndex = -1; + if (metric.has_condition()) { + handleMetricWithConditions(metric.condition(), metricIndex, conditionTrackerMap, + metric.links(), allConditionTrackers, conditionIndex, + conditionToMetricMap); } - int metricIndex = allMetricProducers.size(); - valueProducer = new ValueMetricProducer(metric, condition_it->second, wizard); - // will create new vector if not exist before. - auto& metricList = conditionToMetricMap[condition_it->second]; - metricList.push_back(metricIndex); + sp valueProducer = + new ValueMetricProducer(metric, conditionIndex, wizard, pullTagId); allMetricProducers.push_back(valueProducer); } return true; diff --git a/cmds/statsd/src/stats_events.proto b/cmds/statsd/src/stats_events.proto index 51244c6bdf4b..82d975914682 100644 --- a/cmds/statsd/src/stats_events.proto +++ b/cmds/statsd/src/stats_events.proto @@ -72,6 +72,7 @@ message StatsEvent { PhoneSignalStrengthChanged phone_signal_strength_changed = 40; SettingChanged setting_changed = 41; ActivityForegroundStateChanged activity_foreground_state_changed = 42; + // TODO: Reorder the numbering so that the most frequent occur events occur in the first 15. } @@ -81,7 +82,10 @@ message StatsEvent { WifiBytesTransferredByFgBg wifi_bytes_transferred_by_fg_bg = 1001; MobileBytesTransferred mobile_bytes_transferred = 1002; MobileBytesTransferredByFgBg mobile_bytes_transferred_by_fg_bg = 1003; - KernelWakelocksReported kernel_wakelocks_reported = 1004; + KernelWakelockPulled kernel_wakelock_pulled = 1004; + PowerStatePlatformSleepStatePulled power_state_platform_sleep_state_pulled = 1005; + PowerStateVoterPulled power_state_voter_pulled = 1006; + PowerStateSubsystemSleepStatePulled power_state_subsystem_sleep_state_pulled = 1007; } } @@ -794,7 +798,7 @@ message MobileBytesTransferredByFgBg { * Pulled from: * StatsCompanionService using KernelWakelockReader. */ -message KernelWakelocksReported { +message KernelWakelockPulled { optional string name = 1; optional int32 count = 2; @@ -803,3 +807,44 @@ message KernelWakelocksReported { optional int64 time = 4; } + +/* + * Pulls PowerStatePlatformSleepState. + * + * Definition here: + * hardware/interfaces/power/1.0/types.hal + */ +message PowerStatePlatformSleepStatePulled { + optional string name = 1; + optional uint64 residency_in_msec_since_boot = 2; + optional uint64 total_transitions = 3; + optional bool supported_only_in_suspend = 4; +} + +/** + * Pulls PowerStateVoter. + * + * Definition here: + * hardware/interfaces/power/1.0/types.hal + */ +message PowerStateVoterPulled { + optional string power_state_platform_sleep_state_name = 1; + optional string power_state_voter_name = 2; + optional uint64 total_time_in_msec_voted_for_since_boot = 3; + optional uint64 total_number_of_times_voted_since_boot = 4; +} + +/** + * Pulls PowerStateSubsystemSleepState. + * + * Definition here: + * hardware/interfaces/power/1.1/types.hal + */ +message PowerStateSubsystemSleepStatePulled { + optional string power_state_subsystem_name = 1; + optional string power_state_subsystem_sleep_state_name = 2; + optional uint64 residency_in_msec_since_boot = 3; + optional uint64 total_transitions = 4; + optional uint64 last_entry_timestamp_ms = 5; + optional bool supported_only_in_suspend = 6; +} diff --git a/services/core/java/com/android/server/stats/StatsCompanionService.java b/services/core/java/com/android/server/stats/StatsCompanionService.java index 41534cbb641f..248872338928 100644 --- a/services/core/java/com/android/server/stats/StatsCompanionService.java +++ b/services/core/java/com/android/server/stats/StatsCompanionService.java @@ -286,10 +286,6 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { } } - // These values must be kept in sync with cmd/statsd/StatsPullerManager.h. - // TODO: pull the constant from stats_events.proto instead - private static final int PULL_CODE_KERNEL_WAKELOCKS = 20; - private final KernelWakelockReader mKernelWakelockReader = new KernelWakelockReader(); private final KernelWakelockStats mTmpWakelockStats = new KernelWakelockStats(); @@ -347,12 +343,12 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { } @Override // Binder call - public StatsLogEventWrapper[] pullData(int pullCode) { + public StatsLogEventWrapper[] pullData(int tagId) { enforceCallingPermission(); if (DEBUG) - Slog.d(TAG, "Pulling " + pullCode); + Slog.d(TAG, "Pulling " + tagId); - switch (pullCode) { + switch (tagId) { case StatsLog.WIFI_BYTES_TRANSFERRED: { long token = Binder.clearCallingIdentity(); try { @@ -366,7 +362,7 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { // Combine all the metrics per Uid into one record. NetworkStats stats = nsf.readNetworkStatsDetail(NetworkStats.UID_ALL, ifaces, NetworkStats.TAG_NONE, null).groupedByUid(); - return addNetworkStats(pullCode, stats, false); + return addNetworkStats(tagId, stats, false); } catch (java.io.IOException e) { Slog.e(TAG, "Pulling netstats for wifi bytes has error", e); } finally { @@ -386,7 +382,7 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { // Combine all the metrics per Uid into one record. NetworkStats stats = nsf.readNetworkStatsDetail(NetworkStats.UID_ALL, ifaces, NetworkStats.TAG_NONE, null).groupedByUid(); - return addNetworkStats(pullCode, stats, false); + return addNetworkStats(tagId, stats, false); } catch (java.io.IOException e) { Slog.e(TAG, "Pulling netstats for mobile bytes has error", e); } finally { @@ -406,7 +402,7 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { NetworkStats stats = rollupNetworkStatsByFGBG( nsf.readNetworkStatsDetail(NetworkStats.UID_ALL, ifaces, NetworkStats.TAG_NONE, null)); - return addNetworkStats(pullCode, stats, true); + return addNetworkStats(tagId, stats, true); } catch (java.io.IOException e) { Slog.e(TAG, "Pulling netstats for wifi bytes w/ fg/bg has error", e); } finally { @@ -426,7 +422,7 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { NetworkStats stats = rollupNetworkStatsByFGBG( nsf.readNetworkStatsDetail(NetworkStats.UID_ALL, ifaces, NetworkStats.TAG_NONE, null)); - return addNetworkStats(pullCode, stats, true); + return addNetworkStats(tagId, stats, true); } catch (java.io.IOException e) { Slog.e(TAG, "Pulling netstats for mobile bytes w/ fg/bg has error", e); } finally { @@ -434,14 +430,14 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { } break; } - case StatsLog.KERNEL_WAKELOCKS_REPORTED: { + case StatsLog.KERNEL_WAKELOCK_PULLED: { final KernelWakelockStats wakelockStats = mKernelWakelockReader.readKernelWakelockStats(mTmpWakelockStats); List ret = new ArrayList(); for (Map.Entry ent : wakelockStats.entrySet()) { String name = ent.getKey(); KernelWakelockStats.Entry kws = ent.getValue(); - StatsLogEventWrapper e = new StatsLogEventWrapper(pullCode, 4); + StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, 4); e.writeString(name); e.writeInt(kws.mCount); e.writeInt(kws.mVersion); @@ -451,7 +447,7 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { return ret.toArray(new StatsLogEventWrapper[ret.size()]); } default: - Slog.w(TAG, "No such pollable data as " + pullCode); + Slog.w(TAG, "No such tagId data as " + tagId); return null; } return null; -- 2.11.0