Loading services/core/java/com/android/server/powerstats/PowerStatsService.java +23 −3 Original line number Diff line number Diff line Loading @@ -69,6 +69,8 @@ public class PowerStatsService extends SystemService { private BatteryTrigger mBatteryTrigger; @Nullable private TimerTrigger mTimerTrigger; @Nullable private StatsPullAtomCallbackImpl mPullAtomCallback; @VisibleForTesting static class Injector { Loading Loading @@ -119,6 +121,11 @@ public class PowerStatsService extends SystemService { TimerTrigger createTimerTrigger(Context context, PowerStatsLogger powerStatsLogger) { return new TimerTrigger(context, powerStatsLogger, true /* trigger enabled */); } StatsPullAtomCallbackImpl createStatsPullerImpl(Context context, IPowerStatsHALWrapper powerStatsHALWrapper) { return new StatsPullAtomCallbackImpl(context, powerStatsHALWrapper); } } private final class BinderService extends Binder { Loading Loading @@ -156,8 +163,10 @@ public class PowerStatsService extends SystemService { @Override public void onBootPhase(int phase) { if (phase == SystemService.PHASE_BOOT_COMPLETED) { onSystemServiceReady(); if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) { onSystemServicesReady(); } else if (phase == SystemService.PHASE_BOOT_COMPLETED) { onBootCompleted(); } } Loading @@ -170,7 +179,18 @@ public class PowerStatsService extends SystemService { publishBinderService(Context.POWER_STATS_SERVICE, new BinderService()); } private void onSystemServiceReady() { private void onSystemServicesReady() { if (getPowerStatsHal().isInitialized()) { if (DEBUG) Slog.d(TAG, "Starting PowerStatsService statsd pullers"); // Only start statsd pullers if initialization is successful. mPullAtomCallback = mInjector.createStatsPullerImpl(mContext, getPowerStatsHal()); } else { Slog.e(TAG, "Failed to start PowerStatsService statsd pullers"); } } private void onBootCompleted() { if (getPowerStatsHal().isInitialized()) { if (DEBUG) Slog.d(TAG, "Starting PowerStatsService loggers"); Loading services/core/java/com/android/server/powerstats/StatsPullAtomCallbackImpl.java 0 → 100644 +152 −0 Original line number Diff line number Diff line /* * 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. */ package com.android.server.powerstats; import android.app.StatsManager; import android.content.Context; import android.hardware.power.stats.Channel; import android.hardware.power.stats.EnergyMeasurement; import android.hardware.power.stats.PowerEntity; import android.hardware.power.stats.State; import android.hardware.power.stats.StateResidency; import android.hardware.power.stats.StateResidencyResult; import android.util.StatsEvent; import com.android.internal.util.ConcurrentUtils; import com.android.internal.util.FrameworkStatsLog; import com.android.server.powerstats.PowerStatsHALWrapper.IPowerStatsHALWrapper; import java.util.HashMap; import java.util.List; import java.util.Map; /** * StatsPullAtomCallbackImpl is responsible implementing the stats pullers for * SUBSYSTEM_SLEEP_STATE and ON_DEVICE_POWER_MEASUREMENT statsd atoms. */ public class StatsPullAtomCallbackImpl implements StatsManager.StatsPullAtomCallback { private Context mContext; private IPowerStatsHALWrapper mPowerStatsHALWrapper; private Map<Integer, Channel> mChannels = new HashMap(); private Map<Integer, String> mEntityNames = new HashMap(); private Map<Integer, Map<Integer, String>> mStateNames = new HashMap();; @Override public int onPullAtom(int atomTag, List<StatsEvent> data) { switch (atomTag) { case FrameworkStatsLog.SUBSYSTEM_SLEEP_STATE: return pullSubsystemSleepState(atomTag, data); case FrameworkStatsLog.ON_DEVICE_POWER_MEASUREMENT: return pullOnDevicePowerMeasurement(atomTag, data); default: throw new UnsupportedOperationException("Unknown tagId=" + atomTag); } } private void initPullOnDevicePowerMeasurement() { Channel[] channels = mPowerStatsHALWrapper.getEnergyMeterInfo(); if (channels == null) { return; } for (int i = 0; i < channels.length; i++) { final Channel channel = channels[i]; mChannels.put(channel.id, channel); } } private int pullOnDevicePowerMeasurement(int atomTag, List<StatsEvent> events) { EnergyMeasurement[] energyMeasurements = mPowerStatsHALWrapper.readEnergyMeters(new int[0]); if (energyMeasurements == null) { return StatsManager.PULL_SKIP; } for (int i = 0; i < energyMeasurements.length; i++) { // Only report energy measurements that have been accumulated since boot final EnergyMeasurement energyMeasurement = energyMeasurements[i]; if (energyMeasurement.durationMs == energyMeasurement.timestampMs) { events.add(FrameworkStatsLog.buildStatsEvent( atomTag, mChannels.get(energyMeasurement.id).subsystem, mChannels.get(energyMeasurement.id).name, energyMeasurement.durationMs, energyMeasurement.energyUWs)); } } return StatsManager.PULL_SUCCESS; } private void initSubsystemSleepState() { PowerEntity[] entities = mPowerStatsHALWrapper.getPowerEntityInfo(); if (entities == null) { return; } for (int i = 0; i < entities.length; i++) { final PowerEntity entity = entities[i]; Map<Integer, String> states = new HashMap(); for (int j = 0; j < entity.states.length; j++) { final State state = entity.states[j]; states.put(state.id, state.name); } mEntityNames.put(entity.id, entity.name); mStateNames.put(entity.id, states); } } private int pullSubsystemSleepState(int atomTag, List<StatsEvent> events) { StateResidencyResult[] results = mPowerStatsHALWrapper.getStateResidency(new int[0]); if (results == null) { return StatsManager.PULL_SKIP; } for (int i = 0; i < results.length; i++) { final StateResidencyResult result = results[i]; for (int j = 0; j < result.stateResidencyData.length; j++) { final StateResidency stateResidency = result.stateResidencyData[j]; events.add(FrameworkStatsLog.buildStatsEvent( atomTag, mEntityNames.get(result.id), mStateNames.get(result.id).get(stateResidency.id), stateResidency.totalStateEntryCount, stateResidency.totalTimeInStateMs)); } } return StatsManager.PULL_SUCCESS; } public StatsPullAtomCallbackImpl(Context context, IPowerStatsHALWrapper powerStatsHALWrapper) { mContext = context; mPowerStatsHALWrapper = powerStatsHALWrapper; initPullOnDevicePowerMeasurement(); initSubsystemSleepState(); StatsManager manager = mContext.getSystemService(StatsManager.class); manager.setPullAtomCallback( FrameworkStatsLog.SUBSYSTEM_SLEEP_STATE, null, // use default PullAtomMetadata values ConcurrentUtils.DIRECT_EXECUTOR, this); manager.setPullAtomCallback( FrameworkStatsLog.ON_DEVICE_POWER_MEASUREMENT, null, // use default PullAtomMetadata values ConcurrentUtils.DIRECT_EXECUTOR, this); } } services/core/java/com/android/server/stats/pull/StatsPullAtomService.java +0 −3 Original line number Diff line number Diff line Loading @@ -407,8 +407,6 @@ 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. Loading Loading @@ -681,7 +679,6 @@ public class StatsPullAtomService extends SystemService { super.onBootPhase(phase); if (phase == PHASE_SYSTEM_SERVICES_READY) { BackgroundThread.getHandler().post(() -> { nativeInit(); initializePullersState(); registerPullers(); registerEventListeners(); Loading services/core/jni/Android.bp +1 −3 Original line number Diff line number Diff line Loading @@ -25,8 +25,6 @@ cc_library_static { "gnss/GnssMeasurement.cpp", "gnss/GnssMeasurementCallback.cpp", "gnss/Utils.cpp", "stats/PowerStatsPuller.cpp", "stats/SubsystemSleepStatePuller.cpp", "com_android_server_adb_AdbDebuggingManager.cpp", "com_android_server_am_BatteryStatsService.cpp", "com_android_server_biometrics_SurfaceToNativeHandleConverter.cpp", Loading @@ -45,7 +43,6 @@ cc_library_static { "com_android_server_SerialService.cpp", "com_android_server_soundtrigger_middleware_AudioSessionProviderImpl.cpp", "com_android_server_soundtrigger_middleware_ExternalCaptureStateTracker.cpp", "com_android_server_stats_pull_StatsPullAtomService.cpp", "com_android_server_storage_AppFuseBridge.cpp", "com_android_server_SystemServer.cpp", "com_android_server_tv_TvUinputBridge.cpp", Loading Loading @@ -152,6 +149,7 @@ cc_defaults { "android.hardware.power@1.1", "android.hardware.power-cpp", "android.hardware.power.stats@1.0", "android.hardware.power.stats-ndk_platform", "android.hardware.thermal@1.0", "android.hardware.tv.input@1.0", "android.hardware.vibrator-unstable-cpp", Loading services/core/jni/com_android_server_stats_pull_StatsPullAtomService.cppdeleted 100644 → 0 +0 −71 Original line number Diff line number Diff line /* * 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 <jni.h> #include <log/log.h> #include <nativehelper/JNIHelp.h> #include <stats_event.h> #include <stats_pull_atom_callback.h> #include <statslog.h> #include "stats/PowerStatsPuller.h" #include "stats/SubsystemSleepStatePuller.h" namespace android { static server::stats::PowerStatsPuller gPowerStatsPuller; static server::stats::SubsystemSleepStatePuller gSubsystemSleepStatePuller; static AStatsManager_PullAtomCallbackReturn onDevicePowerMeasurementCallback(int32_t atom_tag, AStatsEventList* data, void* cookie) { return gPowerStatsPuller.Pull(atom_tag, data); } static AStatsManager_PullAtomCallbackReturn subsystemSleepStateCallback(int32_t atom_tag, AStatsEventList* data, void* cookie) { return gSubsystemSleepStatePuller.Pull(atom_tag, data); } static void nativeInit(JNIEnv* env, jobject javaObject) { // on device power measurement gPowerStatsPuller = server::stats::PowerStatsPuller(); AStatsManager_setPullAtomCallback(android::util::ON_DEVICE_POWER_MEASUREMENT, /* metadata= */ nullptr, onDevicePowerMeasurementCallback, /* cookie= */ nullptr); // subsystem sleep state gSubsystemSleepStatePuller = server::stats::SubsystemSleepStatePuller(); AStatsManager_setPullAtomCallback(android::util::SUBSYSTEM_SLEEP_STATE, /* metadata= */ nullptr, subsystemSleepStateCallback, /* 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 Loading
services/core/java/com/android/server/powerstats/PowerStatsService.java +23 −3 Original line number Diff line number Diff line Loading @@ -69,6 +69,8 @@ public class PowerStatsService extends SystemService { private BatteryTrigger mBatteryTrigger; @Nullable private TimerTrigger mTimerTrigger; @Nullable private StatsPullAtomCallbackImpl mPullAtomCallback; @VisibleForTesting static class Injector { Loading Loading @@ -119,6 +121,11 @@ public class PowerStatsService extends SystemService { TimerTrigger createTimerTrigger(Context context, PowerStatsLogger powerStatsLogger) { return new TimerTrigger(context, powerStatsLogger, true /* trigger enabled */); } StatsPullAtomCallbackImpl createStatsPullerImpl(Context context, IPowerStatsHALWrapper powerStatsHALWrapper) { return new StatsPullAtomCallbackImpl(context, powerStatsHALWrapper); } } private final class BinderService extends Binder { Loading Loading @@ -156,8 +163,10 @@ public class PowerStatsService extends SystemService { @Override public void onBootPhase(int phase) { if (phase == SystemService.PHASE_BOOT_COMPLETED) { onSystemServiceReady(); if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) { onSystemServicesReady(); } else if (phase == SystemService.PHASE_BOOT_COMPLETED) { onBootCompleted(); } } Loading @@ -170,7 +179,18 @@ public class PowerStatsService extends SystemService { publishBinderService(Context.POWER_STATS_SERVICE, new BinderService()); } private void onSystemServiceReady() { private void onSystemServicesReady() { if (getPowerStatsHal().isInitialized()) { if (DEBUG) Slog.d(TAG, "Starting PowerStatsService statsd pullers"); // Only start statsd pullers if initialization is successful. mPullAtomCallback = mInjector.createStatsPullerImpl(mContext, getPowerStatsHal()); } else { Slog.e(TAG, "Failed to start PowerStatsService statsd pullers"); } } private void onBootCompleted() { if (getPowerStatsHal().isInitialized()) { if (DEBUG) Slog.d(TAG, "Starting PowerStatsService loggers"); Loading
services/core/java/com/android/server/powerstats/StatsPullAtomCallbackImpl.java 0 → 100644 +152 −0 Original line number Diff line number Diff line /* * 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. */ package com.android.server.powerstats; import android.app.StatsManager; import android.content.Context; import android.hardware.power.stats.Channel; import android.hardware.power.stats.EnergyMeasurement; import android.hardware.power.stats.PowerEntity; import android.hardware.power.stats.State; import android.hardware.power.stats.StateResidency; import android.hardware.power.stats.StateResidencyResult; import android.util.StatsEvent; import com.android.internal.util.ConcurrentUtils; import com.android.internal.util.FrameworkStatsLog; import com.android.server.powerstats.PowerStatsHALWrapper.IPowerStatsHALWrapper; import java.util.HashMap; import java.util.List; import java.util.Map; /** * StatsPullAtomCallbackImpl is responsible implementing the stats pullers for * SUBSYSTEM_SLEEP_STATE and ON_DEVICE_POWER_MEASUREMENT statsd atoms. */ public class StatsPullAtomCallbackImpl implements StatsManager.StatsPullAtomCallback { private Context mContext; private IPowerStatsHALWrapper mPowerStatsHALWrapper; private Map<Integer, Channel> mChannels = new HashMap(); private Map<Integer, String> mEntityNames = new HashMap(); private Map<Integer, Map<Integer, String>> mStateNames = new HashMap();; @Override public int onPullAtom(int atomTag, List<StatsEvent> data) { switch (atomTag) { case FrameworkStatsLog.SUBSYSTEM_SLEEP_STATE: return pullSubsystemSleepState(atomTag, data); case FrameworkStatsLog.ON_DEVICE_POWER_MEASUREMENT: return pullOnDevicePowerMeasurement(atomTag, data); default: throw new UnsupportedOperationException("Unknown tagId=" + atomTag); } } private void initPullOnDevicePowerMeasurement() { Channel[] channels = mPowerStatsHALWrapper.getEnergyMeterInfo(); if (channels == null) { return; } for (int i = 0; i < channels.length; i++) { final Channel channel = channels[i]; mChannels.put(channel.id, channel); } } private int pullOnDevicePowerMeasurement(int atomTag, List<StatsEvent> events) { EnergyMeasurement[] energyMeasurements = mPowerStatsHALWrapper.readEnergyMeters(new int[0]); if (energyMeasurements == null) { return StatsManager.PULL_SKIP; } for (int i = 0; i < energyMeasurements.length; i++) { // Only report energy measurements that have been accumulated since boot final EnergyMeasurement energyMeasurement = energyMeasurements[i]; if (energyMeasurement.durationMs == energyMeasurement.timestampMs) { events.add(FrameworkStatsLog.buildStatsEvent( atomTag, mChannels.get(energyMeasurement.id).subsystem, mChannels.get(energyMeasurement.id).name, energyMeasurement.durationMs, energyMeasurement.energyUWs)); } } return StatsManager.PULL_SUCCESS; } private void initSubsystemSleepState() { PowerEntity[] entities = mPowerStatsHALWrapper.getPowerEntityInfo(); if (entities == null) { return; } for (int i = 0; i < entities.length; i++) { final PowerEntity entity = entities[i]; Map<Integer, String> states = new HashMap(); for (int j = 0; j < entity.states.length; j++) { final State state = entity.states[j]; states.put(state.id, state.name); } mEntityNames.put(entity.id, entity.name); mStateNames.put(entity.id, states); } } private int pullSubsystemSleepState(int atomTag, List<StatsEvent> events) { StateResidencyResult[] results = mPowerStatsHALWrapper.getStateResidency(new int[0]); if (results == null) { return StatsManager.PULL_SKIP; } for (int i = 0; i < results.length; i++) { final StateResidencyResult result = results[i]; for (int j = 0; j < result.stateResidencyData.length; j++) { final StateResidency stateResidency = result.stateResidencyData[j]; events.add(FrameworkStatsLog.buildStatsEvent( atomTag, mEntityNames.get(result.id), mStateNames.get(result.id).get(stateResidency.id), stateResidency.totalStateEntryCount, stateResidency.totalTimeInStateMs)); } } return StatsManager.PULL_SUCCESS; } public StatsPullAtomCallbackImpl(Context context, IPowerStatsHALWrapper powerStatsHALWrapper) { mContext = context; mPowerStatsHALWrapper = powerStatsHALWrapper; initPullOnDevicePowerMeasurement(); initSubsystemSleepState(); StatsManager manager = mContext.getSystemService(StatsManager.class); manager.setPullAtomCallback( FrameworkStatsLog.SUBSYSTEM_SLEEP_STATE, null, // use default PullAtomMetadata values ConcurrentUtils.DIRECT_EXECUTOR, this); manager.setPullAtomCallback( FrameworkStatsLog.ON_DEVICE_POWER_MEASUREMENT, null, // use default PullAtomMetadata values ConcurrentUtils.DIRECT_EXECUTOR, this); } }
services/core/java/com/android/server/stats/pull/StatsPullAtomService.java +0 −3 Original line number Diff line number Diff line Loading @@ -407,8 +407,6 @@ 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. Loading Loading @@ -681,7 +679,6 @@ public class StatsPullAtomService extends SystemService { super.onBootPhase(phase); if (phase == PHASE_SYSTEM_SERVICES_READY) { BackgroundThread.getHandler().post(() -> { nativeInit(); initializePullersState(); registerPullers(); registerEventListeners(); Loading
services/core/jni/Android.bp +1 −3 Original line number Diff line number Diff line Loading @@ -25,8 +25,6 @@ cc_library_static { "gnss/GnssMeasurement.cpp", "gnss/GnssMeasurementCallback.cpp", "gnss/Utils.cpp", "stats/PowerStatsPuller.cpp", "stats/SubsystemSleepStatePuller.cpp", "com_android_server_adb_AdbDebuggingManager.cpp", "com_android_server_am_BatteryStatsService.cpp", "com_android_server_biometrics_SurfaceToNativeHandleConverter.cpp", Loading @@ -45,7 +43,6 @@ cc_library_static { "com_android_server_SerialService.cpp", "com_android_server_soundtrigger_middleware_AudioSessionProviderImpl.cpp", "com_android_server_soundtrigger_middleware_ExternalCaptureStateTracker.cpp", "com_android_server_stats_pull_StatsPullAtomService.cpp", "com_android_server_storage_AppFuseBridge.cpp", "com_android_server_SystemServer.cpp", "com_android_server_tv_TvUinputBridge.cpp", Loading Loading @@ -152,6 +149,7 @@ cc_defaults { "android.hardware.power@1.1", "android.hardware.power-cpp", "android.hardware.power.stats@1.0", "android.hardware.power.stats-ndk_platform", "android.hardware.thermal@1.0", "android.hardware.tv.input@1.0", "android.hardware.vibrator-unstable-cpp", Loading
services/core/jni/com_android_server_stats_pull_StatsPullAtomService.cppdeleted 100644 → 0 +0 −71 Original line number Diff line number Diff line /* * 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 <jni.h> #include <log/log.h> #include <nativehelper/JNIHelp.h> #include <stats_event.h> #include <stats_pull_atom_callback.h> #include <statslog.h> #include "stats/PowerStatsPuller.h" #include "stats/SubsystemSleepStatePuller.h" namespace android { static server::stats::PowerStatsPuller gPowerStatsPuller; static server::stats::SubsystemSleepStatePuller gSubsystemSleepStatePuller; static AStatsManager_PullAtomCallbackReturn onDevicePowerMeasurementCallback(int32_t atom_tag, AStatsEventList* data, void* cookie) { return gPowerStatsPuller.Pull(atom_tag, data); } static AStatsManager_PullAtomCallbackReturn subsystemSleepStateCallback(int32_t atom_tag, AStatsEventList* data, void* cookie) { return gSubsystemSleepStatePuller.Pull(atom_tag, data); } static void nativeInit(JNIEnv* env, jobject javaObject) { // on device power measurement gPowerStatsPuller = server::stats::PowerStatsPuller(); AStatsManager_setPullAtomCallback(android::util::ON_DEVICE_POWER_MEASUREMENT, /* metadata= */ nullptr, onDevicePowerMeasurementCallback, /* cookie= */ nullptr); // subsystem sleep state gSubsystemSleepStatePuller = server::stats::SubsystemSleepStatePuller(); AStatsManager_setPullAtomCallback(android::util::SUBSYSTEM_SLEEP_STATE, /* metadata= */ nullptr, subsystemSleepStateCallback, /* 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