From 52e56a24904389ca8f7e67e8a883f353b887a4af Mon Sep 17 00:00:00 2001 From: Dianne Hackborn Date: Wed, 12 Sep 2012 17:02:23 -0700 Subject: [PATCH] Multi-user battery settings. Aggregates battery use from other users into one line item. Change-Id: I811e681891a9ff098491de1e096232f38bf061a9 --- res/values/strings.xml | 3 + src/com/android/settings/Settings.java | 1 + .../android/settings/fuelgauge/BatterySipper.java | 1 - .../settings/fuelgauge/PowerGaugePreference.java | 3 +- .../settings/fuelgauge/PowerUsageDetail.java | 6 +- .../settings/fuelgauge/PowerUsageSummary.java | 95 ++++++++++++++++++---- 6 files changed, 89 insertions(+), 20 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 8895de2593..815d853612 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -3234,6 +3234,9 @@ The app may offer settings to reduce battery use + + Battery used by user + %1$s since unplugged diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java index 6f2002a9c3..88b3e87fdb 100644 --- a/src/com/android/settings/Settings.java +++ b/src/com/android/settings/Settings.java @@ -105,6 +105,7 @@ public class Settings extends PreferenceActivity R.id.display_settings, R.id.storage_settings, R.id.application_settings, + R.id.battery_settings, R.id.personal_section, R.id.security_settings, R.id.user_settings, diff --git a/src/com/android/settings/fuelgauge/BatterySipper.java b/src/com/android/settings/fuelgauge/BatterySipper.java index dbd664a644..f11d6cabdd 100644 --- a/src/com/android/settings/fuelgauge/BatterySipper.java +++ b/src/com/android/settings/fuelgauge/BatterySipper.java @@ -107,7 +107,6 @@ class BatterySipper implements Comparable { return; } PackageManager pm = mContext.getPackageManager(); - final Drawable defaultActivityIcon = pm.getDefaultActivityIcon(); String[] packages = pm.getPackagesForUid(uid); icon = pm.getDefaultActivityIcon(); if (packages == null) { diff --git a/src/com/android/settings/fuelgauge/PowerGaugePreference.java b/src/com/android/settings/fuelgauge/PowerGaugePreference.java index 7b11ae1ff0..c8bfa217db 100644 --- a/src/com/android/settings/fuelgauge/PowerGaugePreference.java +++ b/src/com/android/settings/fuelgauge/PowerGaugePreference.java @@ -17,6 +17,7 @@ package com.android.settings.fuelgauge; import android.content.Context; +import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.preference.Preference; import android.view.View; @@ -37,7 +38,7 @@ public class PowerGaugePreference extends Preference { public PowerGaugePreference(Context context, Drawable icon, BatterySipper info) { super(context); setLayoutResource(R.layout.app_percentage_item); - setIcon(icon); + setIcon(icon != null ? icon : new ColorDrawable(0)); mInfo = info; } diff --git a/src/com/android/settings/fuelgauge/PowerUsageDetail.java b/src/com/android/settings/fuelgauge/PowerUsageDetail.java index 79cbac644e..bb96ca97ad 100644 --- a/src/com/android/settings/fuelgauge/PowerUsageDetail.java +++ b/src/com/android/settings/fuelgauge/PowerUsageDetail.java @@ -62,7 +62,8 @@ public class PowerUsageDetail extends Fragment implements Button.OnClickListener WIFI, BLUETOOTH, SCREEN, - APP + APP, + USER } // Note: Must match the sequence of the DrainType @@ -73,7 +74,8 @@ public class PowerUsageDetail extends Fragment implements Button.OnClickListener R.string.battery_desc_wifi, R.string.battery_desc_bluetooth, R.string.battery_desc_display, - R.string.battery_desc_apps + R.string.battery_desc_apps, + R.string.battery_desc_users, }; public static final int ACTION_DISPLAY_SETTINGS = 1; diff --git a/src/com/android/settings/fuelgauge/PowerUsageSummary.java b/src/com/android/settings/fuelgauge/PowerUsageSummary.java index ab2c891a98..173efef1a7 100644 --- a/src/com/android/settings/fuelgauge/PowerUsageSummary.java +++ b/src/com/android/settings/fuelgauge/PowerUsageSummary.java @@ -20,6 +20,8 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.content.pm.UserInfo; +import android.graphics.drawable.Drawable; import android.hardware.SensorManager; import android.net.Uri; import android.os.BatteryStats; @@ -32,6 +34,8 @@ import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemClock; +import android.os.UserHandle; +import android.os.UserManager; import android.preference.Preference; import android.preference.PreferenceActivity; import android.preference.PreferenceFragment; @@ -79,10 +83,14 @@ public class PowerUsageSummary extends PreferenceFragment implements Runnable { private static BatteryStatsImpl sStatsXfer; IBatteryStats mBatteryInfo; + UserManager mUm; BatteryStatsImpl mStats; private final List mUsageList = new ArrayList(); private final List mWifiSippers = new ArrayList(); private final List mBluetoothSippers = new ArrayList(); + private final SparseArray> mUserSippers + = new SparseArray>(); + private final SparseArray mUserPower = new SparseArray(); private PreferenceGroup mAppListGroup; private Preference mBatteryStatusPref; @@ -134,6 +142,7 @@ public class PowerUsageSummary extends PreferenceFragment implements Runnable { addPreferencesFromResource(R.xml.power_usage_summary); mBatteryInfo = IBatteryStats.Stub.asInterface( ServiceManager.getService("batteryinfo")); + mUm = (UserManager)getActivity().getSystemService(Context.USER_SERVICE); mAppListGroup = (PreferenceGroup) findPreference(KEY_APP_LIST); mBatteryStatusPref = mAppListGroup.findPreference(KEY_BATTERY_STATUS); mPowerProfile = new PowerProfile(getActivity()); @@ -204,6 +213,7 @@ public class PowerUsageSummary extends PreferenceFragment implements Runnable { double[] values; switch (sipper.drainType) { case APP: + case USER: { Uid uid = sipper.uidObj; types = new int[] { @@ -229,15 +239,18 @@ public class PowerUsageSummary extends PreferenceFragment implements Runnable { 0 }; - Writer result = new StringWriter(); - PrintWriter printWriter = new PrintWriter(result); - mStats.dumpLocked(printWriter, "", mStatsType, uid.getUid()); - args.putString(PowerUsageDetail.EXTRA_REPORT_DETAILS, result.toString()); - - result = new StringWriter(); - printWriter = new PrintWriter(result); - mStats.dumpCheckinLocked(printWriter, mStatsType, uid.getUid()); - args.putString(PowerUsageDetail.EXTRA_REPORT_CHECKIN_DETAILS, result.toString()); + if (sipper.drainType == DrainType.APP) { + Writer result = new StringWriter(); + PrintWriter printWriter = new PrintWriter(result); + mStats.dumpLocked(printWriter, "", mStatsType, uid.getUid()); + args.putString(PowerUsageDetail.EXTRA_REPORT_DETAILS, result.toString()); + + result = new StringWriter(); + printWriter = new PrintWriter(result); + mStats.dumpCheckinLocked(printWriter, mStatsType, uid.getUid()); + args.putString(PowerUsageDetail.EXTRA_REPORT_CHECKIN_DETAILS, + result.toString()); + } } break; case CELL: @@ -373,6 +386,8 @@ public class PowerUsageSummary extends PreferenceFragment implements Runnable { mUsageList.clear(); mWifiSippers.clear(); mBluetoothSippers.clear(); + mUserSippers.clear(); + mUserPower.clear(); mAppListGroup.setOrderingAsAdded(false); mBatteryStatusPref.setOrder(-2); @@ -570,6 +585,8 @@ public class PowerUsageSummary extends PreferenceFragment implements Runnable { if (DEBUG) Log.i(TAG, String.format("UID %d total power=%.2f", u.getUid(), power)); // Add the app to the list if it is consuming power + boolean isOtherUser = false; + final int userId = UserHandle.getUserId(u.getUid()); if (power != 0 || u.getUid() == 0) { BatterySipper app = new BatterySipper(getActivity(), mRequestQueue, mHandler, packageWithHighestDrain, DrainType.APP, 0, u, @@ -585,6 +602,15 @@ public class PowerUsageSummary extends PreferenceFragment implements Runnable { mWifiSippers.add(app); } else if (u.getUid() == Process.BLUETOOTH_GID) { mBluetoothSippers.add(app); + } else if (userId != UserHandle.myUserId() + && UserHandle.getAppId(u.getUid()) >= Process.FIRST_APPLICATION_UID) { + isOtherUser = true; + List list = mUserSippers.get(userId); + if (list == null) { + list = new ArrayList(); + mUserSippers.put(userId, list); + } + list.add(app); } else { mUsageList.add(app); } @@ -592,13 +618,23 @@ public class PowerUsageSummary extends PreferenceFragment implements Runnable { osApp = app; } } - if (u.getUid() == Process.WIFI_UID) { - mWifiPower += power; - } else if (u.getUid() == Process.BLUETOOTH_GID) { - mBluetoothPower += power; - } else { - if (power > mMaxPower) mMaxPower = power; - mTotalPower += power; + if (power != 0) { + if (u.getUid() == Process.WIFI_UID) { + mWifiPower += power; + } else if (u.getUid() == Process.BLUETOOTH_GID) { + mBluetoothPower += power; + } else if (isOtherUser) { + Double userPower = mUserPower.get(userId); + if (userPower == null) { + userPower = power; + } else { + userPower += power; + } + mUserPower.put(userId, userPower); + } else { + if (power > mMaxPower) mMaxPower = power; + mTotalPower += power; + } } } @@ -725,6 +761,32 @@ public class PowerUsageSummary extends PreferenceFragment implements Runnable { aggregateSippers(bs, mBluetoothSippers, "Bluetooth"); } + private void addUserUsage() { + for (int i=0; i sippers = mUserSippers.valueAt(i); + UserInfo info = mUm.getUserInfo(userId); + Drawable icon = null; + if (info != null && info.iconPath != null) { + try { + icon = Drawable.createFromPath(info.iconPath); + } catch (Exception e) { + Log.w(TAG, "Failure loading user picture " + info.iconPath, e); + } + } + String name = info != null ? info.name : null; + if (name == null) { + name = Integer.toString(info.id); + } + double power = mUserPower.get(userId); + String label = getActivity().getResources().getString( + R.string.running_process_item_user_label, name); + BatterySipper bs = addEntry(label, DrainType.USER, 0, 0, power); + bs.icon = icon; + aggregateSippers(bs, sippers, "User"); + } + } + private double getAverageDataCost() { final long WIFI_BPS = 1000000; // TODO: Extract average bit rates from system final long MOBILE_BPS = 200000; // TODO: Extract average bit rates from system @@ -760,6 +822,7 @@ public class PowerUsageSummary extends PreferenceFragment implements Runnable { Log.i(TAG, "Uptime since last unplugged = " + (timeSinceUnplugged / 1000)); } + addUserUsage(); addPhoneUsage(uSecNow); addScreenUsage(uSecNow); addWiFiUsage(uSecNow); -- 2.11.0