1 /* 2 * Copyright (C) 2020 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.internal.os; 18 19 import android.os.BatteryStats; 20 import android.os.BatteryUsageStats; 21 import android.os.BatteryUsageStatsQuery; 22 import android.os.Process; 23 import android.os.UidBatteryConsumer; 24 import android.os.UserHandle; 25 import android.util.SparseArray; 26 27 import com.android.internal.util.ArrayUtils; 28 29 import java.util.List; 30 31 /** 32 * Computes power consumed by Users 33 */ 34 public class UserPowerCalculator extends PowerCalculator { 35 36 @Override calculate(BatteryUsageStats.Builder builder, BatteryStats batteryStats, long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query)37 public void calculate(BatteryUsageStats.Builder builder, BatteryStats batteryStats, 38 long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query) { 39 final int[] userIds = query.getUserIds(); 40 if (ArrayUtils.contains(userIds, UserHandle.USER_ALL)) { 41 return; 42 } 43 44 SparseArray<UidBatteryConsumer.Builder> uidBatteryConsumerBuilders = 45 builder.getUidBatteryConsumerBuilders(); 46 47 for (int i = uidBatteryConsumerBuilders.size() - 1; i >= 0; i--) { 48 UidBatteryConsumer.Builder uidBuilder = uidBatteryConsumerBuilders.valueAt(i); 49 final int uid = uidBuilder.getUid(); 50 if (UserHandle.getAppId(uid) < Process.FIRST_APPLICATION_UID) { 51 continue; 52 } 53 54 final int userId = UserHandle.getUserId(uid); 55 if (!ArrayUtils.contains(userIds, userId)) { 56 uidBuilder.excludeFromBatteryUsageStats(); 57 builder.getOrCreateUserBatteryConsumerBuilder(userId) 58 .addUidBatteryConsumer(uidBuilder); 59 } 60 } 61 } 62 63 @Override calculate(List<BatterySipper> sippers, BatteryStats batteryStats, long rawRealtimeUs, long rawUptimeUs, int statsType, SparseArray<UserHandle> asUsers)64 public void calculate(List<BatterySipper> sippers, BatteryStats batteryStats, 65 long rawRealtimeUs, long rawUptimeUs, int statsType, SparseArray<UserHandle> asUsers) { 66 final boolean forAllUsers = (asUsers.get(UserHandle.USER_ALL) != null); 67 if (forAllUsers) { 68 return; 69 } 70 71 SparseArray<BatterySipper> userSippers = new SparseArray<>(); 72 73 for (int i = sippers.size() - 1; i >= 0; i--) { 74 BatterySipper sipper = sippers.get(i); 75 final int uid = sipper.getUid(); 76 final int userId = UserHandle.getUserId(uid); 77 if (asUsers.get(userId) == null 78 && UserHandle.getAppId(uid) >= Process.FIRST_APPLICATION_UID) { 79 // We are told to just report this user's apps as one accumulated entry. 80 BatterySipper userSipper = userSippers.get(userId); 81 if (userSipper == null) { 82 userSipper = new BatterySipper(BatterySipper.DrainType.USER, null, 0); 83 userSipper.userId = userId; 84 userSippers.put(userId, userSipper); 85 } 86 userSipper.add(sipper); 87 sipper.isAggregated = true; 88 } 89 } 90 91 for (int i = 0; i < userSippers.size(); i++) { 92 BatterySipper sipper = userSippers.valueAt(i); 93 if (sipper.sumPower() > 0) { 94 sippers.add(sipper); 95 } 96 } 97 } 98 } 99