Loading core/proto/android/server/powerstatsservice.proto +11 −0 Original line number Diff line number Diff line Loading @@ -191,6 +191,14 @@ message EnergyConsumerProto { optional string name = 4; } message EnergyConsumerAttributionProto { /** Android ID / Linux UID, the accumulated energy should be attributed to. */ optional int32 uid = 1; /** Accumulated energy since boot in microwatt-seconds (uWs) for this AID. */ optional int64 energy_uws = 2; } /** * Energy consumer result: * An estimate of energy consumption since boot for the subsystem identified Loading @@ -205,6 +213,9 @@ message EnergyConsumerResultProto { /** Accumulated energy since device boot in microwatt-seconds (uWs) */ optional int64 energy_uws = 3; /** Optional attribution per UID for this EnergyConsumer. */ repeated EnergyConsumerAttributionProto attribution = 4; } /** Loading services/core/java/com/android/server/powerstats/PowerStatsLogger.java +21 −9 Original line number Diff line number Diff line Loading @@ -53,8 +53,9 @@ import java.io.IOException; public final class PowerStatsLogger extends Handler { private static final String TAG = PowerStatsLogger.class.getSimpleName(); private static final boolean DEBUG = false; protected static final int MSG_LOG_TO_DATA_STORAGE_TIMER = 0; protected static final int MSG_LOG_TO_DATA_STORAGE_BATTERY_DROP = 1; protected static final int MSG_LOG_TO_DATA_STORAGE_BATTERY_DROP = 0; protected static final int MSG_LOG_TO_DATA_STORAGE_LOW_FREQUENCY = 1; protected static final int MSG_LOG_TO_DATA_STORAGE_HIGH_FREQUENCY = 2; private final PowerStatsDataStorage mPowerStatsMeterStorage; private final PowerStatsDataStorage mPowerStatsModelStorage; Loading @@ -64,8 +65,8 @@ public final class PowerStatsLogger extends Handler { @Override public void handleMessage(Message msg) { switch (msg.what) { case MSG_LOG_TO_DATA_STORAGE_TIMER: if (DEBUG) Slog.d(TAG, "Logging to data storage on timer"); case MSG_LOG_TO_DATA_STORAGE_HIGH_FREQUENCY: if (DEBUG) Slog.d(TAG, "Logging to data storage on high frequency timer"); // Log power meter data. EnergyMeasurement[] energyMeasurements = Loading @@ -74,12 +75,23 @@ public final class PowerStatsLogger extends Handler { EnergyMeasurementUtils.getProtoBytes(energyMeasurements)); if (DEBUG) EnergyMeasurementUtils.print(energyMeasurements); // Log power model data. EnergyConsumerResult[] energyConsumerResults = // Log power model data without attribution data. EnergyConsumerResult[] ecrNoAttribution = mPowerStatsHALWrapper.getEnergyConsumed(new int[0]); mPowerStatsModelStorage.write( EnergyConsumerResultUtils.getProtoBytes(energyConsumerResults)); if (DEBUG) EnergyConsumerResultUtils.print(energyConsumerResults); EnergyConsumerResultUtils.getProtoBytes(ecrNoAttribution, false)); if (DEBUG) EnergyConsumerResultUtils.print(ecrNoAttribution); break; case MSG_LOG_TO_DATA_STORAGE_LOW_FREQUENCY: if (DEBUG) Slog.d(TAG, "Logging to data storage on low frequency timer"); // Log power model data with attribution data. EnergyConsumerResult[] ecrAttribution = mPowerStatsHALWrapper.getEnergyConsumed(new int[0]); mPowerStatsModelStorage.write( EnergyConsumerResultUtils.getProtoBytes(ecrAttribution, true)); if (DEBUG) EnergyConsumerResultUtils.print(ecrAttribution); break; case MSG_LOG_TO_DATA_STORAGE_BATTERY_DROP: Loading Loading @@ -163,7 +175,7 @@ public final class PowerStatsLogger extends Handler { // deserialize, then re-serialize. This is computationally inefficient. EnergyConsumerResult[] energyConsumerResult = EnergyConsumerResultUtils.unpackProtoMessage(data); EnergyConsumerResultUtils.packProtoMessage(energyConsumerResult, pos); EnergyConsumerResultUtils.packProtoMessage(energyConsumerResult, pos, true); if (DEBUG) EnergyConsumerResultUtils.print(energyConsumerResult); } catch (IOException e) { Slog.e(TAG, "Failed to write energy model data to incident report."); Loading services/core/java/com/android/server/powerstats/ProtoStreamUtils.java +80 −8 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.server.powerstats; import android.hardware.power.stats.Channel; import android.hardware.power.stats.EnergyConsumer; import android.hardware.power.stats.EnergyConsumerAttribution; import android.hardware.power.stats.EnergyConsumerResult; import android.hardware.power.stats.EnergyMeasurement; import android.hardware.power.stats.PowerEntity; Loading Loading @@ -433,23 +434,40 @@ public class ProtoStreamUtils { } static class EnergyConsumerResultUtils { public static byte[] getProtoBytes(EnergyConsumerResult[] energyConsumerResult) { public static byte[] getProtoBytes(EnergyConsumerResult[] energyConsumerResult, boolean includeAttribution) { ProtoOutputStream pos = new ProtoOutputStream(); packProtoMessage(energyConsumerResult, pos); packProtoMessage(energyConsumerResult, pos, includeAttribution); return pos.getBytes(); } public static void packProtoMessage(EnergyConsumerResult[] energyConsumerResult, ProtoOutputStream pos) { ProtoOutputStream pos, boolean includeAttribution) { if (energyConsumerResult == null) return; for (int i = 0; i < energyConsumerResult.length; i++) { long token = pos.start(PowerStatsServiceModelProto.ENERGY_CONSUMER_RESULT); long ecrToken = pos.start(PowerStatsServiceModelProto.ENERGY_CONSUMER_RESULT); pos.write(EnergyConsumerResultProto.ID, energyConsumerResult[i].id); pos.write(EnergyConsumerResultProto.TIMESTAMP_MS, energyConsumerResult[i].timestampMs); pos.write(EnergyConsumerResultProto.ENERGY_UWS, energyConsumerResult[i].energyUWs); pos.end(token); if (includeAttribution) { final int attributionLength = energyConsumerResult[i].attribution.length; for (int j = 0; j < attributionLength; j++) { final EnergyConsumerAttribution energyConsumerAttribution = energyConsumerResult[i].attribution[j]; final long ecaToken = pos.start(EnergyConsumerResultProto.ATTRIBUTION); pos.write(EnergyConsumerAttributionProto.UID, energyConsumerAttribution.uid); pos.write(EnergyConsumerAttributionProto.ENERGY_UWS, energyConsumerAttribution.energyUWs); pos.end(ecaToken); } } pos.end(ecrToken); } } Loading Loading @@ -480,9 +498,45 @@ public class ProtoStreamUtils { } } private static EnergyConsumerAttribution unpackEnergyConsumerAttributionProto( ProtoInputStream pis) throws IOException { final EnergyConsumerAttribution energyConsumerAttribution = new EnergyConsumerAttribution(); while (true) { try { switch (pis.nextField()) { case (int) EnergyConsumerAttributionProto.UID: energyConsumerAttribution.uid = pis.readInt(EnergyConsumerAttributionProto.UID); break; case (int) EnergyConsumerAttributionProto.ENERGY_UWS: energyConsumerAttribution.energyUWs = pis.readLong(EnergyConsumerAttributionProto.ENERGY_UWS); break; case ProtoInputStream.NO_MORE_FIELDS: return energyConsumerAttribution; default: Slog.e(TAG, "Unhandled field in EnergyConsumerAttributionProto: " + ProtoUtils.currentFieldToString(pis)); break; } } catch (WireTypeMismatchException wtme) { Slog.e(TAG, "Wire Type mismatch in EnergyConsumerAttributionProto: " + ProtoUtils.currentFieldToString(pis)); } } } private static EnergyConsumerResult unpackEnergyConsumerResultProto(ProtoInputStream pis) throws IOException { EnergyConsumerResult energyConsumerResult = new EnergyConsumerResult(); final List<EnergyConsumerAttribution> energyConsumerAttributionList = new ArrayList<EnergyConsumerAttribution>(); while (true) { try { Loading @@ -501,7 +555,18 @@ public class ProtoStreamUtils { pis.readLong(EnergyConsumerResultProto.ENERGY_UWS); break; case (int) EnergyConsumerResultProto.ATTRIBUTION: final long token = pis.start(EnergyConsumerResultProto.ATTRIBUTION); energyConsumerAttributionList.add( unpackEnergyConsumerAttributionProto(pis)); pis.end(token); break; case ProtoInputStream.NO_MORE_FIELDS: energyConsumerResult.attribution = energyConsumerAttributionList.toArray( new EnergyConsumerAttribution[ energyConsumerAttributionList.size()]); return energyConsumerResult; default: Loading @@ -520,9 +585,16 @@ public class ProtoStreamUtils { if (energyConsumerResult == null) return; for (int i = 0; i < energyConsumerResult.length; i++) { Slog.d(TAG, "EnergyConsumerId: " + energyConsumerResult[i].id + ", Timestamp (ms): " + energyConsumerResult[i].timestampMs + ", Energy (uWs): " + energyConsumerResult[i].energyUWs); final EnergyConsumerResult result = energyConsumerResult[i]; Slog.d(TAG, "EnergyConsumerId: " + result.id + ", Timestamp (ms): " + result.timestampMs + ", Energy (uWs): " + result.energyUWs); final int attributionLength = result.attribution.length; for (int j = 0; j < attributionLength; j++) { final EnergyConsumerAttribution attribution = result.attribution[j]; Slog.d(TAG, " UID: " + attribution.uid + " Energy (uWs): " + attribution.energyUWs); } } } } Loading services/core/java/com/android/server/powerstats/TimerTrigger.java +20 −7 Original line number Diff line number Diff line Loading @@ -29,18 +29,30 @@ public final class TimerTrigger extends PowerStatsLogTrigger { private static final String TAG = TimerTrigger.class.getSimpleName(); private static final boolean DEBUG = false; // TODO(b/166689029): Make configurable through global settings. private static final long LOG_PERIOD_MS = 120 * 1000; private static final long LOG_PERIOD_MS_LOW_FREQUENCY = 60 * 60 * 1000; // 1 hour private static final long LOG_PERIOD_MS_HIGH_FREQUENCY = 2 * 60 * 1000; // 2 minutes private final Handler mHandler; private Runnable mLogData = new Runnable() { private Runnable mLogDataLowFrequency = new Runnable() { @Override public void run() { // Do not wake the device for these messages. Opportunistically log rail data every // LOG_PERIOD_MS. mHandler.postDelayed(mLogData, LOG_PERIOD_MS); if (DEBUG) Slog.d(TAG, "Received delayed message. Log rail data"); logPowerStatsData(PowerStatsLogger.MSG_LOG_TO_DATA_STORAGE_TIMER); // LOG_PERIOD_MS_LOW_FREQUENCY. mHandler.postDelayed(mLogDataLowFrequency, LOG_PERIOD_MS_LOW_FREQUENCY); if (DEBUG) Slog.d(TAG, "Received delayed message. Log rail data low frequency"); logPowerStatsData(PowerStatsLogger.MSG_LOG_TO_DATA_STORAGE_LOW_FREQUENCY); } }; private Runnable mLogDataHighFrequency = new Runnable() { @Override public void run() { // Do not wake the device for these messages. Opportunistically log rail data every // LOG_PERIOD_MS_HIGH_FREQUENCY. mHandler.postDelayed(mLogDataHighFrequency, LOG_PERIOD_MS_HIGH_FREQUENCY); if (DEBUG) Slog.d(TAG, "Received delayed message. Log rail data high frequency"); logPowerStatsData(PowerStatsLogger.MSG_LOG_TO_DATA_STORAGE_HIGH_FREQUENCY); } }; Loading @@ -50,7 +62,8 @@ public final class TimerTrigger extends PowerStatsLogTrigger { mHandler = mContext.getMainThreadHandler(); if (triggerEnabled) { mLogData.run(); mLogDataLowFrequency.run(); mLogDataHighFrequency.run(); } } } services/tests/servicestests/src/com/android/server/powerstats/PowerStatsServiceTest.java +17 −2 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import static org.junit.Assert.fail; import android.content.Context; import android.hardware.power.stats.Channel; import android.hardware.power.stats.EnergyConsumer; import android.hardware.power.stats.EnergyConsumerAttribution; import android.hardware.power.stats.EnergyConsumerResult; import android.hardware.power.stats.EnergyMeasurement; import android.hardware.power.stats.PowerEntity; Loading Loading @@ -73,6 +74,7 @@ public class PowerStatsServiceTest { private static final String ENERGY_CONSUMER_NAME = "energyconsumer"; private static final int ENERGY_METER_COUNT = 8; private static final int ENERGY_CONSUMER_COUNT = 2; private static final int ENERGY_CONSUMER_ATTRIBUTION_COUNT = 5; private static final int POWER_ENTITY_COUNT = 3; private static final int STATE_INFO_COUNT = 5; private static final int STATE_RESIDENCY_COUNT = 4; Loading Loading @@ -204,6 +206,13 @@ public class PowerStatsServiceTest { energyConsumedList[i].id = i; energyConsumedList[i].timestampMs = i; energyConsumedList[i].energyUWs = i; energyConsumedList[i].attribution = new EnergyConsumerAttribution[ENERGY_CONSUMER_ATTRIBUTION_COUNT]; for (int j = 0; j < energyConsumedList[i].attribution.length; j++) { energyConsumedList[i].attribution[j] = new EnergyConsumerAttribution(); energyConsumedList[i].attribution[j].uid = j; energyConsumedList[i].attribution[j].energyUWs = j; } } return energyConsumedList; } Loading Loading @@ -250,7 +259,7 @@ public class PowerStatsServiceTest { mService.onBootPhase(SystemService.PHASE_BOOT_COMPLETED); // Write data to on-device storage. mTimerTrigger.logPowerStatsData(PowerStatsLogger.MSG_LOG_TO_DATA_STORAGE_TIMER); mTimerTrigger.logPowerStatsData(PowerStatsLogger.MSG_LOG_TO_DATA_STORAGE_HIGH_FREQUENCY); // The above call puts a message on a handler. Wait for // it to be processed. Loading Loading @@ -293,7 +302,7 @@ public class PowerStatsServiceTest { mService.onBootPhase(SystemService.PHASE_BOOT_COMPLETED); // Write data to on-device storage. mTimerTrigger.logPowerStatsData(PowerStatsLogger.MSG_LOG_TO_DATA_STORAGE_TIMER); mTimerTrigger.logPowerStatsData(PowerStatsLogger.MSG_LOG_TO_DATA_STORAGE_LOW_FREQUENCY); // The above call puts a message on a handler. Wait for // it to be processed. Loading Loading @@ -324,6 +333,12 @@ public class PowerStatsServiceTest { assertTrue(pssProto.energyConsumerResult[i].id == i); assertTrue(pssProto.energyConsumerResult[i].timestampMs == i); assertTrue(pssProto.energyConsumerResult[i].energyUws == i); assertTrue(pssProto.energyConsumerResult[i].attribution.length == ENERGY_CONSUMER_ATTRIBUTION_COUNT); for (int j = 0; j < pssProto.energyConsumerResult[i].attribution.length; j++) { assertTrue(pssProto.energyConsumerResult[i].attribution[j].uid == j); assertTrue(pssProto.energyConsumerResult[i].attribution[j].energyUws == j); } } } Loading Loading
core/proto/android/server/powerstatsservice.proto +11 −0 Original line number Diff line number Diff line Loading @@ -191,6 +191,14 @@ message EnergyConsumerProto { optional string name = 4; } message EnergyConsumerAttributionProto { /** Android ID / Linux UID, the accumulated energy should be attributed to. */ optional int32 uid = 1; /** Accumulated energy since boot in microwatt-seconds (uWs) for this AID. */ optional int64 energy_uws = 2; } /** * Energy consumer result: * An estimate of energy consumption since boot for the subsystem identified Loading @@ -205,6 +213,9 @@ message EnergyConsumerResultProto { /** Accumulated energy since device boot in microwatt-seconds (uWs) */ optional int64 energy_uws = 3; /** Optional attribution per UID for this EnergyConsumer. */ repeated EnergyConsumerAttributionProto attribution = 4; } /** Loading
services/core/java/com/android/server/powerstats/PowerStatsLogger.java +21 −9 Original line number Diff line number Diff line Loading @@ -53,8 +53,9 @@ import java.io.IOException; public final class PowerStatsLogger extends Handler { private static final String TAG = PowerStatsLogger.class.getSimpleName(); private static final boolean DEBUG = false; protected static final int MSG_LOG_TO_DATA_STORAGE_TIMER = 0; protected static final int MSG_LOG_TO_DATA_STORAGE_BATTERY_DROP = 1; protected static final int MSG_LOG_TO_DATA_STORAGE_BATTERY_DROP = 0; protected static final int MSG_LOG_TO_DATA_STORAGE_LOW_FREQUENCY = 1; protected static final int MSG_LOG_TO_DATA_STORAGE_HIGH_FREQUENCY = 2; private final PowerStatsDataStorage mPowerStatsMeterStorage; private final PowerStatsDataStorage mPowerStatsModelStorage; Loading @@ -64,8 +65,8 @@ public final class PowerStatsLogger extends Handler { @Override public void handleMessage(Message msg) { switch (msg.what) { case MSG_LOG_TO_DATA_STORAGE_TIMER: if (DEBUG) Slog.d(TAG, "Logging to data storage on timer"); case MSG_LOG_TO_DATA_STORAGE_HIGH_FREQUENCY: if (DEBUG) Slog.d(TAG, "Logging to data storage on high frequency timer"); // Log power meter data. EnergyMeasurement[] energyMeasurements = Loading @@ -74,12 +75,23 @@ public final class PowerStatsLogger extends Handler { EnergyMeasurementUtils.getProtoBytes(energyMeasurements)); if (DEBUG) EnergyMeasurementUtils.print(energyMeasurements); // Log power model data. EnergyConsumerResult[] energyConsumerResults = // Log power model data without attribution data. EnergyConsumerResult[] ecrNoAttribution = mPowerStatsHALWrapper.getEnergyConsumed(new int[0]); mPowerStatsModelStorage.write( EnergyConsumerResultUtils.getProtoBytes(energyConsumerResults)); if (DEBUG) EnergyConsumerResultUtils.print(energyConsumerResults); EnergyConsumerResultUtils.getProtoBytes(ecrNoAttribution, false)); if (DEBUG) EnergyConsumerResultUtils.print(ecrNoAttribution); break; case MSG_LOG_TO_DATA_STORAGE_LOW_FREQUENCY: if (DEBUG) Slog.d(TAG, "Logging to data storage on low frequency timer"); // Log power model data with attribution data. EnergyConsumerResult[] ecrAttribution = mPowerStatsHALWrapper.getEnergyConsumed(new int[0]); mPowerStatsModelStorage.write( EnergyConsumerResultUtils.getProtoBytes(ecrAttribution, true)); if (DEBUG) EnergyConsumerResultUtils.print(ecrAttribution); break; case MSG_LOG_TO_DATA_STORAGE_BATTERY_DROP: Loading Loading @@ -163,7 +175,7 @@ public final class PowerStatsLogger extends Handler { // deserialize, then re-serialize. This is computationally inefficient. EnergyConsumerResult[] energyConsumerResult = EnergyConsumerResultUtils.unpackProtoMessage(data); EnergyConsumerResultUtils.packProtoMessage(energyConsumerResult, pos); EnergyConsumerResultUtils.packProtoMessage(energyConsumerResult, pos, true); if (DEBUG) EnergyConsumerResultUtils.print(energyConsumerResult); } catch (IOException e) { Slog.e(TAG, "Failed to write energy model data to incident report."); Loading
services/core/java/com/android/server/powerstats/ProtoStreamUtils.java +80 −8 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.server.powerstats; import android.hardware.power.stats.Channel; import android.hardware.power.stats.EnergyConsumer; import android.hardware.power.stats.EnergyConsumerAttribution; import android.hardware.power.stats.EnergyConsumerResult; import android.hardware.power.stats.EnergyMeasurement; import android.hardware.power.stats.PowerEntity; Loading Loading @@ -433,23 +434,40 @@ public class ProtoStreamUtils { } static class EnergyConsumerResultUtils { public static byte[] getProtoBytes(EnergyConsumerResult[] energyConsumerResult) { public static byte[] getProtoBytes(EnergyConsumerResult[] energyConsumerResult, boolean includeAttribution) { ProtoOutputStream pos = new ProtoOutputStream(); packProtoMessage(energyConsumerResult, pos); packProtoMessage(energyConsumerResult, pos, includeAttribution); return pos.getBytes(); } public static void packProtoMessage(EnergyConsumerResult[] energyConsumerResult, ProtoOutputStream pos) { ProtoOutputStream pos, boolean includeAttribution) { if (energyConsumerResult == null) return; for (int i = 0; i < energyConsumerResult.length; i++) { long token = pos.start(PowerStatsServiceModelProto.ENERGY_CONSUMER_RESULT); long ecrToken = pos.start(PowerStatsServiceModelProto.ENERGY_CONSUMER_RESULT); pos.write(EnergyConsumerResultProto.ID, energyConsumerResult[i].id); pos.write(EnergyConsumerResultProto.TIMESTAMP_MS, energyConsumerResult[i].timestampMs); pos.write(EnergyConsumerResultProto.ENERGY_UWS, energyConsumerResult[i].energyUWs); pos.end(token); if (includeAttribution) { final int attributionLength = energyConsumerResult[i].attribution.length; for (int j = 0; j < attributionLength; j++) { final EnergyConsumerAttribution energyConsumerAttribution = energyConsumerResult[i].attribution[j]; final long ecaToken = pos.start(EnergyConsumerResultProto.ATTRIBUTION); pos.write(EnergyConsumerAttributionProto.UID, energyConsumerAttribution.uid); pos.write(EnergyConsumerAttributionProto.ENERGY_UWS, energyConsumerAttribution.energyUWs); pos.end(ecaToken); } } pos.end(ecrToken); } } Loading Loading @@ -480,9 +498,45 @@ public class ProtoStreamUtils { } } private static EnergyConsumerAttribution unpackEnergyConsumerAttributionProto( ProtoInputStream pis) throws IOException { final EnergyConsumerAttribution energyConsumerAttribution = new EnergyConsumerAttribution(); while (true) { try { switch (pis.nextField()) { case (int) EnergyConsumerAttributionProto.UID: energyConsumerAttribution.uid = pis.readInt(EnergyConsumerAttributionProto.UID); break; case (int) EnergyConsumerAttributionProto.ENERGY_UWS: energyConsumerAttribution.energyUWs = pis.readLong(EnergyConsumerAttributionProto.ENERGY_UWS); break; case ProtoInputStream.NO_MORE_FIELDS: return energyConsumerAttribution; default: Slog.e(TAG, "Unhandled field in EnergyConsumerAttributionProto: " + ProtoUtils.currentFieldToString(pis)); break; } } catch (WireTypeMismatchException wtme) { Slog.e(TAG, "Wire Type mismatch in EnergyConsumerAttributionProto: " + ProtoUtils.currentFieldToString(pis)); } } } private static EnergyConsumerResult unpackEnergyConsumerResultProto(ProtoInputStream pis) throws IOException { EnergyConsumerResult energyConsumerResult = new EnergyConsumerResult(); final List<EnergyConsumerAttribution> energyConsumerAttributionList = new ArrayList<EnergyConsumerAttribution>(); while (true) { try { Loading @@ -501,7 +555,18 @@ public class ProtoStreamUtils { pis.readLong(EnergyConsumerResultProto.ENERGY_UWS); break; case (int) EnergyConsumerResultProto.ATTRIBUTION: final long token = pis.start(EnergyConsumerResultProto.ATTRIBUTION); energyConsumerAttributionList.add( unpackEnergyConsumerAttributionProto(pis)); pis.end(token); break; case ProtoInputStream.NO_MORE_FIELDS: energyConsumerResult.attribution = energyConsumerAttributionList.toArray( new EnergyConsumerAttribution[ energyConsumerAttributionList.size()]); return energyConsumerResult; default: Loading @@ -520,9 +585,16 @@ public class ProtoStreamUtils { if (energyConsumerResult == null) return; for (int i = 0; i < energyConsumerResult.length; i++) { Slog.d(TAG, "EnergyConsumerId: " + energyConsumerResult[i].id + ", Timestamp (ms): " + energyConsumerResult[i].timestampMs + ", Energy (uWs): " + energyConsumerResult[i].energyUWs); final EnergyConsumerResult result = energyConsumerResult[i]; Slog.d(TAG, "EnergyConsumerId: " + result.id + ", Timestamp (ms): " + result.timestampMs + ", Energy (uWs): " + result.energyUWs); final int attributionLength = result.attribution.length; for (int j = 0; j < attributionLength; j++) { final EnergyConsumerAttribution attribution = result.attribution[j]; Slog.d(TAG, " UID: " + attribution.uid + " Energy (uWs): " + attribution.energyUWs); } } } } Loading
services/core/java/com/android/server/powerstats/TimerTrigger.java +20 −7 Original line number Diff line number Diff line Loading @@ -29,18 +29,30 @@ public final class TimerTrigger extends PowerStatsLogTrigger { private static final String TAG = TimerTrigger.class.getSimpleName(); private static final boolean DEBUG = false; // TODO(b/166689029): Make configurable through global settings. private static final long LOG_PERIOD_MS = 120 * 1000; private static final long LOG_PERIOD_MS_LOW_FREQUENCY = 60 * 60 * 1000; // 1 hour private static final long LOG_PERIOD_MS_HIGH_FREQUENCY = 2 * 60 * 1000; // 2 minutes private final Handler mHandler; private Runnable mLogData = new Runnable() { private Runnable mLogDataLowFrequency = new Runnable() { @Override public void run() { // Do not wake the device for these messages. Opportunistically log rail data every // LOG_PERIOD_MS. mHandler.postDelayed(mLogData, LOG_PERIOD_MS); if (DEBUG) Slog.d(TAG, "Received delayed message. Log rail data"); logPowerStatsData(PowerStatsLogger.MSG_LOG_TO_DATA_STORAGE_TIMER); // LOG_PERIOD_MS_LOW_FREQUENCY. mHandler.postDelayed(mLogDataLowFrequency, LOG_PERIOD_MS_LOW_FREQUENCY); if (DEBUG) Slog.d(TAG, "Received delayed message. Log rail data low frequency"); logPowerStatsData(PowerStatsLogger.MSG_LOG_TO_DATA_STORAGE_LOW_FREQUENCY); } }; private Runnable mLogDataHighFrequency = new Runnable() { @Override public void run() { // Do not wake the device for these messages. Opportunistically log rail data every // LOG_PERIOD_MS_HIGH_FREQUENCY. mHandler.postDelayed(mLogDataHighFrequency, LOG_PERIOD_MS_HIGH_FREQUENCY); if (DEBUG) Slog.d(TAG, "Received delayed message. Log rail data high frequency"); logPowerStatsData(PowerStatsLogger.MSG_LOG_TO_DATA_STORAGE_HIGH_FREQUENCY); } }; Loading @@ -50,7 +62,8 @@ public final class TimerTrigger extends PowerStatsLogTrigger { mHandler = mContext.getMainThreadHandler(); if (triggerEnabled) { mLogData.run(); mLogDataLowFrequency.run(); mLogDataHighFrequency.run(); } } }
services/tests/servicestests/src/com/android/server/powerstats/PowerStatsServiceTest.java +17 −2 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import static org.junit.Assert.fail; import android.content.Context; import android.hardware.power.stats.Channel; import android.hardware.power.stats.EnergyConsumer; import android.hardware.power.stats.EnergyConsumerAttribution; import android.hardware.power.stats.EnergyConsumerResult; import android.hardware.power.stats.EnergyMeasurement; import android.hardware.power.stats.PowerEntity; Loading Loading @@ -73,6 +74,7 @@ public class PowerStatsServiceTest { private static final String ENERGY_CONSUMER_NAME = "energyconsumer"; private static final int ENERGY_METER_COUNT = 8; private static final int ENERGY_CONSUMER_COUNT = 2; private static final int ENERGY_CONSUMER_ATTRIBUTION_COUNT = 5; private static final int POWER_ENTITY_COUNT = 3; private static final int STATE_INFO_COUNT = 5; private static final int STATE_RESIDENCY_COUNT = 4; Loading Loading @@ -204,6 +206,13 @@ public class PowerStatsServiceTest { energyConsumedList[i].id = i; energyConsumedList[i].timestampMs = i; energyConsumedList[i].energyUWs = i; energyConsumedList[i].attribution = new EnergyConsumerAttribution[ENERGY_CONSUMER_ATTRIBUTION_COUNT]; for (int j = 0; j < energyConsumedList[i].attribution.length; j++) { energyConsumedList[i].attribution[j] = new EnergyConsumerAttribution(); energyConsumedList[i].attribution[j].uid = j; energyConsumedList[i].attribution[j].energyUWs = j; } } return energyConsumedList; } Loading Loading @@ -250,7 +259,7 @@ public class PowerStatsServiceTest { mService.onBootPhase(SystemService.PHASE_BOOT_COMPLETED); // Write data to on-device storage. mTimerTrigger.logPowerStatsData(PowerStatsLogger.MSG_LOG_TO_DATA_STORAGE_TIMER); mTimerTrigger.logPowerStatsData(PowerStatsLogger.MSG_LOG_TO_DATA_STORAGE_HIGH_FREQUENCY); // The above call puts a message on a handler. Wait for // it to be processed. Loading Loading @@ -293,7 +302,7 @@ public class PowerStatsServiceTest { mService.onBootPhase(SystemService.PHASE_BOOT_COMPLETED); // Write data to on-device storage. mTimerTrigger.logPowerStatsData(PowerStatsLogger.MSG_LOG_TO_DATA_STORAGE_TIMER); mTimerTrigger.logPowerStatsData(PowerStatsLogger.MSG_LOG_TO_DATA_STORAGE_LOW_FREQUENCY); // The above call puts a message on a handler. Wait for // it to be processed. Loading Loading @@ -324,6 +333,12 @@ public class PowerStatsServiceTest { assertTrue(pssProto.energyConsumerResult[i].id == i); assertTrue(pssProto.energyConsumerResult[i].timestampMs == i); assertTrue(pssProto.energyConsumerResult[i].energyUws == i); assertTrue(pssProto.energyConsumerResult[i].attribution.length == ENERGY_CONSUMER_ATTRIBUTION_COUNT); for (int j = 0; j < pssProto.energyConsumerResult[i].attribution.length; j++) { assertTrue(pssProto.energyConsumerResult[i].attribution[j].uid == j); assertTrue(pssProto.energyConsumerResult[i].attribution[j].energyUws == j); } } } Loading