Loading cmds/statsd/Android.bp +2 −0 Original line number Diff line number Diff line Loading @@ -72,6 +72,7 @@ cc_defaults { "src/external/StatsPuller.cpp", "src/external/StatsCompanionServicePuller.cpp", "src/external/SubsystemSleepStatePuller.cpp", "src/external/PowerStatsPuller.cpp", "src/external/ResourceHealthManagerPuller.cpp", "src/external/ResourceThermalManagerPuller.cpp", "src/external/StatsPullerManager.cpp", Loading Loading @@ -134,6 +135,7 @@ cc_defaults { "android.hardware.health@2.0", "android.hardware.power@1.0", "android.hardware.power@1.1", "android.hardware.power.stats@1.0", "android.hardware.thermal@1.0", "libpackagelistparser", "libsysutils", Loading cmds/statsd/src/atoms.proto +22 −0 Original line number Diff line number Diff line Loading @@ -190,6 +190,7 @@ message Atom { ProcessCpuTime process_cpu_time = 10035; NativeProcessMemoryState native_process_memory_state = 10036; CpuTimePerThreadFreq cpu_time_per_thread_freq = 10037; OnDevicePowerMeasurement on_device_power_measurement = 10038; } // DO NOT USE field numbers above 100,000 in AOSP. Loading Loading @@ -2261,6 +2262,27 @@ message SubsystemSleepState { optional uint64 time_millis = 4; } /** * Pulls on-device power measurement information. * Data defined by hardware/interfaces/power/stats/1.0/types.hal. * Pulled from: * frameworks/base/cmds/statsd/src/external/PowerStatsPuller.cpp */ message OnDevicePowerMeasurement { // Name of the subsystem (to which the rail belongs). optional string subsystem_name = 1; // Rail name. The rail lies within the subsystem. optional string rail_name = 2; // Time (in ms since boot) at which the rail energy value was measured. // This may differ slightly from the time that statsd logs this information. optional uint64 measurement_timestamp_millis = 3; // Accumulated energy used via the rail since device boot in uWs. optional uint64 energy_microwatt_secs = 4; } /** * Pulls Cpu time per frequency. * Pulls the time the cpu spend on the frequency index. Frequency index Loading cmds/statsd/src/external/PowerStatsPuller.cpp 0 → 100644 +146 −0 Original line number Diff line number Diff line /* * Copyright (C) 2018 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define DEBUG false // STOPSHIP if true #include "Log.h" #include <android/hardware/power/stats/1.0/IPowerStats.h> #include <vector> #include "PowerStatsPuller.h" #include "stats_log_util.h" using android::hardware::hidl_vec; using android::hardware::power::stats::V1_0::IPowerStats; using android::hardware::power::stats::V1_0::EnergyData; using android::hardware::power::stats::V1_0::RailInfo; using android::hardware::power::stats::V1_0::Status; using android::hardware::Return; using android::hardware::Void; using std::make_shared; using std::shared_ptr; namespace android { namespace os { namespace statsd { sp<android::hardware::power::stats::V1_0::IPowerStats> gPowerStatsHal = nullptr; std::mutex gPowerStatsHalMutex; bool gPowerStatsExist = true; // Initialized to ensure making a first attempt. std::vector<RailInfo> gRailInfo; bool getPowerStatsHal() { if (gPowerStatsHal == nullptr && gPowerStatsExist) { gPowerStatsHal = android::hardware::power::stats::V1_0::IPowerStats::getService(); if (gPowerStatsHal == nullptr) { ALOGW("Couldn't load power.stats HAL service"); gPowerStatsExist = false; } } return gPowerStatsHal != nullptr; } PowerStatsPuller::PowerStatsPuller() : StatsPuller(android::util::ON_DEVICE_POWER_MEASUREMENT) { } bool PowerStatsPuller::PullInternal(vector<shared_ptr<LogEvent>>* data) { std::lock_guard<std::mutex> lock(gPowerStatsHalMutex); if (!getPowerStatsHal()) { ALOGE("power.stats Hal not loaded"); return false; } int64_t wallClockTimestampNs = getWallClockNs(); int64_t elapsedTimestampNs = getElapsedRealtimeNs(); data->clear(); // Pull getRailInfo if necessary if (gRailInfo.empty()) { bool resultSuccess = true; Return<void> ret = gPowerStatsHal->getRailInfo( [&resultSuccess](const hidl_vec<RailInfo> &list, Status status) { resultSuccess = (status == Status::SUCCESS || status == Status::NOT_SUPPORTED); if (status != Status::SUCCESS) return; gRailInfo.reserve(list.size()); for (size_t i = 0; i < list.size(); ++i) { gRailInfo.push_back(list[i]); } }); if (!resultSuccess || !ret.isOk()) { ALOGE("power.stats getRailInfo() failed. Description: %s", ret.description().c_str()); gPowerStatsHal = nullptr; return false; } // If SUCCESS but empty, or if NOT_SUPPORTED, then never try again. if (gRailInfo.empty()) { ALOGE("power.stats has no rail information"); gPowerStatsExist = false; // No rail info, so never try again. return false; } } // Pull getEnergyData and write the data out const hidl_vec<uint32_t> desiredRailIndices; // Empty vector indicates we want all. bool resultSuccess = true; Return<void> ret = gPowerStatsHal->getEnergyData(desiredRailIndices, [&data, wallClockTimestampNs, elapsedTimestampNs, &resultSuccess] (hidl_vec<EnergyData> energyDataList, Status status) { resultSuccess = (status == Status::SUCCESS); if (!resultSuccess) return; for (size_t i = 0; i < energyDataList.size(); i++) { const EnergyData& energyData = energyDataList[i]; if (energyData.index >= gRailInfo.size()) { ALOGE("power.stats getEnergyData() returned an invalid rail index %u.", energyData.index); resultSuccess = false; return; } const RailInfo& rail = gRailInfo[energyData.index]; auto ptr = make_shared<LogEvent>(android::util::ON_DEVICE_POWER_MEASUREMENT, wallClockTimestampNs, elapsedTimestampNs); ptr->write(rail.subsysName); ptr->write(rail.railName); ptr->write(energyData.timestamp); ptr->write(energyData.energy); ptr->init(); data->push_back(ptr); VLOG("power.stat: %s.%s: %llu, %llu", rail.subsysName.c_str(), rail.railName.c_str(), (unsigned long long)energyData.timestamp, (unsigned long long)energyData.energy); } }); if (!resultSuccess || !ret.isOk()) { ALOGE("power.stats getEnergyData() failed. Description: %s", ret.description().c_str()); gPowerStatsHal = nullptr; return false; } return true; } } // namespace statsd } // namespace os } // namespace android cmds/statsd/src/external/PowerStatsPuller.h 0 → 100644 +36 −0 Original line number Diff line number Diff line /* * Copyright (C) 2018 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include "StatsPuller.h" namespace android { namespace os { namespace statsd { /** * Reads hal for power.stats */ class PowerStatsPuller : public StatsPuller { public: PowerStatsPuller(); bool PullInternal(vector<std::shared_ptr<LogEvent>>* data) override; }; } // namespace statsd } // namespace os } // namespace android cmds/statsd/src/external/StatsPullerManager.cpp +4 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ #include "../logd/LogEvent.h" #include "../stats_log_util.h" #include "../statscompanion_util.h" #include "PowerStatsPuller.h" #include "ResourceHealthManagerPuller.h" #include "ResourceThermalManagerPuller.h" #include "StatsCompanionServicePuller.h" Loading Loading @@ -86,6 +87,9 @@ const std::map<int, PullAtomInfo> StatsPullerManager::kAllPullAtomInfo = { // subsystem_sleep_state {android::util::SUBSYSTEM_SLEEP_STATE, {{}, {}, 1 * NS_PER_SEC, new SubsystemSleepStatePuller()}}, // on_device_power_measurement {android::util::ON_DEVICE_POWER_MEASUREMENT, {{}, {}, 1 * NS_PER_SEC, new PowerStatsPuller()}}, // cpu_time_per_freq {android::util::CPU_TIME_PER_FREQ, {{3}, Loading Loading
cmds/statsd/Android.bp +2 −0 Original line number Diff line number Diff line Loading @@ -72,6 +72,7 @@ cc_defaults { "src/external/StatsPuller.cpp", "src/external/StatsCompanionServicePuller.cpp", "src/external/SubsystemSleepStatePuller.cpp", "src/external/PowerStatsPuller.cpp", "src/external/ResourceHealthManagerPuller.cpp", "src/external/ResourceThermalManagerPuller.cpp", "src/external/StatsPullerManager.cpp", Loading Loading @@ -134,6 +135,7 @@ cc_defaults { "android.hardware.health@2.0", "android.hardware.power@1.0", "android.hardware.power@1.1", "android.hardware.power.stats@1.0", "android.hardware.thermal@1.0", "libpackagelistparser", "libsysutils", Loading
cmds/statsd/src/atoms.proto +22 −0 Original line number Diff line number Diff line Loading @@ -190,6 +190,7 @@ message Atom { ProcessCpuTime process_cpu_time = 10035; NativeProcessMemoryState native_process_memory_state = 10036; CpuTimePerThreadFreq cpu_time_per_thread_freq = 10037; OnDevicePowerMeasurement on_device_power_measurement = 10038; } // DO NOT USE field numbers above 100,000 in AOSP. Loading Loading @@ -2261,6 +2262,27 @@ message SubsystemSleepState { optional uint64 time_millis = 4; } /** * Pulls on-device power measurement information. * Data defined by hardware/interfaces/power/stats/1.0/types.hal. * Pulled from: * frameworks/base/cmds/statsd/src/external/PowerStatsPuller.cpp */ message OnDevicePowerMeasurement { // Name of the subsystem (to which the rail belongs). optional string subsystem_name = 1; // Rail name. The rail lies within the subsystem. optional string rail_name = 2; // Time (in ms since boot) at which the rail energy value was measured. // This may differ slightly from the time that statsd logs this information. optional uint64 measurement_timestamp_millis = 3; // Accumulated energy used via the rail since device boot in uWs. optional uint64 energy_microwatt_secs = 4; } /** * Pulls Cpu time per frequency. * Pulls the time the cpu spend on the frequency index. Frequency index Loading
cmds/statsd/src/external/PowerStatsPuller.cpp 0 → 100644 +146 −0 Original line number Diff line number Diff line /* * Copyright (C) 2018 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define DEBUG false // STOPSHIP if true #include "Log.h" #include <android/hardware/power/stats/1.0/IPowerStats.h> #include <vector> #include "PowerStatsPuller.h" #include "stats_log_util.h" using android::hardware::hidl_vec; using android::hardware::power::stats::V1_0::IPowerStats; using android::hardware::power::stats::V1_0::EnergyData; using android::hardware::power::stats::V1_0::RailInfo; using android::hardware::power::stats::V1_0::Status; using android::hardware::Return; using android::hardware::Void; using std::make_shared; using std::shared_ptr; namespace android { namespace os { namespace statsd { sp<android::hardware::power::stats::V1_0::IPowerStats> gPowerStatsHal = nullptr; std::mutex gPowerStatsHalMutex; bool gPowerStatsExist = true; // Initialized to ensure making a first attempt. std::vector<RailInfo> gRailInfo; bool getPowerStatsHal() { if (gPowerStatsHal == nullptr && gPowerStatsExist) { gPowerStatsHal = android::hardware::power::stats::V1_0::IPowerStats::getService(); if (gPowerStatsHal == nullptr) { ALOGW("Couldn't load power.stats HAL service"); gPowerStatsExist = false; } } return gPowerStatsHal != nullptr; } PowerStatsPuller::PowerStatsPuller() : StatsPuller(android::util::ON_DEVICE_POWER_MEASUREMENT) { } bool PowerStatsPuller::PullInternal(vector<shared_ptr<LogEvent>>* data) { std::lock_guard<std::mutex> lock(gPowerStatsHalMutex); if (!getPowerStatsHal()) { ALOGE("power.stats Hal not loaded"); return false; } int64_t wallClockTimestampNs = getWallClockNs(); int64_t elapsedTimestampNs = getElapsedRealtimeNs(); data->clear(); // Pull getRailInfo if necessary if (gRailInfo.empty()) { bool resultSuccess = true; Return<void> ret = gPowerStatsHal->getRailInfo( [&resultSuccess](const hidl_vec<RailInfo> &list, Status status) { resultSuccess = (status == Status::SUCCESS || status == Status::NOT_SUPPORTED); if (status != Status::SUCCESS) return; gRailInfo.reserve(list.size()); for (size_t i = 0; i < list.size(); ++i) { gRailInfo.push_back(list[i]); } }); if (!resultSuccess || !ret.isOk()) { ALOGE("power.stats getRailInfo() failed. Description: %s", ret.description().c_str()); gPowerStatsHal = nullptr; return false; } // If SUCCESS but empty, or if NOT_SUPPORTED, then never try again. if (gRailInfo.empty()) { ALOGE("power.stats has no rail information"); gPowerStatsExist = false; // No rail info, so never try again. return false; } } // Pull getEnergyData and write the data out const hidl_vec<uint32_t> desiredRailIndices; // Empty vector indicates we want all. bool resultSuccess = true; Return<void> ret = gPowerStatsHal->getEnergyData(desiredRailIndices, [&data, wallClockTimestampNs, elapsedTimestampNs, &resultSuccess] (hidl_vec<EnergyData> energyDataList, Status status) { resultSuccess = (status == Status::SUCCESS); if (!resultSuccess) return; for (size_t i = 0; i < energyDataList.size(); i++) { const EnergyData& energyData = energyDataList[i]; if (energyData.index >= gRailInfo.size()) { ALOGE("power.stats getEnergyData() returned an invalid rail index %u.", energyData.index); resultSuccess = false; return; } const RailInfo& rail = gRailInfo[energyData.index]; auto ptr = make_shared<LogEvent>(android::util::ON_DEVICE_POWER_MEASUREMENT, wallClockTimestampNs, elapsedTimestampNs); ptr->write(rail.subsysName); ptr->write(rail.railName); ptr->write(energyData.timestamp); ptr->write(energyData.energy); ptr->init(); data->push_back(ptr); VLOG("power.stat: %s.%s: %llu, %llu", rail.subsysName.c_str(), rail.railName.c_str(), (unsigned long long)energyData.timestamp, (unsigned long long)energyData.energy); } }); if (!resultSuccess || !ret.isOk()) { ALOGE("power.stats getEnergyData() failed. Description: %s", ret.description().c_str()); gPowerStatsHal = nullptr; return false; } return true; } } // namespace statsd } // namespace os } // namespace android
cmds/statsd/src/external/PowerStatsPuller.h 0 → 100644 +36 −0 Original line number Diff line number Diff line /* * Copyright (C) 2018 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include "StatsPuller.h" namespace android { namespace os { namespace statsd { /** * Reads hal for power.stats */ class PowerStatsPuller : public StatsPuller { public: PowerStatsPuller(); bool PullInternal(vector<std::shared_ptr<LogEvent>>* data) override; }; } // namespace statsd } // namespace os } // namespace android
cmds/statsd/src/external/StatsPullerManager.cpp +4 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ #include "../logd/LogEvent.h" #include "../stats_log_util.h" #include "../statscompanion_util.h" #include "PowerStatsPuller.h" #include "ResourceHealthManagerPuller.h" #include "ResourceThermalManagerPuller.h" #include "StatsCompanionServicePuller.h" Loading Loading @@ -86,6 +87,9 @@ const std::map<int, PullAtomInfo> StatsPullerManager::kAllPullAtomInfo = { // subsystem_sleep_state {android::util::SUBSYSTEM_SLEEP_STATE, {{}, {}, 1 * NS_PER_SEC, new SubsystemSleepStatePuller()}}, // on_device_power_measurement {android::util::ON_DEVICE_POWER_MEASUREMENT, {{}, {}, 1 * NS_PER_SEC, new PowerStatsPuller()}}, // cpu_time_per_freq {android::util::CPU_TIME_PER_FREQ, {{3}, Loading