Merge "Convert SensorPowerCalculator to work with BatteryUsageStats"
This commit is contained in:
committed by
Android (Google) Code Review
commit
d23c73f017
@@ -45,6 +45,8 @@ public abstract class BatteryConsumer {
|
||||
POWER_COMPONENT_FLASHLIGHT,
|
||||
POWER_COMPONENT_MOBILE_RADIO,
|
||||
POWER_COMPONENT_SYSTEM_SERVICES,
|
||||
POWER_COMPONENT_SENSORS,
|
||||
POWER_COMPONENT_GNSS,
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public static @interface PowerComponent {
|
||||
@@ -59,8 +61,10 @@ public abstract class BatteryConsumer {
|
||||
public static final int POWER_COMPONENT_FLASHLIGHT = 6;
|
||||
public static final int POWER_COMPONENT_SYSTEM_SERVICES = 7;
|
||||
public static final int POWER_COMPONENT_MOBILE_RADIO = 8;
|
||||
public static final int POWER_COMPONENT_SENSORS = 9;
|
||||
public static final int POWER_COMPONENT_GNSS = 10;
|
||||
|
||||
public static final int POWER_COMPONENT_COUNT = 9;
|
||||
public static final int POWER_COMPONENT_COUNT = 11;
|
||||
|
||||
public static final int FIRST_CUSTOM_POWER_COMPONENT_ID = 1000;
|
||||
public static final int LAST_CUSTOM_POWER_COMPONENT_ID = 9999;
|
||||
@@ -90,6 +94,8 @@ public abstract class BatteryConsumer {
|
||||
TIME_COMPONENT_CAMERA,
|
||||
TIME_COMPONENT_FLASHLIGHT,
|
||||
TIME_COMPONENT_MOBILE_RADIO,
|
||||
TIME_COMPONENT_SENSORS,
|
||||
TIME_COMPONENT_GNSS,
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public static @interface TimeComponent {
|
||||
@@ -104,8 +110,10 @@ public abstract class BatteryConsumer {
|
||||
public static final int TIME_COMPONENT_VIDEO = 6;
|
||||
public static final int TIME_COMPONENT_FLASHLIGHT = 7;
|
||||
public static final int TIME_COMPONENT_MOBILE_RADIO = 8;
|
||||
public static final int TIME_COMPONENT_SENSORS = 9;
|
||||
public static final int TIME_COMPONENT_GNSS = 10;
|
||||
|
||||
public static final int TIME_COMPONENT_COUNT = 9;
|
||||
public static final int TIME_COMPONENT_COUNT = 11;
|
||||
|
||||
public static final int FIRST_CUSTOM_TIME_COMPONENT_ID = 1000;
|
||||
public static final int LAST_CUSTOM_TIME_COMPONENT_ID = 9999;
|
||||
|
||||
@@ -339,8 +339,9 @@ public class BatteryStatsHelper {
|
||||
}
|
||||
mPowerCalculators.add(new WifiPowerCalculator(mPowerProfile));
|
||||
mPowerCalculators.add(new BluetoothPowerCalculator(mPowerProfile));
|
||||
mPowerCalculators.add(new SensorPowerCalculator(mPowerProfile,
|
||||
mPowerCalculators.add(new SensorPowerCalculator(
|
||||
mContext.getSystemService(SensorManager.class)));
|
||||
mPowerCalculators.add(new GnssPowerCalculator(mPowerProfile));
|
||||
mPowerCalculators.add(new CameraPowerCalculator(mPowerProfile));
|
||||
mPowerCalculators.add(new FlashlightPowerCalculator(mPowerProfile));
|
||||
mPowerCalculators.add(new MediaPowerCalculator(mPowerProfile));
|
||||
|
||||
@@ -62,8 +62,9 @@ public class BatteryUsageStatsProvider {
|
||||
}
|
||||
mPowerCalculators.add(new WifiPowerCalculator(mPowerProfile));
|
||||
mPowerCalculators.add(new BluetoothPowerCalculator(mPowerProfile));
|
||||
mPowerCalculators.add(new SensorPowerCalculator(mPowerProfile,
|
||||
mPowerCalculators.add(new SensorPowerCalculator(
|
||||
mContext.getSystemService(SensorManager.class)));
|
||||
mPowerCalculators.add(new GnssPowerCalculator(mPowerProfile));
|
||||
mPowerCalculators.add(new CameraPowerCalculator(mPowerProfile));
|
||||
mPowerCalculators.add(new FlashlightPowerCalculator(mPowerProfile));
|
||||
mPowerCalculators.add(new AudioPowerCalculator(mPowerProfile));
|
||||
|
||||
124
core/java/com/android/internal/os/GnssPowerCalculator.java
Normal file
124
core/java/com/android/internal/os/GnssPowerCalculator.java
Normal file
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright (C) 2015 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 android.location.GnssSignalQuality;
|
||||
import android.os.BatteryConsumer;
|
||||
import android.os.BatteryStats;
|
||||
import android.os.BatteryUsageStats;
|
||||
import android.os.BatteryUsageStatsQuery;
|
||||
import android.os.UidBatteryConsumer;
|
||||
import android.os.UserHandle;
|
||||
import android.util.SparseArray;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Estimates the amount of power consumed by the GNSS (e.g. GPS).
|
||||
*/
|
||||
public class GnssPowerCalculator extends PowerCalculator {
|
||||
private final double mAveragePowerGnssOn;
|
||||
private final double[] mAveragePowerPerSignalQuality;
|
||||
|
||||
public GnssPowerCalculator(PowerProfile profile) {
|
||||
mAveragePowerGnssOn = profile.getAveragePowerOrDefault(PowerProfile.POWER_GPS_ON, -1);
|
||||
mAveragePowerPerSignalQuality =
|
||||
new double[GnssSignalQuality.NUM_GNSS_SIGNAL_QUALITY_LEVELS];
|
||||
for (int i = 0; i < GnssSignalQuality.NUM_GNSS_SIGNAL_QUALITY_LEVELS; i++) {
|
||||
mAveragePowerPerSignalQuality[i] = profile.getAveragePower(
|
||||
PowerProfile.POWER_GPS_SIGNAL_QUALITY_BASED, i);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void calculate(BatteryUsageStats.Builder builder, BatteryStats batteryStats,
|
||||
long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query,
|
||||
SparseArray<UserHandle> asUsers) {
|
||||
final double averageGnssPowerMa = getAverageGnssPower(batteryStats, rawRealtimeUs,
|
||||
BatteryStats.STATS_SINCE_CHARGED);
|
||||
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, app.getBatteryStatsUid(), rawRealtimeUs, rawUptimeUs, query,
|
||||
averageGnssPowerMa);
|
||||
}
|
||||
}
|
||||
|
||||
private void calculateApp(UidBatteryConsumer.Builder app, BatteryStats.Uid u,
|
||||
long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query,
|
||||
double averageGnssPowerMa) {
|
||||
final long durationMs = computeDuration(u, rawRealtimeUs, BatteryStats.STATS_SINCE_CHARGED);
|
||||
double powerMah = computePower(durationMs, averageGnssPowerMa);
|
||||
app.setUsageDurationMillis(BatteryConsumer.TIME_COMPONENT_GNSS, durationMs)
|
||||
.setConsumedPower(BatteryConsumer.POWER_COMPONENT_GNSS, powerMah);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void calculate(List<BatterySipper> sippers, BatteryStats batteryStats,
|
||||
long rawRealtimeUs, long rawUptimeUs, int statsType, SparseArray<UserHandle> asUsers) {
|
||||
double averageGnssPowerMa = getAverageGnssPower(batteryStats, rawRealtimeUs, statsType);
|
||||
for (int i = sippers.size() - 1; i >= 0; i--) {
|
||||
final BatterySipper app = sippers.get(i);
|
||||
if (app.drainType == BatterySipper.DrainType.APP) {
|
||||
calculateApp(app, app.uidObj, rawRealtimeUs, statsType, averageGnssPowerMa);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void calculateApp(BatterySipper app, BatteryStats.Uid u, long rawRealtimeUs,
|
||||
int statsType, double averageGnssPowerMa) {
|
||||
final long durationMs = computeDuration(u, rawRealtimeUs, BatteryStats.STATS_SINCE_CHARGED);
|
||||
double powerMah = computePower(durationMs, averageGnssPowerMa);
|
||||
|
||||
app.gpsTimeMs = durationMs;
|
||||
app.gpsPowerMah = powerMah;
|
||||
}
|
||||
|
||||
private long computeDuration(BatteryStats.Uid u, long rawRealtimeUs, int statsType) {
|
||||
final SparseArray<? extends BatteryStats.Uid.Sensor> sensorStats = u.getSensorStats();
|
||||
final BatteryStats.Uid.Sensor sensor = sensorStats.get(BatteryStats.Uid.Sensor.GPS);
|
||||
if (sensor == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
final BatteryStats.Timer timer = sensor.getSensorTime();
|
||||
return timer.getTotalTimeLocked(rawRealtimeUs, statsType) / 1000;
|
||||
}
|
||||
|
||||
private double computePower(long sensorTime, double averageGnssPowerMa) {
|
||||
return (sensorTime * averageGnssPowerMa) / (1000 * 60 * 60);
|
||||
}
|
||||
|
||||
private double getAverageGnssPower(BatteryStats stats, long rawRealtimeUs, int statsType) {
|
||||
double averagePower = mAveragePowerGnssOn;
|
||||
if (averagePower != -1) {
|
||||
return averagePower;
|
||||
}
|
||||
averagePower = 0;
|
||||
long totalTime = 0;
|
||||
double totalPower = 0;
|
||||
for (int i = 0; i < GnssSignalQuality.NUM_GNSS_SIGNAL_QUALITY_LEVELS; i++) {
|
||||
long timePerLevel = stats.getGpsSignalQualityTime(i, rawRealtimeUs, statsType);
|
||||
totalTime += timePerLevel;
|
||||
totalPower += mAveragePowerPerSignalQuality[i] * timePerLevel;
|
||||
}
|
||||
if (totalTime != 0) {
|
||||
averagePower = totalPower / totalTime;
|
||||
}
|
||||
return averagePower;
|
||||
}
|
||||
}
|
||||
@@ -17,81 +17,79 @@ package com.android.internal.os;
|
||||
|
||||
import android.hardware.Sensor;
|
||||
import android.hardware.SensorManager;
|
||||
import android.location.GnssSignalQuality;
|
||||
import android.os.BatteryConsumer;
|
||||
import android.os.BatteryStats;
|
||||
import android.os.UserHandle;
|
||||
import android.os.BatteryUsageStatsQuery;
|
||||
import android.os.UidBatteryConsumer;
|
||||
import android.util.SparseArray;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class SensorPowerCalculator extends PowerCalculator {
|
||||
private final PowerProfile mPowerProfile;
|
||||
private final List<Sensor> mSensors;
|
||||
private double mGpsPower;
|
||||
private final SparseArray<Sensor> mSensors;
|
||||
|
||||
public SensorPowerCalculator(PowerProfile profile, SensorManager sensorManager) {
|
||||
mPowerProfile = profile;
|
||||
mSensors = sensorManager.getSensorList(Sensor.TYPE_ALL);
|
||||
public SensorPowerCalculator(SensorManager sensorManager) {
|
||||
List<Sensor> sensors = sensorManager.getSensorList(Sensor.TYPE_ALL);
|
||||
mSensors = new SparseArray<>(sensors.size());
|
||||
for (int i = 0; i < sensors.size(); i++) {
|
||||
Sensor sensor = sensors.get(i);
|
||||
mSensors.put(sensor.getHandle(), sensor);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void calculate(List<BatterySipper> sippers, BatteryStats batteryStats,
|
||||
long rawRealtimeUs, long rawUptimeUs, int statsType, SparseArray<UserHandle> asUsers) {
|
||||
mGpsPower = getAverageGpsPower(batteryStats, rawRealtimeUs, statsType);
|
||||
super.calculate(sippers, batteryStats, rawRealtimeUs, rawUptimeUs, statsType, asUsers);
|
||||
protected void calculateApp(UidBatteryConsumer.Builder app, BatteryStats.Uid u,
|
||||
long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query) {
|
||||
app.setUsageDurationMillis(BatteryConsumer.TIME_COMPONENT_SENSORS,
|
||||
calculateDuration(u, rawRealtimeUs, BatteryStats.STATS_SINCE_CHARGED))
|
||||
.setConsumedPower(BatteryConsumer.POWER_COMPONENT_SENSORS,
|
||||
calculatePowerMah(u, rawRealtimeUs, BatteryStats.STATS_SINCE_CHARGED));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void calculateApp(BatterySipper app, BatteryStats.Uid u, long rawRealtimeUs,
|
||||
long rawUptimeUs, int statsType) {
|
||||
// Process Sensor usage
|
||||
app.sensorPowerMah = calculatePowerMah(u, rawRealtimeUs, statsType);
|
||||
}
|
||||
|
||||
private long calculateDuration(BatteryStats.Uid u, long rawRealtimeUs, int statsType) {
|
||||
long durationMs = 0;
|
||||
final SparseArray<? extends BatteryStats.Uid.Sensor> sensorStats = u.getSensorStats();
|
||||
final int NSE = sensorStats.size();
|
||||
for (int ise = 0; ise < NSE; ise++) {
|
||||
final BatteryStats.Uid.Sensor sensor = sensorStats.valueAt(ise);
|
||||
final int sensorHandle = sensorStats.keyAt(ise);
|
||||
if (sensorHandle == BatteryStats.Uid.Sensor.GPS) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final BatteryStats.Uid.Sensor sensor = sensorStats.valueAt(ise);
|
||||
final BatteryStats.Timer timer = sensor.getSensorTime();
|
||||
durationMs += timer.getTotalTimeLocked(rawRealtimeUs, statsType) / 1000;
|
||||
}
|
||||
return durationMs;
|
||||
}
|
||||
|
||||
private double calculatePowerMah(BatteryStats.Uid u, long rawRealtimeUs, int statsType) {
|
||||
double powerMah = 0;
|
||||
final SparseArray<? extends BatteryStats.Uid.Sensor> sensorStats = u.getSensorStats();
|
||||
final int count = sensorStats.size();
|
||||
for (int ise = 0; ise < count; ise++) {
|
||||
final int sensorHandle = sensorStats.keyAt(ise);
|
||||
// TODO(b/178127364): remove BatteryStats.Uid.Sensor.GPS and references to it.
|
||||
if (sensorHandle == BatteryStats.Uid.Sensor.GPS) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final BatteryStats.Uid.Sensor sensor = sensorStats.valueAt(ise);
|
||||
final BatteryStats.Timer timer = sensor.getSensorTime();
|
||||
final long sensorTime = timer.getTotalTimeLocked(rawRealtimeUs, statsType) / 1000;
|
||||
|
||||
switch (sensorHandle) {
|
||||
case BatteryStats.Uid.Sensor.GPS:
|
||||
app.gpsTimeMs = sensorTime;
|
||||
app.gpsPowerMah = (app.gpsTimeMs * mGpsPower) / (1000 * 60 * 60);
|
||||
break;
|
||||
default:
|
||||
final int sensorsCount = mSensors.size();
|
||||
for (int i = 0; i < sensorsCount; i++) {
|
||||
final Sensor s = mSensors.get(i);
|
||||
if (s.getHandle() == sensorHandle) {
|
||||
app.sensorPowerMah += (sensorTime * s.getPower()) / (1000 * 60 * 60);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
if (sensorTime != 0) {
|
||||
Sensor s = mSensors.get(sensorHandle);
|
||||
if (s != null) {
|
||||
powerMah += (sensorTime * s.getPower()) / (1000 * 60 * 60);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private double getAverageGpsPower(BatteryStats stats, long rawRealtimeUs,
|
||||
int statsType) {
|
||||
double averagePower =
|
||||
mPowerProfile.getAveragePowerOrDefault(PowerProfile.POWER_GPS_ON, -1);
|
||||
if (averagePower != -1) {
|
||||
return averagePower;
|
||||
}
|
||||
averagePower = 0;
|
||||
long totalTime = 0;
|
||||
double totalPower = 0;
|
||||
for (int i = 0; i < GnssSignalQuality.NUM_GNSS_SIGNAL_QUALITY_LEVELS; i++) {
|
||||
long timePerLevel = stats.getGpsSignalQualityTime(i, rawRealtimeUs, statsType);
|
||||
totalTime += timePerLevel;
|
||||
totalPower +=
|
||||
mPowerProfile.getAveragePower(PowerProfile.POWER_GPS_SIGNAL_QUALITY_BASED, i)
|
||||
* timePerLevel;
|
||||
}
|
||||
if (totalTime != 0) {
|
||||
averagePower = totalPower / totalTime;
|
||||
}
|
||||
return averagePower;
|
||||
return powerMah;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,6 +46,7 @@ import org.junit.runners.Suite;
|
||||
BstatsCpuTimesValidationTest.class,
|
||||
CameraPowerCalculatorTest.class,
|
||||
FlashlightPowerCalculatorTest.class,
|
||||
GnssPowerCalculatorTest.class,
|
||||
IdlePowerCalculatorTest.class,
|
||||
KernelCpuProcStringReaderTest.class,
|
||||
KernelCpuUidActiveTimeReaderTest.class,
|
||||
@@ -62,6 +63,7 @@ import org.junit.runners.Suite;
|
||||
PowerCalculatorTest.class,
|
||||
PowerProfileTest.class,
|
||||
ScreenPowerCalculatorTest.class,
|
||||
SensorPowerCalculatorTest.class,
|
||||
SystemServicePowerCalculatorTest.class,
|
||||
VideoPowerCalculatorTest.class,
|
||||
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.os.BatteryConsumer;
|
||||
import android.os.Process;
|
||||
import android.os.UidBatteryConsumer;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
@SmallTest
|
||||
public class GnssPowerCalculatorTest {
|
||||
private static final double PRECISION = 0.00001;
|
||||
|
||||
private static final int APP_UID = Process.FIRST_APPLICATION_UID + 42;
|
||||
|
||||
@Rule
|
||||
public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule()
|
||||
.setAveragePower(PowerProfile.POWER_GPS_ON, 360.0)
|
||||
.setAveragePower(PowerProfile.POWER_GPS_SIGNAL_QUALITY_BASED,
|
||||
new double[] {720.0, 1440.0, 1800.0});
|
||||
|
||||
@Test
|
||||
public void testTimerBasedModel() {
|
||||
BatteryStatsImpl.Uid uidStats = mStatsRule.getUidStats(APP_UID);
|
||||
uidStats.noteStartGps(1000);
|
||||
uidStats.noteStopGps(2000);
|
||||
|
||||
GnssPowerCalculator calculator =
|
||||
new GnssPowerCalculator(mStatsRule.getPowerProfile());
|
||||
|
||||
mStatsRule.apply(calculator);
|
||||
|
||||
UidBatteryConsumer consumer = mStatsRule.getUidBatteryConsumer(APP_UID);
|
||||
assertThat(consumer.getUsageDurationMillis(BatteryConsumer.TIME_COMPONENT_GNSS))
|
||||
.isEqualTo(1000);
|
||||
assertThat(consumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_GNSS))
|
||||
.isWithin(PRECISION).of(0.1);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.hardware.Sensor;
|
||||
import android.hardware.SensorManager;
|
||||
import android.hardware.input.InputSensorInfo;
|
||||
import android.os.BatteryConsumer;
|
||||
import android.os.Process;
|
||||
import android.os.UidBatteryConsumer;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
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)
|
||||
@SmallTest
|
||||
public class SensorPowerCalculatorTest {
|
||||
private static final double PRECISION = 0.00001;
|
||||
|
||||
private static final int SENSOR_HANDLE_1 = 1;
|
||||
private static final int SENSOR_HANDLE_2 = 2;
|
||||
|
||||
private static final int APP_UID = Process.FIRST_APPLICATION_UID + 42;
|
||||
|
||||
@Rule
|
||||
public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule();
|
||||
|
||||
@Test
|
||||
public void testTimerBasedModel() {
|
||||
Sensor sensor1 = createSensor(SENSOR_HANDLE_1, Sensor.TYPE_AMBIENT_TEMPERATURE, 360);
|
||||
Sensor sensor2 = createSensor(SENSOR_HANDLE_2, Sensor.TYPE_STEP_COUNTER, 720);
|
||||
|
||||
SensorManager sensorManager = mock(SensorManager.class);
|
||||
when(sensorManager.getSensorList(Sensor.TYPE_ALL))
|
||||
.thenReturn(List.of(sensor1, sensor2));
|
||||
|
||||
BatteryStatsImpl.Uid uidStats = mStatsRule.getUidStats(APP_UID);
|
||||
uidStats.noteStartSensor(SENSOR_HANDLE_1, 1000);
|
||||
uidStats.noteStopSensor(SENSOR_HANDLE_1, 2000);
|
||||
uidStats.noteStartSensor(SENSOR_HANDLE_2, 3000);
|
||||
uidStats.noteStopSensor(SENSOR_HANDLE_2, 5000);
|
||||
|
||||
SensorPowerCalculator calculator = new SensorPowerCalculator(sensorManager);
|
||||
|
||||
mStatsRule.apply(calculator);
|
||||
|
||||
UidBatteryConsumer consumer = mStatsRule.getUidBatteryConsumer(APP_UID);
|
||||
assertThat(consumer.getUsageDurationMillis(BatteryConsumer.TIME_COMPONENT_SENSORS))
|
||||
.isEqualTo(3000);
|
||||
assertThat(consumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_SENSORS))
|
||||
.isWithin(PRECISION).of(0.5);
|
||||
}
|
||||
|
||||
private Sensor createSensor(int handle, int type, double power) {
|
||||
return new Sensor(new InputSensorInfo("name", "vendor", 0 /* version */,
|
||||
handle, type, 100.0f /*maxRange */, 0.02f /* resolution */,
|
||||
(float) power, 1000 /* minDelay */, 0 /* fifoReservedEventCount */,
|
||||
0 /* fifoMaxEventCount */, "" /* stringType */, "" /* requiredPermission */,
|
||||
0 /* maxDelay */, 0 /* flags */, 0 /* id */));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user