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

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

Merge "Add perf test for BatteryUsageStats transfer over Binder"

parents 6a586598 72df58ef
Loading
Loading
Loading
Loading
+2 −0
Original line number Original line Diff line number Diff line
@@ -20,6 +20,8 @@


    <application>
    <application>
        <uses-library android:name="android.test.runner" />
        <uses-library android:name="android.test.runner" />
        <service android:name="com.android.internal.os.BatteryUsageStatsPerfTest$BatteryUsageStatsService"
                 android:process=":BatteryUsageStatsService" />
    </application>
    </application>


    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+128 −1
Original line number Original line Diff line number Diff line
@@ -18,13 +18,25 @@ package com.android.internal.os;


import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertThat;


import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.BatteryConsumer;
import android.os.BatteryStatsManager;
import android.os.BatteryStatsManager;
import android.os.BatteryUsageStats;
import android.os.BatteryUsageStats;
import android.os.BatteryUsageStatsQuery;
import android.os.Binder;
import android.os.ConditionVariable;
import android.os.IBinder;
import android.os.Parcel;
import android.os.UidBatteryConsumer;
import android.os.UidBatteryConsumer;
import android.perftests.utils.BenchmarkState;
import android.perftests.utils.BenchmarkState;
import android.perftests.utils.PerfStatusReporter;
import android.perftests.utils.PerfStatusReporter;


import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.test.InstrumentationRegistry;
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.LargeTest;
import androidx.test.filters.LargeTest;
import androidx.test.runner.AndroidJUnit4;
import androidx.test.runner.AndroidJUnit4;
@@ -54,7 +66,8 @@ public class BatteryUsageStatsPerfTest {


        final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
        final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
        while (state.keepRunning()) {
        while (state.keepRunning()) {
            BatteryUsageStats batteryUsageStats = batteryStatsManager.getBatteryUsageStats();
            BatteryUsageStats batteryUsageStats = batteryStatsManager.getBatteryUsageStats(
                    new BatteryUsageStatsQuery.Builder().setMaxStatsAgeMs(0).build());


            state.pauseTiming();
            state.pauseTiming();


@@ -71,4 +84,118 @@ public class BatteryUsageStatsPerfTest {
            state.resumeTiming();
            state.resumeTiming();
        }
        }
    }
    }

    private final ConditionVariable mServiceConnected = new ConditionVariable();
    private IBinder mService;

    private final ServiceConnection mConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName name, IBinder service) {
            mService = service;
            mServiceConnected.open();
        }

        public void onServiceDisconnected(ComponentName name) {
            mService = null;
        }
    };

    /**
     * Measures the performance of transferring BatteryUsageStats over a Binder.
     */
    @Test
    public void testBatteryUsageStatsTransferOverBinder() throws Exception {
        final Context context = InstrumentationRegistry.getContext();
        context.bindService(
                new Intent(context, BatteryUsageStatsService.class),
                mConnection, Context.BIND_AUTO_CREATE);
        mServiceConnected.block(30000);
        assertThat(mService).isNotNull();

        final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
        while (state.keepRunning()) {
            final Parcel data = Parcel.obtain();
            final Parcel reply = Parcel.obtain();
            mService.transact(42, data, reply, 0);
            final BatteryUsageStats batteryUsageStats =
                    BatteryUsageStats.CREATOR.createFromParcel(reply);
            reply.recycle();
            data.recycle();

            state.pauseTiming();

            assertThat(batteryUsageStats.getBatteryCapacity()).isEqualTo(4000);
            assertThat(batteryUsageStats.getUidBatteryConsumers()).hasSize(1000);
            final UidBatteryConsumer uidBatteryConsumer =
                    batteryUsageStats.getUidBatteryConsumers().get(0);
            assertThat(uidBatteryConsumer.getConsumedPower(1)).isEqualTo(123);

            state.resumeTiming();
        }

        context.unbindService(mConnection);
    }

    /* This service runs in a separate process */
    public static class BatteryUsageStatsService extends Service {
        private final BatteryUsageStats mBatteryUsageStats;

        public BatteryUsageStatsService() {
            mBatteryUsageStats = buildBatteryUsageStats();
        }

        @Nullable
        @Override
        public IBinder onBind(Intent intent) {
            return new Binder() {
                @Override
                protected boolean onTransact(int code, @NonNull Parcel data, @Nullable Parcel reply,
                        int flags) {
                    mBatteryUsageStats.writeToParcel(reply, 0);
                    return true;
                }
            };
        }
    }

    private static BatteryUsageStats buildBatteryUsageStats() {
        final BatteryUsageStats.Builder builder =
                new BatteryUsageStats.Builder(new String[]{"FOO"}, true)
                        .setBatteryCapacity(4000)
                        .setDischargePercentage(20)
                        .setDischargedPowerRange(1000, 2000)
                        .setStatsStartTimestamp(1000)
                        .setStatsEndTimestamp(3000);

        builder.getAggregateBatteryConsumerBuilder(
                BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS)
                .setConsumedPower(123)
                .setConsumedPower(
                        BatteryConsumer.POWER_COMPONENT_CPU, 10100)
                .setConsumedPowerForCustomComponent(
                        BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, 10200)
                .setUsageDurationMillis(
                        BatteryConsumer.POWER_COMPONENT_CPU, 10300)
                .setUsageDurationForCustomComponentMillis(
                        BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, 10400);

        for (int i = 0; i < 1000; i++) {
            final UidBatteryConsumer.Builder consumerBuilder =
                    builder.getOrCreateUidBatteryConsumerBuilder(i)
                            .setPackageWithHighestDrain("example.packagename" + i)
                            .setTimeInStateMs(UidBatteryConsumer.STATE_FOREGROUND, i * 2000)
                            .setTimeInStateMs(UidBatteryConsumer.STATE_BACKGROUND, i * 1000);
            for (int componentId = 0; componentId < BatteryConsumer.POWER_COMPONENT_COUNT;
                    componentId++) {
                consumerBuilder.setConsumedPower(componentId, componentId * 123.0,
                        BatteryConsumer.POWER_MODEL_POWER_PROFILE);
                consumerBuilder.setUsageDurationMillis(componentId, componentId * 1000);
            }

            consumerBuilder.setConsumedPowerForCustomComponent(
                    BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, 1234)
                    .setUsageDurationForCustomComponentMillis(
                            BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, 4321);
        }
        return builder.build();
    }
}
}