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

Commit 3bf626d1 authored by Benjamin Schwartz's avatar Benjamin Schwartz Committed by Android (Google) Code Review
Browse files

Merge changes from topic "energyconsumer"

* changes:
  Update BatteryExternalStatsWorker to use the new EnergyConsumerType
  Update to new version of PowerStats HAL 2.0
parents f5e542d6 32d103d0
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -14235,6 +14235,7 @@ public class BatteryStatsImpl extends BatteryStats {
            for (int i = 0; i < NUMBER_ENERGY_BUCKETS; i++) {
                if (mGlobalMeasuredEnergyStats.isEnergyBucketSupported(i)
                        != supportedEnergyBuckets[i]) {
                    mGlobalMeasuredEnergyStats = new MeasuredEnergyStats(supportedEnergyBuckets);
                    supportedBucketMismatch = true;
                    break;
                }
+51 −31
Original line number Diff line number Diff line
@@ -53,12 +53,12 @@ message IncidentReportResidencyProto {
/**
 * EnergyConsumer (model) data is exposed by the PowerStats HAL.  This data
 * represents modeled energy consumption estimates and is provided per
 * subsystem.  The default subsystems are defined in EnergyConsumerId.aidl.
 * subsystem.  The default subsystems are defined in EnergyConsumerType.aidl.
 * Energy model estimates will be logged to incident reports in addition to
 * the raw energy meter data.
 */
message PowerStatsServiceModelProto {
    repeated EnergyConsumerIdProto energy_consumer_id = 1;
    repeated EnergyConsumerProto energy_consumer = 1;
    repeated EnergyConsumerResultProto energy_consumer_result = 2;
}

@@ -68,13 +68,13 @@ message PowerStatsServiceModelProto {
 * This raw energy meter data will be logged to incident reports.
 */
message PowerStatsServiceMeterProto {
    repeated ChannelInfoProto channel_info = 1;
    repeated ChannelProto channel = 1;
    repeated EnergyMeasurementProto energy_measurement = 2;
}

/**
 * A PowerEntity is defined as a platform subsystem, peripheral, or power domain
 * that impacts the total device power consumption.  PowerEntityInfo is
 * that impacts the total device power consumption.  PowerEntity is
 * information related to each power entity.  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
@@ -83,44 +83,44 @@ message PowerStatsServiceMeterProto {
 * entered.
 */
message PowerStatsServiceResidencyProto {
    repeated PowerEntityInfoProto power_entity_info = 1;
    repeated PowerEntityProto power_entity = 1;
    repeated StateResidencyResultProto state_residency_result = 2;
}

/**
 * Information about the possible states for a particular PowerEntity.
 */
message StateInfoProto {
message StateProto {
    /**
     * Unique (for a given PowerEntityInfo) ID of this StateInfo
     * Unique (for a given PowerEntity) ID of this State
     */
    optional int32 state_id = 1;
    optional int32 id = 1;
    /**
     * Unique (for a given PowerEntityInfo) name of the state. Vendor/device specific.
     * Unique (for a given PowerEntity) name of the state. Vendor/device specific.
     * Opaque to framework
     */
    optional string state_name = 2;
    optional string name = 2;
}

/**
 * A PowerEntity is defined as a platform subsystem, peripheral, or power domain
 * that impacts the total device power consumption.  PowerEntityInfo is
 * that impacts the total device power consumption.  PowerEntity is
 * information about a PowerEntity.  It includes an array of information about
 * each possible state of the PowerEntity.
 */
message PowerEntityInfoProto {
message PowerEntityProto {
    /**
     * Unique ID of this PowerEntityInfo
     * Unique ID of this PowerEntity
     */
    optional int32 power_entity_id = 1;
    optional int32 id = 1;
    /**
     * Unique name of the PowerEntity. Vendor/device specific. Opaque to framework
     */
    optional string power_entity_name = 2;
    optional string name = 2;
    /**
     * List of states that the PowerEntity may reside in
     */
    repeated StateInfoProto states = 3;
    repeated StateProto states = 3;
}

/**
@@ -133,7 +133,7 @@ message StateResidencyProto {
    /**
     * ID of the state associated with this residency
     */
    optional int32 state_id = 1;
    optional int32 id = 1;
    /**
     * Total time in milliseconds that the corresponding PowerEntity resided
     * in this state since boot
@@ -152,13 +152,13 @@ message StateResidencyProto {
/**
 * A StateResidencyResult is an array of StateResidencies for a particular
 * PowerEntity.  The StateResidencyResult can be matched to its corresponding
 * PowerEntityInfo through the power_entity_id field.
 * PowerEntity through the id field.
 */
message StateResidencyResultProto {
    /**
     * ID of the PowerEntity associated with this result
     */
    optional int32 power_entity_id = 1;
    optional int32 id = 1;
    /**
     * Residency for each state in the PowerEntity's state space
     */
@@ -166,23 +166,39 @@ message StateResidencyResultProto {
}

/**
 * Energy consumer ID:
 * Energy consumer:
 * A list of default subsystems for which energy consumption estimates
 * may be provided (hardware dependent).
 */
message EnergyConsumerIdProto {
    /** Unique index identifying the energy consumer. */
    optional int32 energy_consumer_id = 1;
message EnergyConsumerProto {
    /** Unique ID of this EnergyConsumer */
    optional int32 id = 1;

    /**
     * For a group of EnergyConsumers of the same logical type, sorting by
     * ordinal should be give their physical order. No other meaning is
     * carried by it.
     */
    optional int32 ordinal = 2;

    /** Type of this EnergyConsumer */
    optional int32 type = 3;

    /**
     * Unique name of this EnergyConsumer. Vendor/device specific. Opaque
     * to framework
     */
    optional string name = 4;
}

/**
 * Energy consumer result:
 * An estimate of energy consumption since boot for the subsystem identified
 * by the unique energy_consumer_id.
 * by the unique id.
 */
message EnergyConsumerResultProto {
    /** Unique index identifying the energy consumer. */
    optional int32 energy_consumer_id = 1;
    optional int32 id = 1;

    /** Time since device boot(CLOCK_BOOTTIME) in milli-seconds */
    optional int64 timestamp_ms = 2;
@@ -195,15 +211,15 @@ message EnergyConsumerResultProto {
 * Channel information:
 * Reports information related to the energy meter channels being monitored.
 */
message ChannelInfoProto {
message ChannelProto {
    /**
     * Index corresponding to the energy meter channel. This index matches
     * the index returned in ChannelInfo.
     * the index returned in Channel.
     */
    optional int32 channel_id = 1;
    optional int32 id = 1;

    /** Name of the energy meter channel */
    optional string channel_name = 2;
    optional string name = 2;
}

/**
@@ -213,13 +229,17 @@ message ChannelInfoProto {
message EnergyMeasurementProto {
    /**
     * Index corresponding to the energy meter channel. This index matches
     * the index returned in ChannelInfo.
     * the index returned in Channel.
     */
    optional int32 channel_id = 1;
    optional int32 id = 1;

    /** Time since device boot(CLOCK_BOOTTIME) in milli-seconds */
    optional int64 timestamp_ms = 2;

    /** Accumulated energy since device boot in microwatt-seconds (uWs) */
    optional int64 energy_uws = 3;

    /** Duration in milliseconds that energy has been accumulated */
    optional int64 duration_ms = 4;

}
+14 −2
Original line number Diff line number Diff line
@@ -16,7 +16,9 @@

package android.power;

import android.hardware.power.stats.EnergyConsumerId;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.hardware.power.stats.EnergyConsumer;
import android.hardware.power.stats.EnergyConsumerResult;

import java.util.concurrent.CompletableFuture;
@@ -27,6 +29,15 @@ import java.util.concurrent.CompletableFuture;
 * @hide Only for use within Android OS.
 */
public abstract class PowerStatsInternal {
    /**
     * Returns the energy consumer info for all available {@link EnergyConsumer}
     *
     * @return List of available {@link EnergyConsumer}, or null if {@link EnergyConsumer} not
     * supported
     */
    @Nullable
    public abstract EnergyConsumer[] getEnergyConsumerInfo();

    /**
     * Returns a CompletableFuture that will get an {@link EnergyConsumerResult} array for the
     * available requested energy consumers (power models).
@@ -37,6 +48,7 @@ public abstract class PowerStatsInternal {
     * @return A Future containing a list of {@link EnergyConsumerResult} objects containing energy
     *         consumer results for all listed {@link EnergyConsumerId}.
     */
    @NonNull
    public abstract CompletableFuture<EnergyConsumerResult[]> getEnergyConsumedAsync(
            @EnergyConsumerId int[] energyConsumerIds);
            int[] energyConsumerIds);
}
+81 −24
Original line number Diff line number Diff line
@@ -17,13 +17,13 @@ package com.android.server.am;

import static com.android.internal.power.MeasuredEnergyArray.SUBSYSTEM_DISPLAY;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.bluetooth.BluetoothActivityEnergyInfo;
import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.hardware.power.stats.EnergyConsumerId;
import android.hardware.power.stats.EnergyConsumer;
import android.hardware.power.stats.EnergyConsumerResult;
import android.hardware.power.stats.EnergyConsumerType;
import android.net.wifi.WifiManager;
import android.os.BatteryStats;
import android.os.Bundle;
@@ -39,6 +39,7 @@ import android.telephony.ModemActivityInfo;
import android.telephony.TelephonyManager;
import android.util.IntArray;
import android.util.Slog;
import android.util.SparseIntArray;
import android.util.SparseLongArray;

import com.android.internal.annotations.GuardedBy;
@@ -148,6 +149,14 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync {
    private WifiActivityEnergyInfo mLastWifiInfo =
            new WifiActivityEnergyInfo(0, 0, 0, 0, 0, 0);

    /** Maps the EnergyConsumer id to it's corresponding {@link MeasuredEnergySubsystem} */
    @GuardedBy("mWorkerLock")
    private @Nullable SparseIntArray mEnergyConsumerToSubsystemMap = null;

    /** Maps a {@link MeasuredEnergySubsystem} to it's corresponding EnergyConsumer id */
    @GuardedBy("mWorkerLock")
    private @Nullable SparseIntArray mSubsystemToEnergyConsumerMap = null;

    /** Snapshot of measured energies, or null if no measured energies are supported. */
    @GuardedBy("mWorkerLock")
    private @Nullable MeasuredEnergySnapshot mMeasuredEnergySnapshot = null;
@@ -168,12 +177,15 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync {
        final WifiManager wm = mContext.getSystemService(WifiManager.class);
        final TelephonyManager tm = mContext.getSystemService(TelephonyManager.class);
        final PowerStatsInternal psi = LocalServices.getService(PowerStatsInternal.class);
        final MeasuredEnergyArray initialMeasuredEnergies = getEnergyConsumptionData(psi);
        final boolean[] supportedBuckets = getSupportedEnergyBuckets(initialMeasuredEnergies);
        synchronized (mWorkerLock) {
            mWifiManager = wm;
            mTelephony = tm;
            mPowerStatsInternal = psi;
            if (mPowerStatsInternal != null) {
                populateEnergyConsumerSubsystemMapsLocked();
                final MeasuredEnergyArray initialMeasuredEnergies = getEnergyConsumptionData();
                final boolean[] supportedBuckets = getSupportedEnergyBuckets(
                        initialMeasuredEnergies);
                mMeasuredEnergySnapshot = initialMeasuredEnergies == null
                        ? null : new MeasuredEnergySnapshot(initialMeasuredEnergies);
                synchronized (mStats) {
@@ -181,6 +193,7 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync {
                }
            }
        }
    }

    @Override
    public synchronized Future<?> scheduleSync(String reason, int flags) {
@@ -733,11 +746,11 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync {
     * TODO(b/176988041): Replace {@link MeasuredEnergyArray} usage with {@link
     * EnergyConsumerResult}[]
     */
    private static @Nullable
            MeasuredEnergyArray getEnergyConsumptionData(@NonNull PowerStatsInternal psi) {
    @GuardedBy("mWorkerLock")
    private @Nullable MeasuredEnergyArray getEnergyConsumptionData() {
        final EnergyConsumerResult[] results;
        try {
            results = psi.getEnergyConsumedAsync(new int[0])
            results = mPowerStatsInternal.getEnergyConsumedAsync(new int[0])
                    .get(EXTERNAL_STATS_SYNC_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
        } catch (Exception e) {
            Slog.e(TAG, "Failed to getEnergyConsumedAsync", e);
@@ -750,14 +763,9 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync {

        for (int i = 0; i < size; i++) {
            final EnergyConsumerResult consumer = results[i];
            final int subsystem;
            switch (consumer.energyConsumerId) {
                case EnergyConsumerId.DISPLAY:
                    subsystem = MeasuredEnergyArray.SUBSYSTEM_DISPLAY;
                    break;
                default:
                    continue;
            }
            final int subsystem = mEnergyConsumerToSubsystemMap.get(consumer.id,
                    MeasuredEnergyArray.SUBSYSTEM_UNKNOWN);
            if (subsystem == MeasuredEnergyArray.SUBSYSTEM_UNKNOWN) continue;
            subsystems[i] = subsystem;
            energyUJ[i] = consumer.energyUWs;
        }
@@ -786,19 +794,19 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync {

        if (flags == UPDATE_ALL) {
            // Gotta catch 'em all... including custom (non-specific) subsystems
            return getEnergyConsumptionData(mPowerStatsInternal);
            return getEnergyConsumptionData();
        }

        final List<Integer> energyConsumerIds = new ArrayList<>();
        final List<Integer> energySubsystems = new ArrayList<>();
        if ((flags & UPDATE_DISPLAY) != 0) {
            addEnergyConsumerIdLocked(energyConsumerIds, SUBSYSTEM_DISPLAY);
            addEnergyConsumerIdLocked(energySubsystems, SUBSYSTEM_DISPLAY);
        }
        // TODO: Wifi, Bluetooth, etc., go here
        if (energyConsumerIds.isEmpty()) {
        if (energySubsystems.isEmpty()) {
            return null;
        }
        // TODO: Query *specific* subsystems from HAL based on energyConsumerIds.toArray()
        return getEnergyConsumptionData(mPowerStatsInternal);
        return getEnergyConsumptionData();
    }

    @GuardedBy("mWorkerLock")
@@ -808,4 +816,53 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync {
            energyConsumerIds.add(consumerId);
        }
    }

    @GuardedBy("mWorkerLock")
    private void populateEnergyConsumerSubsystemMapsLocked() {
        if (mPowerStatsInternal == null) {
            // PowerStatsInternal unavailable, don't bother populating maps.
            mEnergyConsumerToSubsystemMap = null;
            mSubsystemToEnergyConsumerMap = null;
            return;
        }
        final EnergyConsumer[] energyConsumers = mPowerStatsInternal.getEnergyConsumerInfo();
        if (energyConsumers == null) {
            // EnergyConsumer data unavailable, don't bother populating maps.
            mEnergyConsumerToSubsystemMap = null;
            mSubsystemToEnergyConsumerMap = null;
            return;
        }

        final int length = energyConsumers.length;
        if (length == 0) {
            // EnergyConsumer array empty, don't bother populating maps.
            mEnergyConsumerToSubsystemMap = null;
            mSubsystemToEnergyConsumerMap = null;
            return;
        } else {
            mEnergyConsumerToSubsystemMap = new SparseIntArray(length);
            mSubsystemToEnergyConsumerMap = new SparseIntArray(length);
        }

        // Add all expected EnergyConsumers to the maps
        for (int i = 0; i < length; i++) {
            final EnergyConsumer consumer = energyConsumers[i];
            switch (consumer.type) {
                case EnergyConsumerType.DISPLAY:
                    if (consumer.ordinal == 0) {
                        mEnergyConsumerToSubsystemMap.put(consumer.id,
                                MeasuredEnergyArray.SUBSYSTEM_DISPLAY);
                        mSubsystemToEnergyConsumerMap.put(MeasuredEnergyArray.SUBSYSTEM_DISPLAY,
                                consumer.id);
                    } else {
                        Slog.w(TAG, "Unexpected ordinal (" + consumer.ordinal
                                + ") for EnergyConsumerType.DISPLAY");
                    }
                    break;
                default:
                    Slog.w(TAG, "Unexpected EnergyConsumerType (" + consumer.type + ")");
            }

        }
    }
}
+25 −25
Original line number Diff line number Diff line
@@ -16,10 +16,10 @@

package com.android.server.powerstats;

import android.hardware.power.stats.ChannelInfo;
import android.hardware.power.stats.Channel;
import android.hardware.power.stats.EnergyMeasurement;
import android.hardware.power.stats.IPowerStats;
import android.hardware.power.stats.PowerEntityInfo;
import android.hardware.power.stats.PowerEntity;
import android.hardware.power.stats.StateResidencyResult;
import android.os.Binder;
import android.os.IBinder;
@@ -51,7 +51,7 @@ public final class PowerStatsHALWrapper {
         *
         * @return List of information on each PowerEntity.
         */
        android.hardware.power.stats.PowerEntityInfo[] getPowerEntityInfo();
        android.hardware.power.stats.PowerEntity[] getPowerEntityInfo();

        /**
         * Reports the accumulated state residency for each requested PowerEntity.
@@ -66,22 +66,22 @@ public final class PowerStatsHALWrapper {
         * @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.
         *                       PowerEntity.
         *
         * @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
         * Returns the energy consumer info 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
         * found in the PowerStats HAL definition (EnergyConsumerType.aidl).  The availability of
         * energy consumer IDs is hardware dependent.
         *
         * @return List of EnergyConsumerIds all available energy consumers.
         * @return List of EnergyConsumers all available energy consumers.
         */
        int[] getEnergyConsumerInfo();
        android.hardware.power.stats.EnergyConsumer[] getEnergyConsumerInfo();

        /**
         * Returns the energy consumer result for all available energy consumers (power models).
@@ -102,10 +102,10 @@ public final class PowerStatsHALWrapper {
        /**
         * Returns channel info for all available energy meters.
         *
         * @return List of ChannelInfo objects containing channel info for all available energy
         * @return List of Channel objects containing channel info for all available energy
         *         meters.
         */
        android.hardware.power.stats.ChannelInfo[] getEnergyMeterInfo();
        android.hardware.power.stats.Channel[] getEnergyMeterInfo();

        /**
         * Returns energy measurements for all available energy meters.  Available channels can be
@@ -152,18 +152,18 @@ public final class PowerStatsHALWrapper {
        }

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

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

            return powerEntityInfoHAL;
            return powerEntityHAL;
        }

        @Override
@@ -184,12 +184,12 @@ public final class PowerStatsHALWrapper {
        }

        @Override
        public int[] getEnergyConsumerInfo() {
            int[] energyConsumerInfoHAL = null;
        public android.hardware.power.stats.EnergyConsumer[] getEnergyConsumerInfo() {
            android.hardware.power.stats.EnergyConsumer[] energyConsumerHAL = null;

            if (sVintfPowerStats != null) {
                try {
                    energyConsumerInfoHAL = sVintfPowerStats.get().getEnergyConsumerInfo();
                    energyConsumerHAL = sVintfPowerStats.get().getEnergyConsumerInfo();
                } catch (RemoteException e) {
                    if (DEBUG) {
                        Slog.d(TAG, "Failed to get energy consumer info from PowerStats HAL");
@@ -197,7 +197,7 @@ public final class PowerStatsHALWrapper {
                }
            }

            return energyConsumerInfoHAL;
            return energyConsumerHAL;
        }

        @Override
@@ -220,8 +220,8 @@ public final class PowerStatsHALWrapper {
        }

        @Override
        public android.hardware.power.stats.ChannelInfo[] getEnergyMeterInfo() {
            android.hardware.power.stats.ChannelInfo[] energyMeterInfoHAL = null;
        public android.hardware.power.stats.Channel[] getEnergyMeterInfo() {
            android.hardware.power.stats.Channel[] energyMeterInfoHAL = null;

            if (sVintfPowerStats != null) {
                try {
@@ -267,9 +267,9 @@ public final class PowerStatsHALWrapper {

        // PowerStatsHAL 1.0 native functions exposed by JNI layer.
        private static native boolean nativeInit();
        private static native PowerEntityInfo[] nativeGetPowerEntityInfo();
        private static native PowerEntity[] nativeGetPowerEntityInfo();
        private static native StateResidencyResult[] nativeGetStateResidency(int[] powerEntityIds);
        private static native ChannelInfo[] nativeGetEnergyMeterInfo();
        private static native Channel[] nativeGetEnergyMeterInfo();
        private static native EnergyMeasurement[] nativeReadEnergyMeters(int[] channelIds);

        public PowerStatsHAL10WrapperImpl() {
@@ -282,7 +282,7 @@ public final class PowerStatsHALWrapper {
        }

        @Override
        public android.hardware.power.stats.PowerEntityInfo[] getPowerEntityInfo() {
        public android.hardware.power.stats.PowerEntity[] getPowerEntityInfo() {
            return nativeGetPowerEntityInfo();
        }

@@ -293,7 +293,7 @@ public final class PowerStatsHALWrapper {
        }

        @Override
        public int[] getEnergyConsumerInfo() {
        public android.hardware.power.stats.EnergyConsumer[] getEnergyConsumerInfo() {
            if (DEBUG) Slog.d(TAG, "Energy consumer info is not supported");
            return null;
        }
@@ -306,7 +306,7 @@ public final class PowerStatsHALWrapper {
        }

        @Override
        public android.hardware.power.stats.ChannelInfo[] getEnergyMeterInfo() {
        public android.hardware.power.stats.Channel[] getEnergyMeterInfo() {
            return nativeGetEnergyMeterInfo();
        }

Loading