From 4c52716287867d2afbc2c9e19eb790d3005189a0 Mon Sep 17 00:00:00 2001 From: Jeffrey Huang Date: Thu, 30 Jan 2020 17:53:13 -0800 Subject: [PATCH] Migrate onDevicePowerMeasurement to JNI code Formatted PowerStatsPuller with clang. Bug: 148618655 Test: atest HostAtomTests#testOnDevicePowerMeasurement Change-Id: I08c9a64ebaa469d94b1c72a85e8e44f9d8cb7cb8 --- cmds/statsd/Android.bp | 1 - .../src/external/StatsPullerManager.cpp | 4 - .../stats/pull/StatsPullAtomService.java | 3 + services/core/jni/Android.bp | 2 + ...server_stats_pull_StatsPullAtomService.cpp | 58 +++++++++ services/core/jni/onload.cpp | 2 + services/core/jni/stats/PowerStatsPuller.cpp | 117 ++++++++---------- .../core/jni/stats}/PowerStatsPuller.h | 19 ++- 8 files changed, 129 insertions(+), 77 deletions(-) create mode 100644 services/core/jni/com_android_server_stats_pull_StatsPullAtomService.cpp rename {cmds/statsd/src/external => services/core/jni/stats}/PowerStatsPuller.h (72%) diff --git a/cmds/statsd/Android.bp b/cmds/statsd/Android.bp index fdc7fce3b8845..f26062b3eea39 100644 --- a/cmds/statsd/Android.bp +++ b/cmds/statsd/Android.bp @@ -66,7 +66,6 @@ cc_defaults { "src/config/ConfigManager.cpp", "src/external/GpuStatsPuller.cpp", "src/external/Perfetto.cpp", - "src/external/PowerStatsPuller.cpp", "src/external/PullResultReceiver.cpp", "src/external/puller_util.cpp", "src/external/StatsCallbackPuller.cpp", diff --git a/cmds/statsd/src/external/StatsPullerManager.cpp b/cmds/statsd/src/external/StatsPullerManager.cpp index 668c11ef55f55..982aab5a63809 100644 --- a/cmds/statsd/src/external/StatsPullerManager.cpp +++ b/cmds/statsd/src/external/StatsPullerManager.cpp @@ -33,7 +33,6 @@ #include "../stats_log_util.h" #include "../statscompanion_util.h" #include "GpuStatsPuller.h" -#include "PowerStatsPuller.h" #include "StatsCallbackPuller.h" #include "SubsystemSleepStatePuller.h" #include "TrainInfoPuller.h" @@ -58,9 +57,6 @@ StatsPullerManager::StatsPullerManager() // subsystem_sleep_state {{.atomTag = android::util::SUBSYSTEM_SLEEP_STATE}, new SubsystemSleepStatePuller()}, - // on_device_power_measurement - {{.atomTag = android::util::ON_DEVICE_POWER_MEASUREMENT}, new PowerStatsPuller()}, - // TrainInfo. {{.atomTag = android::util::TRAIN_INFO}, new TrainInfoPuller()}, diff --git a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java index 4f8a86d3f3c6a..0f79a111df5b5 100644 --- a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java +++ b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java @@ -256,6 +256,8 @@ public class StatsPullAtomService extends SystemService { mContext = context; } + private native void nativeInit(); + /** * Use of this StatsPullAtomCallbackImpl means we avoid one class per tagId, which we would * get if we used lambdas. @@ -399,6 +401,7 @@ public class StatsPullAtomService extends SystemService { super.onBootPhase(phase); if (phase == PHASE_SYSTEM_SERVICES_READY) { BackgroundThread.getHandler().post(() -> { + nativeInit(); initializePullersState(); registerAllPullers(); registerEventListeners(); diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp index 4a2636ee6ca42..9e01fd60885fe 100644 --- a/services/core/jni/Android.bp +++ b/services/core/jni/Android.bp @@ -22,6 +22,7 @@ cc_library_static { "BroadcastRadio/TunerCallback.cpp", "BroadcastRadio/convert.cpp", "BroadcastRadio/regions.cpp", + "stats/PowerStatsPuller.cpp", "com_android_server_am_BatteryStatsService.cpp", "com_android_server_connectivity_Vpn.cpp", "com_android_server_ConsumerIrService.cpp", @@ -37,6 +38,7 @@ cc_library_static { "com_android_server_security_VerityUtils.cpp", "com_android_server_SerialService.cpp", "com_android_server_soundtrigger_middleware_AudioSessionProviderImpl.cpp", + "com_android_server_stats_pull_StatsPullAtomService.cpp", "com_android_server_storage_AppFuseBridge.cpp", "com_android_server_SystemServer.cpp", "com_android_server_TestNetworkService.cpp", diff --git a/services/core/jni/com_android_server_stats_pull_StatsPullAtomService.cpp b/services/core/jni/com_android_server_stats_pull_StatsPullAtomService.cpp new file mode 100644 index 0000000000000..f6c0a8307b133 --- /dev/null +++ b/services/core/jni/com_android_server_stats_pull_StatsPullAtomService.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2020 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 LOG_TAG "StatsPullAtomService" + +#include +#include +#include +#include +#include +#include + +#include "stats/PowerStatsPuller.h" + +namespace android { + +static server::stats::PowerStatsPuller gPowerStatsPuller; + +static status_pull_atom_return_t onDevicePowerMeasurementCallback(int32_t atom_tag, + pulled_stats_event_list* data, + void* cookie) { + return gPowerStatsPuller.Pull(atom_tag, data); +} + +static void nativeInit(JNIEnv* env, jobject javaObject) { + // on device power measurement + gPowerStatsPuller = server::stats::PowerStatsPuller(); + register_stats_pull_atom_callback(android::util::ON_DEVICE_POWER_MEASUREMENT, + onDevicePowerMeasurementCallback, + /* metadata= */ nullptr, + /* cookie= */ nullptr); +} + +static const JNINativeMethod sMethods[] = {{"nativeInit", "()V", (void*)nativeInit}}; + +int register_android_server_stats_pull_StatsPullAtomService(JNIEnv* env) { + int res = jniRegisterNativeMethods(env, "com/android/server/stats/pull/StatsPullAtomService", + sMethods, NELEM(sMethods)); + if (res < 0) { + ALOGE("failed to register native methods"); + } + return res; +} + +} // namespace android diff --git a/services/core/jni/onload.cpp b/services/core/jni/onload.cpp index 19fa062bd9f94..1202ad33996de 100644 --- a/services/core/jni/onload.cpp +++ b/services/core/jni/onload.cpp @@ -59,6 +59,7 @@ int register_android_server_am_LowMemDetector(JNIEnv* env); int register_com_android_server_soundtrigger_middleware_AudioSessionProviderImpl( JNIEnv* env); int register_android_server_incremental_IncrementalManagerService(JNIEnv* env); +int register_android_server_stats_pull_StatsPullAtomService(JNIEnv* env); }; using namespace android; @@ -111,5 +112,6 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */) register_com_android_server_soundtrigger_middleware_AudioSessionProviderImpl( env); register_android_server_incremental_IncrementalManagerService(env); + register_android_server_stats_pull_StatsPullAtomService(env); return JNI_VERSION_1_4; } diff --git a/services/core/jni/stats/PowerStatsPuller.cpp b/services/core/jni/stats/PowerStatsPuller.cpp index dc69b78f03299..e80b5cfc4a715 100644 --- a/services/core/jni/stats/PowerStatsPuller.cpp +++ b/services/core/jni/stats/PowerStatsPuller.cpp @@ -14,31 +14,28 @@ * limitations under the License. */ -#define DEBUG false // STOPSHIP if true -#include "Log.h" +#define DEBUG false // STOPSHIP if true +#define LOG_TAG "PowerStatsPuller" #include +#include +#include #include #include "PowerStatsPuller.h" -#include "statslog.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; +using android::hardware::power::stats::V1_0::EnergyData; +using android::hardware::power::stats::V1_0::IPowerStats; +using android::hardware::power::stats::V1_0::RailInfo; +using android::hardware::power::stats::V1_0::Status; namespace android { -namespace os { -namespace statsd { +namespace server { +namespace stats { static sp gPowerStatsHal = nullptr; static std::mutex gPowerStatsHalMutex; @@ -47,7 +44,7 @@ static std::vector gRailInfo; struct PowerStatsPullerDeathRecipient : virtual public hardware::hidl_death_recipient { virtual void serviceDied(uint64_t cookie, - const wp& who) override { + const wp& who) override { // The HAL just died. Reset all handles to HAL services. std::lock_guard lock(gPowerStatsHalMutex); gPowerStatsHal = nullptr; @@ -67,7 +64,7 @@ static bool getPowerStatsHalLocked() { hardware::Return linked = gPowerStatsHal->linkToDeath(gDeathRecipient, 0); if (!linked.isOk()) { ALOGE("Transaction error in linking to power.stats HAL death: %s", - linked.description().c_str()); + linked.description().c_str()); gPowerStatsHal = nullptr; return false; } else if (!linked) { @@ -79,29 +76,22 @@ static bool getPowerStatsHalLocked() { return gPowerStatsHal != nullptr; } -PowerStatsPuller::PowerStatsPuller() : StatsPuller(android::util::ON_DEVICE_POWER_MEASUREMENT) { -} +PowerStatsPuller::PowerStatsPuller() {} -bool PowerStatsPuller::PullInternal(vector>* data) { +status_pull_atom_return_t PowerStatsPuller::Pull(int32_t atomTag, pulled_stats_event_list* data) { std::lock_guard lock(gPowerStatsHalMutex); if (!getPowerStatsHalLocked()) { - return false; + return STATS_PULL_SKIP; } - int64_t wallClockTimestampNs = getWallClockNs(); - int64_t elapsedTimestampNs = getElapsedRealtimeNs(); - - data->clear(); - // Pull getRailInfo if necessary if (gRailInfo.empty()) { bool resultSuccess = true; Return ret = gPowerStatsHal->getRailInfo( - [&resultSuccess](const hidl_vec &list, Status status) { + [&resultSuccess](const hidl_vec& 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]); @@ -110,61 +100,64 @@ bool PowerStatsPuller::PullInternal(vector>* data) { if (!resultSuccess || !ret.isOk()) { ALOGE("power.stats getRailInfo() failed. Description: %s", ret.description().c_str()); gPowerStatsHal = nullptr; - return false; + return STATS_PULL_SKIP; } // 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. gPowerStatsHal = nullptr; - return false; + return STATS_PULL_SKIP; } } // Pull getEnergyData and write the data out const hidl_vec desiredRailIndices; // Empty vector indicates we want all. bool resultSuccess = true; - Return ret = gPowerStatsHal->getEnergyData(desiredRailIndices, - [&data, wallClockTimestampNs, elapsedTimestampNs, &resultSuccess] - (hidl_vec energyDataList, Status status) { - resultSuccess = (status == Status::SUCCESS); - if (!resultSuccess) return; + Return ret = + gPowerStatsHal + ->getEnergyData(desiredRailIndices, + [&data, &resultSuccess](hidl_vec energyDataList, + Status status) { + resultSuccess = (status == Status::SUCCESS); + if (!resultSuccess) return; - for (size_t i = 0; i < energyDataList.size(); i++) { - const EnergyData& energyData = energyDataList[i]; + 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]; + 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(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); + stats_event* event = add_stats_event_to_pull_data(data); + stats_event_set_atom_id(event, + android::util::ON_DEVICE_POWER_MEASUREMENT); + stats_event_write_string8(event, + rail.subsysName.c_str()); + stats_event_write_string8(event, rail.railName.c_str()); + stats_event_write_int64(event, energyData.timestamp); + stats_event_write_int64(event, energyData.energy); + stats_event_build(event); - 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); - } - }); + ALOGV("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 STATS_PULL_SKIP; } - return true; + return STATS_PULL_SUCCESS; } -} // namespace statsd -} // namespace os -} // namespace android +} // namespace stats +} // namespace server +} // namespace android diff --git a/cmds/statsd/src/external/PowerStatsPuller.h b/services/core/jni/stats/PowerStatsPuller.h similarity index 72% rename from cmds/statsd/src/external/PowerStatsPuller.h rename to services/core/jni/stats/PowerStatsPuller.h index 6f15bd68fa946..048dbb933f52b 100644 --- a/cmds/statsd/src/external/PowerStatsPuller.h +++ b/services/core/jni/stats/PowerStatsPuller.h @@ -16,23 +16,22 @@ #pragma once -#include "StatsPuller.h" +#include +#include namespace android { -namespace os { -namespace statsd { +namespace server { +namespace stats { /** * Reads hal for power.stats */ -class PowerStatsPuller : public StatsPuller { +class PowerStatsPuller { public: PowerStatsPuller(); - -private: - bool PullInternal(vector>* data) override; + status_pull_atom_return_t Pull(int32_t atomTag, pulled_stats_event_list* data); }; -} // namespace statsd -} // namespace os -} // namespace android +} // namespace stats +} // namespace server +} // namespace android