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.frameworks.core.batterystatsviewer; 18 19 import android.content.pm.ApplicationInfo; 20 import android.content.pm.PackageManager; 21 import android.os.BatteryUsageStats; 22 import android.os.Process; 23 import android.os.UidBatteryConsumer; 24 25 import androidx.annotation.NonNull; 26 27 import java.util.List; 28 29 class BatteryConsumerInfoHelper { 30 31 private static final String SYSTEM_SERVER_PACKAGE_NAME = "android"; 32 33 public static class BatteryConsumerInfo { 34 public String id; 35 public CharSequence label; 36 public double powerMah; 37 public ApplicationInfo iconInfo; 38 public CharSequence packages; 39 public CharSequence details; 40 public BatteryConsumerData.ConsumerType consumerType; 41 } 42 43 @NonNull makeBatteryConsumerInfo( @onNull BatteryUsageStats batteryUsageStats, String batteryConsumerId, PackageManager packageManager)44 public static BatteryConsumerInfo makeBatteryConsumerInfo( 45 @NonNull BatteryUsageStats batteryUsageStats, String batteryConsumerId, 46 PackageManager packageManager) { 47 BatteryConsumerData.ConsumerType consumerType = BatteryConsumerData.getConsumerType( 48 batteryConsumerId); 49 switch (consumerType) { 50 case UID_BATTERY_CONSUMER: 51 final List<UidBatteryConsumer> consumers = 52 batteryUsageStats.getUidBatteryConsumers(); 53 for (UidBatteryConsumer consumer : consumers) { 54 if (BatteryConsumerData.batteryConsumerId(consumer).equals(batteryConsumerId)) { 55 return makeBatteryConsumerInfo(consumer, packageManager); 56 } 57 } 58 break; 59 case DEVICE_POWER_COMPONENT: 60 return makeAggregateBatteryConsumerInfo(batteryUsageStats); 61 } 62 63 BatteryConsumerInfo info = new BatteryConsumerInfo(); 64 info.id = batteryConsumerId; 65 return info; 66 } 67 makeBatteryConsumerInfo( UidBatteryConsumer uidBatteryConsumer, PackageManager packageManager)68 private static BatteryConsumerInfo makeBatteryConsumerInfo( 69 UidBatteryConsumer uidBatteryConsumer, PackageManager packageManager) { 70 BatteryConsumerInfo info = new BatteryConsumerInfo(); 71 info.consumerType = BatteryConsumerData.ConsumerType.UID_BATTERY_CONSUMER; 72 info.id = BatteryConsumerData.batteryConsumerId(uidBatteryConsumer); 73 info.powerMah = uidBatteryConsumer.getConsumedPower(); 74 int uid = uidBatteryConsumer.getUid(); 75 info.details = String.format("UID: %d", uid); 76 String packageWithHighestDrain = uidBatteryConsumer.getPackageWithHighestDrain(); 77 if (uid == Process.ROOT_UID) { 78 info.label = "<root>"; 79 } else { 80 String[] packages = packageManager.getPackagesForUid(uid); 81 String primaryPackageName = null; 82 if (uid == Process.SYSTEM_UID) { 83 primaryPackageName = SYSTEM_SERVER_PACKAGE_NAME; 84 } else if (packages != null) { 85 for (String name : packages) { 86 primaryPackageName = name; 87 if (name.equals(packageWithHighestDrain)) { 88 break; 89 } 90 } 91 } 92 93 if (primaryPackageName != null) { 94 try { 95 ApplicationInfo applicationInfo = 96 packageManager.getApplicationInfo(primaryPackageName, 0); 97 info.label = applicationInfo.loadLabel(packageManager); 98 info.iconInfo = applicationInfo; 99 } catch (PackageManager.NameNotFoundException e) { 100 info.label = primaryPackageName; 101 } 102 } else if (packageWithHighestDrain != null) { 103 info.label = packageWithHighestDrain; 104 } 105 106 if (packages != null && packages.length > 0) { 107 StringBuilder sb = new StringBuilder(); 108 if (primaryPackageName != null) { 109 sb.append(primaryPackageName); 110 } 111 for (String packageName : packages) { 112 if (packageName.equals(primaryPackageName)) { 113 continue; 114 } 115 116 if (sb.length() != 0) { 117 sb.append(", "); 118 } 119 sb.append(packageName); 120 } 121 122 info.packages = sb; 123 } 124 } 125 // Default the app icon to System Server. This includes root, dex2oat and other UIDs. 126 if (info.iconInfo == null) { 127 try { 128 info.iconInfo = 129 packageManager.getApplicationInfo(SYSTEM_SERVER_PACKAGE_NAME, 0); 130 } catch (PackageManager.NameNotFoundException nameNotFoundException) { 131 // Won't happen 132 } 133 } 134 return info; 135 } 136 makeAggregateBatteryConsumerInfo( BatteryUsageStats batteryUsageStats)137 private static BatteryConsumerInfo makeAggregateBatteryConsumerInfo( 138 BatteryUsageStats batteryUsageStats) { 139 BatteryConsumerInfo info = new BatteryConsumerInfo(); 140 info.consumerType = BatteryConsumerData.ConsumerType.DEVICE_POWER_COMPONENT; 141 info.id = BatteryConsumerData.AGGREGATE_BATTERY_CONSUMER_ID; 142 info.powerMah = batteryUsageStats.getConsumedPower(); 143 info.label = "Device"; 144 return info; 145 } 146 } 147