summaryrefslogtreecommitdiffstats
path: root/src/com/android/settings/fuelgauge
diff options
context:
space:
mode:
authorAdam Lesinski <adamlesinski@google.com>2015-08-13 16:56:30 -0700
committerAdam Lesinski <adamlesinski@google.com>2015-08-13 22:12:47 -0700
commit8f743471d5367935aea7663e362913e9b68b8e61 (patch)
treef4c5f8c09c1fe7cb4122a37fc8b4bdc2209ed6d5 /src/com/android/settings/fuelgauge
parenteea96f22a1ec156d78374f49352341c46c219ca0 (diff)
downloadpackages_apps_Settings-8f743471d5367935aea7663e362913e9b68b8e61.zip
packages_apps_Settings-8f743471d5367935aea7663e362913e9b68b8e61.tar.gz
packages_apps_Settings-8f743471d5367935aea7663e362913e9b68b8e61.tar.bz2
BatteryStats: Fix coalescing of shared app GIDs and system UIDs
UIDs that consumed power and were actually shared app GIDs are now coelsced for system apps as well as regular applications. In addition, system UIDs like logd, NFC, DRM, etc are coalesced into Android System. Bug:23189342 Change-Id: I6c8eb4baec66fba3d1f71a155d8ea1fe920ffec9
Diffstat (limited to 'src/com/android/settings/fuelgauge')
-rw-r--r--src/com/android/settings/fuelgauge/BatteryEntry.java137
-rw-r--r--src/com/android/settings/fuelgauge/PowerUsageSummary.java81
2 files changed, 132 insertions, 86 deletions
diff --git a/src/com/android/settings/fuelgauge/BatteryEntry.java b/src/com/android/settings/fuelgauge/BatteryEntry.java
index edab729..fbde228 100644
--- a/src/com/android/settings/fuelgauge/BatteryEntry.java
+++ b/src/com/android/settings/fuelgauge/BatteryEntry.java
@@ -24,7 +24,6 @@ import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
import android.graphics.drawable.Drawable;
-import android.os.BatteryStats;
import android.os.Handler;
import android.os.RemoteException;
import android.os.UserHandle;
@@ -191,7 +190,7 @@ public class BatteryEntry {
icon = context.getDrawable(iconId);
}
if ((name == null || iconId == 0) && this.sipper.uidObj != null) {
- getQuickNameIconForUid(this.sipper.uidObj);
+ getQuickNameIconForUid(this.sipper.uidObj.getUid());
}
}
@@ -206,8 +205,7 @@ public class BatteryEntry {
return name;
}
- void getQuickNameIconForUid(BatteryStats.Uid uidObj) {
- final int uid = uidObj.getUid();
+ void getQuickNameIconForUid(final int uid) {
final String uidString = Integer.toString(uid);
if (sUidCache.containsKey(uidString)) {
UidToDetail utd = sUidCache.get(uidString);
@@ -217,10 +215,8 @@ public class BatteryEntry {
return;
}
PackageManager pm = context.getPackageManager();
- String[] packages = pm.getPackagesForUid(uid);
icon = pm.getDefaultActivityIcon();
- if (packages == null) {
- //name = Integer.toString(uid);
+ if (pm.getPackagesForUid(uid) == null) {
if (uid == 0) {
name = context.getResources().getString(R.string.process_kernel_label);
} else if ("mediaserver".equals(name)) {
@@ -230,10 +226,8 @@ public class BatteryEntry {
}
iconId = R.drawable.ic_power_system;
icon = context.getDrawable(iconId);
- return;
- } else {
- //name = packages[0];
}
+
if (sHandler != null) {
synchronized (mRequestQueue) {
mRequestQueue.add(this);
@@ -249,79 +243,82 @@ public class BatteryEntry {
if (sipper.uidObj == null) {
return;
}
+
PackageManager pm = context.getPackageManager();
final int uid = sipper.uidObj.getUid();
- final Drawable defaultActivityIcon = pm.getDefaultActivityIcon();
sipper.mPackages = pm.getPackagesForUid(uid);
- if (sipper.mPackages == null) {
- name = Integer.toString(uid);
- return;
- }
-
- String[] packageLabels = new String[sipper.mPackages.length];
- System.arraycopy(sipper.mPackages, 0, packageLabels, 0, sipper.mPackages.length);
+ if (sipper.mPackages != null) {
+ String[] packageLabels = new String[sipper.mPackages.length];
+ System.arraycopy(sipper.mPackages, 0, packageLabels, 0, sipper.mPackages.length);
- // Convert package names to user-facing labels where possible
- IPackageManager ipm = AppGlobals.getPackageManager();
- final int userId = UserHandle.getUserId(uid);
- for (int i = 0; i < packageLabels.length; i++) {
- try {
- final ApplicationInfo ai = ipm.getApplicationInfo(packageLabels[i],
- 0 /* no flags */, userId);
- if (ai == null) {
- Log.d(PowerUsageSummary.TAG, "Retrieving null app info for package "
- + packageLabels[i] + ", user " + userId);
- continue;
- }
- CharSequence label = ai.loadLabel(pm);
- if (label != null) {
- packageLabels[i] = label.toString();
- }
- if (ai.icon != 0) {
- defaultPackageName = sipper.mPackages[i];
- icon = ai.loadIcon(pm);
- break;
- }
- } catch (RemoteException e) {
- Log.d(PowerUsageSummary.TAG, "Error while retrieving app info for package "
- + packageLabels[i] + ", user " + userId, e);
- }
- }
- if (icon == null) {
- icon = defaultActivityIcon;
- }
-
- if (packageLabels.length == 1) {
- name = packageLabels[0];
- } else {
- // Look for an official name for this UID.
- for (String pkgName : sipper.mPackages) {
+ // Convert package names to user-facing labels where possible
+ IPackageManager ipm = AppGlobals.getPackageManager();
+ final int userId = UserHandle.getUserId(uid);
+ for (int i = 0; i < packageLabels.length; i++) {
try {
- final PackageInfo pi = ipm.getPackageInfo(pkgName, 0 /* no flags */, userId);
- if (pi == null) {
- Log.d(PowerUsageSummary.TAG, "Retrieving null package info for package "
- + pkgName + ", user " + userId);
+ final ApplicationInfo ai = ipm.getApplicationInfo(packageLabels[i],
+ 0 /* no flags */, userId);
+ if (ai == null) {
+ Log.d(PowerUsageSummary.TAG, "Retrieving null app info for package "
+ + packageLabels[i] + ", user " + userId);
continue;
}
- if (pi.sharedUserLabel != 0) {
- final CharSequence nm = pm.getText(pkgName,
- pi.sharedUserLabel, pi.applicationInfo);
- if (nm != null) {
- name = nm.toString();
- if (pi.applicationInfo.icon != 0) {
- defaultPackageName = pkgName;
- icon = pi.applicationInfo.loadIcon(pm);
+ CharSequence label = ai.loadLabel(pm);
+ if (label != null) {
+ packageLabels[i] = label.toString();
+ }
+ if (ai.icon != 0) {
+ defaultPackageName = sipper.mPackages[i];
+ icon = ai.loadIcon(pm);
+ break;
+ }
+ } catch (RemoteException e) {
+ Log.d(PowerUsageSummary.TAG, "Error while retrieving app info for package "
+ + packageLabels[i] + ", user " + userId, e);
+ }
+ }
+
+ if (packageLabels.length == 1) {
+ name = packageLabels[0];
+ } else {
+ // Look for an official name for this UID.
+ for (String pkgName : sipper.mPackages) {
+ try {
+ final PackageInfo pi = ipm.getPackageInfo(pkgName, 0 /* no flags */, userId);
+ if (pi == null) {
+ Log.d(PowerUsageSummary.TAG, "Retrieving null package info for package "
+ + pkgName + ", user " + userId);
+ continue;
+ }
+ if (pi.sharedUserLabel != 0) {
+ final CharSequence nm = pm.getText(pkgName,
+ pi.sharedUserLabel, pi.applicationInfo);
+ if (nm != null) {
+ name = nm.toString();
+ if (pi.applicationInfo.icon != 0) {
+ defaultPackageName = pkgName;
+ icon = pi.applicationInfo.loadIcon(pm);
+ }
+ break;
}
- break;
}
+ } catch (RemoteException e) {
+ Log.d(PowerUsageSummary.TAG, "Error while retrieving package info for package "
+ + pkgName + ", user " + userId, e);
}
- } catch (RemoteException e) {
- Log.d(PowerUsageSummary.TAG, "Error while retrieving package info for package "
- + pkgName + ", user " + userId, e);
}
}
}
- final String uidString = Integer.toString(sipper.uidObj.getUid());
+
+ final String uidString = Integer.toString(uid);
+ if (name == null) {
+ name = uidString;
+ }
+
+ if (icon == null) {
+ icon = pm.getDefaultActivityIcon();
+ }
+
UidToDetail utd = new UidToDetail();
utd.name = name;
utd.icon = icon;
diff --git a/src/com/android/settings/fuelgauge/PowerUsageSummary.java b/src/com/android/settings/fuelgauge/PowerUsageSummary.java
index 9248075..445896d 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageSummary.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageSummary.java
@@ -76,7 +76,7 @@ public class PowerUsageSummary extends PowerUsageBase {
private int mStatsType = BatteryStats.STATS_SINCE_CHARGED;
private static final int MIN_POWER_THRESHOLD_MILLI_AMP = 5;
- private static final int MAX_ITEMS_TO_LIST = 10;
+ private static final int MAX_ITEMS_TO_LIST = USE_FAKE_DATA ? 30 : 10;
private static final int MIN_AVERAGE_POWER_THRESHOLD_MILLI_AMP = 10;
private static final int SECONDS_IN_HOUR = 60 * 60;
@@ -181,11 +181,19 @@ public class PowerUsageSummary extends PowerUsageBase {
mAppListGroup.addPreference(notAvailable);
}
+ private static boolean isSharedGid(int uid) {
+ return UserHandle.getAppIdFromSharedAppGid(uid) > 0;
+ }
+
+ private static boolean isSystemUid(int uid) {
+ return uid >= Process.SYSTEM_UID && uid < Process.FIRST_APPLICATION_UID;
+ }
+
/**
* We want to coalesce some UIDs. For example, dex2oat runs under a shared gid that
* exists for all users of the same app. We detect this case and merge the power use
* for dex2oat to the device OWNER's use of the app.
- * @return A sorted list of app's using power.
+ * @return A sorted list of apps using power.
*/
private static List<BatterySipper> getCoalescedUsageList(final List<BatterySipper> sippers) {
final SparseArray<BatterySipper> uidList = new SparseArray<>();
@@ -193,30 +201,62 @@ public class PowerUsageSummary extends PowerUsageBase {
final ArrayList<BatterySipper> results = new ArrayList<>();
final int numSippers = sippers.size();
for (int i = 0; i < numSippers; i++) {
- final BatterySipper sipper = sippers.get(i);
+ BatterySipper sipper = sippers.get(i);
if (sipper.getUid() > 0) {
int realUid = sipper.getUid();
- if (sipper.getUid() >= Process.FIRST_SHARED_APPLICATION_GID &&
- sipper.getUid() <= Process.LAST_SHARED_APPLICATION_GID) {
- // This is a shared gid being used to do work on behalf of an app across all
- // users. But we'll blame the power on the device OWNER.
+
+ // Check if this UID is a shared GID. If so, we combine it with the OWNER's
+ // actual app UID.
+ if (isSharedGid(sipper.getUid())) {
realUid = UserHandle.getUid(UserHandle.USER_OWNER,
UserHandle.getAppIdFromSharedAppGid(sipper.getUid()));
}
+ // Check if this UID is a system UID (mediaserver, logd, nfc, drm, etc).
+ if (isSystemUid(realUid)
+ && !"mediaserver".equals(sipper.packageWithHighestDrain)) {
+ // Use the system UID for all UIDs running in their own sandbox that
+ // are not apps. We exclude mediaserver because we already are expected to
+ // report that as a separate item.
+ realUid = Process.SYSTEM_UID;
+ }
+
+ if (realUid != sipper.getUid()) {
+ // Replace the BatterySipper with a new one with the real UID set.
+ BatterySipper newSipper = new BatterySipper(sipper.drainType,
+ new FakeUid(realUid), 0.0);
+ newSipper.add(sipper);
+ newSipper.packageWithHighestDrain = sipper.packageWithHighestDrain;
+ newSipper.mPackages = sipper.mPackages;
+ sipper = newSipper;
+ }
+
int index = uidList.indexOfKey(realUid);
if (index < 0) {
+ // New entry.
uidList.put(realUid, sipper);
} else {
- BatterySipper existingSipper = uidList.valueAt(index);
- if (existingSipper.getUid() >= Process.FIRST_SHARED_APPLICATION_GID &&
- existingSipper.getUid() <= Process.FIRST_SHARED_APPLICATION_GID) {
- // If the app already under this uid is a dex2oat run, then combine and
- // substitute it with the actual app.
- sipper.add(existingSipper);
- uidList.setValueAt(index, sipper);
- } else {
- existingSipper.add(sipper);
+ // Combine BatterySippers if we already have one with this UID.
+ final BatterySipper existingSipper = uidList.valueAt(index);
+ existingSipper.add(sipper);
+ if (existingSipper.packageWithHighestDrain == null
+ && sipper.packageWithHighestDrain != null) {
+ existingSipper.packageWithHighestDrain = sipper.packageWithHighestDrain;
+ }
+
+ final int existingPackageLen = existingSipper.mPackages != null ?
+ existingSipper.mPackages.length : 0;
+ final int newPackageLen = sipper.mPackages != null ?
+ sipper.mPackages.length : 0;
+ if (newPackageLen > 0) {
+ String[] newPackages = new String[existingPackageLen + newPackageLen];
+ if (existingPackageLen > 0) {
+ System.arraycopy(existingSipper.mPackages, 0, newPackages, 0,
+ existingPackageLen);
+ }
+ System.arraycopy(sipper.mPackages, 0, newPackages, existingPackageLen,
+ newPackageLen);
+ existingSipper.mPackages = newPackages;
}
}
} else {
@@ -355,6 +395,15 @@ public class PowerUsageSummary extends PowerUsageBase {
sipper.packageWithHighestDrain = "dex2oat";
stats.add(sipper);
+ sipper = new BatterySipper(DrainType.APP,
+ new FakeUid(UserHandle.getSharedAppGid(Process.FIRST_APPLICATION_UID + 1)), 10.0f);
+ sipper.packageWithHighestDrain = "dex2oat";
+ stats.add(sipper);
+
+ sipper = new BatterySipper(DrainType.APP,
+ new FakeUid(UserHandle.getSharedAppGid(Process.LOG_UID)), 9.0f);
+ stats.add(sipper);
+
return stats;
}