Merge "Support multi-user privacy for battery usage chart" into tm-qpr-dev am: fedab69c9a am: a51b1baeaa

Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Settings/+/19235726

Change-Id: Ib9c678e1bcb7dcc562301a1f039f20eb7d3caccd
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
TreeHugger Robot
2022-07-12 17:22:43 +00:00
committed by Automerger Merge Worker
7 changed files with 191 additions and 16 deletions

View File

@@ -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,

View File

@@ -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;

View File

@@ -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;
}
}