1 /*
2  * Copyright (C) 2021 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 
17 package com.android.server.power.stats;
18 
19 import android.os.BatteryConsumer;
20 import android.os.BatteryStats;
21 import android.os.BatteryUsageStats;
22 import android.os.BatteryUsageStatsQuery;
23 
24 /**
25  * Estimates the battery discharge amounts.
26  */
27 public class BatteryChargeCalculator extends PowerCalculator {
28 
29     @Override
isPowerComponentSupported(@atteryConsumer.PowerComponent int powerComponent)30     public boolean isPowerComponentSupported(@BatteryConsumer.PowerComponent int powerComponent) {
31         // Always apply this power calculator, no matter what power components were requested
32         return true;
33     }
34 
35     @Override
calculate(BatteryUsageStats.Builder builder, BatteryStats batteryStats, long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query)36     public void calculate(BatteryUsageStats.Builder builder, BatteryStats batteryStats,
37             long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query) {
38         builder.setDischargePercentage(
39                 batteryStats.getDischargeAmount(BatteryStats.STATS_SINCE_CHARGED));
40 
41         int batteryCapacityMah = batteryStats.getLearnedBatteryCapacity() / 1000;
42         if (batteryCapacityMah <= 0) {
43             batteryCapacityMah = batteryStats.getMinLearnedBatteryCapacity() / 1000;
44             if (batteryCapacityMah <= 0) {
45                 batteryCapacityMah = batteryStats.getEstimatedBatteryCapacity();
46             }
47         }
48         builder.setBatteryCapacity(batteryCapacityMah);
49 
50         final double dischargedPowerLowerBoundMah =
51                 batteryStats.getLowDischargeAmountSinceCharge() * batteryCapacityMah / 100.0;
52         final double dischargedPowerUpperBoundMah =
53                 batteryStats.getHighDischargeAmountSinceCharge() * batteryCapacityMah / 100.0;
54         builder.setDischargePercentage(
55                 batteryStats.getDischargeAmount(BatteryStats.STATS_SINCE_CHARGED))
56                 .setDischargedPowerRange(dischargedPowerLowerBoundMah,
57                         dischargedPowerUpperBoundMah)
58                 .setDischargeDurationMs(batteryStats.getBatteryRealtime(rawRealtimeUs) / 1000);
59 
60         final long batteryTimeRemainingMs = batteryStats.computeBatteryTimeRemaining(rawRealtimeUs);
61         if (batteryTimeRemainingMs != -1) {
62             builder.setBatteryTimeRemainingMs(batteryTimeRemainingMs / 1000);
63         }
64 
65         final long chargeTimeRemainingMs = batteryStats.computeChargeTimeRemaining(rawRealtimeUs);
66         if (chargeTimeRemainingMs != -1) {
67             builder.setChargeTimeRemainingMs(chargeTimeRemainingMs / 1000);
68         }
69 
70         long dischargeMah = batteryStats.getUahDischarge(BatteryStats.STATS_SINCE_CHARGED) / 1000;
71         if (dischargeMah == 0) {
72             dischargeMah = (long) ((dischargedPowerLowerBoundMah + dischargedPowerUpperBoundMah) / 2
73                     + 0.5);
74         }
75 
76         builder.getAggregateBatteryConsumerBuilder(
77                 BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE)
78                 .setConsumedPower(dischargeMah);
79     }
80 }
81