Support multi-user privacy for battery usage chart
When there are multiple accounts in the devices, the battery usage list is shared in the current design. We will aggregate other users usage data into a single item to support multi-user privacy requirements Screenshot: https://screenshot.googleplex.com/AkFTUtNvnoxcuGR Bug: 202119550 Test: make RunSettingsRoboTests Change-Id: I6cb55f0d50a4caca83212a0a54410530a032c089
This commit is contained in:
@@ -69,6 +69,8 @@ public class BatteryUtils {
|
||||
public static final int UID_REMOVED_APPS = -4;
|
||||
/** Special UID value for data usage by tethering. */
|
||||
public static final int UID_TETHERING = -5;
|
||||
/** Special UID for aggregated other users. */
|
||||
public static final long UID_OTHER_USERS = Long.MIN_VALUE;
|
||||
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef({StatusType.SCREEN_USAGE,
|
||||
|
@@ -113,6 +113,9 @@ public class BatteryDiffEntry {
|
||||
|
||||
/** Gets the app label name for this entry. */
|
||||
public String getAppLabel() {
|
||||
if (isOtherUsers()) {
|
||||
return mContext.getString(R.string.battery_usage_other_users);
|
||||
}
|
||||
loadLabelAndIcon();
|
||||
// Returns default applicationn label if we cannot find it.
|
||||
return mAppLabel == null || mAppLabel.length() == 0
|
||||
@@ -122,6 +125,9 @@ public class BatteryDiffEntry {
|
||||
|
||||
/** Gets the app icon {@link Drawable} for this entry. */
|
||||
public Drawable getAppIcon() {
|
||||
if (isOtherUsers()) {
|
||||
return mContext.getDrawable(R.drawable.ic_power_system);
|
||||
}
|
||||
loadLabelAndIcon();
|
||||
return mAppIcon != null && mAppIcon.getConstantState() != null
|
||||
? mAppIcon.getConstantState().newDrawable()
|
||||
@@ -156,6 +162,9 @@ public class BatteryDiffEntry {
|
||||
|
||||
/** Whether the current BatteryDiffEntry is system component or not. */
|
||||
public boolean isSystemEntry() {
|
||||
if (isOtherUsers()) {
|
||||
return true;
|
||||
}
|
||||
switch (mBatteryHistEntry.mConsumerType) {
|
||||
case ConvertUtils.CONSUMER_TYPE_USER_BATTERY:
|
||||
case ConvertUtils.CONSUMER_TYPE_SYSTEM_BATTERY:
|
||||
@@ -175,6 +184,11 @@ public class BatteryDiffEntry {
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isOtherUsers() {
|
||||
return mBatteryHistEntry.mConsumerType == ConvertUtils.CONSUMER_TYPE_UID_BATTERY
|
||||
&& mBatteryHistEntry.mUid == BatteryUtils.UID_OTHER_USERS;
|
||||
}
|
||||
|
||||
void loadLabelAndIcon() {
|
||||
if (mIsLoaded) {
|
||||
return;
|
||||
|
@@ -21,6 +21,7 @@ import android.content.Context;
|
||||
import android.os.BatteryUsageStats;
|
||||
import android.os.LocaleList;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.text.format.DateFormat;
|
||||
import android.text.format.DateUtils;
|
||||
import android.util.ArraySet;
|
||||
@@ -28,6 +29,8 @@ import android.util.Log;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.fuelgauge.BatteryUtils;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
@@ -265,17 +268,55 @@ public final class ConvertUtils {
|
||||
}
|
||||
}
|
||||
insert24HoursData(BatteryChartView.SELECTED_INDEX_ALL, resultMap);
|
||||
resolveMultiUsersData(context, resultMap);
|
||||
if (purgeLowPercentageAndFakeData) {
|
||||
purgeLowPercentageAndFakeData(context, resultMap);
|
||||
}
|
||||
return resultMap;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static void resolveMultiUsersData(
|
||||
final Context context,
|
||||
final Map<Integer, List<BatteryDiffEntry>> indexedUsageMap) {
|
||||
final int currentUserId = context.getUserId();
|
||||
final UserHandle userHandle =
|
||||
Utils.getManagedProfile(context.getSystemService(UserManager.class));
|
||||
final int workProfileUserId =
|
||||
userHandle != null ? userHandle.getIdentifier() : Integer.MIN_VALUE;
|
||||
// Loops for all BatteryDiffEntry in the different slots.
|
||||
for (List<BatteryDiffEntry> entryList : indexedUsageMap.values()) {
|
||||
double consumePowerFromOtherUsers = 0f;
|
||||
double consumePercentageFromOtherUsers = 0f;
|
||||
final Iterator<BatteryDiffEntry> iterator = entryList.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
final BatteryDiffEntry entry = iterator.next();
|
||||
final BatteryHistEntry batteryHistEntry = entry.mBatteryHistEntry;
|
||||
if (batteryHistEntry.mConsumerType != CONSUMER_TYPE_UID_BATTERY) {
|
||||
continue;
|
||||
}
|
||||
// Whether the BatteryHistEntry represents the current user data?
|
||||
if (batteryHistEntry.mUserId == currentUserId
|
||||
|| batteryHistEntry.mUserId == workProfileUserId) {
|
||||
continue;
|
||||
}
|
||||
// Removes and aggregates non-current users data from the list.
|
||||
iterator.remove();
|
||||
consumePowerFromOtherUsers += entry.mConsumePower;
|
||||
consumePercentageFromOtherUsers += entry.getPercentOfTotal();
|
||||
}
|
||||
if (consumePercentageFromOtherUsers != 0) {
|
||||
entryList.add(createOtherUsersEntry(context, consumePowerFromOtherUsers,
|
||||
consumePercentageFromOtherUsers));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void insert24HoursData(
|
||||
final int desiredIndex,
|
||||
final Map<Integer, List<BatteryDiffEntry>> indexedUsageMap) {
|
||||
final Map<String, BatteryDiffEntry> resultMap = new HashMap<>();
|
||||
double totalConsumePower = 0.0;
|
||||
double totalConsumePower = 0f;
|
||||
// Loops for all BatteryDiffEntry and aggregate them together.
|
||||
for (List<BatteryDiffEntry> entryList : indexedUsageMap.values()) {
|
||||
for (BatteryDiffEntry entry : entryList) {
|
||||
@@ -361,4 +402,22 @@ public final class ConvertUtils {
|
||||
return locales != null && !locales.isEmpty() ? locales.get(0)
|
||||
: Locale.getDefault();
|
||||
}
|
||||
|
||||
private static BatteryDiffEntry createOtherUsersEntry(
|
||||
Context context, double consumePower, double consumePercentage) {
|
||||
final ContentValues values = new ContentValues();
|
||||
values.put(BatteryHistEntry.KEY_UID, BatteryUtils.UID_OTHER_USERS);
|
||||
values.put(BatteryHistEntry.KEY_USER_ID, BatteryUtils.UID_OTHER_USERS);
|
||||
values.put(BatteryHistEntry.KEY_CONSUMER_TYPE, CONSUMER_TYPE_UID_BATTERY);
|
||||
// We will show the percentage for the "other users" item only, the aggregated
|
||||
// running time information is useless for users to identify individual apps.
|
||||
final BatteryDiffEntry batteryDiffEntry = new BatteryDiffEntry(
|
||||
context,
|
||||
/*foregroundUsageTimeInMs=*/ 0,
|
||||
/*backgroundUsageTimeInMs=*/ 0,
|
||||
consumePower,
|
||||
new BatteryHistEntry(values));
|
||||
batteryDiffEntry.setTotalConsumePower(100 * consumePower / consumePercentage);
|
||||
return batteryDiffEntry;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user