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:
@@ -6646,6 +6646,8 @@
|
|||||||
<string name="battery_not_usage_24hr">No usage for past 24 hr</string>
|
<string name="battery_not_usage_24hr">No usage for past 24 hr</string>
|
||||||
<!-- Description for no usage time but have battery usage [CHAR LIMIT=120] -->
|
<!-- Description for no usage time but have battery usage [CHAR LIMIT=120] -->
|
||||||
<string name="battery_usage_without_time"></string>
|
<string name="battery_usage_without_time"></string>
|
||||||
|
<!-- Description for other users aggregated battery usage data [CHAR LIMIT=120] -->
|
||||||
|
<string name="battery_usage_other_users">Other users</string>
|
||||||
|
|
||||||
<!-- Graph subtext displayed to user when enhanced battery estimate is being used [CHAR LIMIT=120] -->
|
<!-- Graph subtext displayed to user when enhanced battery estimate is being used [CHAR LIMIT=120] -->
|
||||||
<string name="advanced_battery_graph_subtext">Battery left estimate is based on your device usage</string>
|
<string name="advanced_battery_graph_subtext">Battery left estimate is based on your device usage</string>
|
||||||
|
@@ -69,6 +69,8 @@ public class BatteryUtils {
|
|||||||
public static final int UID_REMOVED_APPS = -4;
|
public static final int UID_REMOVED_APPS = -4;
|
||||||
/** Special UID value for data usage by tethering. */
|
/** Special UID value for data usage by tethering. */
|
||||||
public static final int UID_TETHERING = -5;
|
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)
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
@IntDef({StatusType.SCREEN_USAGE,
|
@IntDef({StatusType.SCREEN_USAGE,
|
||||||
|
@@ -113,6 +113,9 @@ public class BatteryDiffEntry {
|
|||||||
|
|
||||||
/** Gets the app label name for this entry. */
|
/** Gets the app label name for this entry. */
|
||||||
public String getAppLabel() {
|
public String getAppLabel() {
|
||||||
|
if (isOtherUsers()) {
|
||||||
|
return mContext.getString(R.string.battery_usage_other_users);
|
||||||
|
}
|
||||||
loadLabelAndIcon();
|
loadLabelAndIcon();
|
||||||
// Returns default applicationn label if we cannot find it.
|
// Returns default applicationn label if we cannot find it.
|
||||||
return mAppLabel == null || mAppLabel.length() == 0
|
return mAppLabel == null || mAppLabel.length() == 0
|
||||||
@@ -122,6 +125,9 @@ public class BatteryDiffEntry {
|
|||||||
|
|
||||||
/** Gets the app icon {@link Drawable} for this entry. */
|
/** Gets the app icon {@link Drawable} for this entry. */
|
||||||
public Drawable getAppIcon() {
|
public Drawable getAppIcon() {
|
||||||
|
if (isOtherUsers()) {
|
||||||
|
return mContext.getDrawable(R.drawable.ic_power_system);
|
||||||
|
}
|
||||||
loadLabelAndIcon();
|
loadLabelAndIcon();
|
||||||
return mAppIcon != null && mAppIcon.getConstantState() != null
|
return mAppIcon != null && mAppIcon.getConstantState() != null
|
||||||
? mAppIcon.getConstantState().newDrawable()
|
? mAppIcon.getConstantState().newDrawable()
|
||||||
@@ -156,6 +162,9 @@ public class BatteryDiffEntry {
|
|||||||
|
|
||||||
/** Whether the current BatteryDiffEntry is system component or not. */
|
/** Whether the current BatteryDiffEntry is system component or not. */
|
||||||
public boolean isSystemEntry() {
|
public boolean isSystemEntry() {
|
||||||
|
if (isOtherUsers()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
switch (mBatteryHistEntry.mConsumerType) {
|
switch (mBatteryHistEntry.mConsumerType) {
|
||||||
case ConvertUtils.CONSUMER_TYPE_USER_BATTERY:
|
case ConvertUtils.CONSUMER_TYPE_USER_BATTERY:
|
||||||
case ConvertUtils.CONSUMER_TYPE_SYSTEM_BATTERY:
|
case ConvertUtils.CONSUMER_TYPE_SYSTEM_BATTERY:
|
||||||
@@ -175,6 +184,11 @@ public class BatteryDiffEntry {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isOtherUsers() {
|
||||||
|
return mBatteryHistEntry.mConsumerType == ConvertUtils.CONSUMER_TYPE_UID_BATTERY
|
||||||
|
&& mBatteryHistEntry.mUid == BatteryUtils.UID_OTHER_USERS;
|
||||||
|
}
|
||||||
|
|
||||||
void loadLabelAndIcon() {
|
void loadLabelAndIcon() {
|
||||||
if (mIsLoaded) {
|
if (mIsLoaded) {
|
||||||
return;
|
return;
|
||||||
|
@@ -21,6 +21,7 @@ import android.content.Context;
|
|||||||
import android.os.BatteryUsageStats;
|
import android.os.BatteryUsageStats;
|
||||||
import android.os.LocaleList;
|
import android.os.LocaleList;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
|
import android.os.UserManager;
|
||||||
import android.text.format.DateFormat;
|
import android.text.format.DateFormat;
|
||||||
import android.text.format.DateUtils;
|
import android.text.format.DateUtils;
|
||||||
import android.util.ArraySet;
|
import android.util.ArraySet;
|
||||||
@@ -28,6 +29,8 @@ import android.util.Log;
|
|||||||
|
|
||||||
import androidx.annotation.VisibleForTesting;
|
import androidx.annotation.VisibleForTesting;
|
||||||
|
|
||||||
|
import com.android.settings.Utils;
|
||||||
|
import com.android.settings.fuelgauge.BatteryUtils;
|
||||||
import com.android.settings.overlay.FeatureFactory;
|
import com.android.settings.overlay.FeatureFactory;
|
||||||
|
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
@@ -265,17 +268,55 @@ public final class ConvertUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
insert24HoursData(BatteryChartView.SELECTED_INDEX_ALL, resultMap);
|
insert24HoursData(BatteryChartView.SELECTED_INDEX_ALL, resultMap);
|
||||||
|
resolveMultiUsersData(context, resultMap);
|
||||||
if (purgeLowPercentageAndFakeData) {
|
if (purgeLowPercentageAndFakeData) {
|
||||||
purgeLowPercentageAndFakeData(context, resultMap);
|
purgeLowPercentageAndFakeData(context, resultMap);
|
||||||
}
|
}
|
||||||
return 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(
|
private static void insert24HoursData(
|
||||||
final int desiredIndex,
|
final int desiredIndex,
|
||||||
final Map<Integer, List<BatteryDiffEntry>> indexedUsageMap) {
|
final Map<Integer, List<BatteryDiffEntry>> indexedUsageMap) {
|
||||||
final Map<String, BatteryDiffEntry> resultMap = new HashMap<>();
|
final Map<String, BatteryDiffEntry> resultMap = new HashMap<>();
|
||||||
double totalConsumePower = 0.0;
|
double totalConsumePower = 0f;
|
||||||
// Loops for all BatteryDiffEntry and aggregate them together.
|
// Loops for all BatteryDiffEntry and aggregate them together.
|
||||||
for (List<BatteryDiffEntry> entryList : indexedUsageMap.values()) {
|
for (List<BatteryDiffEntry> entryList : indexedUsageMap.values()) {
|
||||||
for (BatteryDiffEntry entry : entryList) {
|
for (BatteryDiffEntry entry : entryList) {
|
||||||
@@ -361,4 +402,22 @@ public final class ConvertUtils {
|
|||||||
return locales != null && !locales.isEmpty() ? locales.get(0)
|
return locales != null && !locales.isEmpty() ? locales.get(0)
|
||||||
: Locale.getDefault();
|
: 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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -70,6 +70,7 @@ import org.robolectric.annotation.Resetter;
|
|||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
@RunWith(RobolectricTestRunner.class)
|
@RunWith(RobolectricTestRunner.class)
|
||||||
@@ -343,9 +344,17 @@ public final class BatteryBackupHelperTest {
|
|||||||
|
|
||||||
private void verifyBackupData(String expectedResult) throws Exception {
|
private void verifyBackupData(String expectedResult) throws Exception {
|
||||||
final byte[] expectedBytes = expectedResult.getBytes();
|
final byte[] expectedBytes = expectedResult.getBytes();
|
||||||
|
final ArgumentCaptor<byte[]> captor = ArgumentCaptor.forClass(byte[].class);
|
||||||
|
final Set<String> expectedResultSet =
|
||||||
|
Set.of(expectedResult.split(BatteryBackupHelper.DELIMITER));
|
||||||
|
|
||||||
verify(mBackupDataOutput).writeEntityHeader(
|
verify(mBackupDataOutput).writeEntityHeader(
|
||||||
BatteryBackupHelper.KEY_OPTIMIZATION_LIST, expectedBytes.length);
|
BatteryBackupHelper.KEY_OPTIMIZATION_LIST, expectedBytes.length);
|
||||||
verify(mBackupDataOutput).writeEntityData(expectedBytes, expectedBytes.length);
|
verify(mBackupDataOutput).writeEntityData(captor.capture(), eq(expectedBytes.length));
|
||||||
|
final String actualResult = new String(captor.getValue());
|
||||||
|
final Set<String> actualResultSet =
|
||||||
|
Set.of(actualResult.split(BatteryBackupHelper.DELIMITER));
|
||||||
|
assertThat(actualResultSet).isEqualTo(expectedResultSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createTestingData(
|
private void createTestingData(
|
||||||
|
@@ -138,7 +138,7 @@ public final class BatteryDiffEntryTest {
|
|||||||
// Generates fake testing data.
|
// Generates fake testing data.
|
||||||
final ContentValues values = getContentValuesWithType(
|
final ContentValues values = getContentValuesWithType(
|
||||||
ConvertUtils.CONSUMER_TYPE_SYSTEM_BATTERY);
|
ConvertUtils.CONSUMER_TYPE_SYSTEM_BATTERY);
|
||||||
values.put("drainType",
|
values.put(BatteryHistEntry.KEY_DRAIN_TYPE,
|
||||||
Integer.valueOf(BatteryConsumer.POWER_COMPONENT_AMBIENT_DISPLAY));
|
Integer.valueOf(BatteryConsumer.POWER_COMPONENT_AMBIENT_DISPLAY));
|
||||||
final BatteryHistEntry batteryHistEntry = new BatteryHistEntry(values);
|
final BatteryHistEntry batteryHistEntry = new BatteryHistEntry(values);
|
||||||
|
|
||||||
@@ -164,7 +164,7 @@ public final class BatteryDiffEntryTest {
|
|||||||
// Generates fake testing data.
|
// Generates fake testing data.
|
||||||
final ContentValues values = getContentValuesWithType(
|
final ContentValues values = getContentValuesWithType(
|
||||||
ConvertUtils.CONSUMER_TYPE_USER_BATTERY);
|
ConvertUtils.CONSUMER_TYPE_USER_BATTERY);
|
||||||
values.put("userId", Integer.valueOf(1001));
|
values.put(BatteryHistEntry.KEY_USER_ID, Integer.valueOf(1001));
|
||||||
final BatteryHistEntry batteryHistEntry = new BatteryHistEntry(values);
|
final BatteryHistEntry batteryHistEntry = new BatteryHistEntry(values);
|
||||||
|
|
||||||
final BatteryDiffEntry entry = createBatteryDiffEntry(10, batteryHistEntry);
|
final BatteryDiffEntry entry = createBatteryDiffEntry(10, batteryHistEntry);
|
||||||
@@ -189,8 +189,8 @@ public final class BatteryDiffEntryTest {
|
|||||||
final String fakePackageName = "com.fake.google.com";
|
final String fakePackageName = "com.fake.google.com";
|
||||||
final ContentValues values = getContentValuesWithType(
|
final ContentValues values = getContentValuesWithType(
|
||||||
ConvertUtils.CONSUMER_TYPE_UID_BATTERY);
|
ConvertUtils.CONSUMER_TYPE_UID_BATTERY);
|
||||||
values.put("uid", /*invalid uid*/ 10001);
|
values.put(BatteryHistEntry.KEY_UID, /*invalid uid*/ 10001);
|
||||||
values.put("packageName", fakePackageName);
|
values.put(BatteryHistEntry.KEY_PACKAGE_NAME, fakePackageName);
|
||||||
doReturn(mMockAppInfo).when(mMockPackageManager)
|
doReturn(mMockAppInfo).when(mMockPackageManager)
|
||||||
.getApplicationInfo(fakePackageName, 0);
|
.getApplicationInfo(fakePackageName, 0);
|
||||||
doReturn(expectedAppLabel).when(mMockPackageManager)
|
doReturn(expectedAppLabel).when(mMockPackageManager)
|
||||||
@@ -233,7 +233,7 @@ public final class BatteryDiffEntryTest {
|
|||||||
final String expectedAppLabel = "fake app label";
|
final String expectedAppLabel = "fake app label";
|
||||||
final ContentValues values = getContentValuesWithType(
|
final ContentValues values = getContentValuesWithType(
|
||||||
ConvertUtils.CONSUMER_TYPE_UID_BATTERY);
|
ConvertUtils.CONSUMER_TYPE_UID_BATTERY);
|
||||||
values.put("appLabel", expectedAppLabel);
|
values.put(BatteryHistEntry.KEY_APP_LABEL, expectedAppLabel);
|
||||||
final BatteryHistEntry batteryHistEntry = new BatteryHistEntry(values);
|
final BatteryHistEntry batteryHistEntry = new BatteryHistEntry(values);
|
||||||
|
|
||||||
final BatteryDiffEntry entry = createBatteryDiffEntry(10, batteryHistEntry);
|
final BatteryDiffEntry entry = createBatteryDiffEntry(10, batteryHistEntry);
|
||||||
@@ -391,8 +391,8 @@ public final class BatteryDiffEntryTest {
|
|||||||
final String fakePackageName = "com.fake.google.com";
|
final String fakePackageName = "com.fake.google.com";
|
||||||
final ContentValues values = getContentValuesWithType(
|
final ContentValues values = getContentValuesWithType(
|
||||||
ConvertUtils.CONSUMER_TYPE_UID_BATTERY);
|
ConvertUtils.CONSUMER_TYPE_UID_BATTERY);
|
||||||
values.put("uid", /*invalid uid*/ 10001);
|
values.put(BatteryHistEntry.KEY_UID, /*invalid uid*/ 10001);
|
||||||
values.put("packageName", fakePackageName);
|
values.put(BatteryHistEntry.KEY_PACKAGE_NAME, fakePackageName);
|
||||||
final BatteryDiffEntry entry =
|
final BatteryDiffEntry entry =
|
||||||
createBatteryDiffEntry(10, new BatteryHistEntry(values));
|
createBatteryDiffEntry(10, new BatteryHistEntry(values));
|
||||||
|
|
||||||
@@ -424,7 +424,7 @@ public final class BatteryDiffEntryTest {
|
|||||||
final String expectedPackageName = "com.fake.google.com";
|
final String expectedPackageName = "com.fake.google.com";
|
||||||
final ContentValues values = getContentValuesWithType(
|
final ContentValues values = getContentValuesWithType(
|
||||||
ConvertUtils.CONSUMER_TYPE_UID_BATTERY);
|
ConvertUtils.CONSUMER_TYPE_UID_BATTERY);
|
||||||
values.put("packageName", expectedPackageName);
|
values.put(BatteryHistEntry.KEY_PACKAGE_NAME, expectedPackageName);
|
||||||
final BatteryDiffEntry entry =
|
final BatteryDiffEntry entry =
|
||||||
createBatteryDiffEntry(10, new BatteryHistEntry(values));
|
createBatteryDiffEntry(10, new BatteryHistEntry(values));
|
||||||
|
|
||||||
@@ -437,7 +437,7 @@ public final class BatteryDiffEntryTest {
|
|||||||
final ContentValues values = getContentValuesWithType(
|
final ContentValues values = getContentValuesWithType(
|
||||||
ConvertUtils.CONSUMER_TYPE_UID_BATTERY);
|
ConvertUtils.CONSUMER_TYPE_UID_BATTERY);
|
||||||
values.put(
|
values.put(
|
||||||
"packageName",
|
BatteryHistEntry.KEY_PACKAGE_NAME,
|
||||||
expectedPackageName + ":privileged_process0");
|
expectedPackageName + ":privileged_process0");
|
||||||
final BatteryDiffEntry entry =
|
final BatteryDiffEntry entry =
|
||||||
createBatteryDiffEntry(10, new BatteryHistEntry(values));
|
createBatteryDiffEntry(10, new BatteryHistEntry(values));
|
||||||
@@ -445,11 +445,24 @@ public final class BatteryDiffEntryTest {
|
|||||||
assertThat(entry.getPackageName()).isEqualTo(expectedPackageName);
|
assertThat(entry.getPackageName()).isEqualTo(expectedPackageName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getAppLabel_withOtherUsersUid_returnExpectedLabel() {
|
||||||
|
final ContentValues values = getContentValuesWithType(
|
||||||
|
ConvertUtils.CONSUMER_TYPE_UID_BATTERY);
|
||||||
|
values.put(BatteryHistEntry.KEY_UID, BatteryUtils.UID_OTHER_USERS);
|
||||||
|
|
||||||
|
final BatteryDiffEntry batteryDiffEntry = createBatteryDiffEntry(
|
||||||
|
/*consumePower=*/ 0, new BatteryHistEntry(values));
|
||||||
|
|
||||||
|
assertThat(batteryDiffEntry.getAppLabel())
|
||||||
|
.isEqualTo(mContext.getString(R.string.battery_usage_other_users));
|
||||||
|
}
|
||||||
|
|
||||||
private BatteryDiffEntry createBatteryDiffEntry(
|
private BatteryDiffEntry createBatteryDiffEntry(
|
||||||
int consumerType, long uid, boolean isHidden) {
|
int consumerType, long uid, boolean isHidden) {
|
||||||
final ContentValues values = getContentValuesWithType(consumerType);
|
final ContentValues values = getContentValuesWithType(consumerType);
|
||||||
values.put("isHidden", isHidden);
|
values.put(BatteryHistEntry.KEY_IS_HIDDEN, isHidden);
|
||||||
values.put("uid", uid);
|
values.put(BatteryHistEntry.KEY_UID, uid);
|
||||||
return new BatteryDiffEntry(
|
return new BatteryDiffEntry(
|
||||||
mContext,
|
mContext,
|
||||||
/*foregroundUsageTimeInMs=*/ 0,
|
/*foregroundUsageTimeInMs=*/ 0,
|
||||||
@@ -472,15 +485,15 @@ public final class BatteryDiffEntryTest {
|
|||||||
|
|
||||||
private static ContentValues getContentValuesWithType(int consumerType) {
|
private static ContentValues getContentValuesWithType(int consumerType) {
|
||||||
final ContentValues values = new ContentValues();
|
final ContentValues values = new ContentValues();
|
||||||
values.put("consumerType", Integer.valueOf(consumerType));
|
values.put(BatteryHistEntry.KEY_CONSUMER_TYPE, Integer.valueOf(consumerType));
|
||||||
return values;
|
return values;
|
||||||
}
|
}
|
||||||
|
|
||||||
private BatteryDiffEntry createBatteryDiffEntry(Drawable drawable) throws Exception {
|
private BatteryDiffEntry createBatteryDiffEntry(Drawable drawable) throws Exception {
|
||||||
final ContentValues values = getContentValuesWithType(
|
final ContentValues values = getContentValuesWithType(
|
||||||
ConvertUtils.CONSUMER_TYPE_UID_BATTERY);
|
ConvertUtils.CONSUMER_TYPE_UID_BATTERY);
|
||||||
values.put("uid", 1001);
|
values.put(BatteryHistEntry.KEY_UID, 1001);
|
||||||
values.put("packageName", "com.a.b.c");
|
values.put(BatteryHistEntry.KEY_PACKAGE_NAME, "com.a.b.c");
|
||||||
final BatteryHistEntry batteryHistEntry = new BatteryHistEntry(values);
|
final BatteryHistEntry batteryHistEntry = new BatteryHistEntry(values);
|
||||||
doReturn(drawable).when(mMockPackageManager).getDefaultActivityIcon();
|
doReturn(drawable).when(mMockPackageManager).getDefaultActivityIcon();
|
||||||
doReturn(null).when(mMockPackageManager).getApplicationInfo("com.a.b.c", 0);
|
doReturn(null).when(mMockPackageManager).getApplicationInfo("com.a.b.c", 0);
|
||||||
|
@@ -27,6 +27,7 @@ import android.os.BatteryUsageStats;
|
|||||||
import android.os.LocaleList;
|
import android.os.LocaleList;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
|
|
||||||
|
import com.android.settings.fuelgauge.BatteryUtils;
|
||||||
import com.android.settings.fuelgauge.PowerUsageFeatureProvider;
|
import com.android.settings.fuelgauge.PowerUsageFeatureProvider;
|
||||||
import com.android.settings.testutils.FakeFeatureFactory;
|
import com.android.settings.testutils.FakeFeatureFactory;
|
||||||
|
|
||||||
@@ -39,6 +40,7 @@ import org.robolectric.RobolectricTestRunner;
|
|||||||
import org.robolectric.RuntimeEnvironment;
|
import org.robolectric.RuntimeEnvironment;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -371,6 +373,71 @@ public final class ConvertUtilsTest {
|
|||||||
assertThat(ConvertUtils.getLocale(mContext)).isEqualTo(Locale.getDefault());
|
assertThat(ConvertUtils.getLocale(mContext)).isEqualTo(Locale.getDefault());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void resolveMultiUsersData_replaceOtherUsersItemWithExpectedEntry() {
|
||||||
|
final int currentUserId = mContext.getUserId();
|
||||||
|
final Map<Integer, List<BatteryDiffEntry>> entryMap = new HashMap<>();
|
||||||
|
// Without other users time slot.
|
||||||
|
entryMap.put(0, Arrays.asList(
|
||||||
|
createBatteryDiffEntry(
|
||||||
|
currentUserId,
|
||||||
|
ConvertUtils.CONSUMER_TYPE_UID_BATTERY,
|
||||||
|
/*consumePercentage=*/ 50)));
|
||||||
|
// With other users time slot.
|
||||||
|
final List<BatteryDiffEntry> withOtherUsersList = new ArrayList<>();
|
||||||
|
entryMap.put(1, withOtherUsersList);
|
||||||
|
withOtherUsersList.add(
|
||||||
|
createBatteryDiffEntry(
|
||||||
|
currentUserId + 1,
|
||||||
|
ConvertUtils.CONSUMER_TYPE_SYSTEM_BATTERY,
|
||||||
|
/*consumePercentage=*/ 20));
|
||||||
|
withOtherUsersList.add(
|
||||||
|
createBatteryDiffEntry(
|
||||||
|
currentUserId + 2,
|
||||||
|
ConvertUtils.CONSUMER_TYPE_UID_BATTERY,
|
||||||
|
/*consumePercentage=*/ 30));
|
||||||
|
withOtherUsersList.add(
|
||||||
|
createBatteryDiffEntry(
|
||||||
|
currentUserId + 3,
|
||||||
|
ConvertUtils.CONSUMER_TYPE_UID_BATTERY,
|
||||||
|
/*consumePercentage=*/ 40));
|
||||||
|
|
||||||
|
ConvertUtils.resolveMultiUsersData(mContext, entryMap);
|
||||||
|
|
||||||
|
assertThat(entryMap.get(0).get(0).getPercentOfTotal()).isEqualTo(50);
|
||||||
|
// Asserts with other users items.
|
||||||
|
final List<BatteryDiffEntry> entryList = entryMap.get(1);
|
||||||
|
assertThat(entryList).hasSize(2);
|
||||||
|
assertBatteryDiffEntry(
|
||||||
|
entryList.get(0),
|
||||||
|
currentUserId + 1,
|
||||||
|
/*uid=*/ 0,
|
||||||
|
ConvertUtils.CONSUMER_TYPE_SYSTEM_BATTERY,
|
||||||
|
/*consumePercentage=*/ 20);
|
||||||
|
assertBatteryDiffEntry(
|
||||||
|
entryList.get(1),
|
||||||
|
BatteryUtils.UID_OTHER_USERS,
|
||||||
|
BatteryUtils.UID_OTHER_USERS,
|
||||||
|
ConvertUtils.CONSUMER_TYPE_UID_BATTERY,
|
||||||
|
/*consumePercentage=*/ 70);
|
||||||
|
}
|
||||||
|
|
||||||
|
private BatteryDiffEntry createBatteryDiffEntry(
|
||||||
|
long userId, int counsumerType, double consumePercentage) {
|
||||||
|
final ContentValues values = new ContentValues();
|
||||||
|
values.put(BatteryHistEntry.KEY_USER_ID, userId);
|
||||||
|
values.put(BatteryHistEntry.KEY_CONSUMER_TYPE, counsumerType);
|
||||||
|
final BatteryDiffEntry batteryDiffEntry =
|
||||||
|
new BatteryDiffEntry(
|
||||||
|
mContext,
|
||||||
|
/*foregroundUsageTimeInMs=*/ 0,
|
||||||
|
/*backgroundUsageTimeInMs=*/ 0,
|
||||||
|
/*consumePower=*/ consumePercentage,
|
||||||
|
new BatteryHistEntry(values));
|
||||||
|
batteryDiffEntry.setTotalConsumePower(100f);
|
||||||
|
return batteryDiffEntry;
|
||||||
|
}
|
||||||
|
|
||||||
private static BatteryHistEntry createBatteryHistEntry(
|
private static BatteryHistEntry createBatteryHistEntry(
|
||||||
String packageName, String appLabel, double consumePower,
|
String packageName, String appLabel, double consumePower,
|
||||||
long uid, long foregroundUsageTimeInMs, long backgroundUsageTimeInMs) {
|
long uid, long foregroundUsageTimeInMs, long backgroundUsageTimeInMs) {
|
||||||
@@ -389,6 +456,15 @@ public final class ConvertUtilsTest {
|
|||||||
return new BatteryHistEntry(values);
|
return new BatteryHistEntry(values);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void assertBatteryDiffEntry(
|
||||||
|
BatteryDiffEntry entry, long userId, long uid, int counsumerType,
|
||||||
|
double consumePercentage) {
|
||||||
|
assertThat(entry.mBatteryHistEntry.mUid).isEqualTo(uid);
|
||||||
|
assertThat(entry.mBatteryHistEntry.mUserId).isEqualTo(userId);
|
||||||
|
assertThat(entry.mBatteryHistEntry.mConsumerType).isEqualTo(counsumerType);
|
||||||
|
assertThat(entry.getPercentOfTotal()).isEqualTo(consumePercentage);
|
||||||
|
}
|
||||||
|
|
||||||
private static void assertBatteryDiffEntry(
|
private static void assertBatteryDiffEntry(
|
||||||
BatteryDiffEntry entry, int percentOfTotal,
|
BatteryDiffEntry entry, int percentOfTotal,
|
||||||
long foregroundUsageTimeInMs, long backgroundUsageTimeInMs) {
|
long foregroundUsageTimeInMs, long backgroundUsageTimeInMs) {
|
||||||
|
Reference in New Issue
Block a user