Merge "Add SystemBatteryConsumer for the Bluetooth drain type"

This commit is contained in:
TreeHugger Robot
2020-12-19 07:36:44 +00:00
committed by Android (Google) Code Review
9 changed files with 364 additions and 53 deletions

View File

@@ -36,7 +36,9 @@ public abstract class BatteryConsumer {
* @hide
*/
@IntDef(prefix = {"POWER_COMPONENT_"}, value = {
POWER_COMPONENT_USAGE,
POWER_COMPONENT_CPU,
POWER_COMPONENT_BLUETOOTH,
})
@Retention(RetentionPolicy.SOURCE)
public static @interface PowerComponent {
@@ -44,8 +46,9 @@ public abstract class BatteryConsumer {
public static final int POWER_COMPONENT_USAGE = 0;
public static final int POWER_COMPONENT_CPU = 1;
public static final int POWER_COMPONENT_BLUETOOTH = 2;
public static final int POWER_COMPONENT_COUNT = 2;
public static final int POWER_COMPONENT_COUNT = 3;
public static final int FIRST_CUSTOM_POWER_COMPONENT_ID = 1000;
public static final int LAST_CUSTOM_POWER_COMPONENT_ID = 9999;
@@ -68,8 +71,10 @@ public abstract class BatteryConsumer {
* @hide
*/
@IntDef(prefix = {"TIME_COMPONENT_"}, value = {
TIME_COMPONENT_USAGE,
TIME_COMPONENT_CPU,
TIME_COMPONENT_CPU_FOREGROUND,
TIME_COMPONENT_BLUETOOTH,
})
@Retention(RetentionPolicy.SOURCE)
public static @interface TimeComponent {
@@ -78,8 +83,9 @@ public abstract class BatteryConsumer {
public static final int TIME_COMPONENT_USAGE = 0;
public static final int TIME_COMPONENT_CPU = 1;
public static final int TIME_COMPONENT_CPU_FOREGROUND = 2;
public static final int TIME_COMPONENT_BLUETOOTH = 3;
public static final int TIME_COMPONENT_COUNT = 3;
public static final int TIME_COMPONENT_COUNT = 4;
public static final int FIRST_CUSTOM_TIME_COMPONENT_ID = 1000;
public static final int LAST_CUSTOM_TIME_COMPONENT_ID = 9999;

View File

@@ -289,6 +289,15 @@ class PowerComponents {
return this;
}
public void addPowerAndDuration(Builder other) {
for (int i = 0; i < mPowerComponents.length; i++) {
mPowerComponents[i] += other.mPowerComponents[i];
}
for (int i = 0; i < mTimeComponents.length; i++) {
mTimeComponents[i] += other.mTimeComponents[i];
}
}
/**
* Creates a read-only object out of the Builder values.
*/

View File

@@ -21,6 +21,8 @@ import android.annotation.NonNull;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.List;
/**
@@ -118,6 +120,7 @@ public class SystemBatteryConsumer extends BatteryConsumer implements Parcelable
public static final class Builder extends BaseBuilder<Builder> {
@DrainType
private final int mDrainType;
private List<UidBatteryConsumer.Builder> mUidBatteryConsumers;
Builder(int customPowerComponentCount, int customTimeComponentCount,
boolean includeModeledComponents, @DrainType int drainType) {
@@ -125,11 +128,36 @@ public class SystemBatteryConsumer extends BatteryConsumer implements Parcelable
mDrainType = drainType;
}
/**
* Add a UidBatteryConsumer to this SystemBatteryConsumer. For example,
* the UidBatteryConsumer with the UID == {@link Process#BLUETOOTH_UID} should
* be added to the SystemBatteryConsumer with the drain type == {@link
* #DRAIN_TYPE_BLUETOOTH}.
* <p>
* Calculated power and duration components of the added battery consumers
* are aggregated at the time the SystemBatteryConsumer is built by the {@link #build()}
* method.
* </p>
*/
public void addUidBatteryConsumer(UidBatteryConsumer.Builder uidBatteryConsumerBuilder) {
if (mUidBatteryConsumers == null) {
mUidBatteryConsumers = new ArrayList<>();
}
mUidBatteryConsumers.add(uidBatteryConsumerBuilder);
}
/**
* Creates a read-only object out of the Builder values.
*/
@NonNull
public SystemBatteryConsumer build() {
if (mUidBatteryConsumers != null) {
for (int i = mUidBatteryConsumers.size() - 1; i >= 0; i--) {
UidBatteryConsumer.Builder uidBatteryConsumer = mUidBatteryConsumers.get(i);
mPowerComponentsBuilder.addPowerAndDuration(
uidBatteryConsumer.mPowerComponentsBuilder);
}
}
return new SystemBatteryConsumer(this);
}
}

View File

@@ -29,11 +29,21 @@ public final class UidBatteryConsumer extends BatteryConsumer implements Parcela
private final int mUid;
@Nullable
private final String mPackageWithHighestDrain;
private boolean mSystemComponent;
public int getUid() {
return mUid;
}
/**
* Returns true if this battery consumer is considered to be a part of the operating
* system itself. For example, the UidBatteryConsumer with the UID {@link Process#BLUETOOTH_UID}
* is a system component.
*/
public boolean isSystemComponent() {
return mSystemComponent;
}
@Nullable
public String getPackageWithHighestDrain() {
return mPackageWithHighestDrain;
@@ -42,6 +52,7 @@ public final class UidBatteryConsumer extends BatteryConsumer implements Parcela
private UidBatteryConsumer(@NonNull Builder builder) {
super(builder.mPowerComponentsBuilder.build());
mUid = builder.mUid;
mSystemComponent = builder.mSystemComponent;
mPackageWithHighestDrain = builder.mPackageWithHighestDrain;
}
@@ -84,6 +95,7 @@ public final class UidBatteryConsumer extends BatteryConsumer implements Parcela
private final BatteryStats.Uid mBatteryStatsUid;
private final int mUid;
private String mPackageWithHighestDrain;
private boolean mSystemComponent;
public Builder(int customPowerComponentCount, int customTimeComponentCount,
boolean includeModeledComponents, BatteryStats.Uid batteryStatsUid) {
@@ -117,5 +129,14 @@ public final class UidBatteryConsumer extends BatteryConsumer implements Parcela
mPackageWithHighestDrain = packageName;
return this;
}
/**
* Marks the UidBatteryConsumer as part of the system. For example,
* the UidBatteryConsumer with the UID {@link Process#BLUETOOTH_UID} is considered
* as a system component.
*/
public void setSystemComponent(boolean systemComponent) {
mSystemComponent = systemComponent;
}
}
}

View File

@@ -953,7 +953,8 @@ public class BatteryStatsImpl extends BatteryStats {
/**
* The Bluetooth controller activity (time in tx, rx, idle, and power consumed) for the device.
*/
ControllerActivityCounterImpl mBluetoothActivity;
@VisibleForTesting
protected ControllerActivityCounterImpl mBluetoothActivity;
/**
* The Modem controller activity (time in tx, rx, idle, and power consumed) for the device.

View File

@@ -15,8 +15,13 @@
*/
package com.android.internal.os;
import android.os.BatteryConsumer;
import android.os.BatteryStats;
import android.os.BatteryUsageStats;
import android.os.BatteryUsageStatsQuery;
import android.os.Process;
import android.os.SystemBatteryConsumer;
import android.os.UidBatteryConsumer;
import android.os.UserHandle;
import android.util.Log;
import android.util.SparseArray;
@@ -30,8 +35,16 @@ public class BluetoothPowerCalculator extends PowerCalculator {
private final double mRxMa;
private final double mTxMa;
private final boolean mHasBluetoothPowerController;
private double mAppTotalPowerMah = 0;
private long mAppTotalTimeMs = 0;
private static class PowerAndDuration {
public long durationMs;
public double powerMah;
}
// Objects used for passing calculation results. Fields are used to avoid allocations.
private final PowerAndDuration mUidPowerAndDuration = new PowerAndDuration();
private final PowerAndDuration mTotalPowerAndDuration = new PowerAndDuration();
private final PowerAndDuration mSystemPowerAndDuration = new PowerAndDuration();
public BluetoothPowerCalculator(PowerProfile profile) {
mIdleMa = profile.getAveragePower(PowerProfile.POWER_BLUETOOTH_CONTROLLER_IDLE);
@@ -40,6 +53,63 @@ public class BluetoothPowerCalculator extends PowerCalculator {
mHasBluetoothPowerController = mIdleMa != 0 && mRxMa != 0 && mTxMa != 0;
}
@Override
public void calculate(BatteryUsageStats.Builder builder, BatteryStats batteryStats,
long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query,
SparseArray<UserHandle> asUsers) {
if (!mHasBluetoothPowerController || !batteryStats.hasBluetoothActivityReporting()) {
return;
}
mTotalPowerAndDuration.durationMs = 0;
mTotalPowerAndDuration.powerMah = 0;
SystemBatteryConsumer.Builder systemBatteryConsumerBuilder =
builder.getOrCreateSystemBatteryConsumerBuilder(
SystemBatteryConsumer.DRAIN_TYPE_BLUETOOTH);
final SparseArray<UidBatteryConsumer.Builder> uidBatteryConsumerBuilders =
builder.getUidBatteryConsumerBuilders();
for (int i = uidBatteryConsumerBuilders.size() - 1; i >= 0; i--) {
final UidBatteryConsumer.Builder app = uidBatteryConsumerBuilders.valueAt(i);
calculateApp(app);
if (app.getUid() == Process.BLUETOOTH_UID) {
app.setSystemComponent(true);
systemBatteryConsumerBuilder.addUidBatteryConsumer(app);
}
}
final BatteryStats.ControllerActivityCounter counter =
batteryStats.getBluetoothControllerActivity();
calculatePowerAndDuration(counter, mSystemPowerAndDuration);
// Subtract what the apps used, but clamp to 0.
final long systemComponentDurationMs = Math.max(0,
mSystemPowerAndDuration.durationMs - mTotalPowerAndDuration.durationMs);
final double systemComponentPowerMah = Math.max(0,
mSystemPowerAndDuration.powerMah - mTotalPowerAndDuration.powerMah);
systemBatteryConsumerBuilder
.setUsageDurationMillis(BatteryConsumer.TIME_COMPONENT_BLUETOOTH,
systemComponentDurationMs)
.setConsumedPower(BatteryConsumer.POWER_COMPONENT_BLUETOOTH,
systemComponentPowerMah);
}
private void calculateApp(UidBatteryConsumer.Builder app) {
calculatePowerAndDuration(app.getBatteryStatsUid().getBluetoothControllerActivity(),
mUidPowerAndDuration);
app.setUsageDurationMillis(BatteryConsumer.TIME_COMPONENT_BLUETOOTH,
mUidPowerAndDuration.durationMs)
.setConsumedPower(BatteryConsumer.POWER_COMPONENT_BLUETOOTH,
mUidPowerAndDuration.powerMah);
mTotalPowerAndDuration.powerMah += mUidPowerAndDuration.powerMah;
mTotalPowerAndDuration.durationMs += mUidPowerAndDuration.durationMs;
}
@Override
public void calculate(List<BatterySipper> sippers, BatteryStats batteryStats,
long rawRealtimeUs, long rawUptimeUs, int statsType, SparseArray<UserHandle> asUsers) {
@@ -47,10 +117,27 @@ public class BluetoothPowerCalculator extends PowerCalculator {
return;
}
mTotalPowerAndDuration.durationMs = 0;
mTotalPowerAndDuration.powerMah = 0;
super.calculate(sippers, batteryStats, rawRealtimeUs, rawUptimeUs, statsType, asUsers);
BatterySipper bs = new BatterySipper(BatterySipper.DrainType.BLUETOOTH, null, 0);
calculateRemaining(bs, batteryStats, rawRealtimeUs, rawUptimeUs, statsType);
calculatePowerAndDuration(batteryStats.getBluetoothControllerActivity(),
mSystemPowerAndDuration);
// Subtract what the apps used, but clamp to 0.
double powerMah =
Math.max(0, mSystemPowerAndDuration.powerMah - mTotalPowerAndDuration.powerMah);
final long durationMs =
Math.max(0, mSystemPowerAndDuration.durationMs - mTotalPowerAndDuration.durationMs);
if (DEBUG && powerMah != 0) {
Log.d(TAG, "Bluetooth active: time=" + (durationMs)
+ " power=" + formatCharge(powerMah));
}
bs.bluetoothPowerMah = powerMah;
bs.bluetoothRunningTimeMs = durationMs;
for (int i = sippers.size() - 1; i >= 0; i--) {
BatterySipper app = sippers.get(i);
@@ -69,65 +156,42 @@ public class BluetoothPowerCalculator extends PowerCalculator {
protected void calculateApp(BatterySipper app, BatteryStats.Uid u, long rawRealtimeUs,
long rawUptimeUs, int statsType) {
final BatteryStats.ControllerActivityCounter counter = u.getBluetoothControllerActivity();
if (counter == null) {
return;
}
calculatePowerAndDuration(u.getBluetoothControllerActivity(), mUidPowerAndDuration);
final long idleTimeMs = counter.getIdleTimeCounter().getCountLocked(statsType);
final long rxTimeMs = counter.getRxTimeCounter().getCountLocked(statsType);
final long txTimeMs = counter.getTxTimeCounters()[0].getCountLocked(statsType);
final long totalTimeMs = idleTimeMs + txTimeMs + rxTimeMs;
double powerMah = counter.getPowerCounter().getCountLocked(statsType)
/ (double)(1000*60*60);
if (powerMah == 0) {
powerMah = ((idleTimeMs * mIdleMa) + (rxTimeMs * mRxMa) + (txTimeMs * mTxMa))
/ (1000*60*60);
}
app.bluetoothPowerMah = powerMah;
app.bluetoothRunningTimeMs = totalTimeMs;
app.bluetoothPowerMah = mUidPowerAndDuration.powerMah;
app.bluetoothRunningTimeMs = mUidPowerAndDuration.durationMs;
app.btRxBytes = u.getNetworkActivityBytes(BatteryStats.NETWORK_BT_RX_DATA, statsType);
app.btTxBytes = u.getNetworkActivityBytes(BatteryStats.NETWORK_BT_TX_DATA, statsType);
mAppTotalPowerMah += powerMah;
mAppTotalTimeMs += totalTimeMs;
mTotalPowerAndDuration.powerMah += mUidPowerAndDuration.powerMah;
mTotalPowerAndDuration.durationMs += mUidPowerAndDuration.durationMs;
}
private void calculateRemaining(BatterySipper app, BatteryStats stats, long rawRealtimeUs,
long rawUptimeUs, int statsType) {
final BatteryStats.ControllerActivityCounter counter =
stats.getBluetoothControllerActivity();
private void calculatePowerAndDuration(BatteryStats.ControllerActivityCounter counter,
PowerAndDuration powerAndDuration) {
if (counter == null) {
powerAndDuration.durationMs = 0;
powerAndDuration.powerMah = 0;
return;
}
final long idleTimeMs = counter.getIdleTimeCounter().getCountLocked(statsType);
final long txTimeMs = counter.getTxTimeCounters()[0].getCountLocked(statsType);
final long rxTimeMs = counter.getRxTimeCounter().getCountLocked(statsType);
final long idleTimeMs =
counter.getIdleTimeCounter().getCountLocked(BatteryStats.STATS_SINCE_CHARGED);
final long rxTimeMs =
counter.getRxTimeCounter().getCountLocked(BatteryStats.STATS_SINCE_CHARGED);
final long txTimeMs =
counter.getTxTimeCounters()[0].getCountLocked(BatteryStats.STATS_SINCE_CHARGED);
final long totalTimeMs = idleTimeMs + txTimeMs + rxTimeMs;
double powerMah = counter.getPowerCounter().getCountLocked(statsType)
/ (double)(1000*60*60);
double powerMah =
counter.getPowerCounter().getCountLocked(BatteryStats.STATS_SINCE_CHARGED)
/ (double) (1000 * 60 * 60);
if (powerMah == 0) {
// Some devices do not report the power, so calculate it.
powerMah = ((idleTimeMs * mIdleMa) + (rxTimeMs * mRxMa) + (txTimeMs * mTxMa))
/ (1000*60*60);
/ (1000 * 60 * 60);
}
// Subtract what the apps used, but clamp to 0.
powerMah = Math.max(0, powerMah - mAppTotalPowerMah);
if (DEBUG && powerMah != 0) {
Log.d(TAG, "Bluetooth active: time=" + (totalTimeMs)
+ " power=" + formatCharge(powerMah));
}
app.bluetoothPowerMah = powerMah;
app.bluetoothRunningTimeMs = Math.max(0, totalTimeMs - mAppTotalTimeMs);
}
@Override
public void reset() {
mAppTotalPowerMah = 0;
mAppTotalTimeMs = 0;
powerAndDuration.durationMs = totalTimeMs;
powerAndDuration.powerMah = powerMah;
}
}

View File

@@ -39,6 +39,7 @@ import org.junit.runners.Suite;
BatteryStatsTimerTest.class,
BatteryStatsUidTest.class,
BatteryStatsUserLifecycleTests.class,
BluetoothPowerCalculatorTest.class,
BstatsCpuTimesValidationTest.class,
KernelCpuProcStringReaderTest.class,
KernelCpuUidActiveTimeReaderTest.class,

View File

@@ -0,0 +1,180 @@
/*
* 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 static org.mockito.Mockito.when;
import android.annotation.Nullable;
import android.os.BatteryConsumer;
import android.os.BatteryUsageStats;
import android.os.BatteryUsageStatsQuery;
import android.os.Process;
import android.os.SystemBatteryConsumer;
import android.os.UidBatteryConsumer;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@RunWith(AndroidJUnit4.class)
@SmallTest
public class BluetoothPowerCalculatorTest {
private static final double PRECISION = 0.00001;
private static final int APP_UID = Process.FIRST_APPLICATION_UID + 42;
@Mock
private PowerProfile mMockPowerProfile;
private MockBatteryStatsImpl mMockBatteryStats;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mMockBatteryStats = new MockBatteryStatsImpl(new MockClocks()) {
@Override
public boolean hasBluetoothActivityReporting() {
return true;
}
};
mMockBatteryStats.getOnBatteryTimeBase().setRunning(true, 100_000, 100_000);
when(mMockPowerProfile.getAveragePower(
PowerProfile.POWER_BLUETOOTH_CONTROLLER_IDLE)).thenReturn(10.0);
when(mMockPowerProfile.getAveragePower(
PowerProfile.POWER_BLUETOOTH_CONTROLLER_RX)).thenReturn(50.0);
when(mMockPowerProfile.getAveragePower(
PowerProfile.POWER_BLUETOOTH_CONTROLLER_TX)).thenReturn(100.0);
}
@Test
public void testTimerBasedModel() {
setDurationsAndPower(
mMockBatteryStats.getUidStatsLocked(Process.BLUETOOTH_UID)
.getOrCreateBluetoothControllerActivityLocked(),
1000, 2000, 3000, 0);
setDurationsAndPower(mMockBatteryStats.getUidStatsLocked(APP_UID)
.getOrCreateBluetoothControllerActivityLocked(),
4000, 5000, 6000, 0);
setDurationsAndPower((BatteryStatsImpl.ControllerActivityCounterImpl)
mMockBatteryStats.getBluetoothControllerActivity(),
6000, 8000, 10000, 0);
BatteryUsageStats batteryUsageStats = buildBatteryUsageStats();
assertBluetoothPowerAndDuration(
getUidBatteryConsumer(batteryUsageStats, Process.BLUETOOTH_UID),
0.11388, 6000);
assertBluetoothPowerAndDuration(
getUidBatteryConsumer(batteryUsageStats, APP_UID),
0.24722, 15000);
assertBluetoothPowerAndDuration(
getBluetoothSystemBatteryConsumer(batteryUsageStats,
SystemBatteryConsumer.DRAIN_TYPE_BLUETOOTH),
0.15833, 9000);
}
@Test
public void testReportedPowerBasedModel() {
setDurationsAndPower(
mMockBatteryStats.getUidStatsLocked(Process.BLUETOOTH_UID)
.getOrCreateBluetoothControllerActivityLocked(),
1000, 2000, 3000, 360000);
setDurationsAndPower(mMockBatteryStats.getUidStatsLocked(APP_UID)
.getOrCreateBluetoothControllerActivityLocked(),
4000, 5000, 6000, 720000);
setDurationsAndPower((BatteryStatsImpl.ControllerActivityCounterImpl)
mMockBatteryStats.getBluetoothControllerActivity(),
6000, 8000, 10000, 1260000);
BatteryUsageStats batteryUsageStats = buildBatteryUsageStats();
assertBluetoothPowerAndDuration(
getUidBatteryConsumer(batteryUsageStats, Process.BLUETOOTH_UID),
0.1, 6000);
assertBluetoothPowerAndDuration(
getUidBatteryConsumer(batteryUsageStats, APP_UID),
0.2, 15000);
assertBluetoothPowerAndDuration(
getBluetoothSystemBatteryConsumer(batteryUsageStats,
SystemBatteryConsumer.DRAIN_TYPE_BLUETOOTH),
0.15, 9000);
}
private void setDurationsAndPower(
BatteryStatsImpl.ControllerActivityCounterImpl controllerActivity, int idleDurationMs,
int rxDurationMs, int txDurationMs, long powerMaMs) {
controllerActivity.getIdleTimeCounter().addCountLocked(idleDurationMs);
controllerActivity.getRxTimeCounter().addCountLocked(rxDurationMs);
controllerActivity.getTxTimeCounters()[0].addCountLocked(txDurationMs);
controllerActivity.getPowerCounter().addCountLocked(powerMaMs);
}
private BatteryUsageStats buildBatteryUsageStats() {
BatteryUsageStats.Builder builder = new BatteryUsageStats.Builder(0, 0, false);
builder.getOrCreateUidBatteryConsumerBuilder(
mMockBatteryStats.getUidStatsLocked(Process.BLUETOOTH_UID));
builder.getOrCreateUidBatteryConsumerBuilder(
mMockBatteryStats.getUidStatsLocked(APP_UID));
BluetoothPowerCalculator bpc = new BluetoothPowerCalculator(mMockPowerProfile);
bpc.calculate(builder, mMockBatteryStats, 200_000, 200_000, BatteryUsageStatsQuery.DEFAULT,
null);
return builder.build();
}
private UidBatteryConsumer getUidBatteryConsumer(BatteryUsageStats batteryUsageStats, int uid) {
for (UidBatteryConsumer ubc : batteryUsageStats.getUidBatteryConsumers()) {
if (ubc.getUid() == uid) {
return ubc;
}
}
return null;
}
private SystemBatteryConsumer getBluetoothSystemBatteryConsumer(
BatteryUsageStats batteryUsageStats, int drainType) {
for (SystemBatteryConsumer sbc : batteryUsageStats.getSystemBatteryConsumers()) {
if (sbc.getDrainType() == drainType) {
return sbc;
}
}
return null;
}
private void assertBluetoothPowerAndDuration(@Nullable BatteryConsumer batteryConsumer,
double powerMah, int durationMs) {
assertThat(batteryConsumer).isNotNull();
double consumedPower = batteryConsumer.getConsumedPower(
BatteryConsumer.POWER_COMPONENT_BLUETOOTH);
assertThat(consumedPower).isWithin(PRECISION).of(powerMah);
long usageDurationMillis = batteryConsumer.getUsageDurationMillis(
BatteryConsumer.TIME_COMPONENT_BLUETOOTH);
assertThat(usageDurationMillis).isEqualTo(durationMs);
}
}

View File

@@ -47,6 +47,7 @@ public class MockBatteryStatsImpl extends BatteryStatsImpl {
mScreenDozeTimer = new BatteryStatsImpl.StopwatchTimer(clocks, null, -1, null,
mOnBatteryTimeBase);
mBluetoothScanTimer = new StopwatchTimer(mClocks, null, -14, null, mOnBatteryTimeBase);
mBluetoothActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, 1);
setExternalStatsSyncLocked(new DummyExternalStatsSync());
for (int i = 0; i < GnssSignalQuality.NUM_GNSS_SIGNAL_QUALITY_LEVELS; i++) {