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

Commit 5548a776 authored by Dmitri Plotnikov's avatar Dmitri Plotnikov Committed by Android (Google) Code Review
Browse files

Merge "Do not crash system server on powerstats HAL errors" into main

parents 1f4b7642 2fc0463b
Loading
Loading
Loading
Loading
+29 −5
Original line number Diff line number Diff line
@@ -304,12 +304,22 @@ public class PowerStatsService extends SystemService {
    @Override
    public void onStart() {
        if (getPowerStatsHal().isInitialized()) {
            mPowerStatsInternal = new LocalService();
            publishLocalService(PowerStatsInternal.class, mPowerStatsInternal);
            publishLocalService(PowerStatsInternal.class, getPowerStatsInternal());
        }
        publishBinderService(Context.POWER_STATS_SERVICE, mService);
    }

    /**
     * Returns the PowerStatsInternal associated with this service, maybe creating it if needed.
     */
    @VisibleForTesting
    public PowerStatsInternal getPowerStatsInternal() {
        if (mPowerStatsInternal == null) {
            mPowerStatsInternal = new LocalService();
        }
        return mPowerStatsInternal;
    }

    private void onSystemServicesReady() {
        mPullAtomCallback = mInjector.createStatsPullerImpl(mContext, mPowerStatsInternal);
        mDeviceConfigListener.startListening();
@@ -456,7 +466,13 @@ public class PowerStatsService extends SystemService {

    private void getEnergyConsumedAsync(CompletableFuture<EnergyConsumerResult[]> future,
            int[] energyConsumerIds) {
        EnergyConsumerResult[] results = getPowerStatsHal().getEnergyConsumed(energyConsumerIds);
        EnergyConsumerResult[] results;
        try {
            results = getPowerStatsHal().getEnergyConsumed(energyConsumerIds);
        } catch (Exception e) {
            future.completeExceptionally(e);
            return;
        }

        // STOPSHIP(253292374): Remove once missing EnergyConsumer results issue is resolved.
        EnergyConsumer[] energyConsumers = getEnergyConsumerInfo();
@@ -523,12 +539,20 @@ public class PowerStatsService extends SystemService {

    private void getStateResidencyAsync(CompletableFuture<StateResidencyResult[]> future,
            int[] powerEntityIds) {
        try {
            future.complete(getPowerStatsHal().getStateResidency(powerEntityIds));
        } catch (Exception e) {
            future.completeExceptionally(e);
        }
    }

    private void readEnergyMeterAsync(CompletableFuture<EnergyMeasurement[]> future,
            int[] channelIds) {
        try {
            future.complete(getPowerStatsHal().readEnergyMeter(channelIds));
        } catch (Exception e) {
            future.completeExceptionally(e);
        }
    }

    private static class PowerMonitorState {
+39 −0
Original line number Diff line number Diff line
@@ -74,6 +74,8 @@ import java.nio.file.Files;
import java.util.Arrays;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;

/**
@@ -221,6 +223,7 @@ public class PowerStatsServiceTest {
    };

    public static final class TestPowerStatsHALWrapper implements IPowerStatsHALWrapper {
        public RuntimeException exception;
        public EnergyConsumerResult[] energyConsumerResults;
        public EnergyMeasurement[] energyMeasurements;

@@ -243,6 +246,9 @@ public class PowerStatsServiceTest {

        @Override
        public StateResidencyResult[] getStateResidency(int[] powerEntityIds) {
            if (exception != null) {
                throw exception;
            }
            StateResidencyResult[] stateResidencyResultList =
                    new StateResidencyResult[POWER_ENTITY_COUNT];
            for (int i = 0; i < stateResidencyResultList.length; i++) {
@@ -294,6 +300,9 @@ public class PowerStatsServiceTest {

        @Override
        public EnergyConsumerResult[] getEnergyConsumed(int[] energyConsumerIds) {
            if (exception != null) {
                throw exception;
            }
            return energyConsumerResults;
        }

@@ -322,6 +331,9 @@ public class PowerStatsServiceTest {

        @Override
        public EnergyMeasurement[] readEnergyMeter(int[] channelIds) {
            if (exception != null) {
                throw exception;
            }
            return energyMeasurements;
        }

@@ -1222,4 +1234,31 @@ public class PowerStatsServiceTest {
        assertThrows(NullPointerException.class, () -> iPowerStatsService.getPowerMonitorReadings(
                new int[] {0}, null));
    }

    @Test
    public void getEnergyConsumedAsync_halException() {
        mPowerStatsHALWrapper.exception = new IllegalArgumentException();
        CompletableFuture<EnergyConsumerResult[]> future =
                mService.getPowerStatsInternal().getEnergyConsumedAsync(new int[]{1});
        ExecutionException exception = assertThrows(ExecutionException.class, future::get);
        assertThat(exception.getCause()).isInstanceOf(IllegalArgumentException.class);
    }

    @Test
    public void getStateResidencyAsync_halException() {
        mPowerStatsHALWrapper.exception = new IllegalArgumentException();
        CompletableFuture<StateResidencyResult[]> future =
                mService.getPowerStatsInternal().getStateResidencyAsync(new int[]{1});
        ExecutionException exception = assertThrows(ExecutionException.class, future::get);
        assertThat(exception.getCause()).isInstanceOf(IllegalArgumentException.class);
    }

    @Test
    public void readEnergyMeterAsync_halException() {
        mPowerStatsHALWrapper.exception = new IllegalArgumentException();
        CompletableFuture<EnergyMeasurement[]> future =
                mService.getPowerStatsInternal().readEnergyMeterAsync(new int[]{1});
        ExecutionException exception = assertThrows(ExecutionException.class, future::get);
        assertThat(exception.getCause()).isInstanceOf(IllegalArgumentException.class);
    }
}