Separate allow lists for profile and full non-system users.
This change does 2 things - > Separate Backup helper allow lists for profile and full non-system users Due to the work supporting the new headless config (aka 'main' user) we are adding new helpers to the multi-user allowlist in SystemBackupAgent. This allowlist was effectively for work profile so these helpers will start running for profile users as well. Since it might not make sense for all helpers to run for profile user, this CL separates the allowlists. > Separate Backup Eligibility allow lists for profile and full non-system users. Due to the work supporting the new headless config (aka 'main' user) we are adding new packages to the multi-user allowlist in BackupEligibilityRules. This allowlist was effectively for work profile so these packages will start getting backed up for profile users as well. Since it does not make sense for all those packages to be backed up for profile user, this CL separates the allowlists. Bug: 265142782 Test: atest SystemBackupAgentTest Manual by running `adb shell bmgr backupnow android` for a system, profile, and full non-system user and verifying only the correct helpers are added via IntelliJ debugger. atest BackupEligibilityRulesTest Change-Id: I6115d8ef56629293eac0885d9db98da2a5f916bb
This commit is contained in:
committed by
Piyush Mehrotra
parent
b0199cdbbb
commit
702ce6c27c
@@ -551,7 +551,7 @@ public class UserBackupManagerService {
|
||||
mPackageManagerBinder = AppGlobals.getPackageManager();
|
||||
mActivityManager = ActivityManager.getService();
|
||||
mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
|
||||
mScheduledBackupEligibility = getEligibilityRules(mPackageManager, userId,
|
||||
mScheduledBackupEligibility = getEligibilityRules(mPackageManager, userId, mContext,
|
||||
BackupDestination.CLOUD);
|
||||
|
||||
mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
|
||||
@@ -4118,13 +4118,14 @@ public class UserBackupManagerService {
|
||||
|
||||
public BackupEligibilityRules getEligibilityRulesForOperation(
|
||||
@BackupDestination int backupDestination) {
|
||||
return getEligibilityRules(mPackageManager, mUserId, backupDestination);
|
||||
return getEligibilityRules(mPackageManager, mUserId, mContext, backupDestination);
|
||||
}
|
||||
|
||||
private static BackupEligibilityRules getEligibilityRules(PackageManager packageManager,
|
||||
int userId, @BackupDestination int backupDestination) {
|
||||
int userId, Context context, @BackupDestination int backupDestination) {
|
||||
return new BackupEligibilityRules(packageManager,
|
||||
LocalServices.getService(PackageManagerInternal.class), userId, backupDestination);
|
||||
LocalServices.getService(PackageManagerInternal.class), userId, context,
|
||||
backupDestination);
|
||||
}
|
||||
|
||||
/** Prints service state for 'dumpsys backup'. */
|
||||
|
||||
@@ -112,7 +112,9 @@ public class PerformAdbRestoreTask implements Runnable {
|
||||
BackupEligibilityRules eligibilityRules = new BackupEligibilityRules(
|
||||
mBackupManagerService.getPackageManager(),
|
||||
LocalServices.getService(PackageManagerInternal.class),
|
||||
mBackupManagerService.getUserId(), BackupDestination.ADB_BACKUP);
|
||||
mBackupManagerService.getUserId(),
|
||||
mBackupManagerService.getContext(),
|
||||
BackupDestination.ADB_BACKUP);
|
||||
FullRestoreEngine mEngine = new FullRestoreEngine(mBackupManagerService,
|
||||
mOperationStorage, null, mObserver, null, null,
|
||||
true, 0 /*unused*/, true, eligibilityRules);
|
||||
|
||||
@@ -31,6 +31,7 @@ import android.app.compat.CompatChanges;
|
||||
import android.compat.annotation.ChangeId;
|
||||
import android.compat.annotation.EnabledSince;
|
||||
import android.compat.annotation.Overridable;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
@@ -39,10 +40,12 @@ import android.content.pm.Signature;
|
||||
import android.content.pm.SigningInfo;
|
||||
import android.os.Build;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.util.Slog;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.util.ArrayUtils;
|
||||
import com.android.server.backup.SetUtils;
|
||||
import com.android.server.backup.transport.BackupTransportClient;
|
||||
import com.android.server.backup.transport.TransportConnection;
|
||||
|
||||
@@ -56,13 +59,26 @@ import java.util.Set;
|
||||
*/
|
||||
public class BackupEligibilityRules {
|
||||
private static final boolean DEBUG = false;
|
||||
// List of system packages that are eligible for backup in non-system users.
|
||||
private static final Set<String> systemPackagesAllowedForAllUsers = Sets.newArraySet(
|
||||
PACKAGE_MANAGER_SENTINEL, PLATFORM_PACKAGE_NAME, WALLPAPER_PACKAGE, SETTINGS_PACKAGE);
|
||||
|
||||
/**
|
||||
* List of system packages that are eligible for backup in "profile" users (such as work
|
||||
* profile). See {@link UserManager#isProfile()}. This is a subset of {@link
|
||||
* #systemPackagesAllowedForNonSystemUsers}
|
||||
*/
|
||||
private static final Set<String> systemPackagesAllowedForProfileUser =
|
||||
Sets.newArraySet(PACKAGE_MANAGER_SENTINEL, PLATFORM_PACKAGE_NAME);
|
||||
|
||||
/**
|
||||
* List of system packages that are eligible for backup in non-system users.
|
||||
*/
|
||||
private static final Set<String> systemPackagesAllowedForNonSystemUsers = SetUtils.union(
|
||||
systemPackagesAllowedForProfileUser,
|
||||
Sets.newArraySet(WALLPAPER_PACKAGE, SETTINGS_PACKAGE));
|
||||
|
||||
private final PackageManager mPackageManager;
|
||||
private final PackageManagerInternal mPackageManagerInternal;
|
||||
private final int mUserId;
|
||||
private boolean mIsProfileUser = false;
|
||||
@BackupDestination private final int mBackupDestination;
|
||||
|
||||
/**
|
||||
@@ -85,19 +101,23 @@ public class BackupEligibilityRules {
|
||||
|
||||
public static BackupEligibilityRules forBackup(PackageManager packageManager,
|
||||
PackageManagerInternal packageManagerInternal,
|
||||
int userId) {
|
||||
return new BackupEligibilityRules(packageManager, packageManagerInternal, userId,
|
||||
int userId,
|
||||
Context context) {
|
||||
return new BackupEligibilityRules(packageManager, packageManagerInternal, userId, context,
|
||||
BackupDestination.CLOUD);
|
||||
}
|
||||
|
||||
public BackupEligibilityRules(PackageManager packageManager,
|
||||
PackageManagerInternal packageManagerInternal,
|
||||
int userId,
|
||||
Context context,
|
||||
@BackupDestination int backupDestination) {
|
||||
mPackageManager = packageManager;
|
||||
mPackageManagerInternal = packageManagerInternal;
|
||||
mUserId = userId;
|
||||
mBackupDestination = backupDestination;
|
||||
UserManager userManager = context.getSystemService(UserManager.class);
|
||||
mIsProfileUser = userManager.isProfile();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -125,11 +145,17 @@ public class BackupEligibilityRules {
|
||||
|
||||
// 2. they run as a system-level uid
|
||||
if (UserHandle.isCore(app.uid)) {
|
||||
// and the backup is happening for a non-system user on a package that is not explicitly
|
||||
// allowed.
|
||||
if (mUserId != UserHandle.USER_SYSTEM
|
||||
&& !systemPackagesAllowedForAllUsers.contains(app.packageName)) {
|
||||
return false;
|
||||
// and the backup is happening for a non-system user or profile on a package that is
|
||||
// not explicitly allowed.
|
||||
if (mUserId != UserHandle.USER_SYSTEM) {
|
||||
if (mIsProfileUser && !systemPackagesAllowedForProfileUser.contains(
|
||||
app.packageName)) {
|
||||
return false;
|
||||
}
|
||||
if (!mIsProfileUser && !systemPackagesAllowedForNonSystemUsers.contains(
|
||||
app.packageName)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// or do not supply their own backup agent
|
||||
|
||||
@@ -160,7 +160,8 @@ public class RestoreUtils {
|
||||
PackageManagerInternal pmi = LocalServices.getService(
|
||||
PackageManagerInternal.class);
|
||||
BackupEligibilityRules eligibilityRules =
|
||||
BackupEligibilityRules.forBackup(packageManager, pmi, userId);
|
||||
BackupEligibilityRules.forBackup(packageManager, pmi, userId,
|
||||
context);
|
||||
if (eligibilityRules.signaturesMatch(sigs, pkg)) {
|
||||
// If this is a system-uid app without a declared backup agent,
|
||||
// don't restore any of the file data.
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.server.backup.utils;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Helper class containing common operation on {@link java.util.Set}.
|
||||
*/
|
||||
public final class SetUtils {
|
||||
// Statics only
|
||||
private SetUtils() {}
|
||||
|
||||
/**
|
||||
* Returns union of two sets.
|
||||
*/
|
||||
public static <T> Set<T> union(Set<T> set1, Set<T> set2) {
|
||||
Set<T> unionSet = new HashSet<>(set1);
|
||||
unionSet.addAll(set2);
|
||||
return unionSet;
|
||||
}
|
||||
}
|
||||
@@ -47,6 +47,7 @@ import android.app.backup.BackupAgent;
|
||||
import android.app.backup.BackupManagerMonitor;
|
||||
import android.app.backup.FullBackup;
|
||||
import android.app.backup.IBackupManagerMonitor;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
@@ -384,13 +385,14 @@ public class TarBackupReader {
|
||||
* @param info - file metadata.
|
||||
* @param signatures - array of signatures parsed from backup file.
|
||||
* @param userId - ID of the user for which restore is performed.
|
||||
* @param context - Context instance.
|
||||
* @return a restore policy constant.
|
||||
*/
|
||||
public RestorePolicy chooseRestorePolicy(PackageManager packageManager,
|
||||
boolean allowApks, FileMetadata info, Signature[] signatures,
|
||||
PackageManagerInternal pmi, int userId) {
|
||||
PackageManagerInternal pmi, int userId, Context context) {
|
||||
return chooseRestorePolicy(packageManager, allowApks, info, signatures, pmi, userId,
|
||||
BackupEligibilityRules.forBackup(packageManager, pmi, userId));
|
||||
BackupEligibilityRules.forBackup(packageManager, pmi, userId, context));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
37
services/core/java/com/android/server/backup/SetUtils.java
Normal file
37
services/core/java/com/android/server/backup/SetUtils.java
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.server.backup;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Helper class containing common operation on {@link java.util.Set}.
|
||||
*/
|
||||
public final class SetUtils {
|
||||
// Statics only
|
||||
private SetUtils() {}
|
||||
|
||||
/**
|
||||
* Returns union of two sets.
|
||||
*/
|
||||
public static <T> Set<T> union(Set<T> set1, Set<T> set2) {
|
||||
Set<T> unionSet = new HashSet<>(set1);
|
||||
unionSet.addAll(set2);
|
||||
return unionSet;
|
||||
}
|
||||
}
|
||||
@@ -30,6 +30,7 @@ import android.os.ParcelFileDescriptor;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.util.Slog;
|
||||
|
||||
import com.google.android.collect.Sets;
|
||||
@@ -84,30 +85,50 @@ public class SystemBackupAgent extends BackupAgentHelper {
|
||||
// Use old keys to keep legacy data compatibility and avoid writing two wallpapers
|
||||
private static final String WALLPAPER_IMAGE_KEY = WallpaperBackupHelper.WALLPAPER_IMAGE_KEY;
|
||||
|
||||
private static final Set<String> sEligibleForMultiUser = Sets.newArraySet(
|
||||
PERMISSION_HELPER, NOTIFICATION_HELPER, SYNC_SETTINGS_HELPER, APP_LOCALES_HELPER,
|
||||
ACCOUNT_MANAGER_HELPER, USAGE_STATS_HELPER, PREFERRED_HELPER, SHORTCUT_MANAGER_HELPER
|
||||
);
|
||||
/**
|
||||
* Helpers that are enabled for "profile" users (such as work profile). See {@link
|
||||
* UserManager#isProfile()}. This is a subset of {@link #sEligibleHelpersForNonSystemUser}.
|
||||
*/
|
||||
private static final Set<String> sEligibleHelpersForProfileUser =
|
||||
Sets.newArraySet(
|
||||
PERMISSION_HELPER,
|
||||
NOTIFICATION_HELPER,
|
||||
SYNC_SETTINGS_HELPER,
|
||||
APP_LOCALES_HELPER);
|
||||
|
||||
/** Helpers that are enabled for full, non-system users. */
|
||||
private static final Set<String> sEligibleHelpersForNonSystemUser =
|
||||
SetUtils.union(sEligibleHelpersForProfileUser,
|
||||
Sets.newArraySet(ACCOUNT_MANAGER_HELPER, USAGE_STATS_HELPER, PREFERRED_HELPER,
|
||||
SHORTCUT_MANAGER_HELPER));
|
||||
|
||||
private int mUserId = UserHandle.USER_SYSTEM;
|
||||
private boolean mIsProfileUser = false;
|
||||
|
||||
@Override
|
||||
public void onCreate(UserHandle user, @BackupDestination int backupDestination) {
|
||||
super.onCreate(user, backupDestination);
|
||||
|
||||
mUserId = user.getIdentifier();
|
||||
if (mUserId != UserHandle.USER_SYSTEM) {
|
||||
Context context = createContextAsUser(user, /* flags= */ 0);
|
||||
UserManager userManager = context.getSystemService(UserManager.class);
|
||||
mIsProfileUser = userManager.isProfile();
|
||||
}
|
||||
|
||||
addHelper(SYNC_SETTINGS_HELPER, new AccountSyncSettingsBackupHelper(this, mUserId));
|
||||
addHelper(PREFERRED_HELPER, new PreferredActivityBackupHelper(mUserId));
|
||||
addHelper(NOTIFICATION_HELPER, new NotificationBackupHelper(mUserId));
|
||||
addHelper(PERMISSION_HELPER, new PermissionBackupHelper(mUserId));
|
||||
addHelper(USAGE_STATS_HELPER, new UsageStatsBackupHelper(mUserId));
|
||||
addHelper(SHORTCUT_MANAGER_HELPER, new ShortcutBackupHelper(mUserId));
|
||||
addHelper(ACCOUNT_MANAGER_HELPER, new AccountManagerBackupHelper(mUserId));
|
||||
addHelper(SLICES_HELPER, new SliceBackupHelper(this));
|
||||
addHelper(PEOPLE_HELPER, new PeopleBackupHelper(mUserId));
|
||||
addHelper(APP_LOCALES_HELPER, new AppSpecificLocalesBackupHelper(mUserId));
|
||||
addHelper(APP_GENDER_HELPER, new AppGrammaticalGenderBackupHelper(mUserId));
|
||||
addHelperIfEligibleForUser(
|
||||
SYNC_SETTINGS_HELPER, new AccountSyncSettingsBackupHelper(this, mUserId));
|
||||
addHelperIfEligibleForUser(PREFERRED_HELPER, new PreferredActivityBackupHelper(mUserId));
|
||||
addHelperIfEligibleForUser(NOTIFICATION_HELPER, new NotificationBackupHelper(mUserId));
|
||||
addHelperIfEligibleForUser(PERMISSION_HELPER, new PermissionBackupHelper(mUserId));
|
||||
addHelperIfEligibleForUser(USAGE_STATS_HELPER, new UsageStatsBackupHelper(mUserId));
|
||||
addHelperIfEligibleForUser(SHORTCUT_MANAGER_HELPER, new ShortcutBackupHelper(mUserId));
|
||||
addHelperIfEligibleForUser(ACCOUNT_MANAGER_HELPER, new AccountManagerBackupHelper(mUserId));
|
||||
addHelperIfEligibleForUser(SLICES_HELPER, new SliceBackupHelper(this));
|
||||
addHelperIfEligibleForUser(PEOPLE_HELPER, new PeopleBackupHelper(mUserId));
|
||||
addHelperIfEligibleForUser(APP_LOCALES_HELPER, new AppSpecificLocalesBackupHelper(mUserId));
|
||||
addHelperIfEligibleForUser(APP_GENDER_HELPER,
|
||||
new AppGrammaticalGenderBackupHelper(mUserId));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -131,15 +152,6 @@ public class SystemBackupAgent extends BackupAgentHelper {
|
||||
super.onRestore(data, appVersionCode, newState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addHelper(String keyPrefix, BackupHelper helper) {
|
||||
if (mUserId != UserHandle.USER_SYSTEM && !sEligibleForMultiUser.contains(keyPrefix)) {
|
||||
return;
|
||||
}
|
||||
|
||||
super.addHelper(keyPrefix, helper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Support for 'adb restore' of legacy archives
|
||||
*/
|
||||
@@ -190,4 +202,25 @@ public class SystemBackupAgent extends BackupAgentHelper {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addHelperIfEligibleForUser(String keyPrefix, BackupHelper helper) {
|
||||
if (isHelperEligibleForUser(keyPrefix)) {
|
||||
addHelper(keyPrefix, helper);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isHelperEligibleForUser(String keyPrefix) {
|
||||
// All helpers are eligible for the system user.
|
||||
if (mUserId == UserHandle.USER_SYSTEM) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Profile users (such as work profile) have their own allow list.
|
||||
if (mIsProfileUser) {
|
||||
return sEligibleHelpersForProfileUser.contains(keyPrefix);
|
||||
}
|
||||
|
||||
// Full, non-system users have their own allow list.
|
||||
return sEligibleHelpersForNonSystemUser.contains(keyPrefix);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -267,7 +267,7 @@ public class KeyValueBackupTaskTest {
|
||||
LocalServices.removeServiceForTest(PackageManagerInternal.class);
|
||||
LocalServices.addService(PackageManagerInternal.class, mPackageManagerInternal);
|
||||
mBackupEligibilityRules = new BackupEligibilityRules(mPackageManager,
|
||||
LocalServices.getService(PackageManagerInternal.class), USER_ID,
|
||||
LocalServices.getService(PackageManagerInternal.class), USER_ID, mContext,
|
||||
BACKUP_DESTINATION);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.server.backup;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.app.backup.BackupHelper;
|
||||
import android.content.Context;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
import android.util.ArraySet;
|
||||
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
@SmallTest
|
||||
@Presubmit
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class SystemBackupAgentTest {
|
||||
private static final int NON_SYSTEM_USER_ID = 10;
|
||||
|
||||
private TestableSystemBackupAgent mSystemBackupAgent;
|
||||
|
||||
@Mock private Context mContextMock;
|
||||
@Mock private UserManager mUserManagerMock;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mSystemBackupAgent = new TestableSystemBackupAgent();
|
||||
when(mContextMock.getSystemService(UserManager.class)).thenReturn(mUserManagerMock);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onCreate_systemUser_addsAllHelpers() {
|
||||
UserHandle userHandle = new UserHandle(UserHandle.USER_SYSTEM);
|
||||
when(mUserManagerMock.isProfile()).thenReturn(false);
|
||||
|
||||
mSystemBackupAgent.onCreate(userHandle, /* backupDestination= */ 0);
|
||||
|
||||
assertThat(mSystemBackupAgent.mAddedHelpers)
|
||||
.containsExactly(
|
||||
"account_sync_settings",
|
||||
"preferred_activities",
|
||||
"notifications",
|
||||
"permissions",
|
||||
"usage_stats",
|
||||
"shortcut_manager",
|
||||
"account_manager",
|
||||
"slices",
|
||||
"people",
|
||||
"app_locales",
|
||||
"app_gender");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onCreate_profileUser_addsProfileEligibleHelpers() {
|
||||
UserHandle userHandle = new UserHandle(NON_SYSTEM_USER_ID);
|
||||
when(mUserManagerMock.isProfile()).thenReturn(true);
|
||||
|
||||
mSystemBackupAgent.onCreate(userHandle, /* backupDestination= */ 0);
|
||||
|
||||
assertThat(mSystemBackupAgent.mAddedHelpers)
|
||||
.containsExactly(
|
||||
"account_sync_settings",
|
||||
"notifications",
|
||||
"permissions",
|
||||
"app_locales");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onCreate_nonSystemUser_addsNonSystemEligibleHelpers() {
|
||||
UserHandle userHandle = new UserHandle(NON_SYSTEM_USER_ID);
|
||||
when(mUserManagerMock.isProfile()).thenReturn(false);
|
||||
|
||||
mSystemBackupAgent.onCreate(userHandle, /* backupDestination= */ 0);
|
||||
|
||||
assertThat(mSystemBackupAgent.mAddedHelpers)
|
||||
.containsExactly(
|
||||
"account_sync_settings",
|
||||
"preferred_activities",
|
||||
"notifications",
|
||||
"permissions",
|
||||
"app_locales",
|
||||
"account_manager",
|
||||
"usage_stats",
|
||||
"shortcut_manager");
|
||||
}
|
||||
|
||||
private class TestableSystemBackupAgent extends SystemBackupAgent {
|
||||
final Set<String> mAddedHelpers = new ArraySet<>();
|
||||
|
||||
@Override
|
||||
public void addHelper(String keyPrefix, BackupHelper helper) {
|
||||
mAddedHelpers.add(keyPrefix);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Context createContextAsUser(UserHandle user, @CreatePackageOptions int flags) {
|
||||
return mContextMock;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getSystemService(@ServiceName @NonNull String name) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -25,6 +25,7 @@ import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.backup.BackupAnnotations.BackupDestination;
|
||||
import android.compat.testing.PlatformCompatChangeRule;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
@@ -35,6 +36,7 @@ import android.content.pm.SigningDetails;
|
||||
import android.content.pm.SigningInfo;
|
||||
import android.os.Process;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
@@ -64,11 +66,17 @@ public class BackupEligibilityRulesTest {
|
||||
private static final Signature SIGNATURE_2 = generateSignature((byte) 2);
|
||||
private static final Signature SIGNATURE_3 = generateSignature((byte) 3);
|
||||
private static final Signature SIGNATURE_4 = generateSignature((byte) 4);
|
||||
private static final int NON_SYSTEM_USER = 10;
|
||||
|
||||
@Rule public TestRule compatChangeRule = new PlatformCompatChangeRule();
|
||||
|
||||
@Mock private PackageManagerInternal mMockPackageManagerInternal;
|
||||
@Mock private PackageManager mPackageManager;
|
||||
@Mock
|
||||
private PackageManager mPackageManager;
|
||||
@Mock
|
||||
private Context mContext;
|
||||
@Mock
|
||||
private UserManager mUserManager;
|
||||
|
||||
private BackupEligibilityRules mBackupEligibilityRules;
|
||||
private int mUserId;
|
||||
@@ -78,6 +86,7 @@ public class BackupEligibilityRulesTest {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
mUserId = UserHandle.USER_SYSTEM;
|
||||
mockContextForFullUser();
|
||||
mBackupEligibilityRules = getBackupEligibilityRules(BackupDestination.CLOUD);
|
||||
}
|
||||
|
||||
@@ -94,6 +103,70 @@ public class BackupEligibilityRulesTest {
|
||||
assertThat(isEligible).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void appIsEligibleForBackup_systemUid_nonSystemUser_notAllowedPackage_returnsFalse()
|
||||
throws Exception {
|
||||
setUpForNonSystemUser();
|
||||
|
||||
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;
|
||||
|
||||
boolean isEligible = mBackupEligibilityRules.appIsEligibleForBackup(applicationInfo);
|
||||
|
||||
assertThat(isEligible).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void appIsEligibleForBackup_systemUid_nonSystemUser_allowedPackage_returnsTrue()
|
||||
throws Exception {
|
||||
setUpForNonSystemUser();
|
||||
|
||||
ApplicationInfo applicationInfo = new ApplicationInfo();
|
||||
applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP;
|
||||
applicationInfo.uid = Process.SYSTEM_UID;
|
||||
applicationInfo.backupAgentName = CUSTOM_BACKUP_AGENT_NAME;
|
||||
applicationInfo.packageName = UserBackupManagerService.WALLPAPER_PACKAGE;
|
||||
|
||||
boolean isEligible = mBackupEligibilityRules.appIsEligibleForBackup(applicationInfo);
|
||||
|
||||
assertThat(isEligible).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void appIsEligibleForBackup_systemUid_profileUser_notAllowedPackage_returnsFalse()
|
||||
throws Exception {
|
||||
setUpForProfileUser();
|
||||
|
||||
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;
|
||||
|
||||
boolean isEligible = mBackupEligibilityRules.appIsEligibleForBackup(applicationInfo);
|
||||
|
||||
assertThat(isEligible).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void appIsEligibleForBackup_systemUid_profileUser_allowedPackage_returnsTrue()
|
||||
throws Exception {
|
||||
setUpForProfileUser();
|
||||
|
||||
ApplicationInfo applicationInfo = new ApplicationInfo();
|
||||
applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP;
|
||||
applicationInfo.uid = Process.SYSTEM_UID;
|
||||
applicationInfo.backupAgentName = CUSTOM_BACKUP_AGENT_NAME;
|
||||
applicationInfo.packageName = UserBackupManagerService.PACKAGE_MANAGER_SENTINEL;
|
||||
|
||||
boolean isEligible = mBackupEligibilityRules.appIsEligibleForBackup(applicationInfo);
|
||||
|
||||
assertThat(isEligible).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void appIsEligibleForBackup_systemAppWithoutCustomBackupAgent_returnsFalse()
|
||||
throws Exception {
|
||||
@@ -790,7 +863,7 @@ public class BackupEligibilityRulesTest {
|
||||
private BackupEligibilityRules getBackupEligibilityRules(
|
||||
@BackupDestination int backupDestination) {
|
||||
return new BackupEligibilityRules(mPackageManager, mMockPackageManagerInternal, mUserId,
|
||||
backupDestination);
|
||||
mContext, backupDestination);
|
||||
}
|
||||
|
||||
private static Signature generateSignature(byte i) {
|
||||
@@ -813,4 +886,26 @@ public class BackupEligibilityRulesTest {
|
||||
return new Property(PackageManager.PROPERTY_ALLOW_ADB_BACKUP, allowAdbBackup,
|
||||
TEST_PACKAGE_NAME, /* className */ "");
|
||||
}
|
||||
|
||||
private void setUpForNonSystemUser() {
|
||||
mUserId = NON_SYSTEM_USER;
|
||||
mockContextForFullUser();
|
||||
mBackupEligibilityRules = getBackupEligibilityRules(BackupDestination.CLOUD);
|
||||
}
|
||||
|
||||
private void setUpForProfileUser() {
|
||||
mUserId = NON_SYSTEM_USER;
|
||||
mockContextForProfile();
|
||||
mBackupEligibilityRules = getBackupEligibilityRules(BackupDestination.CLOUD);
|
||||
}
|
||||
|
||||
private void mockContextForProfile() {
|
||||
when(mUserManager.isProfile()).thenReturn(true);
|
||||
when(mContext.getSystemService(UserManager.class)).thenReturn(mUserManager);
|
||||
}
|
||||
|
||||
private void mockContextForFullUser() {
|
||||
when(mUserManager.isProfile()).thenReturn(false);
|
||||
when(mContext.getSystemService(UserManager.class)).thenReturn(mUserManager);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -149,7 +149,7 @@ public class TarBackupReaderTest {
|
||||
fileMetadata);
|
||||
RestorePolicy restorePolicy = tarBackupReader.chooseRestorePolicy(
|
||||
mPackageManagerStub, false /* allowApks */, fileMetadata, signatures,
|
||||
mMockPackageManagerInternal, mUserId);
|
||||
mMockPackageManagerInternal, mUserId, mContext);
|
||||
|
||||
assertThat(restorePolicy).isEqualTo(RestorePolicy.IGNORE);
|
||||
assertThat(fileMetadata.packageName).isEqualTo(TEST_PACKAGE_NAME);
|
||||
@@ -163,7 +163,7 @@ public class TarBackupReaderTest {
|
||||
fileMetadata);
|
||||
restorePolicy = tarBackupReader.chooseRestorePolicy(
|
||||
mPackageManagerStub, false /* allowApks */, fileMetadata, signatures,
|
||||
mMockPackageManagerInternal, mUserId);
|
||||
mMockPackageManagerInternal, mUserId, mContext);
|
||||
|
||||
assertThat(restorePolicy).isEqualTo(RestorePolicy.IGNORE);
|
||||
assertThat(fileMetadata.packageName).isEqualTo(TEST_PACKAGE_NAME);
|
||||
@@ -226,7 +226,7 @@ public class TarBackupReaderTest {
|
||||
|
||||
RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
|
||||
true /* allowApks */, new FileMetadata(), null /* signatures */,
|
||||
mMockPackageManagerInternal, mUserId);
|
||||
mMockPackageManagerInternal, mUserId, mContext);
|
||||
|
||||
assertThat(policy).isEqualTo(RestorePolicy.IGNORE);
|
||||
verifyZeroInteractions(mBackupManagerMonitorMock);
|
||||
@@ -247,7 +247,7 @@ public class TarBackupReaderTest {
|
||||
|
||||
RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
|
||||
true /* allowApks */, info, new Signature[0] /* signatures */,
|
||||
mMockPackageManagerInternal, mUserId);
|
||||
mMockPackageManagerInternal, mUserId, mContext);
|
||||
|
||||
assertThat(policy).isEqualTo(RestorePolicy.ACCEPT_IF_APK);
|
||||
ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
|
||||
@@ -272,7 +272,7 @@ public class TarBackupReaderTest {
|
||||
|
||||
RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
|
||||
true /* allowApks */, info, new Signature[0] /* signatures */,
|
||||
mMockPackageManagerInternal, mUserId);
|
||||
mMockPackageManagerInternal, mUserId, mContext);
|
||||
|
||||
assertThat(policy).isEqualTo(RestorePolicy.ACCEPT_IF_APK);
|
||||
ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
|
||||
@@ -298,7 +298,7 @@ public class TarBackupReaderTest {
|
||||
|
||||
RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
|
||||
false /* allowApks */, new FileMetadata(), new Signature[0] /* signatures */,
|
||||
mMockPackageManagerInternal, mUserId);
|
||||
mMockPackageManagerInternal, mUserId, mContext);
|
||||
|
||||
assertThat(policy).isEqualTo(RestorePolicy.IGNORE);
|
||||
ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
|
||||
@@ -323,7 +323,7 @@ public class TarBackupReaderTest {
|
||||
|
||||
RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
|
||||
false /* allowApks */, new FileMetadata(), new Signature[0] /* signatures */,
|
||||
mMockPackageManagerInternal, mUserId);
|
||||
mMockPackageManagerInternal, mUserId, mContext);
|
||||
|
||||
assertThat(policy).isEqualTo(RestorePolicy.IGNORE);
|
||||
ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
|
||||
@@ -350,7 +350,7 @@ public class TarBackupReaderTest {
|
||||
|
||||
RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
|
||||
false /* allowApks */, new FileMetadata(), new Signature[0] /* signatures */,
|
||||
mMockPackageManagerInternal, mUserId);
|
||||
mMockPackageManagerInternal, mUserId, mContext);
|
||||
|
||||
assertThat(policy).isEqualTo(RestorePolicy.IGNORE);
|
||||
ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
|
||||
@@ -385,7 +385,7 @@ public class TarBackupReaderTest {
|
||||
|
||||
RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
|
||||
false /* allowApks */, new FileMetadata(), signatures,
|
||||
mMockPackageManagerInternal, mUserId);
|
||||
mMockPackageManagerInternal, mUserId, mContext);
|
||||
|
||||
assertThat(policy).isEqualTo(RestorePolicy.IGNORE);
|
||||
ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
|
||||
@@ -424,7 +424,7 @@ public class TarBackupReaderTest {
|
||||
packageInfo.packageName);
|
||||
RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
|
||||
false /* allowApks */, new FileMetadata(), signatures,
|
||||
mMockPackageManagerInternal, mUserId);
|
||||
mMockPackageManagerInternal, mUserId, mContext);
|
||||
|
||||
assertThat(policy).isEqualTo(RestorePolicy.ACCEPT);
|
||||
ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
|
||||
@@ -462,7 +462,7 @@ public class TarBackupReaderTest {
|
||||
packageInfo.packageName);
|
||||
RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
|
||||
false /* allowApks */, new FileMetadata(), signatures,
|
||||
mMockPackageManagerInternal, mUserId);
|
||||
mMockPackageManagerInternal, mUserId, mContext);
|
||||
|
||||
assertThat(policy).isEqualTo(RestorePolicy.ACCEPT);
|
||||
ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
|
||||
@@ -504,7 +504,7 @@ public class TarBackupReaderTest {
|
||||
packageInfo.packageName);
|
||||
RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
|
||||
false /* allowApks */, info, signatures, mMockPackageManagerInternal,
|
||||
mUserId);
|
||||
mUserId, mContext);
|
||||
|
||||
assertThat(policy).isEqualTo(RestorePolicy.ACCEPT);
|
||||
ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
|
||||
@@ -548,7 +548,7 @@ public class TarBackupReaderTest {
|
||||
packageInfo.packageName);
|
||||
RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
|
||||
true /* allowApks */, info, signatures, mMockPackageManagerInternal,
|
||||
mUserId);
|
||||
mUserId, mContext);
|
||||
|
||||
assertThat(policy).isEqualTo(RestorePolicy.ACCEPT_IF_APK);
|
||||
verifyNoMoreInteractions(mBackupManagerMonitorMock);
|
||||
@@ -588,7 +588,7 @@ public class TarBackupReaderTest {
|
||||
packageInfo.packageName);
|
||||
RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
|
||||
false /* allowApks */, info, signatures, mMockPackageManagerInternal,
|
||||
mUserId);
|
||||
mUserId, mContext);
|
||||
|
||||
assertThat(policy).isEqualTo(RestorePolicy.IGNORE);
|
||||
ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
|
||||
|
||||
Reference in New Issue
Block a user