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

Commit 32d103d0 authored by Michael Wachenschwanz's avatar Michael Wachenschwanz Committed by Mat Bevilacqua
Browse files

Update BatteryExternalStatsWorker to use the new EnergyConsumerType

EnergyConsumerId has been replaced with EnergyConsumerType and an ordinal int to determine an EnergyConsumer type

Bug: 178048034
Test: manual ("adb shell dumpsys batterystats --measured-energy" on
PowerStatshal2.0 enabled devices should report energy consumption data
while on battery)

Change-Id: Ie78b46fcb59d0327c00a20fbe2481dc537b910eb
parent 6058dc21
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;
                }
+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 −25
Original line number Diff line number Diff line
@@ -17,12 +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.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;
@@ -38,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;
@@ -147,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;
@@ -167,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) {
@@ -180,6 +193,7 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync {
                }
            }
        }
    }

    @Override
    public synchronized Future<?> scheduleSync(String reason, int flags) {
@@ -732,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);
@@ -749,16 +763,9 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync {

        for (int i = 0; i < size; i++) {
            final EnergyConsumerResult consumer = results[i];
            final int subsystem = 0;
            /*
            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;
        }
@@ -787,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")
@@ -809,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 + ")");
            }

        }
    }
}
+13 −3
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import android.os.UserHandle;
import android.power.PowerStatsInternal;
import android.util.Slog;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.function.pooled.PooledLambda;
@@ -71,6 +72,7 @@ public class PowerStatsService extends SystemService {

    @VisibleForTesting
    static class Injector {
        @GuardedBy("this")
        private IPowerStatsHALWrapper mPowerStatsHALWrapper;

        File createDataStoragePath() {
@@ -95,11 +97,13 @@ public class PowerStatsService extends SystemService {
        }

        IPowerStatsHALWrapper getPowerStatsHALWrapperImpl() {
            synchronized (this) {
                if (mPowerStatsHALWrapper == null) {
                    mPowerStatsHALWrapper = PowerStatsHALWrapper.getPowerStatsHalImpl();
                }
                return mPowerStatsHALWrapper;
            }
        }

        PowerStatsLogger createPowerStatsLogger(Context context, File dataStoragePath,
                String meterFilename, String modelFilename, String residencyFilename,
@@ -206,6 +210,12 @@ public class PowerStatsService extends SystemService {
            mHandler = new Handler(thread.getLooper());
        }


        @Override
        public EnergyConsumer[] getEnergyConsumerInfo() {
            return getPowerStatsHal().getEnergyConsumerInfo();
        }

        @Override
        public CompletableFuture<EnergyConsumerResult[]> getEnergyConsumedAsync(
                int[] energyConsumerIds) {