Loading core/java/android/content/pm/multiuser.aconfig +8 −0 Original line number Diff line number Diff line Loading @@ -480,3 +480,11 @@ flag { description: "Generate file for perfetto, so it can create a users table" bug: "391110239" } flag { name: "backup_activated_for_all_users" namespace: "multiuser" description: "Activate backup for all users in headless system user mode (HSUM)." bug: "374830726" is_fixed_read_only: true } services/backup/java/com/android/server/backup/BackupManagerService.java +13 −6 Original line number Diff line number Diff line Loading @@ -348,25 +348,32 @@ public class BackupManagerService extends IBackupManager.Stub implements BackupM return getActivatedFileForUser(userId).exists(); } /** Returns whether the user's backup is initially set to active. */ /** Determines the default activation state for backup for the specified user ID. */ @SuppressWarnings("AndroidFrameworkRequiresPermission") private boolean isDefaultBackupActiveUser(@UserIdInt int userId) { // In non-HSUM, the system user is the primary user and handles backup. if (!UserManager.isHeadlessSystemUserMode()) { return userId == UserHandle.USER_SYSTEM; } // In HSUM, the system user is not a real user and should not have backup activated. // In HSUM, returns false for the system user, as it's a headless/non-interactive user. if (userId == UserHandle.USER_SYSTEM) { return false; } UserHandle mainUser = getUserManager().getMainUser(); if (mainUser == null) { // Returns false if the user is not a full user. if (!getUserManager().getUserInfo(userId).isFull()) { return false; } // In HSUM, the main user is the one whose backup should be active by default. return userId == mainUser.getIdentifier(); // Returns true for the main user. UserHandle mainUser = getUserManager().getMainUser(); if (mainUser != null && userId == mainUser.getIdentifier()) { return true; } // Returns true for any other full users if the flag is enabled. return android.multiuser.Flags.backupActivatedForAllUsers(); } @VisibleForTesting Loading services/tests/mockingservicestests/src/com/android/server/backup/BackupManagerServiceTest.java +66 −12 Original line number Diff line number Diff line Loading @@ -52,7 +52,10 @@ import android.os.Process; import android.os.RemoteException; import android.os.UserHandle; import android.os.UserManager; import android.platform.test.annotations.DisableFlags; import android.platform.test.annotations.EnableFlags; import android.platform.test.annotations.Presubmit; import android.platform.test.flag.junit.SetFlagsRule; import androidx.test.InstrumentationRegistry; import androidx.test.ext.junit.runners.AndroidJUnit4; Loading @@ -64,9 +67,12 @@ import com.android.server.LocalServices; import com.android.server.SystemService; import com.android.server.backup.utils.RandomAccessFileUtils; import com.google.common.truth.Expect; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InOrder; Loading @@ -88,6 +94,13 @@ public class BackupManagerServiceTest { private static final ComponentName TRANSPORT_COMPONENT_NAME = new ComponentName("package", "class"); private static final int NON_SYSTEM_USER = UserHandle.USER_SYSTEM + 1; private static final int NON_SYSTEM_NON_DEFAULT_USER = NON_SYSTEM_USER + 1; @Rule public final Expect expect = Expect.create(); @Rule public final SetFlagsRule flags = new SetFlagsRule(SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT); @Mock private UserBackupManagerService mSystemUserBackupManagerService; Loading Loading @@ -131,6 +144,8 @@ public class BackupManagerServiceTest { when(mNonSystemUserBackupManagerService.getUserId()).thenReturn(NON_SYSTEM_USER); when(mUserManagerMock.getUserInfo(UserHandle.USER_SYSTEM)).thenReturn(mUserInfoMock); when(mUserManagerMock.getUserInfo(NON_SYSTEM_USER)).thenReturn(mUserInfoMock); when(mUserManagerMock.getUserInfo(NON_SYSTEM_NON_DEFAULT_USER)).thenReturn(mUserInfoMock); when(mUserInfoMock.isFull()).thenReturn(true); // Null main user means there is no main user on the device. when(mUserManagerMock.getMainUser()).thenReturn(null); Loading Loading @@ -255,6 +270,45 @@ public class BackupManagerServiceTest { assertTrue(mService.isBackupServiceActive(NON_SYSTEM_USER)); } @Test @DisableFlags(android.multiuser.Flags.FLAG_BACKUP_ACTIVATED_FOR_ALL_USERS) public void isBackupServiceActive_nonSystemUser_isNotDefault_flagDisabled_returnsFalse() { createBackupManagerServiceAndUnlockSystemUser(); when(mUserInfoMock.isFull()).thenReturn(true); setMockMainUserAndCreateBackupManagerService(NON_SYSTEM_USER); // In HSUM, activation for non-default users is determined by the flag above (disabled). expect.that(mService.isBackupServiceActive(NON_SYSTEM_USER)).isTrue(); expect.that(mService.isBackupServiceActive(NON_SYSTEM_NON_DEFAULT_USER)).isFalse(); } @Test @EnableFlags(android.multiuser.Flags.FLAG_BACKUP_ACTIVATED_FOR_ALL_USERS) public void isBackupServiceActive_nonSystemUser_fullUser_flagEnabled_returnsTrue() { createBackupManagerServiceAndUnlockSystemUser(); when(mUserInfoMock.isFull()).thenReturn(true); setMockMainUserAndCreateBackupManagerService(NON_SYSTEM_USER); // In HSUM, activation for non-default users is determined by the flag above (enabled). expect.that(mService.isBackupServiceActive(NON_SYSTEM_USER)).isTrue(); expect.that(mService.isBackupServiceActive(NON_SYSTEM_NON_DEFAULT_USER)).isTrue(); } @Test @EnableFlags(android.multiuser.Flags.FLAG_BACKUP_ACTIVATED_FOR_ALL_USERS) public void isBackupServiceActive_nonSystemUser_nonFullUser_flagEnabled_returnsFalse() { createBackupManagerServiceAndUnlockSystemUser(); when(mUserInfoMock.isFull()).thenReturn(false); setMockMainUserAndCreateBackupManagerService(NON_SYSTEM_USER); // The flag is enabled but the users are not full users. expect.that(mService.isBackupServiceActive(NON_SYSTEM_USER)).isFalse(); expect.that(mService.isBackupServiceActive(NON_SYSTEM_NON_DEFAULT_USER)).isFalse(); } @Test public void isBackupServiceActive_nonSystemUser_isNotDefault_notActivated_returnsFalse() { createBackupManagerServiceAndUnlockSystemUser(); Loading Loading @@ -384,10 +438,10 @@ public class BackupManagerServiceTest { public void setBackupServiceActive_alreadyActive_ignored() { createBackupManagerServiceAndUnlockSystemUser(); mService.setBackupServiceActive(UserHandle.USER_SYSTEM, true); assertTrue(mService.isBackupServiceActive(UserHandle.USER_SYSTEM)); expect.that(mService.isBackupServiceActive(UserHandle.USER_SYSTEM)).isTrue(); mService.setBackupServiceActive(UserHandle.USER_SYSTEM, true); assertTrue(mService.isBackupServiceActive(UserHandle.USER_SYSTEM)); expect.that(mService.isBackupServiceActive(UserHandle.USER_SYSTEM)).isTrue(); } @Test Loading @@ -411,11 +465,11 @@ public class BackupManagerServiceTest { @Test public void setBackupServiceActive_systemUser_makeNonActive_stopsUserService() { createBackupManagerServiceAndUnlockSystemUser(); assertTrue(mService.isUserReadyForBackup(UserHandle.USER_SYSTEM)); expect.that(mService.isUserReadyForBackup(UserHandle.USER_SYSTEM)).isTrue(); mService.setBackupServiceActive(UserHandle.USER_SYSTEM, false); assertFalse(mService.isUserReadyForBackup(UserHandle.USER_SYSTEM)); expect.that(mService.isUserReadyForBackup(UserHandle.USER_SYSTEM)).isFalse(); } @Test Loading Loading @@ -452,11 +506,11 @@ public class BackupManagerServiceTest { public void setBackupServiceActive_nonSystemUser_isDefault_makeNonActive_stopsUserService() { setMockMainUserAndCreateBackupManagerService(NON_SYSTEM_USER); simulateUserUnlocked(NON_SYSTEM_USER); assertTrue(mService.isUserReadyForBackup(NON_SYSTEM_USER)); expect.that(mService.isUserReadyForBackup(NON_SYSTEM_USER)).isTrue(); mService.setBackupServiceActive(NON_SYSTEM_USER, false); assertFalse(mService.isUserReadyForBackup(NON_SYSTEM_USER)); expect.that(mService.isUserReadyForBackup(NON_SYSTEM_USER)).isFalse(); } @Test Loading Loading @@ -724,12 +778,12 @@ public class BackupManagerServiceTest { mService = new BackupManagerServiceTestable(mContextMock); createBackupServiceLifecycle(mContextMock, mService); when(mUserManagerMock.getMainUser()).thenReturn(UserHandle.of(NON_SYSTEM_USER)); assertFalse(mService.isBackupServiceActive(NON_SYSTEM_USER)); expect.that(mService.isBackupServiceActive(NON_SYSTEM_USER)).isFalse(); mockHeadlessSystemUserMode(true); simulateUserUnlocked(UserHandle.USER_SYSTEM); assertTrue(mService.isBackupServiceActive(NON_SYSTEM_USER)); expect.that(mService.isBackupServiceActive(NON_SYSTEM_USER)).isTrue(); } @Test Loading @@ -739,12 +793,12 @@ public class BackupManagerServiceTest { mService = new BackupManagerServiceTestable(mContextMock); createBackupServiceLifecycle(mContextMock, mService); when(mUserManagerMock.getMainUser()).thenReturn(UserHandle.of(NON_SYSTEM_USER)); assertFalse(mService.isBackupServiceActive(NON_SYSTEM_USER)); expect.that(mService.isBackupServiceActive(NON_SYSTEM_USER)).isFalse(); mockHeadlessSystemUserMode(true); simulateUserUnlocked(UserHandle.USER_SYSTEM); assertFalse(mService.isUserReadyForBackup(UserHandle.USER_SYSTEM)); expect.that(mService.isUserReadyForBackup(UserHandle.USER_SYSTEM)).isFalse(); } @Test Loading @@ -753,11 +807,11 @@ public class BackupManagerServiceTest { // 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)); expect.that(mService.isBackupServiceActive(NON_SYSTEM_USER)).isFalse(); simulateUserUnlocked(NON_SYSTEM_USER); assertFalse(mService.isBackupServiceActive(NON_SYSTEM_USER)); expect.that(mService.isBackupServiceActive(NON_SYSTEM_USER)).isFalse(); } private void createBackupManagerServiceAndUnlockSystemUser() { Loading Loading
core/java/android/content/pm/multiuser.aconfig +8 −0 Original line number Diff line number Diff line Loading @@ -480,3 +480,11 @@ flag { description: "Generate file for perfetto, so it can create a users table" bug: "391110239" } flag { name: "backup_activated_for_all_users" namespace: "multiuser" description: "Activate backup for all users in headless system user mode (HSUM)." bug: "374830726" is_fixed_read_only: true }
services/backup/java/com/android/server/backup/BackupManagerService.java +13 −6 Original line number Diff line number Diff line Loading @@ -348,25 +348,32 @@ public class BackupManagerService extends IBackupManager.Stub implements BackupM return getActivatedFileForUser(userId).exists(); } /** Returns whether the user's backup is initially set to active. */ /** Determines the default activation state for backup for the specified user ID. */ @SuppressWarnings("AndroidFrameworkRequiresPermission") private boolean isDefaultBackupActiveUser(@UserIdInt int userId) { // In non-HSUM, the system user is the primary user and handles backup. if (!UserManager.isHeadlessSystemUserMode()) { return userId == UserHandle.USER_SYSTEM; } // In HSUM, the system user is not a real user and should not have backup activated. // In HSUM, returns false for the system user, as it's a headless/non-interactive user. if (userId == UserHandle.USER_SYSTEM) { return false; } UserHandle mainUser = getUserManager().getMainUser(); if (mainUser == null) { // Returns false if the user is not a full user. if (!getUserManager().getUserInfo(userId).isFull()) { return false; } // In HSUM, the main user is the one whose backup should be active by default. return userId == mainUser.getIdentifier(); // Returns true for the main user. UserHandle mainUser = getUserManager().getMainUser(); if (mainUser != null && userId == mainUser.getIdentifier()) { return true; } // Returns true for any other full users if the flag is enabled. return android.multiuser.Flags.backupActivatedForAllUsers(); } @VisibleForTesting Loading
services/tests/mockingservicestests/src/com/android/server/backup/BackupManagerServiceTest.java +66 −12 Original line number Diff line number Diff line Loading @@ -52,7 +52,10 @@ import android.os.Process; import android.os.RemoteException; import android.os.UserHandle; import android.os.UserManager; import android.platform.test.annotations.DisableFlags; import android.platform.test.annotations.EnableFlags; import android.platform.test.annotations.Presubmit; import android.platform.test.flag.junit.SetFlagsRule; import androidx.test.InstrumentationRegistry; import androidx.test.ext.junit.runners.AndroidJUnit4; Loading @@ -64,9 +67,12 @@ import com.android.server.LocalServices; import com.android.server.SystemService; import com.android.server.backup.utils.RandomAccessFileUtils; import com.google.common.truth.Expect; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InOrder; Loading @@ -88,6 +94,13 @@ public class BackupManagerServiceTest { private static final ComponentName TRANSPORT_COMPONENT_NAME = new ComponentName("package", "class"); private static final int NON_SYSTEM_USER = UserHandle.USER_SYSTEM + 1; private static final int NON_SYSTEM_NON_DEFAULT_USER = NON_SYSTEM_USER + 1; @Rule public final Expect expect = Expect.create(); @Rule public final SetFlagsRule flags = new SetFlagsRule(SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT); @Mock private UserBackupManagerService mSystemUserBackupManagerService; Loading Loading @@ -131,6 +144,8 @@ public class BackupManagerServiceTest { when(mNonSystemUserBackupManagerService.getUserId()).thenReturn(NON_SYSTEM_USER); when(mUserManagerMock.getUserInfo(UserHandle.USER_SYSTEM)).thenReturn(mUserInfoMock); when(mUserManagerMock.getUserInfo(NON_SYSTEM_USER)).thenReturn(mUserInfoMock); when(mUserManagerMock.getUserInfo(NON_SYSTEM_NON_DEFAULT_USER)).thenReturn(mUserInfoMock); when(mUserInfoMock.isFull()).thenReturn(true); // Null main user means there is no main user on the device. when(mUserManagerMock.getMainUser()).thenReturn(null); Loading Loading @@ -255,6 +270,45 @@ public class BackupManagerServiceTest { assertTrue(mService.isBackupServiceActive(NON_SYSTEM_USER)); } @Test @DisableFlags(android.multiuser.Flags.FLAG_BACKUP_ACTIVATED_FOR_ALL_USERS) public void isBackupServiceActive_nonSystemUser_isNotDefault_flagDisabled_returnsFalse() { createBackupManagerServiceAndUnlockSystemUser(); when(mUserInfoMock.isFull()).thenReturn(true); setMockMainUserAndCreateBackupManagerService(NON_SYSTEM_USER); // In HSUM, activation for non-default users is determined by the flag above (disabled). expect.that(mService.isBackupServiceActive(NON_SYSTEM_USER)).isTrue(); expect.that(mService.isBackupServiceActive(NON_SYSTEM_NON_DEFAULT_USER)).isFalse(); } @Test @EnableFlags(android.multiuser.Flags.FLAG_BACKUP_ACTIVATED_FOR_ALL_USERS) public void isBackupServiceActive_nonSystemUser_fullUser_flagEnabled_returnsTrue() { createBackupManagerServiceAndUnlockSystemUser(); when(mUserInfoMock.isFull()).thenReturn(true); setMockMainUserAndCreateBackupManagerService(NON_SYSTEM_USER); // In HSUM, activation for non-default users is determined by the flag above (enabled). expect.that(mService.isBackupServiceActive(NON_SYSTEM_USER)).isTrue(); expect.that(mService.isBackupServiceActive(NON_SYSTEM_NON_DEFAULT_USER)).isTrue(); } @Test @EnableFlags(android.multiuser.Flags.FLAG_BACKUP_ACTIVATED_FOR_ALL_USERS) public void isBackupServiceActive_nonSystemUser_nonFullUser_flagEnabled_returnsFalse() { createBackupManagerServiceAndUnlockSystemUser(); when(mUserInfoMock.isFull()).thenReturn(false); setMockMainUserAndCreateBackupManagerService(NON_SYSTEM_USER); // The flag is enabled but the users are not full users. expect.that(mService.isBackupServiceActive(NON_SYSTEM_USER)).isFalse(); expect.that(mService.isBackupServiceActive(NON_SYSTEM_NON_DEFAULT_USER)).isFalse(); } @Test public void isBackupServiceActive_nonSystemUser_isNotDefault_notActivated_returnsFalse() { createBackupManagerServiceAndUnlockSystemUser(); Loading Loading @@ -384,10 +438,10 @@ public class BackupManagerServiceTest { public void setBackupServiceActive_alreadyActive_ignored() { createBackupManagerServiceAndUnlockSystemUser(); mService.setBackupServiceActive(UserHandle.USER_SYSTEM, true); assertTrue(mService.isBackupServiceActive(UserHandle.USER_SYSTEM)); expect.that(mService.isBackupServiceActive(UserHandle.USER_SYSTEM)).isTrue(); mService.setBackupServiceActive(UserHandle.USER_SYSTEM, true); assertTrue(mService.isBackupServiceActive(UserHandle.USER_SYSTEM)); expect.that(mService.isBackupServiceActive(UserHandle.USER_SYSTEM)).isTrue(); } @Test Loading @@ -411,11 +465,11 @@ public class BackupManagerServiceTest { @Test public void setBackupServiceActive_systemUser_makeNonActive_stopsUserService() { createBackupManagerServiceAndUnlockSystemUser(); assertTrue(mService.isUserReadyForBackup(UserHandle.USER_SYSTEM)); expect.that(mService.isUserReadyForBackup(UserHandle.USER_SYSTEM)).isTrue(); mService.setBackupServiceActive(UserHandle.USER_SYSTEM, false); assertFalse(mService.isUserReadyForBackup(UserHandle.USER_SYSTEM)); expect.that(mService.isUserReadyForBackup(UserHandle.USER_SYSTEM)).isFalse(); } @Test Loading Loading @@ -452,11 +506,11 @@ public class BackupManagerServiceTest { public void setBackupServiceActive_nonSystemUser_isDefault_makeNonActive_stopsUserService() { setMockMainUserAndCreateBackupManagerService(NON_SYSTEM_USER); simulateUserUnlocked(NON_SYSTEM_USER); assertTrue(mService.isUserReadyForBackup(NON_SYSTEM_USER)); expect.that(mService.isUserReadyForBackup(NON_SYSTEM_USER)).isTrue(); mService.setBackupServiceActive(NON_SYSTEM_USER, false); assertFalse(mService.isUserReadyForBackup(NON_SYSTEM_USER)); expect.that(mService.isUserReadyForBackup(NON_SYSTEM_USER)).isFalse(); } @Test Loading Loading @@ -724,12 +778,12 @@ public class BackupManagerServiceTest { mService = new BackupManagerServiceTestable(mContextMock); createBackupServiceLifecycle(mContextMock, mService); when(mUserManagerMock.getMainUser()).thenReturn(UserHandle.of(NON_SYSTEM_USER)); assertFalse(mService.isBackupServiceActive(NON_SYSTEM_USER)); expect.that(mService.isBackupServiceActive(NON_SYSTEM_USER)).isFalse(); mockHeadlessSystemUserMode(true); simulateUserUnlocked(UserHandle.USER_SYSTEM); assertTrue(mService.isBackupServiceActive(NON_SYSTEM_USER)); expect.that(mService.isBackupServiceActive(NON_SYSTEM_USER)).isTrue(); } @Test Loading @@ -739,12 +793,12 @@ public class BackupManagerServiceTest { mService = new BackupManagerServiceTestable(mContextMock); createBackupServiceLifecycle(mContextMock, mService); when(mUserManagerMock.getMainUser()).thenReturn(UserHandle.of(NON_SYSTEM_USER)); assertFalse(mService.isBackupServiceActive(NON_SYSTEM_USER)); expect.that(mService.isBackupServiceActive(NON_SYSTEM_USER)).isFalse(); mockHeadlessSystemUserMode(true); simulateUserUnlocked(UserHandle.USER_SYSTEM); assertFalse(mService.isUserReadyForBackup(UserHandle.USER_SYSTEM)); expect.that(mService.isUserReadyForBackup(UserHandle.USER_SYSTEM)).isFalse(); } @Test Loading @@ -753,11 +807,11 @@ public class BackupManagerServiceTest { // 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)); expect.that(mService.isBackupServiceActive(NON_SYSTEM_USER)).isFalse(); simulateUserUnlocked(NON_SYSTEM_USER); assertFalse(mService.isBackupServiceActive(NON_SYSTEM_USER)); expect.that(mService.isBackupServiceActive(NON_SYSTEM_USER)).isFalse(); } private void createBackupManagerServiceAndUnlockSystemUser() { Loading