1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.internal.os; 17 18 import android.hardware.Sensor; 19 import android.hardware.SensorManager; 20 import android.os.BatteryConsumer; 21 import android.os.BatteryStats; 22 import android.os.BatteryUsageStats; 23 import android.os.BatteryUsageStatsQuery; 24 import android.os.UidBatteryConsumer; 25 import android.util.SparseArray; 26 27 import java.util.List; 28 29 public class SensorPowerCalculator extends PowerCalculator { 30 private final SparseArray<Sensor> mSensors; 31 SensorPowerCalculator(SensorManager sensorManager)32 public SensorPowerCalculator(SensorManager sensorManager) { 33 List<Sensor> sensors = sensorManager.getSensorList(Sensor.TYPE_ALL); 34 mSensors = new SparseArray<>(sensors.size()); 35 for (int i = 0; i < sensors.size(); i++) { 36 Sensor sensor = sensors.get(i); 37 mSensors.put(sensor.getHandle(), sensor); 38 } 39 } 40 41 @Override isPowerComponentSupported(@atteryConsumer.PowerComponent int powerComponent)42 public boolean isPowerComponentSupported(@BatteryConsumer.PowerComponent int powerComponent) { 43 return powerComponent == BatteryConsumer.POWER_COMPONENT_SENSORS; 44 } 45 46 @Override calculate(BatteryUsageStats.Builder builder, BatteryStats batteryStats, long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query)47 public void calculate(BatteryUsageStats.Builder builder, BatteryStats batteryStats, 48 long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query) { 49 double appsPowerMah = 0; 50 final SparseArray<UidBatteryConsumer.Builder> uidBatteryConsumerBuilders = 51 builder.getUidBatteryConsumerBuilders(); 52 for (int i = uidBatteryConsumerBuilders.size() - 1; i >= 0; i--) { 53 final UidBatteryConsumer.Builder app = uidBatteryConsumerBuilders.valueAt(i); 54 if (!app.isVirtualUid()) { 55 appsPowerMah += calculateApp(app, app.getBatteryStatsUid(), rawRealtimeUs); 56 } 57 } 58 59 builder.getAggregateBatteryConsumerBuilder( 60 BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE) 61 .setConsumedPower(BatteryConsumer.POWER_COMPONENT_SENSORS, appsPowerMah); 62 builder.getAggregateBatteryConsumerBuilder( 63 BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS) 64 .setConsumedPower(BatteryConsumer.POWER_COMPONENT_SENSORS, appsPowerMah); 65 } 66 calculateApp(UidBatteryConsumer.Builder app, BatteryStats.Uid u, long rawRealtimeUs)67 private double calculateApp(UidBatteryConsumer.Builder app, BatteryStats.Uid u, 68 long rawRealtimeUs) { 69 final double powerMah = calculatePowerMah(u, rawRealtimeUs, 70 BatteryStats.STATS_SINCE_CHARGED); 71 app.setUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_SENSORS, 72 calculateDuration(u, rawRealtimeUs, BatteryStats.STATS_SINCE_CHARGED)) 73 .setConsumedPower(BatteryConsumer.POWER_COMPONENT_SENSORS, powerMah); 74 return powerMah; 75 } 76 calculateDuration(BatteryStats.Uid u, long rawRealtimeUs, int statsType)77 private long calculateDuration(BatteryStats.Uid u, long rawRealtimeUs, int statsType) { 78 long durationMs = 0; 79 final SparseArray<? extends BatteryStats.Uid.Sensor> sensorStats = u.getSensorStats(); 80 final int NSE = sensorStats.size(); 81 for (int ise = 0; ise < NSE; ise++) { 82 final int sensorHandle = sensorStats.keyAt(ise); 83 if (sensorHandle == BatteryStats.Uid.Sensor.GPS) { 84 continue; 85 } 86 87 final BatteryStats.Uid.Sensor sensor = sensorStats.valueAt(ise); 88 final BatteryStats.Timer timer = sensor.getSensorTime(); 89 durationMs += timer.getTotalTimeLocked(rawRealtimeUs, statsType) / 1000; 90 } 91 return durationMs; 92 } 93 calculatePowerMah(BatteryStats.Uid u, long rawRealtimeUs, int statsType)94 private double calculatePowerMah(BatteryStats.Uid u, long rawRealtimeUs, int statsType) { 95 double powerMah = 0; 96 final SparseArray<? extends BatteryStats.Uid.Sensor> sensorStats = u.getSensorStats(); 97 final int count = sensorStats.size(); 98 for (int ise = 0; ise < count; ise++) { 99 final int sensorHandle = sensorStats.keyAt(ise); 100 // TODO(b/178127364): remove BatteryStats.Uid.Sensor.GPS and references to it. 101 if (sensorHandle == BatteryStats.Uid.Sensor.GPS) { 102 continue; 103 } 104 105 final BatteryStats.Uid.Sensor sensor = sensorStats.valueAt(ise); 106 final BatteryStats.Timer timer = sensor.getSensorTime(); 107 final long sensorTime = timer.getTotalTimeLocked(rawRealtimeUs, statsType) / 1000; 108 if (sensorTime != 0) { 109 Sensor s = mSensors.get(sensorHandle); 110 if (s != null) { 111 powerMah += (sensorTime * s.getPower()) / (1000 * 60 * 60); 112 } 113 } 114 } 115 return powerMah; 116 } 117 } 118