diff --git a/src/com/android/settings/fuelgauge/BatteryBackupHelper.java b/src/com/android/settings/fuelgauge/BatteryBackupHelper.java index eebfaf7d360..d35fc6483bf 100644 --- a/src/com/android/settings/fuelgauge/BatteryBackupHelper.java +++ b/src/com/android/settings/fuelgauge/BatteryBackupHelper.java @@ -37,6 +37,8 @@ import android.util.Log; import androidx.annotation.VisibleForTesting; +import com.android.settingslib.fuelgauge.PowerAllowlistBackend; + import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; @@ -63,6 +65,8 @@ public final class BatteryBackupHelper implements BackupHelper { static final String KEY_FULL_POWER_LIST = "full_power_list"; static final String KEY_OPTIMIZATION_LIST = "optimization_mode_list"; + @VisibleForTesting + PowerAllowlistBackend mPowerAllowlistBackend; @VisibleForTesting IDeviceIdleController mIDeviceIdleController; @VisibleForTesting @@ -127,6 +131,7 @@ public final class BatteryBackupHelper implements BackupHelper { Log.w(TAG, "no data found in the getInstalledApplications()"); return; } + int backupCount = 0; final StringBuilder builder = new StringBuilder(); final AppOpsManager appOps = mContext.getSystemService(AppOpsManager.class); // Converts application into the AppUsageState. @@ -136,20 +141,22 @@ public final class BatteryBackupHelper implements BackupHelper { @BatteryOptimizeUtils.OptimizationMode final int optimizationMode = BatteryOptimizeUtils.getAppOptimizationMode( mode, allowlistedApps.contains(info.packageName)); - // Ignores default optimized or unknown state. + // Ignores default optimized/unknown state or system/default apps. if (optimizationMode == BatteryOptimizeUtils.MODE_OPTIMIZED - || optimizationMode == BatteryOptimizeUtils.MODE_UNKNOWN) { + || optimizationMode == BatteryOptimizeUtils.MODE_UNKNOWN + || isSystemOrDefaultApp(info.packageName)) { continue; } final String packageOptimizeMode = info.packageName + DELIMITER_MODE + optimizationMode; builder.append(packageOptimizeMode + DELIMITER); debugLog(packageOptimizeMode); + backupCount++; } writeBackupData(data, KEY_OPTIMIZATION_LIST, builder.toString()); - Log.d(TAG, String.format("backup getInstalledApplications() size=%d in %d/ms", - applications.size(), (System.currentTimeMillis() - timestamp))); + Log.d(TAG, String.format("backup getInstalledApplications():%d count=%d in %d/ms", + applications.size(), backupCount, (System.currentTimeMillis() - timestamp))); } // Provides an opportunity to inject mock IDeviceIdleController for testing. @@ -170,6 +177,20 @@ public final class BatteryBackupHelper implements BackupHelper { return mIPackageManager; } + private PowerAllowlistBackend getPowerAllowlistBackend() { + if (mPowerAllowlistBackend != null) { + return mPowerAllowlistBackend; + } + mPowerAllowlistBackend = PowerAllowlistBackend.getInstance(mContext); + return mPowerAllowlistBackend; + } + + private boolean isSystemOrDefaultApp(String packageName) { + final PowerAllowlistBackend powerAllowlistBackend = getPowerAllowlistBackend(); + return powerAllowlistBackend.isSysAllowlisted(packageName) + || powerAllowlistBackend.isDefaultActiveApp(packageName); + } + private List getInstalledApplications() { final List applications = new ArrayList<>(); final UserManager um = mContext.getSystemService(UserManager.class); diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryBackupHelperTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryBackupHelperTest.java index 90e9405ba03..f86d7a14e0e 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryBackupHelperTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryBackupHelperTest.java @@ -40,6 +40,8 @@ import android.os.RemoteException; import android.os.UserHandle; import android.os.UserManager; +import com.android.settingslib.fuelgauge.PowerAllowlistBackend; + import java.util.Arrays; import java.util.List; @@ -59,6 +61,9 @@ import org.robolectric.annotation.Resetter; @RunWith(RobolectricTestRunner.class) @Config(shadows = {BatteryBackupHelperTest.ShadowUserHandle.class}) public final class BatteryBackupHelperTest { + private static final String PACKAGE_NAME1 = "com.android.testing.1"; + private static final String PACKAGE_NAME2 = "com.android.testing.2"; + private static final String PACKAGE_NAME3 = "com.android.testing.3"; private Context mContext; private BatteryBackupHelper mBatteryBackupHelper; @@ -73,6 +78,8 @@ public final class BatteryBackupHelperTest { private AppOpsManager mAppOpsManager; @Mock private UserManager mUserManager; + @Mock + private PowerAllowlistBackend mPowerAllowlistBackend; @Before public void setUp() { @@ -84,6 +91,7 @@ public final class BatteryBackupHelperTest { mBatteryBackupHelper = new BatteryBackupHelper(mContext); mBatteryBackupHelper.mIDeviceIdleController = mDeviceController; mBatteryBackupHelper.mIPackageManager = mIPackageManager; + mBatteryBackupHelper.mPowerAllowlistBackend = mPowerAllowlistBackend; } @After @@ -172,16 +180,49 @@ public final class BatteryBackupHelperTest { @Test public void backupOptimizationMode_backupOptimizationMode() throws Exception { - final String packageName1 = "com.android.testing.1"; - final String packageName2 = "com.android.testing.2"; - final String packageName3 = "com.android.testing.3"; - final List allowlistedApps = Arrays.asList(packageName1); - createTestingData(packageName1, packageName2, packageName3); + final List allowlistedApps = Arrays.asList(PACKAGE_NAME1); + createTestingData(PACKAGE_NAME1, PACKAGE_NAME2, PACKAGE_NAME3); mBatteryBackupHelper.backupOptimizationMode(mBackupDataOutput, allowlistedApps); // 2 for UNRESTRICTED mode and 1 for RESTRICTED mode. - final String expectedResult = packageName1 + "|2," + packageName2 + "|1,"; + final String expectedResult = PACKAGE_NAME1 + "|2," + PACKAGE_NAME2 + "|1,"; + verifyBackupData(expectedResult); + } + + @Test + public void backupOptimizationMode_backupOptimizationModeAndIgnoreSystemApp() + throws Exception { + final List allowlistedApps = Arrays.asList(PACKAGE_NAME1); + createTestingData(PACKAGE_NAME1, PACKAGE_NAME2, PACKAGE_NAME3); + // Sets "com.android.testing.1" as system app. + doReturn(true).when(mPowerAllowlistBackend).isSysAllowlisted(PACKAGE_NAME1); + doReturn(false).when(mPowerAllowlistBackend).isDefaultActiveApp(anyString()); + + mBatteryBackupHelper.backupOptimizationMode(mBackupDataOutput, allowlistedApps); + + // "com.android.testing.2" for RESTRICTED mode. + final String expectedResult = PACKAGE_NAME2 + "|1,"; + verifyBackupData(expectedResult); + } + + @Test + public void backupOptimizationMode_backupOptimizationModeAndIgnoreDefaultApp() + throws Exception { + final List allowlistedApps = Arrays.asList(PACKAGE_NAME1); + createTestingData(PACKAGE_NAME1, PACKAGE_NAME2, PACKAGE_NAME3); + // Sets "com.android.testing.1" as device default app. + doReturn(true).when(mPowerAllowlistBackend).isDefaultActiveApp(PACKAGE_NAME1); + doReturn(false).when(mPowerAllowlistBackend).isSysAllowlisted(anyString()); + + mBatteryBackupHelper.backupOptimizationMode(mBackupDataOutput, allowlistedApps); + + // "com.android.testing.2" for RESTRICTED mode. + final String expectedResult = PACKAGE_NAME2 + "|1,"; + verifyBackupData(expectedResult); + } + + private void verifyBackupData(String expectedResult) throws Exception { final byte[] expectedBytes = expectedResult.getBytes(); verify(mBackupDataOutput).writeEntityHeader( BatteryBackupHelper.KEY_OPTIMIZATION_LIST, expectedBytes.length);