diff options
8 files changed, 190 insertions, 49 deletions
diff --git a/services/backup/java/com/android/server/backup/RefactoredBackupManagerService.java b/services/backup/java/com/android/server/backup/RefactoredBackupManagerService.java index c203dff07e89..1dede4713ab8 100644 --- a/services/backup/java/com/android/server/backup/RefactoredBackupManagerService.java +++ b/services/backup/java/com/android/server/backup/RefactoredBackupManagerService.java @@ -887,7 +887,7 @@ public class RefactoredBackupManagerService implements BackupManagerServiceInter PackageInfo pkg = mPackageManager.getPackageInfo(pkgName, 0); if (AppBackupUtils.appGetsFullBackup(pkg) && AppBackupUtils.appIsEligibleForBackup( - pkg.applicationInfo)) { + pkg.applicationInfo, mPackageManager)) { schedule.add(new FullBackupEntry(pkgName, lastBackup)); } else { if (DEBUG) { @@ -908,7 +908,7 @@ public class RefactoredBackupManagerService implements BackupManagerServiceInter for (PackageInfo app : apps) { if (AppBackupUtils.appGetsFullBackup(app) && AppBackupUtils.appIsEligibleForBackup( - app.applicationInfo)) { + app.applicationInfo, mPackageManager)) { if (!foundApps.contains(app.packageName)) { if (MORE_DEBUG) { Slog.i(TAG, "New full backup app " + app.packageName + " found"); @@ -934,7 +934,7 @@ public class RefactoredBackupManagerService implements BackupManagerServiceInter schedule = new ArrayList<>(apps.size()); for (PackageInfo info : apps) { if (AppBackupUtils.appGetsFullBackup(info) && AppBackupUtils.appIsEligibleForBackup( - info.applicationInfo)) { + info.applicationInfo, mPackageManager)) { schedule.add(new FullBackupEntry(info.packageName, 0)); } } @@ -1219,7 +1219,7 @@ public class RefactoredBackupManagerService implements BackupManagerServiceInter PackageInfo app = mPackageManager.getPackageInfo(packageName, 0); if (AppBackupUtils.appGetsFullBackup(app) && AppBackupUtils.appIsEligibleForBackup( - app.applicationInfo)) { + app.applicationInfo, mPackageManager)) { enqueueFullBackup(packageName, now); scheduleNextFullBackupJob(0); } else { @@ -1577,7 +1577,8 @@ public class RefactoredBackupManagerService implements BackupManagerServiceInter try { PackageInfo packageInfo = mPackageManager.getPackageInfo(packageName, PackageManager.GET_SIGNATURES); - if (!AppBackupUtils.appIsEligibleForBackup(packageInfo.applicationInfo)) { + if (!AppBackupUtils.appIsEligibleForBackup(packageInfo.applicationInfo, + mPackageManager)) { BackupObserverUtils.sendBackupOnPackageResult(observer, packageName, BackupManager.ERROR_BACKUP_NOT_ALLOWED); continue; @@ -3206,19 +3207,6 @@ public class RefactoredBackupManagerService implements BackupManagerServiceInter } } - // We also avoid backups of 'disabled' apps - private static boolean appIsDisabled(ApplicationInfo app, PackageManager pm) { - switch (pm.getApplicationEnabledSetting(app.packageName)) { - case PackageManager.COMPONENT_ENABLED_STATE_DISABLED: - case PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER: - case PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED: - return true; - - default: - return false; - } - } - @Override public boolean isAppEligibleForBackup(String packageName) { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP, @@ -3226,9 +3214,10 @@ public class RefactoredBackupManagerService implements BackupManagerServiceInter try { PackageInfo packageInfo = mPackageManager.getPackageInfo(packageName, PackageManager.GET_SIGNATURES); - if (!AppBackupUtils.appIsEligibleForBackup(packageInfo.applicationInfo) || + if (!AppBackupUtils.appIsEligibleForBackup(packageInfo.applicationInfo, + mPackageManager) || AppBackupUtils.appIsStopped(packageInfo.applicationInfo) || - appIsDisabled(packageInfo.applicationInfo, mPackageManager)) { + AppBackupUtils.appIsDisabled(packageInfo.applicationInfo, mPackageManager)) { return false; } IBackupTransport transport = mTransportManager.getCurrentTransportBinder(); diff --git a/services/backup/java/com/android/server/backup/fullbackup/PerformAdbBackupTask.java b/services/backup/java/com/android/server/backup/fullbackup/PerformAdbBackupTask.java index 4085f63afa8c..f0b3e4a023f0 100644 --- a/services/backup/java/com/android/server/backup/fullbackup/PerformAdbBackupTask.java +++ b/services/backup/java/com/android/server/backup/fullbackup/PerformAdbBackupTask.java @@ -236,12 +236,11 @@ public class PerformAdbBackupTask extends FullBackupTask implements BackupRestor obbConnection.establish(); // we'll want this later sendStartBackup(); + PackageManager pm = backupManagerService.getPackageManager(); // doAllApps supersedes the package set if any if (mAllApps) { - List<PackageInfo> allPackages = - backupManagerService.getPackageManager().getInstalledPackages( - PackageManager.GET_SIGNATURES); + List<PackageInfo> allPackages = pm.getInstalledPackages(PackageManager.GET_SIGNATURES); for (int i = 0; i < allPackages.size(); i++) { PackageInfo pkg = allPackages.get(i); // Exclude system apps if we've been asked to do so @@ -288,7 +287,7 @@ public class PerformAdbBackupTask extends FullBackupTask implements BackupRestor Iterator<Entry<String, PackageInfo>> iter = packagesToBackup.entrySet().iterator(); while (iter.hasNext()) { PackageInfo pkg = iter.next().getValue(); - if (!AppBackupUtils.appIsEligibleForBackup(pkg.applicationInfo) + if (!AppBackupUtils.appIsEligibleForBackup(pkg.applicationInfo, pm) || AppBackupUtils.appIsStopped(pkg.applicationInfo)) { iter.remove(); if (DEBUG) { diff --git a/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java b/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java index bc7c1174d17f..edb65a42035f 100644 --- a/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java +++ b/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java @@ -140,10 +140,10 @@ public class PerformFullTransportBackupTask extends FullBackupTask implements Ba for (String pkg : whichPackages) { try { - PackageInfo info = backupManagerService.getPackageManager().getPackageInfo(pkg, - PackageManager.GET_SIGNATURES); + PackageManager pm = backupManagerService.getPackageManager(); + PackageInfo info = pm.getPackageInfo(pkg, PackageManager.GET_SIGNATURES); mCurrentPackage = info; - if (!AppBackupUtils.appIsEligibleForBackup(info.applicationInfo)) { + if (!AppBackupUtils.appIsEligibleForBackup(info.applicationInfo, pm)) { // Cull any packages that have indicated that backups are not permitted, // that run as system-domain uids but do not define their own backup agents, // as well as any explicit mention of the 'special' shared-storage agent diff --git a/services/backup/java/com/android/server/backup/internal/PerformBackupTask.java b/services/backup/java/com/android/server/backup/internal/PerformBackupTask.java index 6bbed8cbfdf9..93277d460da4 100644 --- a/services/backup/java/com/android/server/backup/internal/PerformBackupTask.java +++ b/services/backup/java/com/android/server/backup/internal/PerformBackupTask.java @@ -390,11 +390,9 @@ public class PerformBackupTask implements BackupRestoreTask { // to sanity-check here. This also gives us the classname of the // package's backup agent. try { - mCurrentPackage = backupManagerService.getPackageManager().getPackageInfo( - request.packageName, - PackageManager.GET_SIGNATURES); - if (!AppBackupUtils.appIsEligibleForBackup( - mCurrentPackage.applicationInfo)) { + PackageManager pm = backupManagerService.getPackageManager(); + mCurrentPackage = pm.getPackageInfo(request.packageName, PackageManager.GET_SIGNATURES); + if (!AppBackupUtils.appIsEligibleForBackup(mCurrentPackage.applicationInfo, pm)) { // The manifest has changed but we had a stale backup request pending. // This won't happen again because the app won't be requesting further // backups. diff --git a/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java b/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java index 283a1f0e93dd..4c0bb48792ae 100644 --- a/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java +++ b/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java @@ -198,8 +198,8 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask { boolean hasSettings = false; for (int i = 0; i < filterSet.length; i++) { try { - PackageInfo info = backupManagerService.getPackageManager().getPackageInfo( - filterSet[i], 0); + PackageManager pm = backupManagerService.getPackageManager(); + PackageInfo info = pm.getPackageInfo(filterSet[i], 0); if ("android".equals(info.packageName)) { hasSystem = true; continue; @@ -209,8 +209,7 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask { continue; } - if (AppBackupUtils.appIsEligibleForBackup( - info.applicationInfo)) { + if (AppBackupUtils.appIsEligibleForBackup(info.applicationInfo, pm)) { mAcceptSet.add(info); } } catch (NameNotFoundException e) { diff --git a/services/backup/java/com/android/server/backup/utils/AppBackupUtils.java b/services/backup/java/com/android/server/backup/utils/AppBackupUtils.java index 4abf18add469..86877bab961d 100644 --- a/services/backup/java/com/android/server/backup/utils/AppBackupUtils.java +++ b/services/backup/java/com/android/server/backup/utils/AppBackupUtils.java @@ -22,6 +22,7 @@ import static com.android.server.backup.RefactoredBackupManagerService.TAG; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; import android.content.pm.Signature; import android.os.Process; import android.util.Slog; @@ -44,7 +45,7 @@ public class AppBackupUtils { * <li>it is the special shared-storage backup package used for 'adb backup' * </ol> */ - public static boolean appIsEligibleForBackup(ApplicationInfo app) { + public static boolean appIsEligibleForBackup(ApplicationInfo app, PackageManager pm) { // 1. their manifest states android:allowBackup="false" if ((app.flags & ApplicationInfo.FLAG_ALLOW_BACKUP) == 0) { return false; @@ -60,11 +61,28 @@ public class AppBackupUtils { return false; } - return true; + // Everything else checks out; the only remaining roadblock would be if the + // package were disabled + return !appIsDisabled(app, pm); + } + + /** Avoid backups of 'disabled' apps. */ + public static boolean appIsDisabled(ApplicationInfo app, PackageManager pm) { + switch (pm.getApplicationEnabledSetting(app.packageName)) { + case PackageManager.COMPONENT_ENABLED_STATE_DISABLED: + case PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER: + case PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED: + return true; + + default: + return false; + } } /** - * Checks if the app is in a stopped state, that means it won't receive broadcasts. + * Checks if the app is in a stopped state. This is not part of the general "eligible for + * backup?" check because we *do* still need to restore data to apps in this state (e.g. + * newly-installing ones) */ public static boolean appIsStopped(ApplicationInfo app) { return ((app.flags & ApplicationInfo.FLAG_STOPPED) != 0); diff --git a/services/tests/servicestests/src/com/android/server/backup/testutils/PackageManagerStub.java b/services/tests/servicestests/src/com/android/server/backup/testutils/PackageManagerStub.java index 0e940f25a62a..f22dfdcadc2c 100644 --- a/services/tests/servicestests/src/com/android/server/backup/testutils/PackageManagerStub.java +++ b/services/tests/servicestests/src/com/android/server/backup/testutils/PackageManagerStub.java @@ -45,6 +45,7 @@ import java.util.List; */ public class PackageManagerStub extends PackageManager { public static PackageInfo sPackageInfo; + public static int sApplicationEnabledSetting = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; @Override public PackageInfo getPackageInfo(String packageName, int flags) @@ -820,7 +821,7 @@ public class PackageManagerStub extends PackageManager { @Override public int getApplicationEnabledSetting(String packageName) { - return 0; + return sApplicationEnabledSetting; } @Override diff --git a/services/tests/servicestests/src/com/android/server/backup/utils/AppBackupUtilsTest.java b/services/tests/servicestests/src/com/android/server/backup/utils/AppBackupUtilsTest.java index db0ec0702b9f..ed26296ba72a 100644 --- a/services/tests/servicestests/src/com/android/server/backup/utils/AppBackupUtilsTest.java +++ b/services/tests/servicestests/src/com/android/server/backup/utils/AppBackupUtilsTest.java @@ -20,6 +20,7 @@ import static com.google.common.truth.Truth.assertThat; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; import android.content.pm.Signature; import android.os.Process; import android.platform.test.annotations.Presubmit; @@ -27,6 +28,7 @@ import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; import com.android.server.backup.RefactoredBackupManagerService; +import com.android.server.backup.testutils.PackageManagerStub; import org.junit.Test; import org.junit.runner.RunWith; @@ -43,6 +45,8 @@ public class AppBackupUtilsTest { private static final Signature SIGNATURE_3 = generateSignature((byte) 3); private static final Signature SIGNATURE_4 = generateSignature((byte) 4); + private final PackageManagerStub mPackageManagerStub = new PackageManagerStub(); + @Test public void appIsEligibleForBackup_backupNotAllowed_returnsFalse() throws Exception { ApplicationInfo applicationInfo = new ApplicationInfo(); @@ -51,7 +55,8 @@ public class AppBackupUtilsTest { applicationInfo.backupAgentName = CUSTOM_BACKUP_AGENT_NAME; applicationInfo.packageName = TEST_PACKAGE_NAME; - boolean isEligible = AppBackupUtils.appIsEligibleForBackup(applicationInfo); + boolean isEligible = AppBackupUtils.appIsEligibleForBackup(applicationInfo, + mPackageManagerStub); assertThat(isEligible).isFalse(); } @@ -65,7 +70,8 @@ public class AppBackupUtilsTest { applicationInfo.backupAgentName = null; applicationInfo.packageName = TEST_PACKAGE_NAME; - boolean isEligible = AppBackupUtils.appIsEligibleForBackup(applicationInfo); + boolean isEligible = AppBackupUtils.appIsEligibleForBackup(applicationInfo, + mPackageManagerStub); assertThat(isEligible).isFalse(); } @@ -78,13 +84,14 @@ public class AppBackupUtilsTest { applicationInfo.backupAgentName = CUSTOM_BACKUP_AGENT_NAME; applicationInfo.packageName = RefactoredBackupManagerService.SHARED_BACKUP_AGENT_PACKAGE; - boolean isEligible = AppBackupUtils.appIsEligibleForBackup(applicationInfo); + boolean isEligible = AppBackupUtils.appIsEligibleForBackup(applicationInfo, + mPackageManagerStub); assertThat(isEligible).isFalse(); } @Test - public void appIsEligibleForBackup_systemAppWithCustomBackupAgent_returnsTrue() + public void appIsEligibleForBackup_systemAppWithCustomBackupAgentAndEnabled_returnsTrue() throws Exception { ApplicationInfo applicationInfo = new ApplicationInfo(); applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP; @@ -92,13 +99,17 @@ public class AppBackupUtilsTest { applicationInfo.backupAgentName = CUSTOM_BACKUP_AGENT_NAME; applicationInfo.packageName = TEST_PACKAGE_NAME; - boolean isEligible = AppBackupUtils.appIsEligibleForBackup(applicationInfo); + PackageManagerStub.sApplicationEnabledSetting = + PackageManager.COMPONENT_ENABLED_STATE_ENABLED; + + boolean isEligible = AppBackupUtils.appIsEligibleForBackup(applicationInfo, + mPackageManagerStub); assertThat(isEligible).isTrue(); } @Test - public void appIsEligibleForBackup_nonSystemAppWithoutCustomBackupAgent_returnsTrue() + public void appIsEligibleForBackup_nonSystemAppWithoutCustomBackupAgentAndEnabled_returnsTrue() throws Exception { ApplicationInfo applicationInfo = new ApplicationInfo(); applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP; @@ -106,13 +117,17 @@ public class AppBackupUtilsTest { applicationInfo.backupAgentName = null; applicationInfo.packageName = TEST_PACKAGE_NAME; - boolean isEligible = AppBackupUtils.appIsEligibleForBackup(applicationInfo); + PackageManagerStub.sApplicationEnabledSetting = + PackageManager.COMPONENT_ENABLED_STATE_ENABLED; + + boolean isEligible = AppBackupUtils.appIsEligibleForBackup(applicationInfo, + mPackageManagerStub); assertThat(isEligible).isTrue(); } @Test - public void appIsEligibleForBackup_nonSystemAppWithCustomBackupAgent_returnsTrue() + public void appIsEligibleForBackup_nonSystemAppWithCustomBackupAgentAndEnabled_returnsTrue() throws Exception { ApplicationInfo applicationInfo = new ApplicationInfo(); applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP; @@ -120,12 +135,134 @@ public class AppBackupUtilsTest { applicationInfo.backupAgentName = CUSTOM_BACKUP_AGENT_NAME; applicationInfo.packageName = TEST_PACKAGE_NAME; - boolean isEligible = AppBackupUtils.appIsEligibleForBackup(applicationInfo); + PackageManagerStub.sApplicationEnabledSetting = + PackageManager.COMPONENT_ENABLED_STATE_ENABLED; + + boolean isEligible = AppBackupUtils.appIsEligibleForBackup(applicationInfo, + mPackageManagerStub); assertThat(isEligible).isTrue(); } @Test + public void appIsEligibleForBackup_systemAppWithCustomBackupAgentAndDisabled_returnsFalse() + throws Exception { + ApplicationInfo applicationInfo = new ApplicationInfo(); + applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP; + applicationInfo.uid = Process.SYSTEM_UID; + applicationInfo.backupAgentName = CUSTOM_BACKUP_AGENT_NAME; + applicationInfo.packageName = TEST_PACKAGE_NAME; + + PackageManagerStub.sApplicationEnabledSetting = + PackageManager.COMPONENT_ENABLED_STATE_DISABLED; + + boolean isEligible = AppBackupUtils.appIsEligibleForBackup(applicationInfo, + mPackageManagerStub); + + assertThat(isEligible).isFalse(); + } + + @Test + public void appIsEligibleForBackup_nonSystemAppWithoutCustomBackupAgentAndDisabled_returnsFalse() + throws Exception { + ApplicationInfo applicationInfo = new ApplicationInfo(); + applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP; + applicationInfo.uid = Process.FIRST_APPLICATION_UID; + applicationInfo.backupAgentName = null; + applicationInfo.packageName = TEST_PACKAGE_NAME; + + PackageManagerStub.sApplicationEnabledSetting = + PackageManager.COMPONENT_ENABLED_STATE_DISABLED; + + boolean isEligible = AppBackupUtils.appIsEligibleForBackup(applicationInfo, + mPackageManagerStub); + + assertThat(isEligible).isFalse(); + } + + @Test + public void appIsEligibleForBackup_nonSystemAppWithCustomBackupAgentAndDisbled_returnsFalse() + throws Exception { + ApplicationInfo applicationInfo = new ApplicationInfo(); + applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP; + applicationInfo.uid = Process.FIRST_APPLICATION_UID; + applicationInfo.backupAgentName = CUSTOM_BACKUP_AGENT_NAME; + applicationInfo.packageName = TEST_PACKAGE_NAME; + + PackageManagerStub.sApplicationEnabledSetting = + PackageManager.COMPONENT_ENABLED_STATE_DISABLED; + + boolean isEligible = AppBackupUtils.appIsEligibleForBackup(applicationInfo, + mPackageManagerStub); + + assertThat(isEligible).isFalse(); + } + + @Test + public void appIsDisabled_stateEnabled_returnsFalse() throws Exception { + ApplicationInfo applicationInfo = new ApplicationInfo(); + applicationInfo.flags = 0; + applicationInfo.uid = Process.FIRST_APPLICATION_UID; + applicationInfo.backupAgentName = CUSTOM_BACKUP_AGENT_NAME; + applicationInfo.packageName = TEST_PACKAGE_NAME; + + PackageManagerStub.sApplicationEnabledSetting = + PackageManager.COMPONENT_ENABLED_STATE_ENABLED; + + boolean isDisabled = AppBackupUtils.appIsDisabled(applicationInfo, mPackageManagerStub); + + assertThat(isDisabled).isFalse(); + } + + @Test + public void appIsDisabled_stateDisabled_returnsTrue() throws Exception { + ApplicationInfo applicationInfo = new ApplicationInfo(); + applicationInfo.flags = 0; + applicationInfo.uid = Process.FIRST_APPLICATION_UID; + applicationInfo.backupAgentName = CUSTOM_BACKUP_AGENT_NAME; + applicationInfo.packageName = TEST_PACKAGE_NAME; + + PackageManagerStub.sApplicationEnabledSetting = + PackageManager.COMPONENT_ENABLED_STATE_DISABLED; + + boolean isDisabled = AppBackupUtils.appIsDisabled(applicationInfo, mPackageManagerStub); + + assertThat(isDisabled).isTrue(); + } + + @Test + public void appIsDisabled_stateDisabledUser_returnsTrue() throws Exception { + ApplicationInfo applicationInfo = new ApplicationInfo(); + applicationInfo.flags = 0; + applicationInfo.uid = Process.FIRST_APPLICATION_UID; + applicationInfo.backupAgentName = CUSTOM_BACKUP_AGENT_NAME; + applicationInfo.packageName = TEST_PACKAGE_NAME; + + PackageManagerStub.sApplicationEnabledSetting = + PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER; + + boolean isDisabled = AppBackupUtils.appIsDisabled(applicationInfo, mPackageManagerStub); + + assertThat(isDisabled).isTrue(); + } + + @Test + public void appIsDisabled_stateDisabledUntilUsed_returnsTrue() throws Exception { + ApplicationInfo applicationInfo = new ApplicationInfo(); + applicationInfo.flags = 0; + applicationInfo.uid = Process.FIRST_APPLICATION_UID; + applicationInfo.backupAgentName = CUSTOM_BACKUP_AGENT_NAME; + applicationInfo.packageName = TEST_PACKAGE_NAME; + + PackageManagerStub.sApplicationEnabledSetting = + PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED; + + boolean isDisabled = AppBackupUtils.appIsDisabled(applicationInfo, mPackageManagerStub); + + assertThat(isDisabled).isTrue(); + } + + @Test public void appIsStopped_returnsTrue() throws Exception { ApplicationInfo applicationInfo = new ApplicationInfo(); applicationInfo.flags |= ApplicationInfo.FLAG_STOPPED; |