Merge "Add a perf test for BatteryStatsHelper"
This commit is contained in:
committed by
Android (Google) Code Review
commit
9237e2cf09
@@ -52,7 +52,7 @@ interface IBatteryStats {
|
||||
@UnsupportedAppUsage
|
||||
byte[] getStatistics();
|
||||
|
||||
ParcelFileDescriptor getStatisticsStream();
|
||||
ParcelFileDescriptor getStatisticsStream(boolean updateAll);
|
||||
|
||||
// Return true if we see the battery as currently charging.
|
||||
@UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
|
||||
|
||||
@@ -203,7 +203,7 @@ public class BatteryStatsHelper {
|
||||
}
|
||||
}
|
||||
return getStats(IBatteryStats.Stub.asInterface(
|
||||
ServiceManager.getService(BatteryStats.SERVICE_NAME)));
|
||||
ServiceManager.getService(BatteryStats.SERVICE_NAME)), true);
|
||||
}
|
||||
|
||||
@UnsupportedAppUsage
|
||||
@@ -223,8 +223,13 @@ public class BatteryStatsHelper {
|
||||
|
||||
@UnsupportedAppUsage
|
||||
public BatteryStats getStats() {
|
||||
return getStats(true /* updateAll */);
|
||||
}
|
||||
|
||||
/** Retrieves stats from BatteryService, optionally getting updated numbers */
|
||||
public BatteryStats getStats(boolean updateAll) {
|
||||
if (mStats == null) {
|
||||
load();
|
||||
load(updateAll);
|
||||
}
|
||||
return mStats;
|
||||
}
|
||||
@@ -720,19 +725,23 @@ public class BatteryStatsHelper {
|
||||
|
||||
@UnsupportedAppUsage
|
||||
private void load() {
|
||||
load(true);
|
||||
}
|
||||
|
||||
private void load(boolean updateAll) {
|
||||
if (mBatteryInfo == null) {
|
||||
return;
|
||||
}
|
||||
mStats = getStats(mBatteryInfo);
|
||||
mStats = getStats(mBatteryInfo, updateAll);
|
||||
if (mCollectBatteryBroadcast) {
|
||||
mBatteryBroadcast = mContext.registerReceiver(null,
|
||||
new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
|
||||
}
|
||||
}
|
||||
|
||||
private static BatteryStatsImpl getStats(IBatteryStats service) {
|
||||
private static BatteryStatsImpl getStats(IBatteryStats service, boolean updateAll) {
|
||||
try {
|
||||
ParcelFileDescriptor pfd = service.getStatisticsStream();
|
||||
ParcelFileDescriptor pfd = service.getStatisticsStream(updateAll);
|
||||
if (pfd != null) {
|
||||
if (false) {
|
||||
Log.d(TAG, "selinux context: "
|
||||
|
||||
@@ -519,16 +519,24 @@ public final class BatteryStatsService extends IBatteryStats.Stub
|
||||
return data;
|
||||
}
|
||||
|
||||
public ParcelFileDescriptor getStatisticsStream() {
|
||||
/**
|
||||
* Returns parceled BatteryStats as a MemoryFile.
|
||||
*
|
||||
* @param forceUpdate If true, runs a sync to get fresh battery stats. Otherwise,
|
||||
* returns the current values.
|
||||
*/
|
||||
public ParcelFileDescriptor getStatisticsStream(boolean forceUpdate) {
|
||||
mContext.enforceCallingOrSelfPermission(
|
||||
android.Manifest.permission.BATTERY_STATS, null);
|
||||
//Slog.i("foo", "SENDING BATTERY INFO:");
|
||||
//mStats.dumpLocked(new LogPrinter(Log.INFO, "foo", Log.LOG_ID_SYSTEM));
|
||||
Parcel out = Parcel.obtain();
|
||||
// Drain the handler queue to make sure we've handled all pending works, so we'll get
|
||||
// an accurate stats.
|
||||
awaitCompletion();
|
||||
syncStats("get-stats", BatteryExternalStatsWorker.UPDATE_ALL);
|
||||
if (forceUpdate) {
|
||||
// Drain the handler queue to make sure we've handled all pending works, so we'll get
|
||||
// an accurate stats.
|
||||
awaitCompletion();
|
||||
syncStats("get-stats", BatteryExternalStatsWorker.UPDATE_ALL);
|
||||
}
|
||||
synchronized (mStats) {
|
||||
mStats.writeToParcel(out, 0);
|
||||
}
|
||||
|
||||
25
tests/BatteryStatsPerfTest/Android.bp
Normal file
25
tests/BatteryStatsPerfTest/Android.bp
Normal file
@@ -0,0 +1,25 @@
|
||||
// Copyright (C) 2020 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
android_test {
|
||||
name: "BatteryStatsPerfTests",
|
||||
srcs: ["src/**/*.java"],
|
||||
static_libs: [
|
||||
"androidx.test.rules",
|
||||
"apct-perftests-utils",
|
||||
"truth-prebuilt",
|
||||
],
|
||||
platform_apis: true,
|
||||
certificate: "platform",
|
||||
}
|
||||
27
tests/BatteryStatsPerfTest/AndroidManifest.xml
Normal file
27
tests/BatteryStatsPerfTest/AndroidManifest.xml
Normal file
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2020 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.android.frameworks.perftests.batterystats">
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
||||
<uses-permission android:name="android.permission.BATTERY_STATS"/>
|
||||
|
||||
<application>
|
||||
<uses-library android:name="android.test.runner" />
|
||||
</application>
|
||||
|
||||
<instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
|
||||
android:targetPackage="com.android.frameworks.perftests.batterystats"/>
|
||||
</manifest>
|
||||
28
tests/BatteryStatsPerfTest/AndroidTest.xml
Normal file
28
tests/BatteryStatsPerfTest/AndroidTest.xml
Normal file
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2020 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<configuration description="Runs BatteryStats service Performance Tests">
|
||||
<target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
|
||||
<option name="test-file-name" value="BatteryStatsPerfTests.apk"/>
|
||||
<option name="cleanup-apks" value="true"/>
|
||||
</target_preparer>
|
||||
|
||||
<option name="test-suite-tag" value="apct"/>
|
||||
<option name="test-tag" value="BatteryStatsPerfTests"/>
|
||||
<test class="com.android.tradefed.testtype.AndroidJUnitTest">
|
||||
<option name="package" value="com.android.frameworks.perftests.batterystats"/>
|
||||
<option name="runner" value="androidx.test.runner.AndroidJUnitRunner"/>
|
||||
</test>
|
||||
</configuration>
|
||||
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.internal.os;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.BatteryStats;
|
||||
import android.os.Bundle;
|
||||
import android.os.UserHandle;
|
||||
import android.perftests.utils.BenchmarkState;
|
||||
import android.perftests.utils.PerfStatusReporter;
|
||||
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
import androidx.test.filters.LargeTest;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
@LargeTest
|
||||
public class BatteryStatsHelperPerfTest {
|
||||
|
||||
@Rule
|
||||
public final PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
|
||||
|
||||
/**
|
||||
* Measures the performance of {@link BatteryStatsHelper#getStats()}, which triggers
|
||||
* a battery stats sync on every iteration.
|
||||
*/
|
||||
@Test
|
||||
public void testGetStats_forceUpdate() {
|
||||
final Context context = InstrumentationRegistry.getContext();
|
||||
final BatteryStatsHelper statsHelper = new BatteryStatsHelper(context,
|
||||
true /* collectBatteryBroadcast */);
|
||||
statsHelper.create((Bundle) null);
|
||||
statsHelper.refreshStats(BatteryStats.STATS_SINCE_CHARGED, UserHandle.myUserId());
|
||||
|
||||
final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
|
||||
while (state.keepRunning()) {
|
||||
state.pauseTiming();
|
||||
statsHelper.clearStats();
|
||||
state.resumeTiming();
|
||||
|
||||
statsHelper.getStats();
|
||||
|
||||
assertThat(statsHelper.getUsageList()).isNotEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Measures performance of the {@link BatteryStatsHelper#getStats(boolean)}, which does
|
||||
* not trigger a sync and just returns current values.
|
||||
*/
|
||||
@Test
|
||||
public void testGetStats_cached() {
|
||||
final Context context = InstrumentationRegistry.getContext();
|
||||
final BatteryStatsHelper statsHelper = new BatteryStatsHelper(context,
|
||||
true /* collectBatteryBroadcast */);
|
||||
statsHelper.create((Bundle) null);
|
||||
statsHelper.refreshStats(BatteryStats.STATS_SINCE_CHARGED, UserHandle.myUserId());
|
||||
|
||||
final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
|
||||
while (state.keepRunning()) {
|
||||
state.pauseTiming();
|
||||
statsHelper.clearStats();
|
||||
state.resumeTiming();
|
||||
|
||||
statsHelper.getStats(false /* forceUpdate */);
|
||||
|
||||
assertThat(statsHelper.getUsageList()).isNotEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPowerCalculation() {
|
||||
final Context context = InstrumentationRegistry.getContext();
|
||||
final BatteryStatsHelper statsHelper = new BatteryStatsHelper(context,
|
||||
true /* collectBatteryBroadcast */);
|
||||
statsHelper.create((Bundle) null);
|
||||
statsHelper.getStats();
|
||||
|
||||
final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
|
||||
while (state.keepRunning()) {
|
||||
// This will use the cached BatteryStatsObject
|
||||
statsHelper.refreshStats(BatteryStats.STATS_SINCE_CHARGED, UserHandle.myUserId());
|
||||
|
||||
assertThat(statsHelper.getUsageList()).isNotEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEndToEnd() {
|
||||
final Context context = InstrumentationRegistry.getContext();
|
||||
final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
|
||||
while (state.keepRunning()) {
|
||||
final BatteryStatsHelper statsHelper = new BatteryStatsHelper(context,
|
||||
true /* collectBatteryBroadcast */);
|
||||
statsHelper.create((Bundle) null);
|
||||
statsHelper.clearStats();
|
||||
statsHelper.refreshStats(BatteryStats.STATS_SINCE_CHARGED, UserHandle.myUserId());
|
||||
|
||||
state.pauseTiming();
|
||||
|
||||
List<BatterySipper> usageList = statsHelper.getUsageList();
|
||||
double power = 0;
|
||||
for (int i = 0; i < usageList.size(); i++) {
|
||||
BatterySipper sipper = usageList.get(i);
|
||||
power += sipper.sumPower();
|
||||
}
|
||||
|
||||
assertThat(power).isGreaterThan(0.0);
|
||||
|
||||
state.resumeTiming();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user