[Multi-user] Change BackupManager AIDL to accept userId in methods

Bug: 120120742

Test: 1) atest RunFrameworksServicesRoboTests
2) atest $(find \
frameworks/base/services/tests/servicestests/src/com/android/server/backup \
-name '*Test.java')
3) atest CtsBackupTestCases
4) atest CtsBackupHostTestCases
5) atest GtsBackupTestCases
6) atest GtsBackupHostTestCases
7) Toggle Backup/'Backup Now' in Settings
8) 'adb shell bmgr' enabled/backupnow flow

Change-Id: I5dba38f6a24e07947d1b0948f9caefeca011205d
This commit is contained in:
Chandan Nath
2018-12-07 16:49:37 +00:00
parent a96d8d0b78
commit cd44f75895
7 changed files with 382 additions and 49 deletions

View File

@@ -201,7 +201,7 @@ public class Bmgr {
private void doEnabled(@UserIdInt int userId) {
try {
boolean isEnabled = mBmgr.isBackupEnabled();
boolean isEnabled = mBmgr.isBackupEnabledForUser(userId);
System.out.println("Backup Manager currently "
+ enableToString(isEnabled));
} catch (RemoteException e) {
@@ -219,7 +219,7 @@ public class Bmgr {
try {
boolean enable = Boolean.parseBoolean(arg);
mBmgr.setBackupEnabled(enable);
mBmgr.setBackupEnabledForUser(userId, enable);
System.out.println("Backup Manager now " + enableToString(enable));
} catch (NumberFormatException e) {
showUsage();
@@ -232,7 +232,7 @@ public class Bmgr {
void doRun(@UserIdInt int userId) {
try {
mBmgr.backupNow();
mBmgr.backupNowForUser(userId);
} catch (RemoteException e) {
System.err.println(e.toString());
System.err.println(BMGR_NOT_RUNNING_ERR);
@@ -416,7 +416,8 @@ public class Bmgr {
(monitorState != Monitor.OFF)
? new BackupMonitor(monitorState == Monitor.VERBOSE)
: null;
int err = mBmgr.requestBackup(
int err = mBmgr.requestBackupForUser(
userId,
packages.toArray(new String[packages.size()]),
observer,
monitor,
@@ -477,7 +478,7 @@ public class Bmgr {
String arg = nextArg();
if ("backups".equals(arg)) {
try {
mBmgr.cancelBackups();
mBmgr.cancelBackupsForUser(userId);
} catch (RemoteException e) {
System.err.println(e.toString());
System.err.println(BMGR_NOT_RUNNING_ERR);

View File

@@ -91,6 +91,15 @@ interface IBackupManager {
* at some point in the future.
*
* <p>Callers must hold the android.permission.BACKUP permission to use this method.
* If {@code userId} is different from the calling user id, then the caller must hold the
* android.permission.INTERACT_ACROSS_USERS_FULL permission.
*
* @param userId User id for which backup service should be enabled/disabled.
*/
void setBackupEnabledForUser(int userId, boolean isEnabled);
/**
* {@link android.app.backup.IBackupManager.setBackupEnabledForUser} for the calling user id.
*/
void setBackupEnabled(boolean isEnabled);
@@ -120,6 +129,15 @@ interface IBackupManager {
* Report whether the backup mechanism is currently enabled.
*
* <p>Callers must hold the android.permission.BACKUP permission to use this method.
* If {@code userId} is different from the calling user id, then the caller must hold the
* android.permission.INTERACT_ACROSS_USERS_FULL permission.
*
* @param userId User id for which the backup service status should be reported.
*/
boolean isBackupEnabledForUser(int userId);
/**
* {@link android.app.backup.IBackupManager.isBackupEnabledForUser} for the calling user id.
*/
boolean isBackupEnabled();
@@ -149,6 +167,15 @@ interface IBackupManager {
* method.
*
* <p>Callers must hold the android.permission.BACKUP permission to use this method.
* If {@code userId} is different from the calling user id, then the caller must hold the
* android.permission.INTERACT_ACROSS_USERS_FULL permission.
*
* @param userId User id for which an immediate backup should be scheduled.
*/
void backupNowForUser(int userId);
/**
* {@link android.app.backup.IBackupManager.backupNowForUser} for the calling user id.
*/
void backupNow();
@@ -432,6 +459,12 @@ interface IBackupManager {
* <p>If this method returns zero (meaning success), the OS will attempt to backup all provided
* packages using the remote transport.
*
* <p>Callers must hold the android.permission.BACKUP permission to use this method.
* If {@code userId} is different from the calling user id, then the caller must hold the
* android.permission.INTERACT_ACROSS_USERS_FULL permission.
*
* @param userId User id for which an immediate backup should be requested.
* @param observer The {@link BackupObserver} to receive callbacks during the backup
* operation.
*
@@ -442,12 +475,29 @@ interface IBackupManager {
*
* @return Zero on success; nonzero on error.
*/
int requestBackupForUser(int userId, in String[] packages, IBackupObserver observer,
IBackupManagerMonitor monitor, int flags);
/**
* {@link android.app.backup.IBackupManager.requestBackupForUser} for the calling user id.
*/
int requestBackup(in String[] packages, IBackupObserver observer, IBackupManagerMonitor monitor,
int flags);
/**
* Cancel all running backups. After this call returns, no currently running backups will
* interact with the selected transport.
*
* <p>Callers must hold the android.permission.BACKUP permission to use this method.
* If {@code userId} is different from the calling user id, then the caller must hold the
* android.permission.INTERACT_ACROSS_USERS_FULL permission.
*
* @param userId User id for which backups should be cancelled.
*/
void cancelBackupsForUser(int userId);
/**
* {@link android.app.backup.IBackupManager.cancelBackups} for the calling user id.
*/
void cancelBackups();
}

View File

@@ -16,7 +16,9 @@
package com.android.server.backup;
import android.Manifest;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.ActivityManager;
import android.app.backup.IBackupManagerMonitor;
import android.app.backup.IBackupObserver;
@@ -30,6 +32,7 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Binder;
import android.os.Environment;
import android.os.HandlerThread;
import android.os.IBinder;
@@ -79,6 +82,7 @@ public class BackupManagerService {
return sInstance;
}
private final Context mContext;
private UserBackupManagerService mUserBackupManagerService;
/** Instantiate a new instance of {@link BackupManagerService}. */
@@ -91,11 +95,26 @@ public class BackupManagerService {
transportWhitelist = Collections.emptySet();
}
mContext = context;
mUserBackupManagerService =
UserBackupManagerService.createAndInitializeService(
context, trampoline, backupThread, transportWhitelist);
}
/**
* If {@code userId} is different from the calling user id, then the caller must hold the
* android.permission.INTERACT_ACROSS_USERS_FULL permission.
*
* @param userId User id on which the backup operation is being requested.
* @param message A message to include in the exception if it is thrown.
*/
private void enforceCallingPermissionOnUserId(int userId, String message) {
if (Binder.getCallingUserHandle().getIdentifier() != userId) {
mContext.enforceCallingOrSelfPermission(
Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
}
}
// TODO(b/118520567): Remove when tests are modified to use per-user instance.
@VisibleForTesting
void setUserBackupManagerService(UserBackupManagerService userBackupManagerService) {
@@ -314,7 +333,8 @@ public class BackupManagerService {
// ---------------------------------------------
/** Enable/disable the backup service. This is user-configurable via backup settings. */
public void setBackupEnabled(boolean enable) {
public void setBackupEnabled(@UserIdInt int userId, boolean enable) {
enforceCallingPermissionOnUserId(userId, "setBackupEnabled");
mUserBackupManagerService.setBackupEnabled(enable);
}
@@ -331,7 +351,8 @@ public class BackupManagerService {
/**
* Return {@code true} if the backup mechanism is currently enabled, else returns {@code false}.
*/
public boolean isBackupEnabled() {
public boolean isBackupEnabled(@UserIdInt int userId) {
enforceCallingPermissionOnUserId(userId, "isBackupEnabled");
return mUserBackupManagerService.isBackupEnabled();
}
@@ -355,7 +376,8 @@ public class BackupManagerService {
* Run a backup pass immediately for any key-value backup applications that have declared that
* they have pending updates.
*/
public void backupNow() {
public void backupNow(@UserIdInt int userId) {
enforceCallingPermissionOnUserId(userId, "backupNow");
mUserBackupManagerService.backupNow();
}
@@ -364,12 +386,18 @@ public class BackupManagerService {
* IBackupManagerMonitor} for receiving events during the operation.
*/
public int requestBackup(
String[] packages, IBackupObserver observer, IBackupManagerMonitor monitor, int flags) {
@UserIdInt int userId,
String[] packages,
IBackupObserver observer,
IBackupManagerMonitor monitor,
int flags) {
enforceCallingPermissionOnUserId(userId, "requestBackup");
return mUserBackupManagerService.requestBackup(packages, observer, monitor, flags);
}
/** Cancel all running backup operations. */
public void cancelBackups() {
public void cancelBackups(@UserIdInt int userId) {
enforceCallingPermissionOnUserId(userId, "cancelBackups");
mUserBackupManagerService.cancelBackups();
}
@@ -533,8 +561,10 @@ public class BackupManagerService {
stage.renameTo(enableFile);
// will be synced immediately by the try-with-resources call to close()
} catch (IOException | RuntimeException e) {
Slog.e(TAG, "Unable to record backup enable state; reverting to disabled: "
+ e.getMessage());
Slog.e(
TAG,
"Unable to record backup enable state; reverting to disabled: "
+ e.getMessage());
enableFile.delete();
stage.delete();
}

View File

@@ -19,6 +19,7 @@ package com.android.server.backup;
import static com.android.server.backup.BackupManagerService.TAG;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.admin.DevicePolicyManager;
import android.app.backup.BackupManager;
import android.app.backup.IBackupManager;
@@ -123,6 +124,10 @@ public class Trampoline extends IBackupManager.Stub {
== MULTI_USER_ENABLED;
}
protected int binderGetCallingUserId() {
return Binder.getCallingUserHandle().getIdentifier();
}
protected int binderGetCallingUid() {
return Binder.getCallingUid();
}
@@ -319,13 +324,19 @@ public class Trampoline extends IBackupManager.Stub {
}
@Override
public void setBackupEnabled(boolean isEnabled) throws RemoteException {
public void setBackupEnabledForUser(@UserIdInt int userId, boolean isEnabled)
throws RemoteException {
BackupManagerService svc = mService;
if (svc != null) {
svc.setBackupEnabled(isEnabled);
svc.setBackupEnabled(userId, isEnabled);
}
}
@Override
public void setBackupEnabled(boolean isEnabled) throws RemoteException {
setBackupEnabledForUser(binderGetCallingUserId(), isEnabled);
}
@Override
public void setAutoRestore(boolean doAutoRestore) throws RemoteException {
BackupManagerService svc = mService;
@@ -343,9 +354,14 @@ public class Trampoline extends IBackupManager.Stub {
}
@Override
public boolean isBackupEnabled() throws RemoteException {
public boolean isBackupEnabledForUser(@UserIdInt int userId) throws RemoteException {
BackupManagerService svc = mService;
return (svc != null) ? svc.isBackupEnabled() : false;
return (svc != null) ? svc.isBackupEnabled(userId) : false;
}
@Override
public boolean isBackupEnabled() throws RemoteException {
return isBackupEnabledForUser(binderGetCallingUserId());
}
@Override
@@ -361,13 +377,18 @@ public class Trampoline extends IBackupManager.Stub {
}
@Override
public void backupNow() throws RemoteException {
public void backupNowForUser(@UserIdInt int userId) throws RemoteException {
BackupManagerService svc = mService;
if (svc != null) {
svc.backupNow();
svc.backupNow(userId);
}
}
@Override
public void backupNow() throws RemoteException {
backupNowForUser(binderGetCallingUserId());
}
@Override
public void adbBackup(ParcelFileDescriptor fd, boolean includeApks, boolean includeObbs,
boolean includeShared, boolean doWidgets, boolean allApps,
@@ -543,21 +564,33 @@ public class Trampoline extends IBackupManager.Stub {
}
@Override
public int requestBackup(String[] packages, IBackupObserver observer,
IBackupManagerMonitor monitor, int flags) throws RemoteException {
public int requestBackupForUser(@UserIdInt int userId, String[] packages, IBackupObserver
observer, IBackupManagerMonitor monitor, int flags) throws RemoteException {
BackupManagerService svc = mService;
if (svc == null) {
return BackupManager.ERROR_BACKUP_NOT_ALLOWED;
}
return svc.requestBackup(packages, observer, monitor, flags);
return svc.requestBackup(userId, packages, observer, monitor, flags);
}
@Override
public int requestBackup(String[] packages, IBackupObserver observer,
IBackupManagerMonitor monitor, int flags) throws RemoteException {
return requestBackupForUser(binderGetCallingUserId(), packages,
observer, monitor, flags);
}
@Override
public void cancelBackupsForUser(@UserIdInt int userId) throws RemoteException {
BackupManagerService svc = mService;
if (svc != null) {
svc.cancelBackups(userId);
}
}
@Override
public void cancelBackups() throws RemoteException {
BackupManagerService svc = mService;
if (svc != null) {
svc.cancelBackups();
}
cancelBackupsForUser(binderGetCallingUserId());
}
@Override

View File

@@ -22,7 +22,10 @@ import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.robolectric.Shadows.shadowOf;
import static org.testng.Assert.expectThrows;
import android.annotation.UserIdInt;
import android.app.Application;
import android.app.backup.IBackupManagerMonitor;
import android.app.backup.IBackupObserver;
@@ -32,11 +35,14 @@ import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
import android.os.UserHandle;
import android.platform.test.annotations.Presubmit;
import com.android.server.backup.testing.BackupManagerServiceTestUtils;
import com.android.server.backup.testing.TransportData;
import com.android.server.testing.shadows.ShadowBinder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -44,6 +50,8 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowContextWrapper;
import java.io.File;
import java.io.FileDescriptor;
@@ -51,14 +59,19 @@ import java.io.PrintWriter;
/** Tests for the user-aware backup/restore system service {@link BackupManagerService}. */
@RunWith(RobolectricTestRunner.class)
@Config(shadows = {ShadowBinder.class})
@Presubmit
public class BackupManagerServiceTest {
private static final String TEST_PACKAGE = "package";
private static final String TEST_TRANSPORT = "transport";
private static final int NON_USER_SYSTEM = UserHandle.USER_SYSTEM + 1;
private ShadowContextWrapper mShadowContext;
@Mock private UserBackupManagerService mUserBackupManagerService;
private BackupManagerService mBackupManagerService;
private Context mContext;
@UserIdInt private int mUserId;
/** Initialize {@link BackupManagerService}. */
@Before
@@ -67,6 +80,8 @@ public class BackupManagerServiceTest {
Application application = RuntimeEnvironment.application;
mContext = application;
mShadowContext = shadowOf(application);
mUserId = NON_USER_SYSTEM;
mBackupManagerService =
new BackupManagerService(
application,
@@ -75,6 +90,15 @@ public class BackupManagerServiceTest {
mBackupManagerService.setUserBackupManagerService(mUserBackupManagerService);
}
/**
* Clean up and reset state that was created for testing {@link BackupManagerService}
* operations.
*/
@After
public void tearDown() throws Exception {
ShadowBinder.reset();
}
/**
* Test verifying that {@link BackupManagerService#MORE_DEBUG} is set to {@code false}.
* This is specifically to prevent overloading the logs in production.
@@ -274,11 +298,41 @@ public class BackupManagerServiceTest {
// ---------------------------------------------
// Settings tests
// ---------------------------------------------
/**
* Test verifying that {@link BackupManagerService#setBackupEnabled(int, boolean)} throws a
* {@link SecurityException} if the caller does not have INTERACT_ACROSS_USERS_FULL permission.
*/
@Test
public void setBackupEnabled_withoutPermission_throwsSecurityException() {
mShadowContext.denyPermissions(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
expectThrows(
SecurityException.class,
() -> mBackupManagerService.setBackupEnabled(mUserId, true));
}
/**
* Test verifying that {@link BackupManagerService#setBackupEnabled(int, boolean)} does not
* require the caller to have INTERACT_ACROSS_USERS_FULL permission when the calling user id is
* the same as the target user id.
*/
@Test
public void setBackupEnabled_whenCallingUserIsTargetUser_doesntNeedPermission() {
ShadowBinder.setCallingUserHandle(UserHandle.of(mUserId));
mShadowContext.denyPermissions(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
mBackupManagerService.setBackupEnabled(mUserId, true);
verify(mUserBackupManagerService).setBackupEnabled(true);
}
/** Test that the backup service routes methods correctly to the user that requests it. */
@Test
public void setBackupEnabled_callsSetBackupEnabledForUser() throws Exception {
mBackupManagerService.setBackupEnabled(true);
mShadowContext.grantPermissions(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
mBackupManagerService.setBackupEnabled(mUserId, true);
verify(mUserBackupManagerService).setBackupEnabled(true);
}
@@ -299,10 +353,25 @@ public class BackupManagerServiceTest {
verify(mUserBackupManagerService).setBackupProvisioned(true);
}
/**
* Test verifying that {@link BackupManagerService#isBackupEnabled(int)} throws a
* {@link SecurityException} if the caller does not have INTERACT_ACROSS_USERS_FULL permission.
*/
@Test
public void testIsBackupEnabled_withoutPermission_throwsSecurityException() {
mShadowContext.denyPermissions(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
expectThrows(
SecurityException.class,
() -> mBackupManagerService.isBackupEnabled(mUserId));
}
/** Test that the backup service routes methods correctly to the user that requests it. */
@Test
public void testIsBackupEnabled_callsIsBackupEnabledForUser() throws Exception {
mBackupManagerService.isBackupEnabled();
mShadowContext.grantPermissions(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
mBackupManagerService.isBackupEnabled(mUserId);
verify(mUserBackupManagerService).isBackupEnabled();
}
@@ -330,30 +399,81 @@ public class BackupManagerServiceTest {
verify(mUserBackupManagerService).filterAppsEligibleForBackup(packages);
}
/**
* Test verifying that {@link BackupManagerService#backupNow(int)} throws a
* {@link SecurityException} if the caller does not have INTERACT_ACROSS_USERS_FULL permission.
*/
@Test
public void testBackupNow_withoutPermission_throwsSecurityException() {
mShadowContext.denyPermissions(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
expectThrows(
SecurityException.class,
() -> mBackupManagerService.backupNow(mUserId));
}
/** Test that the backup service routes methods correctly to the user that requests it. */
@Test
public void testBackupNow_callsBackupNowForUser() throws Exception {
mBackupManagerService.backupNow();
mShadowContext.grantPermissions(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
mBackupManagerService.backupNow(mUserId);
verify(mUserBackupManagerService).backupNow();
}
/** Test that the backup service routes methods correctly to the user that requests it. */
/**
* Test verifying that {@link BackupManagerService#requestBackup(int, String[], IBackupObserver,
* IBackupManagerMonitor, int)} throws a {@link SecurityException} if the caller does not have
* INTERACT_ACROSS_USERS_FULL permission.
*/
@Test
public void testRequestBackup_callsRequestBackupForUser() throws Exception {
public void testRequestBackup_withoutPermission_throwsSecurityException() {
mShadowContext.denyPermissions(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
String[] packages = {TEST_PACKAGE};
IBackupObserver observer = mock(IBackupObserver.class);
IBackupManagerMonitor monitor = mock(IBackupManagerMonitor.class);
mBackupManagerService.requestBackup(packages, observer, monitor, /* flags */ 0);
expectThrows(
SecurityException.class,
() -> mBackupManagerService.requestBackup(mUserId, packages, observer, monitor, 0));
}
/** Test that the backup service routes methods correctly to the user that requests it. */
@Test
public void testRequestBackup_callsRequestBackupForUser() throws Exception {
mShadowContext.grantPermissions(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
String[] packages = {TEST_PACKAGE};
IBackupObserver observer = mock(IBackupObserver.class);
IBackupManagerMonitor monitor = mock(IBackupManagerMonitor.class);
mBackupManagerService.requestBackup(mUserId, packages, observer, monitor,
/* flags */ 0);
verify(mUserBackupManagerService).requestBackup(packages, observer, monitor, /* flags */ 0);
}
/**
* Test verifying that {@link BackupManagerService#cancelBackups(int)} throws a
* {@link SecurityException} if the caller does not have INTERACT_ACROSS_USERS_FULL permission.
*/
@Test
public void testCancelBackups_withoutPermission_throwsSecurityException() {
mShadowContext.denyPermissions(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
expectThrows(
SecurityException.class,
() -> mBackupManagerService.cancelBackups(mUserId));
}
/** Test that the backup service routes methods correctly to the user that requests it. */
@Test
public void testCancelBackups_callsCancelBackupsForUser() throws Exception {
mBackupManagerService.cancelBackups();
mShadowContext.grantPermissions(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
mBackupManagerService.cancelBackups(mUserId);
verify(mUserBackupManagerService).cancelBackups();
}

View File

@@ -17,9 +17,11 @@
package com.android.server.testing.shadows;
import android.os.Binder;
import android.os.UserHandle;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
import org.robolectric.annotation.Resetter;
/**
* Extends {@link org.robolectric.shadows.ShadowBinder} with {@link Binder#clearCallingIdentity()}
@@ -30,6 +32,7 @@ import org.robolectric.annotation.Implements;
public class ShadowBinder extends org.robolectric.shadows.ShadowBinder {
public static final Integer LOCAL_UID = 1000;
private static Integer originalCallingUid;
private static UserHandle sCallingUserHandle;
@Implementation
protected static long clearCallingIdentity() {
@@ -42,4 +45,30 @@ public class ShadowBinder extends org.robolectric.shadows.ShadowBinder {
protected static void restoreCallingIdentity(long token) {
setCallingUid(originalCallingUid);
}
public static void setCallingUserHandle(UserHandle userHandle) {
sCallingUserHandle = userHandle;
}
/**
* Shadows {@link Binder#getCallingUserHandle()}. If {@link ShadowBinder#sCallingUserHandle}
* is set, return that; otherwise mimic the default implementation.
*/
@Implementation
public static UserHandle getCallingUserHandle() {
if (sCallingUserHandle != null) {
return sCallingUserHandle;
} else {
return UserHandle.of(UserHandle.getUserId(getCallingUid()));
}
}
/**
* Clean up and reset state that was created for testing.
*/
@Resetter
public static void reset() {
sCallingUserHandle = null;
org.robolectric.shadows.ShadowBinder.reset();
}
}

View File

@@ -29,6 +29,7 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
import android.annotation.UserIdInt;
import android.app.backup.BackupManager;
import android.app.backup.IBackupManagerMonitor;
import android.app.backup.IBackupObserver;
@@ -86,8 +87,9 @@ public class TrampolineTest {
new ComponentName("package1", "class1"),
new ComponentName("package2", "class2")
};
private final int NON_USER_SYSTEM = UserHandle.USER_SYSTEM + 1;
private static final int NON_USER_SYSTEM = UserHandle.USER_SYSTEM + 1;
@UserIdInt private int mUserId;
@Mock private BackupManagerService mBackupManagerServiceMock;
@Mock private Context mContextMock;
@Mock private File mSuppressFileMock;
@@ -110,11 +112,13 @@ public class TrampolineTest {
TrampolineTestable.sBackupManagerServiceMock = mBackupManagerServiceMock;
TrampolineTestable.sSuppressFile = mSuppressFileMock;
TrampolineTestable.sCallingUserId = UserHandle.USER_SYSTEM;
TrampolineTestable.sCallingUid = Process.SYSTEM_UID;
TrampolineTestable.sBackupDisabled = false;
when(mSuppressFileMock.getParentFile()).thenReturn(mSuppressFileParentMock);
mUserId = NON_USER_SYSTEM;
mTrampoline = new TrampolineTestable(mContextMock);
mContentResolver = new MockContentResolver();
@@ -361,10 +365,22 @@ public class TrampolineTest {
}
@Test
public void setBackupEnabled_forwarded() throws RemoteException {
public void setBackupEnabledForUser_forwarded() throws RemoteException {
mTrampoline.initializeService(UserHandle.USER_SYSTEM);
mTrampoline.setBackupEnabledForUser(mUserId, true);
verify(mBackupManagerServiceMock).setBackupEnabled(mUserId, true);
}
@Test
public void setBackupEnabled_forwardedToCallingUserId() throws RemoteException {
TrampolineTestable.sCallingUserId = mUserId;
mTrampoline.initializeService(UserHandle.USER_SYSTEM);
mTrampoline.setBackupEnabled(true);
verify(mBackupManagerServiceMock).setBackupEnabled(true);
verify(mBackupManagerServiceMock).setBackupEnabled(mUserId, true);
}
@Test
@@ -400,10 +416,22 @@ public class TrampolineTest {
}
@Test
public void isBackupEnabled_forwarded() throws RemoteException {
public void isBackupEnabledForUser_forwarded() throws RemoteException {
mTrampoline.initializeService(UserHandle.USER_SYSTEM);
mTrampoline.isBackupEnabledForUser(mUserId);
verify(mBackupManagerServiceMock).isBackupEnabled(mUserId);
}
@Test
public void isBackupEnabled_forwardedToCallingUserId() throws RemoteException {
TrampolineTestable.sCallingUserId = mUserId;
mTrampoline.initializeService(UserHandle.USER_SYSTEM);
mTrampoline.isBackupEnabled();
verify(mBackupManagerServiceMock).isBackupEnabled();
verify(mBackupManagerServiceMock).isBackupEnabled(mUserId);
}
@Test
@@ -439,10 +467,22 @@ public class TrampolineTest {
}
@Test
public void backupNow_forwarded() throws RemoteException {
public void backupNowForUser_forwarded() throws RemoteException {
mTrampoline.initializeService(UserHandle.USER_SYSTEM);
mTrampoline.backupNowForUser(mUserId);
verify(mBackupManagerServiceMock).backupNow(mUserId);
}
@Test
public void backupNow_forwardedToCallingUserId() throws RemoteException {
TrampolineTestable.sCallingUserId = mUserId;
mTrampoline.initializeService(UserHandle.USER_SYSTEM);
mTrampoline.backupNow();
verify(mBackupManagerServiceMock).backupNow();
verify(mBackupManagerServiceMock).backupNow(mUserId);
}
@Test
@@ -798,15 +838,28 @@ public class TrampolineTest {
}
@Test
public void requestBackup_forwarded() throws RemoteException {
when(mBackupManagerServiceMock.requestBackup(PACKAGE_NAMES, mBackupObserverMock,
mBackupManagerMonitorMock, 123)).thenReturn(456);
public void requestBackupForUser_forwarded() throws RemoteException {
when(mBackupManagerServiceMock.requestBackup(mUserId, PACKAGE_NAMES,
mBackupObserverMock, mBackupManagerMonitorMock, 123)).thenReturn(456);
mTrampoline.initializeService(UserHandle.USER_SYSTEM);
assertEquals(456, mTrampoline.requestBackup(PACKAGE_NAMES, mBackupObserverMock,
mBackupManagerMonitorMock, 123));
verify(mBackupManagerServiceMock).requestBackup(PACKAGE_NAMES, mBackupObserverMock,
mBackupManagerMonitorMock, 123);
assertEquals(456, mTrampoline.requestBackupForUser(mUserId, PACKAGE_NAMES,
mBackupObserverMock, mBackupManagerMonitorMock, 123));
verify(mBackupManagerServiceMock).requestBackup(mUserId, PACKAGE_NAMES,
mBackupObserverMock, mBackupManagerMonitorMock, 123);
}
@Test
public void requestBackup_forwardedToCallingUserId() throws RemoteException {
TrampolineTestable.sCallingUserId = mUserId;
when(mBackupManagerServiceMock.requestBackup(NON_USER_SYSTEM, PACKAGE_NAMES,
mBackupObserverMock, mBackupManagerMonitorMock, 123)).thenReturn(456);
mTrampoline.initializeService(UserHandle.USER_SYSTEM);
assertEquals(456, mTrampoline.requestBackup(PACKAGE_NAMES,
mBackupObserverMock, mBackupManagerMonitorMock, 123));
verify(mBackupManagerServiceMock).requestBackup(mUserId, PACKAGE_NAMES,
mBackupObserverMock, mBackupManagerMonitorMock, 123);
}
@Test
@@ -816,10 +869,22 @@ public class TrampolineTest {
}
@Test
public void cancelBackups_forwarded() throws RemoteException {
public void cancelBackupsForUser_forwarded() throws RemoteException {
mTrampoline.initializeService(UserHandle.USER_SYSTEM);
mTrampoline.cancelBackupsForUser(mUserId);
verify(mBackupManagerServiceMock).cancelBackups(mUserId);
}
@Test
public void cancelBackups_forwardedToCallingUserId() throws RemoteException {
TrampolineTestable.sCallingUserId = mUserId;
mTrampoline.initializeService(UserHandle.USER_SYSTEM);
mTrampoline.cancelBackups();
verify(mBackupManagerServiceMock).cancelBackups();
verify(mBackupManagerServiceMock).cancelBackups(mUserId);
}
@Test
@@ -891,6 +956,7 @@ public class TrampolineTest {
private static class TrampolineTestable extends Trampoline {
static boolean sBackupDisabled = false;
static File sSuppressFile = null;
static int sCallingUserId = -1;
static int sCallingUid = -1;
static BackupManagerService sBackupManagerServiceMock = null;
private int mCreateServiceCallsCount = 0;
@@ -909,6 +975,10 @@ public class TrampolineTest {
return sSuppressFile;
}
protected int binderGetCallingUserId() {
return sCallingUserId;
}
@Override
protected int binderGetCallingUid() {
return sCallingUid;