diff options
author | 2023-02-01 17:11:50 +0000 | |
---|---|---|
committer | 2023-02-15 11:25:28 +0000 | |
commit | c9892805d16df1ed5abba424e4df8e6e39f83422 (patch) | |
tree | bcf594eda385ad8de8df994a999c5ce7164140df /services | |
parent | 15ea931900a6eed04eb8ba44737bd54858b112ae (diff) |
Update the default backup user after onUserUnlocking if necessary
On the first ever boot of a HSUM device, UserManager will create the main user after BackupManagerService is created. If that happens the default user will stay as 0 until the device is rebooted. To prevent this we need to update the default user as soon as it's guaranteed that the main user is created (if one is to be created), which is when the first user unlocks.
Bug: 266098768
Test: atest BackupManagerServiceTest
atest BackupFrameworksServicesRoboTests
manually by doing a factory reset and then checking backup is active for the main user via `adb shell bmgr --user 10 activate`
Change-Id: Ic14e7357b468c27d206a57f9e7148d918f747c1d
Diffstat (limited to 'services')
3 files changed, 182 insertions, 74 deletions
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java index dc475f696a96..3a7aa855ea90 100644 --- a/services/backup/java/com/android/server/backup/BackupManagerService.java +++ b/services/backup/java/com/android/server/backup/BackupManagerService.java @@ -158,19 +158,19 @@ public class BackupManagerService extends IBackupManager.Stub { /** * The user that the backup is activated by default for. * - * If there is a {@link UserManager#getMainUser()}, this will be that user. If not, it will be - * {@link UserHandle#USER_SYSTEM}. + * <p>If there is a {@link UserManager#getMainUser()}, this will be that user. If not, it will + * be {@link UserHandle#USER_SYSTEM}. + * + * <p>Note: on the first ever boot of a new device, this might change once the first user is + * unlocked. See {@link #updateDefaultBackupUserIdIfNeeded()}. * * @see #isBackupActivatedForUser(int) */ - @UserIdInt private final int mDefaultBackupUserId; + @UserIdInt private int mDefaultBackupUserId; - public BackupManagerService(Context context) { - this(context, new SparseArray<>()); - } + private boolean mHasFirstUserUnlockedSinceBoot = false; - @VisibleForTesting - BackupManagerService(Context context, SparseArray<UserBackupManagerService> userServices) { + public BackupManagerService(Context context) { mContext = context; mGlobalDisable = isBackupDisabled(); HandlerThread handlerThread = @@ -178,7 +178,7 @@ public class BackupManagerService extends IBackupManager.Stub { handlerThread.start(); mHandler = new Handler(handlerThread.getLooper()); mUserManager = UserManager.get(context); - mUserServices = userServices; + mUserServices = new SparseArray<>(); Set<ComponentName> transportWhitelist = SystemConfig.getInstance().getBackupTransportWhitelist(); mTransportWhitelist = (transportWhitelist == null) ? emptySet() : transportWhitelist; @@ -186,6 +186,9 @@ public class BackupManagerService extends IBackupManager.Stub { mUserRemovedReceiver, new IntentFilter(Intent.ACTION_USER_REMOVED)); UserHandle mainUser = getUserManager().getMainUser(); mDefaultBackupUserId = mainUser == null ? UserHandle.USER_SYSTEM : mainUser.getIdentifier(); + if (DEBUG) { + Slog.d(TAG, "Default backup user id = " + mDefaultBackupUserId); + } } // TODO: Remove this when we implement DI by injecting in the construtor. @@ -361,17 +364,6 @@ public class BackupManagerService extends IBackupManager.Stub { } /** - * Called from {@link BackupManagerService.Lifecycle} when a user {@code userId} is unlocked. - * Starts the backup service for this user if backup is active for this user. Offloads work onto - * the handler thread {@link #mHandlerThread} to keep unlock time low since backup is not - * essential for device functioning. - */ - @VisibleForTesting - void onUnlockUser(int userId) { - postToHandler(() -> startServiceForUser(userId)); - } - - /** * Starts the backup service for user {@code userId} by creating a new instance of {@link * UserBackupManagerService} and registering it with this service. */ @@ -1687,7 +1679,15 @@ public class BackupManagerService extends IBackupManager.Stub { @Override public void onUserUnlocking(@NonNull TargetUser user) { - sInstance.onUnlockUser(user.getUserIdentifier()); + // Starts the backup service for this user if backup is active for this user. Offloads + // work onto the handler thread {@link #mHandlerThread} to keep unlock time low since + // backup is not essential for device functioning. + sInstance.postToHandler( + () -> { + sInstance.updateDefaultBackupUserIdIfNeeded(); + sInstance.startServiceForUser(user.getUserIdentifier()); + sInstance.mHasFirstUserUnlockedSinceBoot = true; + }); } @Override @@ -1700,4 +1700,42 @@ public class BackupManagerService extends IBackupManager.Stub { publishBinderService(name, service); } } + + /** + * On the first ever boot of a new device, the 'main' user might not exist for a short period of + * time and be created after {@link BackupManagerService} is created. In this case the {@link + * #mDefaultBackupUserId} will be the system user initially, but we need to change it to the + * newly created {@link UserManager#getMainUser()} later. + * + * <p>{@link Lifecycle#onUserUnlocking(SystemService.TargetUser)} (for any user) is the earliest + * point where we know that a main user (if there is going to be one) is created. + */ + private void updateDefaultBackupUserIdIfNeeded() { + // The default user can only change before any user unlocks since boot, and it will only + // change from the system user to a non-system user. + if (mHasFirstUserUnlockedSinceBoot || mDefaultBackupUserId != UserHandle.USER_SYSTEM) { + return; + } + + UserHandle mainUser = getUserManager().getMainUser(); + if (mainUser == null) { + return; + } + + if (mDefaultBackupUserId != mainUser.getIdentifier()) { + int oldDefaultBackupUserId = mDefaultBackupUserId; + mDefaultBackupUserId = mainUser.getIdentifier(); + // We don't expect the service to be started for the old default user but we attempt to + // stop its service to be safe. + if (!isBackupActivatedForUser(oldDefaultBackupUserId)) { + stopServiceForUser(oldDefaultBackupUserId); + } + Slog.i( + TAG, + "Default backup user changed from " + + oldDefaultBackupUserId + + " to " + + mDefaultBackupUserId); + } + } } diff --git a/services/robotests/backup/src/com/android/server/backup/BackupManagerServiceRoboTest.java b/services/robotests/backup/src/com/android/server/backup/BackupManagerServiceRoboTest.java index e2f56ba56f3d..94ee0a871448 100644 --- a/services/robotests/backup/src/com/android/server/backup/BackupManagerServiceRoboTest.java +++ b/services/robotests/backup/src/com/android/server/backup/BackupManagerServiceRoboTest.java @@ -1584,11 +1584,7 @@ public class BackupManagerServiceRoboTest { @Test public void testConstructor_withNullContext_throws() throws Exception { expectThrows( - NullPointerException.class, - () -> - new BackupManagerService( - /* context */ null, - new SparseArray<>())); + NullPointerException.class, () -> new BackupManagerService(/* context */ null)); } /** Test that the constructor does not create {@link UserBackupManagerService} instances. */ @@ -1616,18 +1612,6 @@ public class BackupManagerServiceRoboTest { verify(lifecycle).publishService(Context.BACKUP_SERVICE, backupManagerService); } - /** testOnUnlockUser_forwards */ - @Test - public void testOnUnlockUser_forwards() { - BackupManagerService backupManagerService = mock(BackupManagerService.class); - BackupManagerService.Lifecycle lifecycle = - new BackupManagerService.Lifecycle(mContext, backupManagerService); - - lifecycle.onUserUnlocking(new TargetUser(new UserInfo(UserHandle.USER_SYSTEM, null, 0))); - - verify(backupManagerService).onUnlockUser(UserHandle.USER_SYSTEM); - } - /** testOnStopUser_forwards */ @Test public void testOnStopUser_forwards() { diff --git a/services/tests/mockingservicestests/src/com/android/server/backup/BackupManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/backup/BackupManagerServiceTest.java index cd9d8a9d023f..b203cf640097 100644 --- a/services/tests/mockingservicestests/src/com/android/server/backup/BackupManagerServiceTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/backup/BackupManagerServiceTest.java @@ -37,7 +37,6 @@ import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; - import android.Manifest; import android.annotation.UserIdInt; import android.app.backup.BackupManager; @@ -54,13 +53,13 @@ import android.os.RemoteException; import android.os.UserHandle; import android.os.UserManager; import android.platform.test.annotations.Presubmit; -import android.util.SparseArray; import androidx.test.InstrumentationRegistry; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; import com.android.dx.mockito.inline.extended.ExtendedMockito; +import com.android.server.SystemService; import com.android.server.backup.utils.RandomAccessFileUtils; import org.junit.After; @@ -104,8 +103,8 @@ public class BackupManagerServiceTest { private FileDescriptor mFileDescriptorStub = new FileDescriptor(); private BackupManagerServiceTestable mService; + private BackupManagerService.Lifecycle mServiceLifecycle; private static File sTestDir; - private SparseArray<UserBackupManagerService> mUserServices; private MockitoSession mSession; @Before @@ -125,8 +124,6 @@ public class BackupManagerServiceTest { mUserId = UserHandle.USER_SYSTEM; - mUserServices = new SparseArray<>(); - when(mUserManagerMock.getUserInfo(UserHandle.USER_SYSTEM)).thenReturn(mUserInfoMock); when(mUserManagerMock.getUserInfo(NON_SYSTEM_USER)).thenReturn(mUserInfoMock); // Null main user means there is no main user on the device. @@ -142,8 +139,6 @@ public class BackupManagerServiceTest { when(mContextMock.getSystemService(Context.JOB_SCHEDULER_SERVICE)) .thenReturn(mock(JobScheduler.class)); - mService = new BackupManagerServiceTestable(mContextMock, mUserServices); - simulateUserUnlocked(UserHandle.USER_SYSTEM); } @After @@ -154,21 +149,20 @@ public class BackupManagerServiceTest { @Test public void onUnlockUser_startsUserService() { + createBackupManagerServiceAndUnlockSystemUser(); mService.setBackupServiceActive(NON_SYSTEM_USER, true); ConditionVariable unlocked = new ConditionVariable(false); - mService.onUnlockUser(NON_SYSTEM_USER); - mService.getBackupHandler().post(unlocked::open); - unlocked.block(); + simulateUserUnlocked(NON_SYSTEM_USER); assertNotNull(mService.getUserService(NON_SYSTEM_USER)); } @Test public void startServiceForUser_backupDisabledGlobally_doesNotStartUserService() { + createBackupManagerServiceAndUnlockSystemUser(); BackupManagerServiceTestable.sBackupDisabled = true; - BackupManagerServiceTestable service = - new BackupManagerServiceTestable(mContextMock, new SparseArray<>()); + BackupManagerServiceTestable service = new BackupManagerServiceTestable(mContextMock); service.startServiceForUser(UserHandle.USER_SYSTEM); @@ -177,6 +171,7 @@ public class BackupManagerServiceTest { @Test public void startServiceForUser_backupNotActiveForUser_doesNotStartUserService() { + createBackupManagerServiceAndUnlockSystemUser(); mService.setBackupServiceActive(UserHandle.USER_SYSTEM, false); mService.startServiceForUser(UserHandle.USER_SYSTEM); @@ -186,7 +181,8 @@ public class BackupManagerServiceTest { @Test public void startServiceForUser_backupEnabledGloballyAndActiveForUser_startsUserService() { - setMockMainUserAndStartNewBackupManagerService(NON_SYSTEM_USER); + setMockMainUserAndCreateBackupManagerService(NON_SYSTEM_USER); + mService.startServiceForUser(NON_SYSTEM_USER); assertNotNull(mService.getUserService(NON_SYSTEM_USER)); @@ -194,9 +190,9 @@ public class BackupManagerServiceTest { @Test public void isBackupServiceActive_backupDisabledGlobally_returnFalse() { + createBackupManagerServiceAndUnlockSystemUser(); BackupManagerServiceTestable.sBackupDisabled = true; - BackupManagerService service = - new BackupManagerServiceTestable(mContextMock, mUserServices); + BackupManagerService service = new BackupManagerServiceTestable(mContextMock); service.setBackupServiceActive(UserHandle.USER_SYSTEM, true); assertFalse(service.isBackupServiceActive(UserHandle.USER_SYSTEM)); @@ -204,6 +200,7 @@ public class BackupManagerServiceTest { @Test public void isBackupServiceActive_systemUser_isDefault_deactivated_returnsFalse() { + createBackupManagerServiceAndUnlockSystemUser(); // If there's no 'main' user on the device, the default user is the system user. mService.setBackupServiceActive(UserHandle.USER_SYSTEM, false); @@ -212,20 +209,23 @@ public class BackupManagerServiceTest { @Test public void isBackupServiceActive_systemUser_isNotDefault_returnsFalse() { - setMockMainUserAndStartNewBackupManagerService(NON_SYSTEM_USER); + createBackupManagerServiceAndUnlockSystemUser(); + setMockMainUserAndCreateBackupManagerService(NON_SYSTEM_USER); assertFalse(mService.isBackupServiceActive(UserHandle.USER_SYSTEM)); } @Test public void isBackupServiceActive_systemUser_isDefault_returnsTrue() { + createBackupManagerServiceAndUnlockSystemUser(); + // If there's no 'main' user on the device, the default user is the system user. assertTrue(mService.isBackupServiceActive(UserHandle.USER_SYSTEM)); } @Test public void isBackupServiceActive_nonSystemUser_isDefault_systemUserDeactivated_returnsFalse() { - setMockMainUserAndStartNewBackupManagerService(NON_SYSTEM_USER); + setMockMainUserAndCreateBackupManagerService(NON_SYSTEM_USER); mService.setBackupServiceActive(UserHandle.USER_SYSTEM, false); assertFalse(mService.isBackupServiceActive(NON_SYSTEM_USER)); @@ -233,7 +233,7 @@ public class BackupManagerServiceTest { @Test public void isBackupServiceActive_nonSystemUser_isDefault_deactivated_returnsFalse() { - setMockMainUserAndStartNewBackupManagerService(NON_SYSTEM_USER); + setMockMainUserAndCreateBackupManagerService(NON_SYSTEM_USER); mService.setBackupServiceActive(NON_SYSTEM_USER, false); assertFalse(mService.isBackupServiceActive(NON_SYSTEM_USER)); @@ -241,19 +241,24 @@ public class BackupManagerServiceTest { @Test public void isBackupServiceActive_nonSystemUser_isDefault_returnsTrue() { - setMockMainUserAndStartNewBackupManagerService(NON_SYSTEM_USER); + createBackupManagerServiceAndUnlockSystemUser(); + + setMockMainUserAndCreateBackupManagerService(NON_SYSTEM_USER); assertTrue(mService.isBackupServiceActive(NON_SYSTEM_USER)); } @Test public void isBackupServiceActive_nonSystemUser_isNotDefault_notActivated_returnsFalse() { + createBackupManagerServiceAndUnlockSystemUser(); + // By default non-system non-default users are not activated. assertFalse(mService.isBackupServiceActive(NON_SYSTEM_USER)); } @Test public void isBackupServiceActive_nonSystemUser_isNotDefault_activated_returnsTrue() { + createBackupManagerServiceAndUnlockSystemUser(); mService.setBackupServiceActive(NON_SYSTEM_USER, true); assertTrue(mService.isBackupServiceActive(NON_SYSTEM_USER)); @@ -261,6 +266,7 @@ public class BackupManagerServiceTest { @Test public void setBackupServiceActive_forSystemUserAndCallerSystemUid_createsService() { + createBackupManagerServiceAndUnlockSystemUser(); BackupManagerServiceTestable.sCallingUid = Process.SYSTEM_UID; mService.setBackupServiceActive(UserHandle.USER_SYSTEM, true); @@ -270,6 +276,7 @@ public class BackupManagerServiceTest { @Test public void setBackupServiceActive_forSystemUserAndCallerRootUid_createsService() { + createBackupManagerServiceAndUnlockSystemUser(); BackupManagerServiceTestable.sCallingUid = Process.ROOT_UID; mService.setBackupServiceActive(UserHandle.USER_SYSTEM, true); @@ -279,6 +286,7 @@ public class BackupManagerServiceTest { @Test public void setBackupServiceActive_forSystemUserAndCallerNonRootNonSystem_throws() { + createBackupManagerServiceAndUnlockSystemUser(); BackupManagerServiceTestable.sCallingUid = Process.FIRST_APPLICATION_UID; try { @@ -290,6 +298,7 @@ public class BackupManagerServiceTest { @Test public void setBackupServiceActive_forManagedProfileAndCallerSystemUid_createsService() { + createBackupManagerServiceAndUnlockSystemUser(); simulateUserUnlocked(NON_SYSTEM_USER); when(mUserInfoMock.isManagedProfile()).thenReturn(true); BackupManagerServiceTestable.sCallingUid = Process.SYSTEM_UID; @@ -301,6 +310,7 @@ public class BackupManagerServiceTest { @Test public void setBackupServiceActive_forManagedProfileAndCallerRootUid_createsService() { + createBackupManagerServiceAndUnlockSystemUser(); simulateUserUnlocked(NON_SYSTEM_USER); when(mUserInfoMock.isManagedProfile()).thenReturn(true); BackupManagerServiceTestable.sCallingUid = Process.ROOT_UID; @@ -312,6 +322,7 @@ public class BackupManagerServiceTest { @Test public void setBackupServiceActive_forManagedProfileAndCallerNonRootNonSystem_throws() { + createBackupManagerServiceAndUnlockSystemUser(); when(mUserInfoMock.isManagedProfile()).thenReturn(true); BackupManagerServiceTestable.sCallingUid = Process.FIRST_APPLICATION_UID; @@ -324,6 +335,7 @@ public class BackupManagerServiceTest { @Test public void setBackupServiceActive_forNonSystemUserAndCallerWithoutBackupPermission_throws() { + createBackupManagerServiceAndUnlockSystemUser(); doThrow(new SecurityException()) .when(mContextMock) .enforceCallingOrSelfPermission(eq(Manifest.permission.BACKUP), anyString()); @@ -337,6 +349,7 @@ public class BackupManagerServiceTest { @Test public void setBackupServiceActive_forNonSystemUserAndCallerWithoutUserPermission_throws() { + createBackupManagerServiceAndUnlockSystemUser(); doThrow(new SecurityException()) .when(mContextMock) .enforceCallingOrSelfPermission( @@ -351,9 +364,9 @@ public class BackupManagerServiceTest { @Test public void setBackupServiceActive_backupDisabledGlobally_ignored() { + createBackupManagerServiceAndUnlockSystemUser(); BackupManagerServiceTestable.sBackupDisabled = true; - BackupManagerServiceTestable service = - new BackupManagerServiceTestable(mContextMock, mUserServices); + BackupManagerServiceTestable service = new BackupManagerServiceTestable(mContextMock); service.setBackupServiceActive(UserHandle.USER_SYSTEM, true); @@ -362,6 +375,7 @@ public class BackupManagerServiceTest { @Test public void setBackupServiceActive_alreadyActive_ignored() { + createBackupManagerServiceAndUnlockSystemUser(); mService.setBackupServiceActive(UserHandle.USER_SYSTEM, true); assertTrue(mService.isBackupServiceActive(UserHandle.USER_SYSTEM)); @@ -371,6 +385,7 @@ public class BackupManagerServiceTest { @Test public void setBackupServiceActive_systemUser_makeActive_deletesSuppressFile() { + createBackupManagerServiceAndUnlockSystemUser(); mService.setBackupServiceActive(UserHandle.USER_SYSTEM, false); mService.setBackupServiceActive(UserHandle.USER_SYSTEM, true); @@ -380,6 +395,7 @@ public class BackupManagerServiceTest { @Test public void setBackupServiceActive_systemUser_makeNonActive_createsSuppressFile() { + createBackupManagerServiceAndUnlockSystemUser(); mService.setBackupServiceActive(UserHandle.USER_SYSTEM, false); assertTrue(getFakeSuppressFileForUser(UserHandle.USER_SYSTEM).exists()); @@ -387,6 +403,7 @@ public class BackupManagerServiceTest { @Test public void setBackupServiceActive_systemUser_makeNonActive_stopsUserService() { + createBackupManagerServiceAndUnlockSystemUser(); assertTrue(mService.isUserReadyForBackup(UserHandle.USER_SYSTEM)); mService.setBackupServiceActive(UserHandle.USER_SYSTEM, false); @@ -396,7 +413,7 @@ public class BackupManagerServiceTest { @Test public void setBackupServiceActive_nonSystemUser_isDefault_makeActive_createsService() { - setMockMainUserAndStartNewBackupManagerService(NON_SYSTEM_USER); + setMockMainUserAndCreateBackupManagerService(NON_SYSTEM_USER); simulateUserUnlocked(NON_SYSTEM_USER); mService.setBackupServiceActive(NON_SYSTEM_USER, false); @@ -407,7 +424,7 @@ public class BackupManagerServiceTest { @Test public void setBackupServiceActive_nonSystemUser_isDefault_makeActive_deletesSuppressFile() { - setMockMainUserAndStartNewBackupManagerService(NON_SYSTEM_USER); + setMockMainUserAndCreateBackupManagerService(NON_SYSTEM_USER); simulateUserUnlocked(NON_SYSTEM_USER); mService.setBackupServiceActive(NON_SYSTEM_USER, false); @@ -418,7 +435,7 @@ public class BackupManagerServiceTest { @Test public void setBackupServiceActive_nonSystemUser_isDefault_makeNonActive_createsSuppressFile() { - setMockMainUserAndStartNewBackupManagerService(NON_SYSTEM_USER); + setMockMainUserAndCreateBackupManagerService(NON_SYSTEM_USER); mService.setBackupServiceActive(NON_SYSTEM_USER, false); assertTrue(getFakeSuppressFileForUser(NON_SYSTEM_USER).exists()); @@ -426,7 +443,7 @@ public class BackupManagerServiceTest { @Test public void setBackupServiceActive_nonSystemUser_isDefault_makeNonActive_stopsUserService() { - setMockMainUserAndStartNewBackupManagerService(NON_SYSTEM_USER); + setMockMainUserAndCreateBackupManagerService(NON_SYSTEM_USER); simulateUserUnlocked(NON_SYSTEM_USER); assertTrue(mService.isUserReadyForBackup(NON_SYSTEM_USER)); @@ -437,6 +454,7 @@ public class BackupManagerServiceTest { @Test public void setBackupServiceActive_nonSystemUser_isNotDefault_makeActive_createsService() { + createBackupManagerServiceAndUnlockSystemUser(); simulateUserUnlocked(NON_SYSTEM_USER); mService.setBackupServiceActive(NON_SYSTEM_USER, true); @@ -446,6 +464,8 @@ public class BackupManagerServiceTest { @Test public void setBackupServiceActive_nonSystemUser_isNotDefault_makeActive_createActivatedFile() { + createBackupManagerServiceAndUnlockSystemUser(); + mService.setBackupServiceActive(NON_SYSTEM_USER, true); assertTrue(getFakeActivatedFileForUser(NON_SYSTEM_USER).exists()); @@ -453,6 +473,7 @@ public class BackupManagerServiceTest { @Test public void setBackupServiceActive_nonSystemUser_isNotDefault_makeNonActive_stopsUserService() { + createBackupManagerServiceAndUnlockSystemUser(); simulateUserUnlocked(NON_SYSTEM_USER); mService.setBackupServiceActive(NON_SYSTEM_USER, true); @@ -463,6 +484,7 @@ public class BackupManagerServiceTest { @Test public void setBackupServiceActive_nonSystemUser_isNotDefault_makeActive_deleteActivatedFile() { + createBackupManagerServiceAndUnlockSystemUser(); mService.setBackupServiceActive(NON_SYSTEM_USER, true); mService.setBackupServiceActive(NON_SYSTEM_USER, false); @@ -472,6 +494,7 @@ public class BackupManagerServiceTest { @Test public void setBackupServiceActive_forOneNonSystemUser_doesNotActivateForAllNonSystemUsers() { + createBackupManagerServiceAndUnlockSystemUser(); int otherUser = NON_SYSTEM_USER + 1; mService.setBackupServiceActive(UserHandle.USER_SYSTEM, true); @@ -482,6 +505,8 @@ public class BackupManagerServiceTest { @Test public void setBackupServiceActive_forNonSystemUser_remembersActivated() { + createBackupManagerServiceAndUnlockSystemUser(); + mService.setBackupServiceActive(NON_SYSTEM_USER, true); assertTrue(RandomAccessFileUtils.readBoolean( @@ -490,6 +515,8 @@ public class BackupManagerServiceTest { @Test public void setBackupServiceActiveFalse_forNonSystemUser_remembersActivated() { + createBackupManagerServiceAndUnlockSystemUser(); + mService.setBackupServiceActive(NON_SYSTEM_USER, false); assertFalse(RandomAccessFileUtils.readBoolean( @@ -498,6 +525,8 @@ public class BackupManagerServiceTest { @Test public void setBackupServiceActiveTwice_forNonSystemUser_remembersLastActivated() { + createBackupManagerServiceAndUnlockSystemUser(); + mService.setBackupServiceActive(NON_SYSTEM_USER, true); mService.setBackupServiceActive(NON_SYSTEM_USER, false); @@ -508,7 +537,7 @@ public class BackupManagerServiceTest { @Test public void selectBackupTransportAsyncForUser_beforeUserUnlocked_notifiesBackupNotAllowed() throws Exception { - mUserServices.clear(); + mService = new BackupManagerServiceTestable(mContextMock); CompletableFuture<Integer> future = new CompletableFuture<>(); ISelectBackupTransportCallback listener = new ISelectBackupTransportCallback.Stub() { @@ -531,6 +560,8 @@ public class BackupManagerServiceTest { @Test public void selectBackupTransportAsyncForUser_beforeUserUnlockedWithNullListener_doesNotThrow() throws Exception { + createBackupManagerServiceAndUnlockSystemUser(); + mService.selectBackupTransportAsyncForUser(mUserId, TRANSPORT_COMPONENT_NAME, null); // No crash. @@ -539,6 +570,8 @@ public class BackupManagerServiceTest { @Test public void selectBackupTransportAsyncForUser_beforeUserUnlockedListenerThrowing_doesNotThrow() throws Exception { + createBackupManagerServiceAndUnlockSystemUser(); + ISelectBackupTransportCallback.Stub listener = new ISelectBackupTransportCallback.Stub() { @Override @@ -558,6 +591,7 @@ public class BackupManagerServiceTest { @Test public void dump_callerDoesNotHaveDumpPermission_ignored() { + createBackupManagerServiceAndUnlockSystemUser(); when(mContextMock.checkCallingOrSelfPermission( Manifest.permission.DUMP)).thenReturn( PackageManager.PERMISSION_DENIED); @@ -570,6 +604,7 @@ public class BackupManagerServiceTest { @Test public void dump_callerDoesNotHavePackageUsageStatsPermission_ignored() { + createBackupManagerServiceAndUnlockSystemUser(); when(mContextMock.checkCallingOrSelfPermission( Manifest.permission.PACKAGE_USAGE_STATS)).thenReturn( PackageManager.PERMISSION_DENIED); @@ -586,6 +621,7 @@ public class BackupManagerServiceTest { */ @Test public void testDump_systemUserFirst() { + createBackupManagerServiceAndUnlockSystemUser(); mService.setBackupServiceActive(NON_SYSTEM_USER, true); simulateUserUnlocked(NON_SYSTEM_USER); String[] args = new String[0]; @@ -602,6 +638,7 @@ public class BackupManagerServiceTest { @Test public void testGetUserForAncestralSerialNumber_forSystemUser() { + createBackupManagerServiceAndUnlockSystemUser(); simulateUserUnlocked(NON_SYSTEM_USER); when(mUserManagerMock.getProfileIds(UserHandle.getCallingUserId(), false)) .thenReturn(new int[]{UserHandle.USER_SYSTEM, NON_SYSTEM_USER}); @@ -614,10 +651,10 @@ public class BackupManagerServiceTest { @Test public void testGetUserForAncestralSerialNumber_forNonSystemUser() { - setMockMainUserAndStartNewBackupManagerService(NON_SYSTEM_USER); + setMockMainUserAndCreateBackupManagerService(NON_SYSTEM_USER); simulateUserUnlocked(NON_SYSTEM_USER); when(mUserManagerMock.getProfileIds(UserHandle.getCallingUserId(), false)) - .thenReturn(new int[]{UserHandle.USER_SYSTEM, NON_SYSTEM_USER}); + .thenReturn(new int[] {UserHandle.USER_SYSTEM, NON_SYSTEM_USER}); when(mNonSystemUserBackupManagerService.getAncestralSerialNumber()).thenReturn(11L); UserHandle user = mService.getUserForAncestralSerialNumber(11L); @@ -627,9 +664,9 @@ public class BackupManagerServiceTest { @Test public void testGetUserForAncestralSerialNumber_whenDisabled() { + createBackupManagerServiceAndUnlockSystemUser(); BackupManagerServiceTestable.sBackupDisabled = true; - BackupManagerService backupManagerService = - new BackupManagerServiceTestable(mContextMock, mUserServices); + BackupManagerService backupManagerService = new BackupManagerServiceTestable(mContextMock); when(mSystemUserBackupManagerService.getAncestralSerialNumber()).thenReturn(11L); UserHandle user = backupManagerService.getUserForAncestralSerialNumber(11L); @@ -637,18 +674,68 @@ public class BackupManagerServiceTest { assertThat(user).isNull(); } + @Test + public void onUserUnlocking_mainUserChanged_firstUnlockAfterReboot_updatesDefaultUser() { + // Create BMS *before* setting a main user to simulate the main user being created after + // BMS, which can happen for the first ever boot of a new device. + mService = new BackupManagerServiceTestable(mContextMock); + mServiceLifecycle = new BackupManagerService.Lifecycle(mContextMock, mService); + when(mUserManagerMock.getMainUser()).thenReturn(UserHandle.of(NON_SYSTEM_USER)); + assertFalse(mService.isBackupServiceActive(NON_SYSTEM_USER)); + + simulateUserUnlocked(UserHandle.USER_SYSTEM); + + assertTrue(mService.isBackupServiceActive(NON_SYSTEM_USER)); + } + + @Test + public void onUserUnlocking_mainUserChanged_firstUnlockAfterReboot_doesNotStartForSystemUser() { + // Create BMS *before* setting a main user to simulate the main user being created after + // BMS, which can happen for the first ever boot of a new device. + mService = new BackupManagerServiceTestable(mContextMock); + mServiceLifecycle = new BackupManagerService.Lifecycle(mContextMock, mService); + when(mUserManagerMock.getMainUser()).thenReturn(UserHandle.of(NON_SYSTEM_USER)); + assertFalse(mService.isBackupServiceActive(NON_SYSTEM_USER)); + + simulateUserUnlocked(UserHandle.USER_SYSTEM); + + assertFalse(mService.isUserReadyForBackup(UserHandle.USER_SYSTEM)); + } + + @Test + public void onUserUnlocking_mainUserChanged_secondUnlockAfterReboot_doesNotUpdateDefaultUser() { + // Create BMS *before* setting a main user to simulate the main user being created after + // BMS, which can happen for the first ever boot of a new device. + createBackupManagerServiceAndUnlockSystemUser(); + when(mUserManagerMock.getMainUser()).thenReturn(UserHandle.of(NON_SYSTEM_USER)); + assertFalse(mService.isBackupServiceActive(NON_SYSTEM_USER)); + + simulateUserUnlocked(NON_SYSTEM_USER); + + assertFalse(mService.isBackupServiceActive(NON_SYSTEM_USER)); + } + + private void createBackupManagerServiceAndUnlockSystemUser() { + mService = new BackupManagerServiceTestable(mContextMock); + mServiceLifecycle = new BackupManagerService.Lifecycle(mContextMock, mService); + simulateUserUnlocked(UserHandle.USER_SYSTEM); + } + /** * The 'default' user is set in the constructor of {@link BackupManagerService} so we need to * start a new service after mocking the 'main' user. */ - private void setMockMainUserAndStartNewBackupManagerService(int userId) { + private void setMockMainUserAndCreateBackupManagerService(int userId) { when(mUserManagerMock.getMainUser()).thenReturn(UserHandle.of(userId)); - mService = new BackupManagerServiceTestable(mContextMock, mUserServices); + mService = new BackupManagerServiceTestable(mContextMock); + mServiceLifecycle = new BackupManagerService.Lifecycle(mContextMock, mService); } private void simulateUserUnlocked(int userId) { ConditionVariable unlocked = new ConditionVariable(false); - mService.onUnlockUser(userId); + mServiceLifecycle.onUserUnlocking( + new SystemService.TargetUser( + new UserInfo(userId, /* name= */ "test", /* flags= */ 0))); mService.getBackupHandler().post(unlocked::open); unlocked.block(); when(mUserManagerMock.isUserUnlocked(userId)).thenReturn(true); @@ -672,9 +759,8 @@ public class BackupManagerServiceTest { static int sCallingUid = -1; static UserManager sUserManagerMock = null; - BackupManagerServiceTestable( - Context context, SparseArray<UserBackupManagerService> userServices) { - super(context, userServices); + BackupManagerServiceTestable(Context context) { + super(context); } @Override |