diff options
5 files changed, 405 insertions, 467 deletions
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java index 707b09a591d1..bd30a86dcee1 100644 --- a/services/backup/java/com/android/server/backup/BackupManagerService.java +++ b/services/backup/java/com/android/server/backup/BackupManagerService.java @@ -20,10 +20,8 @@ import static com.android.internal.util.Preconditions.checkNotNull; import android.annotation.Nullable; import android.annotation.UserIdInt; -import android.app.backup.IFullBackupRestoreObserver; import android.content.Context; import android.os.IBinder; -import android.os.ParcelFileDescriptor; import android.os.UserHandle; import android.util.SparseArray; @@ -91,99 +89,6 @@ public class BackupManagerService { // TODO (b/118520567): Stop hardcoding system user when we pass in user id as a parameter // --------------------------------------------- - // ADB BACKUP/RESTORE OPERATIONS - // --------------------------------------------- - - /** Sets the backup password used when running adb backup. */ - public boolean setBackupPassword(String currentPassword, String newPassword) { - UserBackupManagerService userBackupManagerService = - getServiceForUserIfCallerHasPermission( - UserHandle.USER_SYSTEM, "setBackupPassword()"); - - return userBackupManagerService != null - && userBackupManagerService.setBackupPassword(currentPassword, newPassword); - } - - /** Returns {@code true} if adb backup was run with a password, else returns {@code false}. */ - public boolean hasBackupPassword() { - UserBackupManagerService userBackupManagerService = - getServiceForUserIfCallerHasPermission( - UserHandle.USER_SYSTEM, "hasBackupPassword()"); - - return userBackupManagerService != null && userBackupManagerService.hasBackupPassword(); - } - - /** - * Used by 'adb backup' to run a backup pass for packages {@code packageNames} supplied via the - * command line, writing the resulting data stream to the supplied {@code fd}. This method is - * synchronous and does not return to the caller until the backup has been completed. It - * requires on-screen confirmation by the user. - */ - public void adbBackup( - @UserIdInt int userId, - ParcelFileDescriptor fd, - boolean includeApks, - boolean includeObbs, - boolean includeShared, - boolean doWidgets, - boolean doAllApps, - boolean includeSystem, - boolean doCompress, - boolean doKeyValue, - String[] packageNames) { - UserBackupManagerService userBackupManagerService = - getServiceForUserIfCallerHasPermission(userId, "adbBackup()"); - - if (userBackupManagerService != null) { - userBackupManagerService.adbBackup( - fd, - includeApks, - includeObbs, - includeShared, - doWidgets, - doAllApps, - includeSystem, - doCompress, - doKeyValue, - packageNames); - } - } - - /** - * Used by 'adb restore' to run a restore pass reading from the supplied {@code fd}. This method - * is synchronous and does not return to the caller until the restore has been completed. It - * requires on-screen confirmation by the user. - */ - public void adbRestore(@UserIdInt int userId, ParcelFileDescriptor fd) { - UserBackupManagerService userBackupManagerService = - getServiceForUserIfCallerHasPermission(userId, "adbRestore()"); - - if (userBackupManagerService != null) { - userBackupManagerService.adbRestore(fd); - } - } - - /** - * Confirm that the previously requested adb backup/restore operation can proceed. This is used - * to require a user-facing disclosure about the operation. - */ - public void acknowledgeAdbBackupOrRestore( - @UserIdInt int userId, - int token, - boolean allow, - String currentPassword, - String encryptionPassword, - IFullBackupRestoreObserver observer) { - UserBackupManagerService userBackupManagerService = - getServiceForUserIfCallerHasPermission(userId, "acknowledgeAdbBackupOrRestore()"); - - if (userBackupManagerService != null) { - userBackupManagerService.acknowledgeAdbBackupOrRestore( - token, allow, currentPassword, encryptionPassword, observer); - } - } - - // --------------------------------------------- // SERVICE OPERATIONS // --------------------------------------------- diff --git a/services/backup/java/com/android/server/backup/Trampoline.java b/services/backup/java/com/android/server/backup/Trampoline.java index 0522102f3786..109d6369fcc1 100644 --- a/services/backup/java/com/android/server/backup/Trampoline.java +++ b/services/backup/java/com/android/server/backup/Trampoline.java @@ -722,16 +722,33 @@ public class Trampoline extends IBackupManager.Stub { return userBackupManagerService != null && userBackupManagerService.isBackupEnabled(); } + /** Sets the backup password used when running adb backup. */ @Override - public boolean setBackupPassword(String currentPw, String newPw) throws RemoteException { + public boolean setBackupPassword(String currentPassword, String newPassword) { int userId = binderGetCallingUserId(); - return (isUserReadyForBackup(userId)) && mService.setBackupPassword(currentPw, newPw); + if (!isUserReadyForBackup(userId)) { + return false; + } + UserBackupManagerService userBackupManagerService = + getServiceForUserIfCallerHasPermission( + UserHandle.USER_SYSTEM, "setBackupPassword()"); + + return userBackupManagerService != null + && userBackupManagerService.setBackupPassword(currentPassword, newPassword); } + /** Returns {@code true} if adb backup was run with a password, else returns {@code false}. */ @Override public boolean hasBackupPassword() throws RemoteException { int userId = binderGetCallingUserId(); - return (isUserReadyForBackup(userId)) && mService.hasBackupPassword(); + if (!isUserReadyForBackup(userId)) { + return false; + } + UserBackupManagerService userBackupManagerService = + getServiceForUserIfCallerHasPermission( + UserHandle.USER_SYSTEM, "hasBackupPassword()"); + + return userBackupManagerService != null && userBackupManagerService.hasBackupPassword(); } @Override @@ -759,13 +776,43 @@ public class Trampoline extends IBackupManager.Stub { } } - public void adbBackup(@UserIdInt int userId, ParcelFileDescriptor fd, - boolean includeApks, boolean includeObbs, boolean includeShared, boolean doWidgets, - boolean allApps, boolean allIncludesSystem, boolean doCompress, boolean doKeyValue, - String[] packageNames) throws RemoteException { - if (isUserReadyForBackup(userId)) { - mService.adbBackup(userId, fd, includeApks, includeObbs, includeShared, doWidgets, - allApps, allIncludesSystem, doCompress, doKeyValue, packageNames); + /** + * Used by 'adb backup' to run a backup pass for packages {@code packageNames} supplied via the + * command line, writing the resulting data stream to the supplied {@code fd}. This method is + * synchronous and does not return to the caller until the backup has been completed. It + * requires on-screen confirmation by the user. + */ + @Override + public void adbBackup( + @UserIdInt int userId, + ParcelFileDescriptor fd, + boolean includeApks, + boolean includeObbs, + boolean includeShared, + boolean doWidgets, + boolean doAllApps, + boolean includeSystem, + boolean doCompress, + boolean doKeyValue, + String[] packageNames) { + if (!isUserReadyForBackup(userId)) { + return; + } + UserBackupManagerService userBackupManagerService = + getServiceForUserIfCallerHasPermission(userId, "adbBackup()"); + + if (userBackupManagerService != null) { + userBackupManagerService.adbBackup( + fd, + includeApks, + includeObbs, + includeShared, + doWidgets, + doAllApps, + includeSystem, + doCompress, + doKeyValue, + packageNames); } } @@ -789,10 +836,21 @@ public class Trampoline extends IBackupManager.Stub { } } + /** + * Used by 'adb restore' to run a restore pass reading from the supplied {@code fd}. This method + * is synchronous and does not return to the caller until the restore has been completed. It + * requires on-screen confirmation by the user. + */ @Override - public void adbRestore(@UserIdInt int userId, ParcelFileDescriptor fd) throws RemoteException { - if (isUserReadyForBackup(userId)) { - mService.adbRestore(userId, fd); + public void adbRestore(@UserIdInt int userId, ParcelFileDescriptor fd) { + if (!isUserReadyForBackup(userId)) { + return; + } + UserBackupManagerService userBackupManagerService = + getServiceForUserIfCallerHasPermission(userId, "adbRestore()"); + + if (userBackupManagerService != null) { + userBackupManagerService.adbRestore(fd); } } @@ -806,11 +864,31 @@ public class Trampoline extends IBackupManager.Stub { IFullBackupRestoreObserver observer) throws RemoteException { if (isUserReadyForBackup(userId)) { - mService.acknowledgeAdbBackupOrRestore(userId, token, allow, + acknowledgeAdbBackupOrRestore(userId, token, allow, curPassword, encryptionPassword, observer); } } + /** + * Confirm that the previously requested adb backup/restore operation can proceed. This is used + * to require a user-facing disclosure about the operation. + */ + public void acknowledgeAdbBackupOrRestore( + @UserIdInt int userId, + int token, + boolean allow, + String currentPassword, + String encryptionPassword, + IFullBackupRestoreObserver observer) { + UserBackupManagerService userBackupManagerService = + getServiceForUserIfCallerHasPermission(userId, "acknowledgeAdbBackupOrRestore()"); + + if (userBackupManagerService != null) { + userBackupManagerService.acknowledgeAdbBackupOrRestore( + token, allow, currentPassword, encryptionPassword, observer); + } + } + @Override public void acknowledgeFullBackupOrRestore(int token, boolean allow, String curPassword, String encryptionPassword, IFullBackupRestoreObserver observer) diff --git a/services/robotests/backup/src/com/android/server/backup/BackupManagerServiceTest.java b/services/robotests/backup/src/com/android/server/backup/BackupManagerServiceTest.java index 6dc9a2e2c1cb..0c79f40857a5 100644 --- a/services/robotests/backup/src/com/android/server/backup/BackupManagerServiceTest.java +++ b/services/robotests/backup/src/com/android/server/backup/BackupManagerServiceTest.java @@ -36,7 +36,6 @@ import static org.testng.Assert.expectThrows; import android.annotation.UserIdInt; import android.app.Application; -import android.app.backup.IFullBackupRestoreObserver; import android.content.Context; import android.os.ParcelFileDescriptor; import android.os.Process; @@ -214,298 +213,6 @@ public class BackupManagerServiceTest { } // --------------------------------------------- - // Adb backup/restore tests - // --------------------------------------------- - - /** Test that the backup service routes methods correctly to the user that requests it. */ - @Test - public void testSetBackupPassword_onRegisteredUser_callsMethodForUser() throws Exception { - registerUser(UserHandle.USER_SYSTEM, mUserOneService); - BackupManagerService backupManagerService = createService(); - - backupManagerService.setBackupPassword("currentPassword", "newPassword"); - - verify(mUserOneService).setBackupPassword("currentPassword", "newPassword"); - } - - /** Test that the backup service does not route methods for non-registered users. */ - @Test - public void testSetBackupPassword_onUnknownUser_doesNotPropagateCall() throws Exception { - BackupManagerService backupManagerService = createService(); - - backupManagerService.setBackupPassword("currentPassword", "newPassword"); - - verify(mUserOneService, never()).setBackupPassword("currentPassword", "newPassword"); - } - - /** Test that the backup service routes methods correctly to the user that requests it. */ - @Test - public void testHasBackupPassword_onRegisteredUser_callsMethodForUser() throws Exception { - registerUser(UserHandle.USER_SYSTEM, mUserOneService); - BackupManagerService backupManagerService = createService(); - - backupManagerService.hasBackupPassword(); - - verify(mUserOneService).hasBackupPassword(); - } - - /** Test that the backup service does not route methods for non-registered users. */ - @Test - public void testHasBackupPassword_onUnknownUser_doesNotPropagateCall() throws Exception { - BackupManagerService backupManagerService = createService(); - - backupManagerService.hasBackupPassword(); - - verify(mUserOneService, never()).hasBackupPassword(); - } - - /** - * Test that the backup services throws a {@link SecurityException} if the caller does not have - * INTERACT_ACROSS_USERS_FULL permission and passes a different user id. - */ - @Test - public void testAdbBackup_withoutPermission_throwsSecurityExceptionForNonCallingUser() { - registerUser(mUserOneId, mUserOneService); - BackupManagerService backupManagerService = createService(); - setCallerAndGrantInteractUserPermission(mUserOneId, /* shouldGrantPermission */ false); - - expectThrows( - SecurityException.class, - () -> - backupManagerService.adbBackup( - mUserTwoId, - /* parcelFileDescriptor*/ null, - /* includeApks */ true, - /* includeObbs */ true, - /* includeShared */ true, - /* doWidgets */ true, - /* doAllApps */ true, - /* includeSystem */ true, - /* doCompress */ true, - /* doKeyValue */ true, - null)); - } - - /** - * Test that the backup service does not throw a {@link SecurityException} if the caller has - * INTERACT_ACROSS_USERS_FULL permission and passes a different user id. - */ - @Test - public void testAdbBackup_withPermission_propagatesForNonCallingUser() throws Exception { - registerUser(mUserOneId, mUserOneService); - registerUser(mUserTwoId, mUserTwoService); - BackupManagerService backupManagerService = createService(); - - ParcelFileDescriptor parcelFileDescriptor = getFileDescriptorForAdbTest(); - setCallerAndGrantInteractUserPermission(mUserOneId, /* shouldGrantPermission */ true); - - backupManagerService.adbBackup( - mUserTwoId, - parcelFileDescriptor, - /* includeApks */ true, - /* includeObbs */ true, - /* includeShared */ true, - /* doWidgets */ true, - /* doAllApps */ true, - /* includeSystem */ true, - /* doCompress */ true, - /* doKeyValue */ true, - ADB_TEST_PACKAGES); - - verify(mUserTwoService) - .adbBackup( - parcelFileDescriptor, - /* includeApks */ true, - /* includeObbs */ true, - /* includeShared */ true, - /* doWidgets */ true, - /* doAllApps */ true, - /* includeSystem */ true, - /* doCompress */ true, - /* doKeyValue */ true, - ADB_TEST_PACKAGES); - } - - /** Test that the backup service routes methods correctly to the user that requests it. */ - @Test - public void testAdbBackup_onRegisteredUser_callsMethodForUser() throws Exception { - registerUser(mUserOneId, mUserOneService); - BackupManagerService backupManagerService = createService(); - ParcelFileDescriptor parcelFileDescriptor = getFileDescriptorForAdbTest(); - setCallerAndGrantInteractUserPermission(mUserOneId, /* shouldGrantPermission */ false); - - backupManagerService.adbBackup( - mUserOneId, - parcelFileDescriptor, - /* includeApks */ true, - /* includeObbs */ true, - /* includeShared */ true, - /* doWidgets */ true, - /* doAllApps */ true, - /* includeSystem */ true, - /* doCompress */ true, - /* doKeyValue */ true, - ADB_TEST_PACKAGES); - - verify(mUserOneService) - .adbBackup( - parcelFileDescriptor, - /* includeApks */ true, - /* includeObbs */ true, - /* includeShared */ true, - /* doWidgets */ true, - /* doAllApps */ true, - /* includeSystem */ true, - /* doCompress */ true, - /* doKeyValue */ true, - ADB_TEST_PACKAGES); - } - - /** Test that the backup service does not route methods for non-registered users. */ - @Test - public void testAdbBackup_onUnknownUser_doesNotPropagateCall() throws Exception { - registerUser(mUserOneId, mUserOneService); - BackupManagerService backupManagerService = createService(); - ParcelFileDescriptor parcelFileDescriptor = getFileDescriptorForAdbTest(); - setCallerAndGrantInteractUserPermission(mUserTwoId, /* shouldGrantPermission */ false); - - backupManagerService.adbBackup( - mUserTwoId, - parcelFileDescriptor, - /* includeApks */ true, - /* includeObbs */ true, - /* includeShared */ true, - /* doWidgets */ true, - /* doAllApps */ true, - /* includeSystem */ true, - /* doCompress */ true, - /* doKeyValue */ true, - ADB_TEST_PACKAGES); - - verify(mUserOneService, never()) - .adbBackup( - parcelFileDescriptor, - /* includeApks */ true, - /* includeObbs */ true, - /* includeShared */ true, - /* doWidgets */ true, - /* doAllApps */ true, - /* includeSystem */ true, - /* doCompress */ true, - /* doKeyValue */ true, - ADB_TEST_PACKAGES); - } - - /** - * Test that the backup services throws a {@link SecurityException} if the caller does not have - * INTERACT_ACROSS_USERS_FULL permission and passes a different user id. - */ - @Test - public void testAdbRestore_withoutPermission_throwsSecurityExceptionForNonCallingUser() { - registerUser(mUserOneId, mUserOneService); - BackupManagerService backupManagerService = createService(); - setCallerAndGrantInteractUserPermission(mUserOneId, /* shouldGrantPermission */ false); - - expectThrows( - SecurityException.class, () -> backupManagerService.adbRestore(mUserTwoId, null)); - } - - /** - * Test that the backup service does not throw a {@link SecurityException} if the caller has - * INTERACT_ACROSS_USERS_FULL permission and passes a different user id. - */ - @Test - public void testAdbRestore_withPermission_propagatesForNonCallingUser() throws Exception { - registerUser(mUserOneId, mUserOneService); - registerUser(mUserTwoId, mUserTwoService); - BackupManagerService backupManagerService = createService(); - ParcelFileDescriptor parcelFileDescriptor = getFileDescriptorForAdbTest(); - setCallerAndGrantInteractUserPermission(mUserOneId, /* shouldGrantPermission */ true); - - backupManagerService.adbRestore(mUserTwoId, parcelFileDescriptor); - - verify(mUserTwoService).adbRestore(parcelFileDescriptor); - } - - /** Test that the backup service routes methods correctly to the user that requests it. */ - @Test - public void testAdbRestore_onRegisteredUser_callsMethodForUser() throws Exception { - registerUser(mUserOneId, mUserOneService); - BackupManagerService backupManagerService = createService(); - ParcelFileDescriptor parcelFileDescriptor = getFileDescriptorForAdbTest(); - setCallerAndGrantInteractUserPermission(mUserOneId, /* shouldGrantPermission */ false); - - backupManagerService.adbRestore(mUserOneId, parcelFileDescriptor); - - verify(mUserOneService).adbRestore(parcelFileDescriptor); - } - - /** Test that the backup service does not route methods for non-registered users. */ - @Test - public void testAdbRestore_onUnknownUser_doesNotPropagateCall() throws Exception { - registerUser(mUserOneId, mUserOneService); - BackupManagerService backupManagerService = createService(); - ParcelFileDescriptor parcelFileDescriptor = getFileDescriptorForAdbTest(); - setCallerAndGrantInteractUserPermission(mUserTwoId, /* shouldGrantPermission */ false); - - backupManagerService.adbRestore(mUserTwoId, parcelFileDescriptor); - - verify(mUserOneService, never()).adbRestore(parcelFileDescriptor); - } - - /** Test that the backup service routes methods correctly to the user that requests it. */ - @Test - public void testAcknowledgeAdbBackupOrRestore_onRegisteredUser_callsMethodForUser() - throws Exception { - registerUser(mUserOneId, mUserOneService); - BackupManagerService backupManagerService = createService(); - setCallerAndGrantInteractUserPermission(mUserOneId, /* shouldGrantPermission */ false); - IFullBackupRestoreObserver observer = mock(IFullBackupRestoreObserver.class); - - backupManagerService.acknowledgeAdbBackupOrRestore( - mUserOneId, - /* token */ 0, - /* allow */ true, - "currentPassword", - "encryptionPassword", - observer); - - verify(mUserOneService) - .acknowledgeAdbBackupOrRestore( - /* token */ 0, - /* allow */ true, - "currentPassword", - "encryptionPassword", - observer); - } - - /** Test that the backup service does not route methods for non-registered users. */ - @Test - public void testAcknowledgeAdbBackupOrRestore_onUnknownUser_doesNotPropagateCall() - throws Exception { - registerUser(mUserOneId, mUserOneService); - BackupManagerService backupManagerService = createService(); - setCallerAndGrantInteractUserPermission(mUserTwoId, /* shouldGrantPermission */ false); - IFullBackupRestoreObserver observer = mock(IFullBackupRestoreObserver.class); - - backupManagerService.acknowledgeAdbBackupOrRestore( - mUserTwoId, - /* token */ 0, - /* allow */ true, - "currentPassword", - "encryptionPassword", - observer); - - verify(mUserOneService, never()) - .acknowledgeAdbBackupOrRestore( - /* token */ 0, - /* allow */ true, - "currentPassword", - "encryptionPassword", - observer); - } - - // --------------------------------------------- // Lifecycle tests // --------------------------------------------- diff --git a/services/robotests/backup/src/com/android/server/backup/TrampolineRoboTest.java b/services/robotests/backup/src/com/android/server/backup/TrampolineRoboTest.java index 7e994f0bed74..b9a926c5d619 100644 --- a/services/robotests/backup/src/com/android/server/backup/TrampolineRoboTest.java +++ b/services/robotests/backup/src/com/android/server/backup/TrampolineRoboTest.java @@ -33,10 +33,12 @@ import android.annotation.UserIdInt; import android.app.Application; import android.app.backup.IBackupManagerMonitor; import android.app.backup.IBackupObserver; +import android.app.backup.IFullBackupRestoreObserver; import android.app.backup.ISelectBackupTransportCallback; import android.content.Context; import android.content.Intent; import android.os.IBinder; +import android.os.ParcelFileDescriptor; import android.os.Process; import android.os.UserHandle; import android.os.UserManager; @@ -61,6 +63,8 @@ import org.robolectric.annotation.Config; import org.robolectric.shadow.api.Shadow; import org.robolectric.shadows.ShadowContextWrapper; +import java.io.File; + /** Tests for {@link com.android.server.backup.Trampoline}. */ @RunWith(RobolectricTestRunner.class) @Config( @@ -75,6 +79,7 @@ import org.robolectric.shadows.ShadowContextWrapper; public class TrampolineRoboTest { private static final String TEST_PACKAGE = "package"; private static final String TEST_TRANSPORT = "transport"; + private static final String[] ADB_TEST_PACKAGES = {TEST_PACKAGE}; private Context mContext; private ShadowContextWrapper mShadowContext; @@ -1107,10 +1112,318 @@ public class TrampolineRoboTest { verify(mUserOneService, never()).getAvailableRestoreToken(TEST_PACKAGE); } + // --------------------------------------------- + // Adb backup/restore tests + // --------------------------------------------- + + /** Test that the backup service routes methods correctly to the user that requests it. */ + @Test + public void testSetBackupPassword_onRegisteredUser_callsMethodForUser() throws Exception { + Trampoline backupManagerService = createService(); + registerUser(backupManagerService, UserHandle.USER_SYSTEM, mUserOneService); + ShadowBinder.setCallingUserHandle(UserHandle.of(UserHandle.USER_SYSTEM)); + + backupManagerService.setBackupPassword("currentPassword", "newPassword"); + + verify(mUserOneService).setBackupPassword("currentPassword", "newPassword"); + } + + /** Test that the backup service does not route methods for non-registered users. */ + @Test + public void testSetBackupPassword_onUnknownUser_doesNotPropagateCall() throws Exception { + Trampoline backupManagerService = createService(); + + backupManagerService.setBackupPassword("currentPassword", "newPassword"); + + verify(mUserOneService, never()).setBackupPassword("currentPassword", "newPassword"); + } + + /** Test that the backup service routes methods correctly to the user that requests it. */ + @Test + public void testHasBackupPassword_onRegisteredUser_callsMethodForUser() throws Exception { + Trampoline backupManagerService = createService(); + registerUser(backupManagerService, UserHandle.USER_SYSTEM, mUserOneService); + ShadowBinder.setCallingUserHandle(UserHandle.of(UserHandle.USER_SYSTEM)); + + backupManagerService.hasBackupPassword(); + + verify(mUserOneService).hasBackupPassword(); + } + + /** Test that the backup service does not route methods for non-registered users. */ + @Test + public void testHasBackupPassword_onUnknownUser_doesNotPropagateCall() throws Exception { + Trampoline backupManagerService = createService(); + + backupManagerService.hasBackupPassword(); + + verify(mUserOneService, never()).hasBackupPassword(); + } + + /** + * Test that the backup services throws a {@link SecurityException} if the caller does not have + * INTERACT_ACROSS_USERS_FULL permission and passes a different user id. + */ + @Test + public void testAdbBackup_withoutPermission_throwsSecurityExceptionForNonCallingUser() { + Trampoline backupManagerService = createSystemRegisteredService(); + registerUser(backupManagerService, mUserOneId, mUserOneService); + registerUser(backupManagerService, mUserTwoId, mUserTwoService); + setCallerAndGrantInteractUserPermission(mUserOneId, /* shouldGrantPermission */ false); + + expectThrows( + SecurityException.class, + () -> + backupManagerService.adbBackup( + mUserTwoId, + /* parcelFileDescriptor*/ null, + /* includeApks */ true, + /* includeObbs */ true, + /* includeShared */ true, + /* doWidgets */ true, + /* doAllApps */ true, + /* includeSystem */ true, + /* doCompress */ true, + /* doKeyValue */ true, + null)); + } + + /** + * Test that the backup service does not throw a {@link SecurityException} if the caller has + * INTERACT_ACROSS_USERS_FULL permission and passes a different user id. + */ + @Test + public void testAdbBackup_withPermission_propagatesForNonCallingUser() throws Exception { + Trampoline backupManagerService = createSystemRegisteredService(); + registerUser(backupManagerService, mUserOneId, mUserOneService); + registerUser(backupManagerService, mUserTwoId, mUserTwoService); + + ParcelFileDescriptor parcelFileDescriptor = getFileDescriptorForAdbTest(); + setCallerAndGrantInteractUserPermission(mUserOneId, /* shouldGrantPermission */ true); + + backupManagerService.adbBackup( + mUserTwoId, + parcelFileDescriptor, + /* includeApks */ true, + /* includeObbs */ true, + /* includeShared */ true, + /* doWidgets */ true, + /* doAllApps */ true, + /* includeSystem */ true, + /* doCompress */ true, + /* doKeyValue */ true, + ADB_TEST_PACKAGES); + + verify(mUserTwoService) + .adbBackup( + parcelFileDescriptor, + /* includeApks */ true, + /* includeObbs */ true, + /* includeShared */ true, + /* doWidgets */ true, + /* doAllApps */ true, + /* includeSystem */ true, + /* doCompress */ true, + /* doKeyValue */ true, + ADB_TEST_PACKAGES); + } + + /** Test that the backup service routes methods correctly to the user that requests it. */ + @Test + public void testAdbBackup_onRegisteredUser_callsMethodForUser() throws Exception { + Trampoline backupManagerService = createSystemRegisteredService(); + registerUser(backupManagerService, mUserOneId, mUserOneService); + ParcelFileDescriptor parcelFileDescriptor = getFileDescriptorForAdbTest(); + setCallerAndGrantInteractUserPermission(mUserOneId, /* shouldGrantPermission */ false); + + backupManagerService.adbBackup( + mUserOneId, + parcelFileDescriptor, + /* includeApks */ true, + /* includeObbs */ true, + /* includeShared */ true, + /* doWidgets */ true, + /* doAllApps */ true, + /* includeSystem */ true, + /* doCompress */ true, + /* doKeyValue */ true, + ADB_TEST_PACKAGES); + + verify(mUserOneService) + .adbBackup( + parcelFileDescriptor, + /* includeApks */ true, + /* includeObbs */ true, + /* includeShared */ true, + /* doWidgets */ true, + /* doAllApps */ true, + /* includeSystem */ true, + /* doCompress */ true, + /* doKeyValue */ true, + ADB_TEST_PACKAGES); + } + + /** Test that the backup service does not route methods for non-registered users. */ + @Test + public void testAdbBackup_onUnknownUser_doesNotPropagateCall() throws Exception { + Trampoline backupManagerService = createSystemRegisteredService(); + registerUser(backupManagerService, mUserOneId, mUserOneService); + ParcelFileDescriptor parcelFileDescriptor = getFileDescriptorForAdbTest(); + setCallerAndGrantInteractUserPermission(mUserTwoId, /* shouldGrantPermission */ false); + + backupManagerService.adbBackup( + mUserTwoId, + parcelFileDescriptor, + /* includeApks */ true, + /* includeObbs */ true, + /* includeShared */ true, + /* doWidgets */ true, + /* doAllApps */ true, + /* includeSystem */ true, + /* doCompress */ true, + /* doKeyValue */ true, + ADB_TEST_PACKAGES); + + verify(mUserOneService, never()) + .adbBackup( + parcelFileDescriptor, + /* includeApks */ true, + /* includeObbs */ true, + /* includeShared */ true, + /* doWidgets */ true, + /* doAllApps */ true, + /* includeSystem */ true, + /* doCompress */ true, + /* doKeyValue */ true, + ADB_TEST_PACKAGES); + } + + /** + * Test that the backup services throws a {@link SecurityException} if the caller does not have + * INTERACT_ACROSS_USERS_FULL permission and passes a different user id. + */ + @Test + public void testAdbRestore_withoutPermission_throwsSecurityExceptionForNonCallingUser() { + Trampoline backupManagerService = createSystemRegisteredService(); + registerUser(backupManagerService, mUserOneId, mUserOneService); + registerUser(backupManagerService, mUserTwoId, mUserTwoService); + setCallerAndGrantInteractUserPermission(mUserOneId, /* shouldGrantPermission */ false); + + expectThrows( + SecurityException.class, () -> backupManagerService.adbRestore(mUserTwoId, null)); + } + + /** + * Test that the backup service does not throw a {@link SecurityException} if the caller has + * INTERACT_ACROSS_USERS_FULL permission and passes a different user id. + */ + @Test + public void testAdbRestore_withPermission_propagatesForNonCallingUser() throws Exception { + Trampoline backupManagerService = createSystemRegisteredService(); + registerUser(backupManagerService, mUserOneId, mUserOneService); + registerUser(backupManagerService, mUserTwoId, mUserTwoService); + ParcelFileDescriptor parcelFileDescriptor = getFileDescriptorForAdbTest(); + setCallerAndGrantInteractUserPermission(mUserOneId, /* shouldGrantPermission */ true); + + backupManagerService.adbRestore(mUserTwoId, parcelFileDescriptor); + + verify(mUserTwoService).adbRestore(parcelFileDescriptor); + } + + /** Test that the backup service routes methods correctly to the user that requests it. */ + @Test + public void testAdbRestore_onRegisteredUser_callsMethodForUser() throws Exception { + Trampoline backupManagerService = createSystemRegisteredService(); + registerUser(backupManagerService, mUserOneId, mUserOneService); + ParcelFileDescriptor parcelFileDescriptor = getFileDescriptorForAdbTest(); + setCallerAndGrantInteractUserPermission(mUserOneId, /* shouldGrantPermission */ false); + + backupManagerService.adbRestore(mUserOneId, parcelFileDescriptor); + + verify(mUserOneService).adbRestore(parcelFileDescriptor); + } + + /** Test that the backup service does not route methods for non-registered users. */ + @Test + public void testAdbRestore_onUnknownUser_doesNotPropagateCall() throws Exception { + Trampoline backupManagerService = createSystemRegisteredService(); + registerUser(backupManagerService, mUserOneId, mUserOneService); + ParcelFileDescriptor parcelFileDescriptor = getFileDescriptorForAdbTest(); + setCallerAndGrantInteractUserPermission(mUserTwoId, /* shouldGrantPermission */ false); + + backupManagerService.adbRestore(mUserTwoId, parcelFileDescriptor); + + verify(mUserOneService, never()).adbRestore(parcelFileDescriptor); + } + + private ParcelFileDescriptor getFileDescriptorForAdbTest() throws Exception { + File testFile = new File(mContext.getFilesDir(), "test"); + testFile.createNewFile(); + return ParcelFileDescriptor.open(testFile, ParcelFileDescriptor.MODE_READ_WRITE); + } + + /** Test that the backup service routes methods correctly to the user that requests it. */ + @Test + public void testAcknowledgeAdbBackupOrRestore_onRegisteredUser_callsMethodForUser() + throws Exception { + Trampoline backupManagerService = createService(); + registerUser(backupManagerService, mUserOneId, mUserOneService); + setCallerAndGrantInteractUserPermission(mUserOneId, /* shouldGrantPermission */ false); + IFullBackupRestoreObserver observer = mock(IFullBackupRestoreObserver.class); + + backupManagerService.acknowledgeAdbBackupOrRestore( + mUserOneId, + /* token */ 0, + /* allow */ true, + "currentPassword", + "encryptionPassword", + observer); + + verify(mUserOneService) + .acknowledgeAdbBackupOrRestore( + /* token */ 0, + /* allow */ true, + "currentPassword", + "encryptionPassword", + observer); + } + + /** Test that the backup service does not route methods for non-registered users. */ + @Test + public void testAcknowledgeAdbBackupOrRestore_onUnknownUser_doesNotPropagateCall() + throws Exception { + Trampoline backupManagerService = createService(); + registerUser(backupManagerService, mUserOneId, mUserOneService); + setCallerAndGrantInteractUserPermission(mUserTwoId, /* shouldGrantPermission */ false); + IFullBackupRestoreObserver observer = mock(IFullBackupRestoreObserver.class); + + backupManagerService.acknowledgeAdbBackupOrRestore( + mUserTwoId, + /* token */ 0, + /* allow */ true, + "currentPassword", + "encryptionPassword", + observer); + + verify(mUserOneService, never()) + .acknowledgeAdbBackupOrRestore( + /* token */ 0, + /* allow */ true, + "currentPassword", + "encryptionPassword", + observer); + } + private Trampoline createService() { return new Trampoline(mContext); } + private Trampoline createSystemRegisteredService() { + Trampoline trampoline = createService(); + registerUser(trampoline, UserHandle.USER_SYSTEM, mock(UserBackupManagerService.class)); + return trampoline; + } + private void registerUser( Trampoline trampoline, int userId, UserBackupManagerService userBackupManagerService) { trampoline.setBackupServiceActive(userId, true); diff --git a/services/tests/servicestests/src/com/android/server/backup/TrampolineTest.java b/services/tests/servicestests/src/com/android/server/backup/TrampolineTest.java index eb90b4553a9b..ecf2d2f3be78 100644 --- a/services/tests/servicestests/src/com/android/server/backup/TrampolineTest.java +++ b/services/tests/servicestests/src/com/android/server/backup/TrampolineTest.java @@ -482,71 +482,6 @@ public class TrampolineTest { } @Test - public void setBackupPassword_forwarded() throws Exception { - mTrampoline.setBackupPassword(CURRENT_PASSWORD, NEW_PASSWORD); - verify(mBackupManagerServiceMock).setBackupPassword(CURRENT_PASSWORD, NEW_PASSWORD); - } - - @Test - public void hasBackupPassword_forwarded() throws Exception { - mTrampoline.hasBackupPassword(); - verify(mBackupManagerServiceMock).hasBackupPassword(); - } - - @Test - public void adbBackup_forwarded() throws Exception { - mTrampoline.adbBackup(mUserId, mParcelFileDescriptorMock, true, true, - true, true, true, true, true, true, - PACKAGE_NAMES); - verify(mBackupManagerServiceMock).adbBackup(mUserId, mParcelFileDescriptorMock, true, - true, true, true, true, true, true, true, PACKAGE_NAMES); - } - - @Test - public void adbRestore_forwarded() throws Exception { - mTrampoline.adbRestore(mUserId, mParcelFileDescriptorMock); - verify(mBackupManagerServiceMock).adbRestore(mUserId, mParcelFileDescriptorMock); - } - - @Test - public void acknowledgeFullBackupOrRestoreForUser_forwarded() throws Exception { - - mTrampoline.acknowledgeFullBackupOrRestoreForUser( - mUserId, - 123, - true, - CURRENT_PASSWORD, - ENCRYPTION_PASSWORD, - mFullBackupRestoreObserverMock); - - verify(mBackupManagerServiceMock) - .acknowledgeAdbBackupOrRestore( - mUserId, - 123, - true, - CURRENT_PASSWORD, - ENCRYPTION_PASSWORD, - mFullBackupRestoreObserverMock); - } - - @Test - public void acknowledgeFullBackupOrRestore_forwarded() throws Exception { - TrampolineTestable.sCallingUserId = mUserId; - - mTrampoline.acknowledgeFullBackupOrRestore(123, true, CURRENT_PASSWORD, ENCRYPTION_PASSWORD, - mFullBackupRestoreObserverMock); - - verify(mBackupManagerServiceMock) - .acknowledgeAdbBackupOrRestore( - mUserId, - 123, - true, - CURRENT_PASSWORD, - ENCRYPTION_PASSWORD, - mFullBackupRestoreObserverMock); - } - - @Test public void selectBackupTransportAsyncForUser_beforeUserUnlocked_notifiesBackupNotAllowed() throws Exception { mUserServices.clear(); |