Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2980ec77 authored by Mat Bevilacqua's avatar Mat Bevilacqua
Browse files

Add full support for PowerStatsHAL 2.0

Bug: 173527851
Test: atest FrameworksServicesTests:PowerStatsServiceTest

Change-Id: I63410b4bf56b4b0fc5a1a4a9c8fe8092118f26e7
parent 30891502
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -194,7 +194,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub

    @Override
    public MeasuredEnergyArray getEnergyConsumptionData() {
        final EnergyConsumerResult[] results = mPowerStatsHALWrapper.getEnergyConsumed();
        final EnergyConsumerResult[] results = mPowerStatsHALWrapper.getEnergyConsumed(new int[0]);
        if (results == null) return null;
        final int size = results.length;
        final int[] subsystems = new int[size];
+89 −17
Original line number Diff line number Diff line
@@ -37,12 +37,42 @@ public final class PowerStatsHALWrapper {
     * IPowerStatsHALWrapper defines the interface to the PowerStatsHAL.
     */
    public interface IPowerStatsHALWrapper {
        /**
         * Returns information related to all supported PowerEntity(s) for which state residency
         * data is available.
         *
         * A PowerEntity is defined as a platform subsystem, peripheral, or power domain that
         * impacts the total device power consumption.
         *
         * @return List of information on each PowerEntity.
         */
        android.hardware.power.stats.PowerEntityInfo[] getPowerEntityInfo();

        /**
         * Reports the accumulated state residency for each requested PowerEntity.
         *
         * Each PowerEntity may reside in one of multiple states. It may also transition from one
         * state to another. StateResidency is defined as an accumulation of time that a
         * PowerEntity resided in each of its possible states, the number of times that each state
         * was entered, and a timestamp corresponding to the last time that state was entered.
         *
         * Data is accumulated starting at device boot.
         *
         * @param powerEntityIds List of IDs of PowerEntities for which data is requested.  Passing
         *                       an empty list will return state residency for all available
         *                       PowerEntities.  ID of each PowerEntity is contained in
         *                       PowerEntityInfo.
         *
         * @return StateResidency since boot for each requested PowerEntity
         */
        android.hardware.power.stats.StateResidencyResult[] getStateResidency(int[] powerEntityIds);

        /**
         * Returns the energy consumer IDs for all available energy consumers (power models) on the
         *         device.  Examples of subsystems for which energy consumer results (power models)
         *         may be available are GPS, display, wifi, etc.  The default list of energy
         *         consumers can be found in the PowerStats HAL definition (EnergyConsumerId.aidl).
         *         The availability of energy consumer IDs is hardware dependent.
         * device.  Examples of subsystems for which energy consumer results (power models) may be
         * available are GPS, display, wifi, etc.  The default list of energy consumers can be
         * found in the PowerStats HAL definition (EnergyConsumerId.aidl).  The availability of
         * energy consumer IDs is hardware dependent.
         *
         * @return List of EnergyConsumerIds all available energy consumers.
         */
@@ -50,14 +80,19 @@ public final class PowerStatsHALWrapper {

        /**
         * Returns the energy consumer result for all available energy consumers (power models).
         *         Available consumers can be retrieved by calling getEnergyConsumerInfo().  The
         *         subsystem corresponding to the energy consumer result is defined by the energy
         *         consumer ID.
         * Available consumers can be retrieved by calling getEnergyConsumerInfo().  The subsystem
         * corresponding to the energy consumer result is defined by the energy consumer ID.
         *
         * @param energyConsumerIds Array of energy consumer IDs for which energy consumed is being
         *                          requested.  Energy consumers available on the device can be
         *                          queried by calling getEnergyConsumerInfo().  Passing an empty
         *                          array will return results for all energy consumers.
         *
         * @return List of EnergyConsumerResult objects containing energy consumer results for all
         *         available energy consumers (power models).
         */
        android.hardware.power.stats.EnergyConsumerResult[] getEnergyConsumed();
        android.hardware.power.stats.EnergyConsumerResult[] getEnergyConsumed(
                int[] energyConsumerIds);

        /**
         * Returns channel info for all available energy meters.
@@ -69,17 +104,21 @@ public final class PowerStatsHALWrapper {

        /**
         * Returns energy measurements for all available energy meters.  Available channels can be
         *         retrieved by calling getEnergyMeterInfo().  Energy measurements and channel info
         *         can be linked through the channelId field.
         * retrieved by calling getEnergyMeterInfo().  Energy measurements and channel info can be
         * linked through the channelId field.
         *
         * @param channelIds Array of channel IDs for which energy measurements are being requested.
         *                   Channel IDs available on the device can be queried by calling
         *                   getEnergyMeterInfo().  Passing an empty array will return energy
         *                   measurements for all channels.
         *
         * @return List of EnergyMeasurement objects containing energy measurements for all
         *         available energy meters.
         */
        android.hardware.power.stats.EnergyMeasurement[] readEnergyMeters();
        android.hardware.power.stats.EnergyMeasurement[] readEnergyMeters(int[] channelIds);

        /**
         * Returns boolean indicating if connection to power stats HAL was
         *         established.
         * Returns boolean indicating if connection to power stats HAL was established.
         *
         * @return true if connection to power stats HAL was correctly established.
         */
@@ -94,6 +133,38 @@ public final class PowerStatsHALWrapper {
    public static final class PowerStatsHALWrapperImpl implements IPowerStatsHALWrapper {
        private static Supplier<IPowerStats> sVintfPowerStats;

        @Override
        public android.hardware.power.stats.PowerEntityInfo[] getPowerEntityInfo() {
            android.hardware.power.stats.PowerEntityInfo[] powerEntityInfoHAL = null;

            if (sVintfPowerStats != null) {
                try {
                    powerEntityInfoHAL = sVintfPowerStats.get().getPowerEntityInfo();
                } catch (RemoteException e) {
                    Slog.e(TAG, "Failed to get power entity info from PowerStats HAL");
                }
            }

            return powerEntityInfoHAL;
        }

        @Override
        public android.hardware.power.stats.StateResidencyResult[] getStateResidency(
                int[] powerEntityIds) {
            android.hardware.power.stats.StateResidencyResult[] stateResidencyResultHAL = null;

            if (sVintfPowerStats != null) {
                try {
                    stateResidencyResultHAL =
                        sVintfPowerStats.get().getStateResidency(powerEntityIds);
                } catch (RemoteException e) {
                    Slog.e(TAG, "Failed to get state residency from PowerStats HAL");
                }
            }

            return stateResidencyResultHAL;
        }

        @Override
        public int[] getEnergyConsumerInfo() {
            int[] energyConsumerInfoHAL = null;
@@ -110,13 +181,14 @@ public final class PowerStatsHALWrapper {
        }

        @Override
        public android.hardware.power.stats.EnergyConsumerResult[] getEnergyConsumed() {
        public android.hardware.power.stats.EnergyConsumerResult[] getEnergyConsumed(
                int[] energyConsumerIds) {
            android.hardware.power.stats.EnergyConsumerResult[] energyConsumedHAL = null;

            if (sVintfPowerStats != null) {
                try {
                    energyConsumedHAL =
                        sVintfPowerStats.get().getEnergyConsumed(new int[0]);
                        sVintfPowerStats.get().getEnergyConsumed(energyConsumerIds);
                } catch (RemoteException e) {
                    Slog.e(TAG, "Failed to get energy consumer results from PowerStats HAL");
                }
@@ -141,13 +213,13 @@ public final class PowerStatsHALWrapper {
        }

        @Override
        public android.hardware.power.stats.EnergyMeasurement[] readEnergyMeters() {
        public android.hardware.power.stats.EnergyMeasurement[] readEnergyMeters(int[] channelIds) {
            android.hardware.power.stats.EnergyMeasurement[] energyMeasurementHAL = null;

            if (sVintfPowerStats != null) {
                try {
                    energyMeasurementHAL =
                        sVintfPowerStats.get().readEnergyMeters(new int[0]);
                        sVintfPowerStats.get().readEnergyMeters(channelIds);
                } catch (RemoteException e) {
                    Slog.e(TAG, "Failed to get energy measurements from PowerStats HAL");
                }
+3 −2
Original line number Diff line number Diff line
@@ -61,14 +61,15 @@ public final class PowerStatsLogger extends Handler {
                if (DEBUG) Slog.d(TAG, "Logging to data storage");

                // Log power meter data.
                EnergyMeasurement[] energyMeasurements = mPowerStatsHALWrapper.readEnergyMeters();
                EnergyMeasurement[] energyMeasurements =
                    mPowerStatsHALWrapper.readEnergyMeters(new int[0]);
                mPowerStatsMeterStorage.write(
                        EnergyMeasurementUtils.getProtoBytes(energyMeasurements));
                if (DEBUG) EnergyMeasurementUtils.print(energyMeasurements);

                // Log power model data.
                EnergyConsumerResult[] energyConsumerResults =
                    mPowerStatsHALWrapper.getEnergyConsumed();
                    mPowerStatsHALWrapper.getEnergyConsumed(new int[0]);
                mPowerStatsModelStorage.write(
                        EnergyConsumerResultUtils.getProtoBytes(energyConsumerResults));
                if (DEBUG) EnergyConsumerResultUtils.print(energyConsumerResults);
+6 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.server.powerstats;
import android.annotation.Nullable;
import android.content.Context;
import android.hardware.power.stats.ChannelInfo;
import android.hardware.power.stats.PowerEntityInfo;
import android.os.Binder;
import android.os.Environment;
import android.os.UserHandle;
@@ -31,6 +32,7 @@ import com.android.server.powerstats.PowerStatsHALWrapper.IPowerStatsHALWrapper;
import com.android.server.powerstats.PowerStatsHALWrapper.PowerStatsHALWrapperImpl;
import com.android.server.powerstats.ProtoStreamUtils.ChannelInfoUtils;
import com.android.server.powerstats.ProtoStreamUtils.EnergyConsumerIdUtils;
import com.android.server.powerstats.ProtoStreamUtils.PowerEntityInfoUtils;

import java.io.File;
import java.io.FileDescriptor;
@@ -110,6 +112,10 @@ public class PowerStatsService extends SystemService {
                        mPowerStatsLogger.writeMeterDataToFile(fd);
                    }
                } else if (args.length == 0) {
                    pw.println("PowerStatsService dumpsys: available PowerEntityInfos");
                    PowerEntityInfo[] powerEntityInfo = mPowerStatsHALWrapper.getPowerEntityInfo();
                    PowerEntityInfoUtils.dumpsys(powerEntityInfo, pw);

                    pw.println("PowerStatsService dumpsys: available ChannelInfos");
                    ChannelInfo[] channelInfo = mPowerStatsHALWrapper.getEnergyMeterInfo();
                    ChannelInfoUtils.dumpsys(channelInfo, pw);
+56 −12
Original line number Diff line number Diff line
@@ -19,6 +19,8 @@ package com.android.server.powerstats;
import android.hardware.power.stats.ChannelInfo;
import android.hardware.power.stats.EnergyConsumerResult;
import android.hardware.power.stats.EnergyMeasurement;
import android.hardware.power.stats.PowerEntityInfo;
import android.hardware.power.stats.StateResidencyResult;
import android.util.Slog;
import android.util.proto.ProtoInputStream;
import android.util.proto.ProtoOutputStream;
@@ -42,6 +44,48 @@ import java.util.List;
public class ProtoStreamUtils {
    private static final String TAG = ProtoStreamUtils.class.getSimpleName();

    static class PowerEntityInfoUtils {
        public static void print(PowerEntityInfo[] powerEntityInfo) {
            for (int i = 0; i < powerEntityInfo.length; i++) {
                Slog.d(TAG, "PowerEntityId: " + powerEntityInfo[i].powerEntityId
                        + ", PowerEntityName: " + powerEntityInfo[i].powerEntityName);
                for (int j = 0; j < powerEntityInfo[i].states.length; j++) {
                    Slog.d(TAG, "  StateId: " + powerEntityInfo[i].states[j].stateId
                            + ", StateName: " + powerEntityInfo[i].states[j].stateName);
                }
            }
        }

        public static void dumpsys(PowerEntityInfo[] powerEntityInfo, PrintWriter pw) {
            for (int i = 0; i < powerEntityInfo.length; i++) {
                pw.println("PowerEntityId: " + powerEntityInfo[i].powerEntityId
                        + ", PowerEntityName: " + powerEntityInfo[i].powerEntityName);
                for (int j = 0; j < powerEntityInfo[i].states.length; j++) {
                    pw.println("  StateId: " + powerEntityInfo[i].states[j].stateId
                            + ", StateName: " + powerEntityInfo[i].states[j].stateName);
                }
            }
        }
    }

    static class StateResidencyResultUtils {
        public static void print(StateResidencyResult[] stateResidencyResult) {
            for (int i = 0; i < stateResidencyResult.length; i++) {
                Slog.d(TAG, "PowerEntityId: " + stateResidencyResult[i].powerEntityId);
                for (int j = 0; j < stateResidencyResult[i].stateResidencyData.length; j++) {
                    Slog.d(TAG, "  StateId: "
                            + stateResidencyResult[i].stateResidencyData[j].stateId
                            + ", TotalTimeInStateMs: "
                            + stateResidencyResult[i].stateResidencyData[j].totalTimeInStateMs
                            + ", TotalStateEntryCount: "
                            + stateResidencyResult[i].stateResidencyData[j].totalStateEntryCount
                            + ", LastEntryTimestampMs: "
                            + stateResidencyResult[i].stateResidencyData[j].lastEntryTimestampMs);
                }
            }
        }
    }

    static class ChannelInfoUtils {
        public static void packProtoMessage(ChannelInfo[] channelInfo, ProtoOutputStream pos) {
            long token;
@@ -57,15 +101,15 @@ public class ProtoStreamUtils {

        public static void print(ChannelInfo[] channelInfo) {
            for (int i = 0; i < channelInfo.length; i++) {
                Slog.d(TAG, "ChannelId = " + channelInfo[i].channelId
                        + ", ChannelName = " + channelInfo[i].channelName);
                Slog.d(TAG, "ChannelId: " + channelInfo[i].channelId
                        + ", ChannelName: " + channelInfo[i].channelName);
            }
        }

        public static void dumpsys(ChannelInfo[] channelInfo, PrintWriter pw) {
            for (int i = 0; i < channelInfo.length; i++) {
                pw.println("ChannelId = " + channelInfo[i].channelId
                        + ", ChannelName = " + channelInfo[i].channelName);
                pw.println("ChannelId: " + channelInfo[i].channelId
                        + ", ChannelName: " + channelInfo[i].channelName);
            }
        }
    }
@@ -157,9 +201,9 @@ public class ProtoStreamUtils {

        public static void print(EnergyMeasurement[] energyMeasurement) {
            for (int i = 0; i < energyMeasurement.length; i++) {
                Slog.d(TAG, "ChannelId = " + energyMeasurement[i].channelId
                        + ", Timestamp (ms) = " + energyMeasurement[i].timestampMs
                        + ", Energy (uWs) = " + energyMeasurement[i].energyUWs);
                Slog.d(TAG, "ChannelId: " + energyMeasurement[i].channelId
                        + ", Timestamp (ms): " + energyMeasurement[i].timestampMs
                        + ", Energy (uWs): " + energyMeasurement[i].energyUWs);
            }
        }
    }
@@ -177,13 +221,13 @@ public class ProtoStreamUtils {

        public static void print(int[] energyConsumerId) {
            for (int i = 0; i < energyConsumerId.length; i++) {
                Slog.d(TAG, "EnergyConsumerId = " + energyConsumerId[i]);
                Slog.d(TAG, "EnergyConsumerId: " + energyConsumerId[i]);
            }
        }

        public static void dumpsys(int[] energyConsumerId, PrintWriter pw) {
            for (int i = 0; i < energyConsumerId.length; i++) {
                pw.println("EnergyConsumerId = " + energyConsumerId[i]);
                pw.println("EnergyConsumerId: " + energyConsumerId[i]);
            }
        }
    }
@@ -278,9 +322,9 @@ public class ProtoStreamUtils {

        public static void print(EnergyConsumerResult[] energyConsumerResult) {
            for (int i = 0; i < energyConsumerResult.length; i++) {
                Slog.d(TAG, "EnergyConsumerId = " + energyConsumerResult[i].energyConsumerId
                        + ", Timestamp (ms) = " + energyConsumerResult[i].timestampMs
                        + ", Energy (uWs) = " + energyConsumerResult[i].energyUWs);
                Slog.d(TAG, "EnergyConsumerId: " + energyConsumerResult[i].energyConsumerId
                        + ", Timestamp (ms): " + energyConsumerResult[i].timestampMs
                        + ", Energy (uWs): " + energyConsumerResult[i].energyUWs);
            }
        }
    }
Loading