diff options
10 files changed, 1848 insertions, 2054 deletions
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java index 23afce6c94e1..222a6f210448 100644 --- a/services/backup/java/com/android/server/backup/BackupManagerService.java +++ b/services/backup/java/com/android/server/backup/BackupManagerService.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 The Android Open Source Project + * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,12 +18,56 @@ package com.android.server.backup; import static com.android.internal.util.Preconditions.checkNotNull; +import static java.util.Collections.emptySet; + +import android.Manifest; +import android.annotation.Nullable; +import android.annotation.UserIdInt; +import android.app.ActivityManager; +import android.app.admin.DevicePolicyManager; +import android.app.backup.BackupManager; +import android.app.backup.IBackupManager; +import android.app.backup.IBackupManagerMonitor; +import android.app.backup.IBackupObserver; +import android.app.backup.IFullBackupRestoreObserver; +import android.app.backup.IRestoreSession; +import android.app.backup.ISelectBackupTransportCallback; +import android.app.job.JobParameters; +import android.app.job.JobScheduler; +import android.app.job.JobService; +import android.content.BroadcastReceiver; +import android.content.ComponentName; import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.pm.PackageManager; +import android.os.Binder; +import android.os.FileUtils; +import android.os.Handler; +import android.os.HandlerThread; import android.os.IBinder; +import android.os.ParcelFileDescriptor; +import android.os.Process; +import android.os.RemoteException; +import android.os.SystemProperties; +import android.os.Trace; +import android.os.UserHandle; +import android.os.UserManager; +import android.util.Slog; import android.util.SparseArray; +import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.util.DumpUtils; +import com.android.server.SystemConfig; import com.android.server.SystemService; +import com.android.server.backup.utils.RandomAccessFileUtils; + +import java.io.File; +import java.io.FileDescriptor; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.Set; /** * Definition of the system service that performs backup/restore operations. @@ -31,53 +75,1502 @@ import com.android.server.SystemService; * <p>This class is responsible for handling user-aware operations and acts as a delegator, routing * incoming calls to the appropriate per-user {@link UserBackupManagerService} to handle the * corresponding backup/restore operation. + * + * <p>It also determines whether the backup service is available. It can be disabled in the + * following two ways: + * + * <ul> + * <li>Temporary - call {@link #setBackupServiceActive(int, boolean)}, or + * <li>Permanent - set the system property {@link #BACKUP_DISABLE_PROPERTY} to true. + * </ul> + * + * Temporary disabling is controlled by {@link #setBackupServiceActive(int, boolean)} through + * privileged callers (currently {@link DevicePolicyManager}). If called on {@link + * UserHandle#USER_SYSTEM}, backup is disabled for all users. */ -public class BackupManagerService { +public class BackupManagerService extends IBackupManager.Stub { public static final String TAG = "BackupManagerService"; public static final boolean DEBUG = true; public static final boolean MORE_DEBUG = false; public static final boolean DEBUG_SCHEDULING = true; + @VisibleForTesting + static final String DUMP_RUNNING_USERS_MESSAGE = "Backup Manager is running for users:"; + + /** + * Name of file that disables the backup service. If this file exists, then backup is disabled + * for all users. + */ + private static final String BACKUP_SUPPRESS_FILENAME = "backup-suppress"; + + /** + * Name of file for non-system users that enables the backup service for the user. Backup is + * disabled by default in non-system users. + */ + private static final String BACKUP_ACTIVATED_FILENAME = "backup-activated"; + + /** + * Name of file for non-system users that remembers whether backup was explicitly activated or + * deactivated with a call to setBackupServiceActive. + */ + private static final String REMEMBER_ACTIVATED_FILENAME = "backup-remember-activated"; + + // Product-level suppression of backup/restore. + private static final String BACKUP_DISABLE_PROPERTY = "ro.backup.disable"; + + private static final String BACKUP_THREAD = "backup"; + + static BackupManagerService sInstance; + + static BackupManagerService getInstance() { + return checkNotNull(sInstance); + } + private final Context mContext; - private final Trampoline mTrampoline; - private final SparseArray<UserBackupManagerService> mServiceUsers; + private final UserManager mUserManager; + + private final boolean mGlobalDisable; + // Lock to write backup suppress files. + // TODD(b/121198006): remove this object and synchronized all methods on "this". + private final Object mStateLock = new Object(); + + private final Handler mHandler; + private final Set<ComponentName> mTransportWhitelist; + + /** Keeps track of all unlocked users registered with this service. Indexed by user id. */ + private final SparseArray<UserBackupManagerService> mUserServices; + + private final BroadcastReceiver mUserRemovedReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if (Intent.ACTION_USER_REMOVED.equals(intent.getAction())) { + int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL); + if (userId > 0) { // for only non system users + mHandler.post(() -> onRemovedNonSystemUser(userId)); + } + } + } + }; + + public BackupManagerService(Context context) { + this(context, new SparseArray<>()); + } + + @VisibleForTesting + BackupManagerService(Context context, SparseArray<UserBackupManagerService> userServices) { + mContext = context; + mGlobalDisable = isBackupDisabled(); + HandlerThread handlerThread = + new HandlerThread(BACKUP_THREAD, Process.THREAD_PRIORITY_BACKGROUND); + handlerThread.start(); + mHandler = new Handler(handlerThread.getLooper()); + mUserManager = UserManager.get(context); + mUserServices = userServices; + Set<ComponentName> transportWhitelist = + SystemConfig.getInstance().getBackupTransportWhitelist(); + mTransportWhitelist = (transportWhitelist == null) ? emptySet() : transportWhitelist; + mContext.registerReceiver( + mUserRemovedReceiver, new IntentFilter(Intent.ACTION_USER_REMOVED)); + } + + // TODO: Remove this when we implement DI by injecting in the construtor. + @VisibleForTesting + Handler getBackupHandler() { + return mHandler; + } + + protected boolean isBackupDisabled() { + return SystemProperties.getBoolean(BACKUP_DISABLE_PROPERTY, false); + } + + protected int binderGetCallingUserId() { + return Binder.getCallingUserHandle().getIdentifier(); + } + + protected int binderGetCallingUid() { + return Binder.getCallingUid(); + } + + /** Stored in the system user's directory. */ + protected File getSuppressFileForSystemUser() { + return new File(UserBackupManagerFiles.getBaseStateDir(UserHandle.USER_SYSTEM), + BACKUP_SUPPRESS_FILENAME); + } + + /** Stored in the system user's directory and the file is indexed by the user it refers to. */ + protected File getRememberActivatedFileForNonSystemUser(int userId) { + return UserBackupManagerFiles.getStateFileInSystemDir(REMEMBER_ACTIVATED_FILENAME, userId); + } + + /** Stored in the system user's directory and the file is indexed by the user it refers to. */ + protected File getActivatedFileForNonSystemUser(int userId) { + return UserBackupManagerFiles.getStateFileInSystemDir(BACKUP_ACTIVATED_FILENAME, userId); + } + + /** + * Remove backup state for non system {@code userId} when the user is removed from the device. + * For non system users, backup state is stored in both the user's own dir and the system dir. + * When the user is removed, the user's own dir gets removed by the OS. This method ensures that + * the part of the user backup state which is in the system dir also gets removed. + */ + private void onRemovedNonSystemUser(int userId) { + Slog.i(TAG, "Removing state for non system user " + userId); + File dir = UserBackupManagerFiles.getStateDirInSystemDir(userId); + if (!FileUtils.deleteContentsAndDir(dir)) { + Slog.w(TAG, "Failed to delete state dir for removed user: " + userId); + } + } + + // TODO (b/124359804) move to util method in FileUtils + private void createFile(File file) throws IOException { + if (file.exists()) { + return; + } + + file.getParentFile().mkdirs(); + if (!file.createNewFile()) { + Slog.w(TAG, "Failed to create file " + file.getPath()); + } + } + + // TODO (b/124359804) move to util method in FileUtils + private void deleteFile(File file) { + if (!file.exists()) { + return; + } + + if (!file.delete()) { + Slog.w(TAG, "Failed to delete file " + file.getPath()); + } + } + + /** + * Deactivates the backup service for user {@code userId}. If this is the system user, it + * creates a suppress file which disables backup for all users. If this is a non-system user, it + * only deactivates backup for that user by deleting its activate file. + */ + @GuardedBy("mStateLock") + private void deactivateBackupForUserLocked(int userId) throws IOException { + if (userId == UserHandle.USER_SYSTEM) { + createFile(getSuppressFileForSystemUser()); + } else { + deleteFile(getActivatedFileForNonSystemUser(userId)); + } + } + + /** + * Enables the backup service for user {@code userId}. If this is the system user, it deletes + * the suppress file. If this is a non-system user, it creates the user's activate file. Note, + * deleting the suppress file does not automatically enable backup for non-system users, they + * need their own activate file in order to participate in the service. + */ + @GuardedBy("mStateLock") + private void activateBackupForUserLocked(int userId) throws IOException { + if (userId == UserHandle.USER_SYSTEM) { + deleteFile(getSuppressFileForSystemUser()); + } else { + createFile(getActivatedFileForNonSystemUser(userId)); + } + } + + // This method should not perform any I/O (e.g. do not call isBackupActivatedForUser), + // it's used in multiple places where I/O waits would cause system lock-ups. + private boolean isUserReadyForBackup(int userId) { + return mUserServices.get(UserHandle.USER_SYSTEM) != null + && mUserServices.get(userId) != null; + } + + /** + * Backup is activated for the system user if the suppress file does not exist. Backup is + * activated for non-system users if the suppress file does not exist AND the user's activated + * file exists. + */ + private boolean isBackupActivatedForUser(int userId) { + if (getSuppressFileForSystemUser().exists()) { + return false; + } + + return userId == UserHandle.USER_SYSTEM + || getActivatedFileForNonSystemUser(userId).exists(); + } + + protected Context getContext() { + return mContext; + } + + protected UserManager getUserManager() { + return mUserManager; + } + + protected void postToHandler(Runnable runnable) { + mHandler.post(runnable); + } + + /** + * 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. + */ + 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. + */ + @VisibleForTesting + void startServiceForUser(int userId) { + // We know that the user is unlocked here because it is called from setBackupServiceActive + // and unlockUser which have these guarantees. So we can check if the file exists. + if (mGlobalDisable) { + Slog.i(TAG, "Backup service not supported"); + return; + } + if (!isBackupActivatedForUser(userId)) { + Slog.i(TAG, "Backup not activated for user " + userId); + return; + } + if (mUserServices.get(userId) != null) { + Slog.i(TAG, "userId " + userId + " already started, so not starting again"); + return; + } + Slog.i(TAG, "Starting service for user: " + userId); + UserBackupManagerService userBackupManagerService = + UserBackupManagerService.createAndInitializeService( + userId, mContext, this, mTransportWhitelist); + startServiceForUser(userId, userBackupManagerService); + } + + /** + * Starts the backup service for user {@code userId} by registering its instance of {@link + * UserBackupManagerService} with this service and setting enabled state. + */ + void startServiceForUser(int userId, UserBackupManagerService userBackupManagerService) { + mUserServices.put(userId, userBackupManagerService); + + Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backup enable"); + userBackupManagerService.initializeBackupEnableState(); + Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); + } + + /** Stops the backup service for user {@code userId} when the user is stopped. */ + @VisibleForTesting + protected void stopServiceForUser(int userId) { + UserBackupManagerService userBackupManagerService = mUserServices.removeReturnOld(userId); + + if (userBackupManagerService != null) { + userBackupManagerService.tearDownService(); + + KeyValueBackupJob.cancel(userId, mContext); + FullBackupJob.cancel(userId, mContext); + } + } + + /** + * Returns a list of users currently unlocked that have a {@link UserBackupManagerService} + * registered. + * + * Warning: Do NOT modify returned object as it's used inside. + * + * TODO: Return a copy or only expose read-only information through other means. + */ + @VisibleForTesting + SparseArray<UserBackupManagerService> getUserServices() { + return mUserServices; + } + + /** + * Called from {@link BackupManagerService.Lifecycle} when a user {@code userId} is stopped. + * Offloads work onto the handler thread {@link #mHandlerThread} to keep stopping time low. + */ + void onStopUser(int userId) { + postToHandler( + () -> { + if (!mGlobalDisable) { + Slog.i(TAG, "Stopping service for user: " + userId); + stopServiceForUser(userId); + } + }); + } + + /** Returns {@link UserBackupManagerService} for user {@code userId}. */ + @Nullable + public UserBackupManagerService getUserService(int userId) { + return mUserServices.get(userId); + } + + /** + * The system user and managed profiles can only be acted on by callers in the system or root + * processes. Other users can be acted on by callers who have both android.permission.BACKUP and + * android.permission.INTERACT_ACROSS_USERS_FULL permissions. + */ + private void enforcePermissionsOnUser(int userId) throws SecurityException { + boolean isRestrictedUser = + userId == UserHandle.USER_SYSTEM + || getUserManager().getUserInfo(userId).isManagedProfile(); + + if (isRestrictedUser) { + int caller = binderGetCallingUid(); + if (caller != Process.SYSTEM_UID && caller != Process.ROOT_UID) { + throw new SecurityException("No permission to configure backup activity"); + } + } else { + mContext.enforceCallingOrSelfPermission( + Manifest.permission.BACKUP, "No permission to configure backup activity"); + mContext.enforceCallingOrSelfPermission( + Manifest.permission.INTERACT_ACROSS_USERS_FULL, + "No permission to configure backup activity"); + } + } + + /** + * Only privileged callers should be changing the backup state. Deactivating backup in the + * system user also deactivates backup in all users. We are not guaranteed that {@code userId} + * is unlocked at this point yet, so handle both cases. + */ + public void setBackupServiceActive(int userId, boolean makeActive) { + enforcePermissionsOnUser(userId); + + // In Q, backup is OFF by default for non-system users. In the future, we will change that + // to ON unless backup was explicitly deactivated with a (permissioned) call to + // setBackupServiceActive. + // Therefore, remember this for use in the future. Basically the default in the future will + // be: rememberFile.exists() ? rememberFile.value() : ON + // Note that this has to be done right after the permission checks and before any other + // action since we need to remember that a permissioned call was made irrespective of + // whether the call changes the state or not. + if (userId != UserHandle.USER_SYSTEM) { + try { + File rememberFile = getRememberActivatedFileForNonSystemUser(userId); + createFile(rememberFile); + RandomAccessFileUtils.writeBoolean(rememberFile, makeActive); + } catch (IOException e) { + Slog.e(TAG, "Unable to persist backup service activity", e); + } + } + + if (mGlobalDisable) { + Slog.i(TAG, "Backup service not supported"); + return; + } + + synchronized (mStateLock) { + Slog.i(TAG, "Making backup " + (makeActive ? "" : "in") + "active"); + if (makeActive) { + try { + activateBackupForUserLocked(userId); + } catch (IOException e) { + Slog.e(TAG, "Unable to persist backup service activity"); + } + + // If the user is unlocked, we can start the backup service for it. Otherwise we + // will start the service when the user is unlocked as part of its unlock callback. + if (getUserManager().isUserUnlocked(userId)) { + // Clear calling identity as initialization enforces the system identity but we + // can be coming from shell. + long oldId = Binder.clearCallingIdentity(); + try { + startServiceForUser(userId); + } finally { + Binder.restoreCallingIdentity(oldId); + } + } + } else { + try { + //TODO(b/121198006): what if this throws an exception? + deactivateBackupForUserLocked(userId); + } catch (IOException e) { + Slog.e(TAG, "Unable to persist backup service inactivity"); + } + //TODO(b/121198006): loop through active users that have work profile and + // stop them as well. + onStopUser(userId); + } + } + } + + // IBackupManager binder API + + /** + * Querying activity state of backup service. + * + * @param userId The user in which the activity state of backup service is queried. + * @return true if the service is active. + */ + @Override + public boolean isBackupServiceActive(int userId) { + synchronized (mStateLock) { + return !mGlobalDisable && isBackupActivatedForUser(userId); + } + } + + @Override + public void dataChangedForUser(int userId, String packageName) throws RemoteException { + if (isUserReadyForBackup(userId)) { + dataChanged(userId, packageName); + } + } + + @Override + public void dataChanged(String packageName) throws RemoteException { + dataChangedForUser(binderGetCallingUserId(), packageName); + } + + /** + * An app's backup agent calls this method to let the service know that there's new data to + * backup for their app {@code packageName}. Only used for apps participating in key-value + * backup. + */ + public void dataChanged(@UserIdInt int userId, String packageName) { + UserBackupManagerService userBackupManagerService = + getServiceForUserIfCallerHasPermission(userId, "dataChanged()"); + + if (userBackupManagerService != null) { + userBackupManagerService.dataChanged(packageName); + } + } + + // --------------------------------------------- + // TRANSPORT OPERATIONS + // --------------------------------------------- + + @Override + public void initializeTransportsForUser( + int userId, String[] transportNames, IBackupObserver observer) throws RemoteException { + if (isUserReadyForBackup(userId)) { + initializeTransports(userId, transportNames, observer); + } + } + + /** Run an initialize operation for the given transports {@code transportNames}. */ + public void initializeTransports( + @UserIdInt int userId, String[] transportNames, IBackupObserver observer) { + UserBackupManagerService userBackupManagerService = + getServiceForUserIfCallerHasPermission(userId, "initializeTransports()"); + + if (userBackupManagerService != null) { + userBackupManagerService.initializeTransports(transportNames, observer); + } + } + + @Override + public void clearBackupDataForUser(int userId, String transportName, String packageName) + throws RemoteException { + if (isUserReadyForBackup(userId)) { + clearBackupData(userId, transportName, packageName); + } + } + + /** + * Clear the given package {@code packageName}'s backup data from the transport {@code + * transportName}. + */ + public void clearBackupData(@UserIdInt int userId, String transportName, String packageName) { + UserBackupManagerService userBackupManagerService = + getServiceForUserIfCallerHasPermission(userId, "clearBackupData()"); + + if (userBackupManagerService != null) { + userBackupManagerService.clearBackupData(transportName, packageName); + } + } + + @Override + public void clearBackupData(String transportName, String packageName) + throws RemoteException { + clearBackupDataForUser(binderGetCallingUserId(), transportName, packageName); + } + + @Override + public void agentConnectedForUser(int userId, String packageName, IBinder agent) + throws RemoteException { + if (isUserReadyForBackup(userId)) { + agentConnected(userId, packageName, agent); + } + } + + @Override + public void agentConnected(String packageName, IBinder agent) throws RemoteException { + agentConnectedForUser(binderGetCallingUserId(), packageName, agent); + } + + /** + * Callback: a requested backup agent has been instantiated. This should only be called from the + * {@link ActivityManager}. + */ + public void agentConnected(@UserIdInt int userId, String packageName, IBinder agentBinder) { + UserBackupManagerService userBackupManagerService = + getServiceForUserIfCallerHasPermission(userId, "agentConnected()"); + + if (userBackupManagerService != null) { + userBackupManagerService.agentConnected(packageName, agentBinder); + } + } + + @Override + public void agentDisconnectedForUser(int userId, String packageName) throws RemoteException { + if (isUserReadyForBackup(userId)) { + agentDisconnected(userId, packageName); + } + } + + @Override + public void agentDisconnected(String packageName) throws RemoteException { + agentDisconnectedForUser(binderGetCallingUserId(), packageName); + } + + /** + * Callback: a backup agent has failed to come up, or has unexpectedly quit. This should only be + * called from the {@link ActivityManager}. + */ + public void agentDisconnected(@UserIdInt int userId, String packageName) { + UserBackupManagerService userBackupManagerService = + getServiceForUserIfCallerHasPermission(userId, "agentDisconnected()"); + + if (userBackupManagerService != null) { + userBackupManagerService.agentDisconnected(packageName); + } + } + + @Override + public void restoreAtInstallForUser(int userId, String packageName, int token) + throws RemoteException { + if (isUserReadyForBackup(userId)) { + restoreAtInstall(userId, packageName, token); + } + } + + @Override + public void restoreAtInstall(String packageName, int token) throws RemoteException { + restoreAtInstallForUser(binderGetCallingUserId(), packageName, token); + } + + /** + * Used to run a restore pass for an application that is being installed. This should only be + * called from the {@link PackageManager}. + */ + public void restoreAtInstall(@UserIdInt int userId, String packageName, int token) { + UserBackupManagerService userBackupManagerService = + getServiceForUserIfCallerHasPermission(userId, "restoreAtInstall()"); + + if (userBackupManagerService != null) { + userBackupManagerService.restoreAtInstall(packageName, token); + } + } + + @Override + public void setBackupEnabledForUser(@UserIdInt int userId, boolean isEnabled) + throws RemoteException { + if (isUserReadyForBackup(userId)) { + setBackupEnabled(userId, isEnabled); + } + } + + @Override + public void setBackupEnabled(boolean isEnabled) throws RemoteException { + setBackupEnabledForUser(binderGetCallingUserId(), isEnabled); + } + + /** Enable/disable the backup service. This is user-configurable via backup settings. */ + public void setBackupEnabled(@UserIdInt int userId, boolean enable) { + UserBackupManagerService userBackupManagerService = + getServiceForUserIfCallerHasPermission(userId, "setBackupEnabled()"); + + if (userBackupManagerService != null) { + userBackupManagerService.setBackupEnabled(enable); + } + } + + @Override + public void setAutoRestoreForUser(int userId, boolean doAutoRestore) throws RemoteException { + if (isUserReadyForBackup(userId)) { + setAutoRestore(userId, doAutoRestore); + } + } + + @Override + public void setAutoRestore(boolean doAutoRestore) throws RemoteException { + setAutoRestoreForUser(binderGetCallingUserId(), doAutoRestore); + } + + /** Enable/disable automatic restore of app data at install time. */ + public void setAutoRestore(@UserIdInt int userId, boolean autoRestore) { + UserBackupManagerService userBackupManagerService = + getServiceForUserIfCallerHasPermission(userId, "setAutoRestore()"); + + if (userBackupManagerService != null) { + userBackupManagerService.setAutoRestore(autoRestore); + } + } + + @Override + public boolean isBackupEnabledForUser(@UserIdInt int userId) throws RemoteException { + return isUserReadyForBackup(userId) && isBackupEnabled(userId); + } + + @Override + public boolean isBackupEnabled() throws RemoteException { + return isBackupEnabledForUser(binderGetCallingUserId()); + } + + /** + * Return {@code true} if the backup mechanism is currently enabled, else returns {@code false}. + */ + public boolean isBackupEnabled(@UserIdInt int userId) { + UserBackupManagerService userBackupManagerService = + getServiceForUserIfCallerHasPermission(userId, "isBackupEnabled()"); + + return userBackupManagerService != null && userBackupManagerService.isBackupEnabled(); + } + + /** Sets the backup password used when running adb backup. */ + @Override + public boolean setBackupPassword(String currentPassword, String newPassword) { + int userId = binderGetCallingUserId(); + 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(); + if (!isUserReadyForBackup(userId)) { + return false; + } + UserBackupManagerService userBackupManagerService = + getServiceForUserIfCallerHasPermission( + UserHandle.USER_SYSTEM, "hasBackupPassword()"); + + return userBackupManagerService != null && userBackupManagerService.hasBackupPassword(); + } + + @Override + public void backupNowForUser(@UserIdInt int userId) throws RemoteException { + if (isUserReadyForBackup(userId)) { + backupNow(userId); + } + } + + @Override + public void backupNow() throws RemoteException { + backupNowForUser(binderGetCallingUserId()); + } + + /** + * Run a backup pass immediately for any key-value backup applications that have declared that + * they have pending updates. + */ + public void backupNow(@UserIdInt int userId) { + UserBackupManagerService userBackupManagerService = + getServiceForUserIfCallerHasPermission(userId, "backupNow()"); + + if (userBackupManagerService != null) { + userBackupManagerService.backupNow(); + } + } + + /** + * 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); + } + } + + @Override + public void fullTransportBackupForUser(int userId, String[] packageNames) + throws RemoteException { + if (isUserReadyForBackup(userId)) { + fullTransportBackup(userId, packageNames); + } + } + + /** + * Run a full backup pass for the given packages {@code packageNames}. Used by 'adb shell bmgr'. + */ + public void fullTransportBackup(@UserIdInt int userId, String[] packageNames) { + UserBackupManagerService userBackupManagerService = + getServiceForUserIfCallerHasPermission(userId, "fullTransportBackup()"); + + if (userBackupManagerService != null) { + userBackupManagerService.fullTransportBackup(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. + */ + @Override + public void adbRestore(@UserIdInt int userId, ParcelFileDescriptor fd) { + if (!isUserReadyForBackup(userId)) { + return; + } + UserBackupManagerService userBackupManagerService = + getServiceForUserIfCallerHasPermission(userId, "adbRestore()"); + + if (userBackupManagerService != null) { + userBackupManagerService.adbRestore(fd); + } + } + + @Override + public void acknowledgeFullBackupOrRestoreForUser( + int userId, + int token, + boolean allow, + String curPassword, + String encryptionPassword, + IFullBackupRestoreObserver observer) + throws RemoteException { + if (isUserReadyForBackup(userId)) { + 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) + throws RemoteException { + acknowledgeFullBackupOrRestoreForUser( + binderGetCallingUserId(), token, allow, curPassword, encryptionPassword, observer); + } + + + @Override + public String getCurrentTransportForUser(int userId) throws RemoteException { + return (isUserReadyForBackup(userId)) ? getCurrentTransport(userId) : null; + } + + @Override + public String getCurrentTransport() throws RemoteException { + return getCurrentTransportForUser(binderGetCallingUserId()); + } + + /** Return the name of the currently active transport. */ + @Nullable + public String getCurrentTransport(@UserIdInt int userId) { + UserBackupManagerService userBackupManagerService = + getServiceForUserIfCallerHasPermission(userId, "getCurrentTransport()"); + + return userBackupManagerService == null + ? null + : userBackupManagerService.getCurrentTransport(); + } + + /** + * Returns the {@link ComponentName} of the host service of the selected transport or + * {@code null} if no transport selected or if the transport selected is not registered. + */ + @Override + @Nullable + public ComponentName getCurrentTransportComponentForUser(int userId) { + return (isUserReadyForBackup(userId)) ? getCurrentTransportComponent(userId) : null; + } + + /** + * Returns the {@link ComponentName} of the host service of the selected transport or {@code + * null} if no transport selected or if the transport selected is not registered. + */ + @Nullable + public ComponentName getCurrentTransportComponent(@UserIdInt int userId) { + UserBackupManagerService userBackupManagerService = + getServiceForUserIfCallerHasPermission(userId, "getCurrentTransportComponent()"); + + return userBackupManagerService == null + ? null + : userBackupManagerService.getCurrentTransportComponent(); + } + + @Override + public String[] listAllTransportsForUser(int userId) throws RemoteException { + return (isUserReadyForBackup(userId)) ? listAllTransports(userId) : null; + } + + /** Report all known, available backup transports by name. */ + @Nullable + public String[] listAllTransports(@UserIdInt int userId) { + UserBackupManagerService userBackupManagerService = + getServiceForUserIfCallerHasPermission(userId, "listAllTransports()"); + + return userBackupManagerService == null + ? null + : userBackupManagerService.listAllTransports(); + } + + @Override + public String[] listAllTransports() throws RemoteException { + return listAllTransportsForUser(binderGetCallingUserId()); + } + + @Override + public ComponentName[] listAllTransportComponentsForUser(int userId) throws RemoteException { + return (isUserReadyForBackup(userId)) + ? listAllTransportComponents(userId) : null; + } + + /** Report all known, available backup transports by {@link ComponentName}. */ + @Nullable + public ComponentName[] listAllTransportComponents(@UserIdInt int userId) { + UserBackupManagerService userBackupManagerService = + getServiceForUserIfCallerHasPermission(userId, "listAllTransportComponents()"); + + return userBackupManagerService == null + ? null + : userBackupManagerService.listAllTransportComponents(); + } + + @Override + public String[] getTransportWhitelist() { + int userId = binderGetCallingUserId(); + if (!isUserReadyForBackup(userId)) { + return null; + } + // No permission check, intentionally. + String[] whitelistedTransports = new String[mTransportWhitelist.size()]; + int i = 0; + for (ComponentName component : mTransportWhitelist) { + whitelistedTransports[i] = component.flattenToShortString(); + i++; + } + return whitelistedTransports; + } + + @Override + public void updateTransportAttributesForUser( + int userId, + ComponentName transportComponent, + String name, + @Nullable Intent configurationIntent, + String currentDestinationString, + @Nullable Intent dataManagementIntent, + CharSequence dataManagementLabel) { + if (isUserReadyForBackup(userId)) { + updateTransportAttributes( + userId, + transportComponent, + name, + configurationIntent, + currentDestinationString, + dataManagementIntent, + dataManagementLabel); + } + } + + /** + * Update the attributes of the transport identified by {@code transportComponent}. If the + * specified transport has not been bound at least once (for registration), this call will be + * ignored. Only the host process of the transport can change its description, otherwise a + * {@link SecurityException} will be thrown. + * + * @param transportComponent The identity of the transport being described. + * @param name A {@link String} with the new name for the transport. This is NOT for + * identification. MUST NOT be {@code null}. + * @param configurationIntent An {@link Intent} that can be passed to {@link + * Context#startActivity} in order to launch the transport's configuration UI. It may be + * {@code null} if the transport does not offer any user-facing configuration UI. + * @param currentDestinationString A {@link String} describing the destination to which the + * transport is currently sending data. MUST NOT be {@code null}. + * @param dataManagementIntent An {@link Intent} that can be passed to {@link + * Context#startActivity} in order to launch the transport's data-management UI. It may be + * {@code null} if the transport does not offer any user-facing data management UI. + * @param dataManagementLabel A {@link CharSequence} to be used as the label for the transport's + * data management affordance. This MUST be {@code null} when dataManagementIntent is {@code + * null} and MUST NOT be {@code null} when dataManagementIntent is not {@code null}. + * @throws SecurityException If the UID of the calling process differs from the package UID of + * {@code transportComponent} or if the caller does NOT have BACKUP permission. + */ + public void updateTransportAttributes( + @UserIdInt int userId, + ComponentName transportComponent, + String name, + @Nullable Intent configurationIntent, + String currentDestinationString, + @Nullable Intent dataManagementIntent, + CharSequence dataManagementLabel) { + UserBackupManagerService userBackupManagerService = + getServiceForUserIfCallerHasPermission(userId, "updateTransportAttributes()"); + + if (userBackupManagerService != null) { + userBackupManagerService.updateTransportAttributes( + transportComponent, + name, + configurationIntent, + currentDestinationString, + dataManagementIntent, + dataManagementLabel); + } + } + + @Override + public String selectBackupTransportForUser(int userId, String transport) + throws RemoteException { + return (isUserReadyForBackup(userId)) + ? selectBackupTransport(userId, transport) : null; + } + + @Override + public String selectBackupTransport(String transport) throws RemoteException { + return selectBackupTransportForUser(binderGetCallingUserId(), transport); + } + + /** + * Selects transport {@code transportName} and returns the previously selected transport. + * + * @deprecated Use {@link #selectBackupTransportAsync(ComponentName, + * ISelectBackupTransportCallback)} instead. + */ + @Deprecated + @Nullable + public String selectBackupTransport(@UserIdInt int userId, String transportName) { + UserBackupManagerService userBackupManagerService = + getServiceForUserIfCallerHasPermission(userId, "selectBackupTransport()"); + + return userBackupManagerService == null + ? null + : userBackupManagerService.selectBackupTransport(transportName); + } + + @Override + public void selectBackupTransportAsyncForUser(int userId, ComponentName transport, + ISelectBackupTransportCallback listener) throws RemoteException { + if (isUserReadyForBackup(userId)) { + selectBackupTransportAsync(userId, transport, listener); + } else { + if (listener != null) { + try { + listener.onFailure(BackupManager.ERROR_BACKUP_NOT_ALLOWED); + } catch (RemoteException ex) { + // ignore + } + } + } + } + + /** + * Selects transport {@code transportComponent} asynchronously and notifies {@code listener} + * with the result upon completion. + */ + public void selectBackupTransportAsync( + @UserIdInt int userId, + ComponentName transportComponent, + ISelectBackupTransportCallback listener) { + UserBackupManagerService userBackupManagerService = + getServiceForUserIfCallerHasPermission(userId, "selectBackupTransportAsync()"); + + if (userBackupManagerService != null) { + userBackupManagerService.selectBackupTransportAsync(transportComponent, listener); + } + } + + @Override + public Intent getConfigurationIntentForUser(int userId, String transport) + throws RemoteException { + return isUserReadyForBackup(userId) ? getConfigurationIntent(userId, transport) + : null; + } + + @Override + public Intent getConfigurationIntent(String transport) + throws RemoteException { + return getConfigurationIntentForUser(binderGetCallingUserId(), transport); + } + + /** + * Supply the configuration intent for the given transport. If the name is not one of the + * available transports, or if the transport does not supply any configuration UI, the method + * returns {@code null}. + */ + @Nullable + public Intent getConfigurationIntent(@UserIdInt int userId, String transportName) { + UserBackupManagerService userBackupManagerService = + getServiceForUserIfCallerHasPermission(userId, "getConfigurationIntent()"); + + return userBackupManagerService == null + ? null + : userBackupManagerService.getConfigurationIntent(transportName); + } + + @Override + public String getDestinationStringForUser(int userId, String transport) throws RemoteException { + return isUserReadyForBackup(userId) ? getDestinationString(userId, transport) + : null; + } + + @Override + public String getDestinationString(String transport) throws RemoteException { + return getDestinationStringForUser(binderGetCallingUserId(), transport); + } + + /** + * Supply the current destination string for the given transport. If the name is not one of the + * registered transports the method will return null. + * + * <p>This string is used VERBATIM as the summary text of the relevant Settings item. + * + * @param transportName The name of the registered transport. + * @return The current destination string or null if the transport is not registered. + */ + @Nullable + public String getDestinationString(@UserIdInt int userId, String transportName) { + UserBackupManagerService userBackupManagerService = + getServiceForUserIfCallerHasPermission(userId, "getDestinationString()"); + + return userBackupManagerService == null + ? null + : userBackupManagerService.getDestinationString(transportName); + } + + @Override + public Intent getDataManagementIntentForUser(int userId, String transport) + throws RemoteException { + return isUserReadyForBackup(userId) + ? getDataManagementIntent(userId, transport) : null; + } + + @Override + public Intent getDataManagementIntent(String transport) + throws RemoteException { + return getDataManagementIntentForUser(binderGetCallingUserId(), transport); + } + + /** Supply the manage-data intent for the given transport. */ + @Nullable + public Intent getDataManagementIntent(@UserIdInt int userId, String transportName) { + UserBackupManagerService userBackupManagerService = + getServiceForUserIfCallerHasPermission(userId, "getDataManagementIntent()"); + + return userBackupManagerService == null + ? null + : userBackupManagerService.getDataManagementIntent(transportName); + } + + @Override + public CharSequence getDataManagementLabelForUser(int userId, String transport) + throws RemoteException { + return isUserReadyForBackup(userId) ? getDataManagementLabel(userId, transport) + : null; + } + + /** + * Supply the menu label for affordances that fire the manage-data intent for the given + * transport. + */ + @Nullable + public CharSequence getDataManagementLabel(@UserIdInt int userId, String transportName) { + UserBackupManagerService userBackupManagerService = + getServiceForUserIfCallerHasPermission(userId, "getDataManagementLabel()"); + + return userBackupManagerService == null + ? null + : userBackupManagerService.getDataManagementLabel(transportName); + } + + @Override + public IRestoreSession beginRestoreSessionForUser( + int userId, String packageName, String transportID) throws RemoteException { + return isUserReadyForBackup(userId) + ? beginRestoreSession(userId, packageName, transportID) : null; + } + + /** + * Begin a restore for the specified package {@code packageName} using the specified transport + * {@code transportName}. + */ + @Nullable + public IRestoreSession beginRestoreSession( + @UserIdInt int userId, String packageName, String transportName) { + UserBackupManagerService userBackupManagerService = + getServiceForUserIfCallerHasPermission(userId, "beginRestoreSession()"); + + return userBackupManagerService == null + ? null + : userBackupManagerService.beginRestoreSession(packageName, transportName); + } + + @Override + public void opCompleteForUser(int userId, int token, long result) throws RemoteException { + if (isUserReadyForBackup(userId)) { + opComplete(userId, token, result); + } + } + + @Override + public void opComplete(int token, long result) throws RemoteException { + opCompleteForUser(binderGetCallingUserId(), token, result); + } + + /** + * Used by a currently-active backup agent to notify the service that it has completed its given + * outstanding asynchronous backup/restore operation. + */ + public void opComplete(@UserIdInt int userId, int token, long result) { + UserBackupManagerService userBackupManagerService = + getServiceForUserIfCallerHasPermission(userId, "opComplete()"); + + if (userBackupManagerService != null) { + userBackupManagerService.opComplete(token, result); + } + } + + @Override + public long getAvailableRestoreTokenForUser(int userId, String packageName) { + return isUserReadyForBackup(userId) ? getAvailableRestoreToken(userId, packageName) : 0; + } + + /** + * Get the restore-set token for the best-available restore set for this {@code packageName}: + * the active set if possible, else the ancestral one. Returns zero if none available. + */ + public long getAvailableRestoreToken(@UserIdInt int userId, String packageName) { + UserBackupManagerService userBackupManagerService = + getServiceForUserIfCallerHasPermission(userId, "getAvailableRestoreToken()"); + + return userBackupManagerService == null + ? 0 + : userBackupManagerService.getAvailableRestoreToken(packageName); + } + + @Override + public boolean isAppEligibleForBackupForUser(int userId, String packageName) { + return isUserReadyForBackup(userId) && isAppEligibleForBackup(userId, + packageName); + } + + /** Checks if the given package {@code packageName} is eligible for backup. */ + public boolean isAppEligibleForBackup(@UserIdInt int userId, String packageName) { + UserBackupManagerService userBackupManagerService = + getServiceForUserIfCallerHasPermission(userId, "isAppEligibleForBackup()"); + + return userBackupManagerService != null + && userBackupManagerService.isAppEligibleForBackup(packageName); + } + + @Override + public String[] filterAppsEligibleForBackupForUser(int userId, String[] packages) { + return isUserReadyForBackup(userId) ? filterAppsEligibleForBackup(userId, packages) : null; + } + + /** + * Returns from the inputted packages {@code packages}, the ones that are eligible for backup. + */ + @Nullable + public String[] filterAppsEligibleForBackup(@UserIdInt int userId, String[] packages) { + UserBackupManagerService userBackupManagerService = + getServiceForUserIfCallerHasPermission(userId, "filterAppsEligibleForBackup()"); + + return userBackupManagerService == null + ? null + : userBackupManagerService.filterAppsEligibleForBackup(packages); + } + + @Override + public int requestBackupForUser(@UserIdInt int userId, String[] packages, IBackupObserver + observer, IBackupManagerMonitor monitor, int flags) throws RemoteException { + if (!isUserReadyForBackup(userId)) { + return BackupManager.ERROR_BACKUP_NOT_ALLOWED; + } + return requestBackup(userId, packages, observer, monitor, flags); + } - /** Instantiate a new instance of {@link BackupManagerService}. */ - public BackupManagerService( - Context context, - Trampoline trampoline, - SparseArray<UserBackupManagerService> userServices) { - mContext = checkNotNull(context); - mTrampoline = checkNotNull(trampoline); - // TODO(b/135661048): Remove - mServiceUsers = userServices; + @Override + public int requestBackup(String[] packages, IBackupObserver observer, + IBackupManagerMonitor monitor, int flags) throws RemoteException { + return requestBackupForUser(binderGetCallingUserId(), packages, + observer, monitor, flags); + } + + /** + * Requests a backup for the inputted {@code packages} with a specified callback {@link + * IBackupManagerMonitor} for receiving events during the operation. + */ + public int requestBackup( + @UserIdInt int userId, + String[] packages, + IBackupObserver observer, + IBackupManagerMonitor monitor, + int flags) { + UserBackupManagerService userBackupManagerService = + getServiceForUserIfCallerHasPermission(userId, "requestBackup()"); + + return userBackupManagerService == null + ? BackupManager.ERROR_BACKUP_NOT_ALLOWED + : userBackupManagerService.requestBackup(packages, observer, monitor, flags); + } + + @Override + public void cancelBackupsForUser(@UserIdInt int userId) throws RemoteException { + if (isUserReadyForBackup(userId)) { + cancelBackups(userId); + } + } + + @Override + public void cancelBackups() throws RemoteException { + cancelBackupsForUser(binderGetCallingUserId()); + } + + /** Cancel all running backup operations. */ + public void cancelBackups(@UserIdInt int userId) { + UserBackupManagerService userBackupManagerService = + getServiceForUserIfCallerHasPermission(userId, "cancelBackups()"); + + if (userBackupManagerService != null) { + userBackupManagerService.cancelBackups(); + } + } + + /** + * Returns a {@link UserHandle} for the user that has {@code ancestralSerialNumber} as the + * serial number of its ancestral work profile or null if there is no {@link + * UserBackupManagerService} associated with that user. + * + * <p> The ancestral work profile is set by {@link #setAncestralSerialNumber(long)} + * and it corresponds to the profile that was used to restore to the callers profile. + */ + @Override + @Nullable + public UserHandle getUserForAncestralSerialNumber(long ancestralSerialNumber) { + if (mGlobalDisable) { + return null; + } + int callingUserId = Binder.getCallingUserHandle().getIdentifier(); + long oldId = Binder.clearCallingIdentity(); + final int[] userIds; + try { + userIds = + mContext + .getSystemService(UserManager.class) + .getProfileIds(callingUserId, false); + } finally { + Binder.restoreCallingIdentity(oldId); + } + + for (int userId : userIds) { + UserBackupManagerService userBackupManagerService = mUserServices.get(userId); + if (userBackupManagerService != null) { + if (userBackupManagerService.getAncestralSerialNumber() == ancestralSerialNumber) { + return UserHandle.of(userId); + } + } + } + + return null; + } + + /** + * Sets the ancestral work profile for the calling user. + * + * <p> The ancestral work profile corresponds to the profile that was used to restore to the + * callers profile. + */ + @Override + public void setAncestralSerialNumber(long ancestralSerialNumber) { + if (mGlobalDisable) { + return; + } + UserBackupManagerService userBackupManagerService = + getServiceForUserIfCallerHasPermission( + Binder.getCallingUserHandle().getIdentifier(), + "setAncestralSerialNumber()"); + + if (userBackupManagerService != null) { + userBackupManagerService.setAncestralSerialNumber(ancestralSerialNumber); + } + } + + @Override + public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { + if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) { + return; + } + int userId = binderGetCallingUserId(); + if (!isUserReadyForBackup(userId)) { + pw.println("Inactive"); + return; + } + + if (args != null) { + for (String arg : args) { + if ("users".equals(arg.toLowerCase())) { + pw.print(DUMP_RUNNING_USERS_MESSAGE); + for (int i = 0; i < mUserServices.size(); i++) { + pw.print(" " + mUserServices.keyAt(i)); + } + pw.println(); + return; + } + } + } + + UserBackupManagerService userBackupManagerService = + getServiceForUserIfCallerHasPermission(UserHandle.USER_SYSTEM, "dump()"); + + if (userBackupManagerService != null) { + userBackupManagerService.dump(fd, pw, args); + } + } + + /** + * Used by the {@link JobScheduler} to run a full backup when conditions are right. The model we + * use is to perform one app backup per scheduled job execution, and to reschedule the job with + * zero latency as long as conditions remain right and we still have work to do. + * + * @return Whether ongoing work will continue. The return value here will be passed along as the + * return value to the callback {@link JobService#onStartJob(JobParameters)}. + */ + public boolean beginFullBackup(@UserIdInt int userId, FullBackupJob scheduledJob) { + if (!isUserReadyForBackup(userId)) { + return false; + } + UserBackupManagerService userBackupManagerService = + getServiceForUserIfCallerHasPermission(userId, "beginFullBackup()"); + + return userBackupManagerService != null + && userBackupManagerService.beginFullBackup(scheduledJob); + } + + /** + * Used by the {@link JobScheduler} to end the current full backup task when conditions are no + * longer met for running the full backup job. + */ + public void endFullBackup(@UserIdInt int userId) { + if (!isUserReadyForBackup(userId)) { + return; + } + UserBackupManagerService userBackupManagerService = + getServiceForUserIfCallerHasPermission(userId, "endFullBackup()"); + + if (userBackupManagerService != null) { + userBackupManagerService.endFullBackup(); + } + } + + /** + * Returns the {@link UserBackupManagerService} instance for the specified user {@code userId}. + * If the user is not registered with the service (either the user is locked or not eligible for + * the backup service) then return {@code null}. + * + * @param userId The id of the user to retrieve its instance of {@link + * UserBackupManagerService}. + * @param caller A {@link String} identifying the caller for logging purposes. + * @throws SecurityException if {@code userId} is different from the calling user id and the + * caller does NOT have the android.permission.INTERACT_ACROSS_USERS_FULL permission. + */ + @Nullable + @VisibleForTesting + UserBackupManagerService getServiceForUserIfCallerHasPermission( + @UserIdInt int userId, String caller) { + enforceCallingPermissionOnUserId(userId, caller); + UserBackupManagerService userBackupManagerService = mUserServices.get(userId); + if (userBackupManagerService == null) { + Slog.w(TAG, "Called " + caller + " for unknown user: " + userId); + } + return userBackupManagerService; + } + + /** + * 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. + */ + void enforceCallingPermissionOnUserId(@UserIdInt int userId, String message) { + if (Binder.getCallingUserHandle().getIdentifier() != userId) { + mContext.enforceCallingOrSelfPermission( + Manifest.permission.INTERACT_ACROSS_USERS_FULL, message); + } } /** Implementation to receive lifecycle event callbacks for system services. */ public static class Lifecycle extends SystemService { public Lifecycle(Context context) { - this(context, new Trampoline(context)); + this(context, new BackupManagerService(context)); } @VisibleForTesting - Lifecycle(Context context, Trampoline trampoline) { + Lifecycle(Context context, BackupManagerService backupManagerService) { super(context); - Trampoline.sInstance = trampoline; + sInstance = backupManagerService; } @Override public void onStart() { - publishService(Context.BACKUP_SERVICE, Trampoline.sInstance); + publishService(Context.BACKUP_SERVICE, BackupManagerService.sInstance); } @Override public void onUnlockUser(int userId) { - Trampoline.sInstance.onUnlockUser(userId); + sInstance.onUnlockUser(userId); } @Override public void onStopUser(int userId) { - Trampoline.sInstance.onStopUser(userId); + sInstance.onStopUser(userId); } @VisibleForTesting diff --git a/services/backup/java/com/android/server/backup/FullBackupJob.java b/services/backup/java/com/android/server/backup/FullBackupJob.java index 19a85432875c..0bb25e360f15 100644 --- a/services/backup/java/com/android/server/backup/FullBackupJob.java +++ b/services/backup/java/com/android/server/backup/FullBackupJob.java @@ -91,7 +91,7 @@ public class FullBackupJob extends JobService { mParamsForUser.put(userId, params); } - Trampoline service = Trampoline.getInstance(); + BackupManagerService service = BackupManagerService.getInstance(); return service.beginFullBackup(userId, this); } @@ -105,7 +105,7 @@ public class FullBackupJob extends JobService { } } - Trampoline service = Trampoline.getInstance(); + BackupManagerService service = BackupManagerService.getInstance(); service.endFullBackup(userId); return false; diff --git a/services/backup/java/com/android/server/backup/KeyValueBackupJob.java b/services/backup/java/com/android/server/backup/KeyValueBackupJob.java index 7b5dbd7ce777..058dcae3102f 100644 --- a/services/backup/java/com/android/server/backup/KeyValueBackupJob.java +++ b/services/backup/java/com/android/server/backup/KeyValueBackupJob.java @@ -144,7 +144,7 @@ public class KeyValueBackupJob extends JobService { } // Time to run a key/value backup! - Trampoline service = Trampoline.getInstance(); + BackupManagerService service = BackupManagerService.getInstance(); try { service.backupNowForUser(userId); } catch (RemoteException e) {} diff --git a/services/backup/java/com/android/server/backup/Trampoline.java b/services/backup/java/com/android/server/backup/Trampoline.java deleted file mode 100644 index 4cd1e17ca578..000000000000 --- a/services/backup/java/com/android/server/backup/Trampoline.java +++ /dev/null @@ -1,1549 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.backup; - -import static com.android.internal.util.Preconditions.checkNotNull; -import static com.android.server.backup.BackupManagerService.TAG; - -import static java.util.Collections.emptySet; - -import android.Manifest; -import android.annotation.Nullable; -import android.annotation.UserIdInt; -import android.app.ActivityManager; -import android.app.admin.DevicePolicyManager; -import android.app.backup.BackupManager; -import android.app.backup.IBackupManager; -import android.app.backup.IBackupManagerMonitor; -import android.app.backup.IBackupObserver; -import android.app.backup.IFullBackupRestoreObserver; -import android.app.backup.IRestoreSession; -import android.app.backup.ISelectBackupTransportCallback; -import android.app.job.JobParameters; -import android.app.job.JobScheduler; -import android.app.job.JobService; -import android.content.BroadcastReceiver; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.pm.PackageManager; -import android.os.Binder; -import android.os.FileUtils; -import android.os.Handler; -import android.os.HandlerThread; -import android.os.IBinder; -import android.os.ParcelFileDescriptor; -import android.os.Process; -import android.os.RemoteException; -import android.os.SystemProperties; -import android.os.Trace; -import android.os.UserHandle; -import android.os.UserManager; -import android.util.Slog; -import android.util.SparseArray; - -import com.android.internal.annotations.GuardedBy; -import com.android.internal.annotations.VisibleForTesting; -import com.android.internal.util.DumpUtils; -import com.android.server.SystemConfig; -import com.android.server.backup.utils.RandomAccessFileUtils; - -import java.io.File; -import java.io.FileDescriptor; -import java.io.IOException; -import java.io.PrintWriter; -import java.util.Set; - -/** - * A proxy to the {@link BackupManagerService} implementation. - * - * <p>This is an external interface to the {@link BackupManagerService} which is being accessed via - * published binder {@link BackupManagerService.Lifecycle}. This lets us turn down the heavy - * implementation object on the fly without disturbing binders that have been cached somewhere in - * the system. - * - * <p>Trampoline determines whether the backup service is available. It can be disabled in the - * following two ways: - * - * <ul> - * <li>Temporary - create the file {@link #BACKUP_SUPPRESS_FILENAME}, or - * <li>Permanent - set the system property {@link #BACKUP_DISABLE_PROPERTY} to true. - * </ul> - * - * Temporary disabling is controlled by {@link #setBackupServiceActive(int, boolean)} through - * privileged callers (currently {@link DevicePolicyManager}). This is called on {@link - * UserHandle#USER_SYSTEM} and disables backup for all users. - */ -public class Trampoline extends IBackupManager.Stub { - @VisibleForTesting - static final String DUMP_RUNNING_USERS_MESSAGE = "Backup Manager is running for users:"; - - /** - * Name of file that disables the backup service. If this file exists, then backup is disabled - * for all users. - */ - private static final String BACKUP_SUPPRESS_FILENAME = "backup-suppress"; - - /** - * Name of file for non-system users that enables the backup service for the user. Backup is - * disabled by default in non-system users. - */ - private static final String BACKUP_ACTIVATED_FILENAME = "backup-activated"; - - /** - * Name of file for non-system users that remembers whether backup was explicitly activated or - * deactivated with a call to setBackupServiceActive. - */ - private static final String REMEMBER_ACTIVATED_FILENAME = "backup-remember-activated"; - - // Product-level suppression of backup/restore. - private static final String BACKUP_DISABLE_PROPERTY = "ro.backup.disable"; - - private static final String BACKUP_THREAD = "backup"; - - static Trampoline sInstance; - - static Trampoline getInstance() { - return checkNotNull(sInstance); - } - - private final Context mContext; - private final UserManager mUserManager; - - private final boolean mGlobalDisable; - // Lock to write backup suppress files. - // TODD(b/121198006): remove this object and synchronized all methods on "this". - private final Object mStateLock = new Object(); - - // TODO: This is not marked as final because of test code. Since we'll merge BMS and Trampoline, - // it doesn't make sense to refactor for final. It's never null. - @VisibleForTesting - protected volatile BackupManagerService mService; - private final Handler mHandler; - private final Set<ComponentName> mTransportWhitelist; - - /** Keeps track of all unlocked users registered with this service. Indexed by user id. */ - private final SparseArray<UserBackupManagerService> mUserServices; - - private final BroadcastReceiver mUserRemovedReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - if (Intent.ACTION_USER_REMOVED.equals(intent.getAction())) { - int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL); - if (userId > 0) { // for only non system users - mHandler.post(() -> onRemovedNonSystemUser(userId)); - } - } - } - }; - - public Trampoline(Context context) { - this(context, new SparseArray<>()); - } - - @VisibleForTesting - Trampoline(Context context, SparseArray<UserBackupManagerService> userServices) { - mContext = context; - mGlobalDisable = isBackupDisabled(); - HandlerThread handlerThread = - new HandlerThread(BACKUP_THREAD, Process.THREAD_PRIORITY_BACKGROUND); - handlerThread.start(); - mHandler = new Handler(handlerThread.getLooper()); - mUserManager = UserManager.get(context); - mUserServices = userServices; - mService = new BackupManagerService(mContext, this, mUserServices); - Set<ComponentName> transportWhitelist = - SystemConfig.getInstance().getBackupTransportWhitelist(); - mTransportWhitelist = (transportWhitelist == null) ? emptySet() : transportWhitelist; - mContext.registerReceiver( - mUserRemovedReceiver, new IntentFilter(Intent.ACTION_USER_REMOVED)); - } - - // TODO: Remove this when we implement DI by injecting in the construtor. - @VisibleForTesting - Handler getBackupHandler() { - return mHandler; - } - - protected boolean isBackupDisabled() { - return SystemProperties.getBoolean(BACKUP_DISABLE_PROPERTY, false); - } - - protected int binderGetCallingUserId() { - return Binder.getCallingUserHandle().getIdentifier(); - } - - protected int binderGetCallingUid() { - return Binder.getCallingUid(); - } - - /** Stored in the system user's directory. */ - protected File getSuppressFileForSystemUser() { - return new File(UserBackupManagerFiles.getBaseStateDir(UserHandle.USER_SYSTEM), - BACKUP_SUPPRESS_FILENAME); - } - - /** Stored in the system user's directory and the file is indexed by the user it refers to. */ - protected File getRememberActivatedFileForNonSystemUser(int userId) { - return UserBackupManagerFiles.getStateFileInSystemDir(REMEMBER_ACTIVATED_FILENAME, userId); - } - - /** Stored in the system user's directory and the file is indexed by the user it refers to. */ - protected File getActivatedFileForNonSystemUser(int userId) { - return UserBackupManagerFiles.getStateFileInSystemDir(BACKUP_ACTIVATED_FILENAME, userId); - } - - /** - * Remove backup state for non system {@code userId} when the user is removed from the device. - * For non system users, backup state is stored in both the user's own dir and the system dir. - * When the user is removed, the user's own dir gets removed by the OS. This method ensures that - * the part of the user backup state which is in the system dir also gets removed. - */ - private void onRemovedNonSystemUser(int userId) { - Slog.i(TAG, "Removing state for non system user " + userId); - File dir = UserBackupManagerFiles.getStateDirInSystemDir(userId); - if (!FileUtils.deleteContentsAndDir(dir)) { - Slog.w(TAG, "Failed to delete state dir for removed user: " + userId); - } - } - - // TODO (b/124359804) move to util method in FileUtils - private void createFile(File file) throws IOException { - if (file.exists()) { - return; - } - - file.getParentFile().mkdirs(); - if (!file.createNewFile()) { - Slog.w(TAG, "Failed to create file " + file.getPath()); - } - } - - // TODO (b/124359804) move to util method in FileUtils - private void deleteFile(File file) { - if (!file.exists()) { - return; - } - - if (!file.delete()) { - Slog.w(TAG, "Failed to delete file " + file.getPath()); - } - } - - /** - * Deactivates the backup service for user {@code userId}. If this is the system user, it - * creates a suppress file which disables backup for all users. If this is a non-system user, it - * only deactivates backup for that user by deleting its activate file. - */ - @GuardedBy("mStateLock") - private void deactivateBackupForUserLocked(int userId) throws IOException { - if (userId == UserHandle.USER_SYSTEM) { - createFile(getSuppressFileForSystemUser()); - } else { - deleteFile(getActivatedFileForNonSystemUser(userId)); - } - } - - /** - * Enables the backup service for user {@code userId}. If this is the system user, it deletes - * the suppress file. If this is a non-system user, it creates the user's activate file. Note, - * deleting the suppress file does not automatically enable backup for non-system users, they - * need their own activate file in order to participate in the service. - */ - @GuardedBy("mStateLock") - private void activateBackupForUserLocked(int userId) throws IOException { - if (userId == UserHandle.USER_SYSTEM) { - deleteFile(getSuppressFileForSystemUser()); - } else { - createFile(getActivatedFileForNonSystemUser(userId)); - } - } - - // This method should not perform any I/O (e.g. do not call isBackupActivatedForUser), - // it's used in multiple places where I/O waits would cause system lock-ups. - private boolean isUserReadyForBackup(int userId) { - return mUserServices.get(UserHandle.USER_SYSTEM) != null - && mUserServices.get(userId) != null; - } - - /** - * Backup is activated for the system user if the suppress file does not exist. Backup is - * activated for non-system users if the suppress file does not exist AND the user's activated - * file exists. - */ - private boolean isBackupActivatedForUser(int userId) { - if (getSuppressFileForSystemUser().exists()) { - return false; - } - - return userId == UserHandle.USER_SYSTEM - || getActivatedFileForNonSystemUser(userId).exists(); - } - - protected Context getContext() { - return mContext; - } - - protected UserManager getUserManager() { - return mUserManager; - } - - protected void postToHandler(Runnable runnable) { - mHandler.post(runnable); - } - - /** - * 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. - */ - 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. - */ - @VisibleForTesting - void startServiceForUser(int userId) { - // We know that the user is unlocked here because it is called from setBackupServiceActive - // and unlockUser which have these guarantees. So we can check if the file exists. - if (mGlobalDisable) { - Slog.i(TAG, "Backup service not supported"); - return; - } - if (!isBackupActivatedForUser(userId)) { - Slog.i(TAG, "Backup not activated for user " + userId); - return; - } - if (mUserServices.get(userId) != null) { - Slog.i(TAG, "userId " + userId + " already started, so not starting again"); - return; - } - Slog.i(TAG, "Starting service for user: " + userId); - UserBackupManagerService userBackupManagerService = - UserBackupManagerService.createAndInitializeService( - userId, mContext, this, mTransportWhitelist); - startServiceForUser(userId, userBackupManagerService); - } - - /** - * Starts the backup service for user {@code userId} by registering its instance of {@link - * UserBackupManagerService} with this service and setting enabled state. - */ - void startServiceForUser(int userId, UserBackupManagerService userBackupManagerService) { - mUserServices.put(userId, userBackupManagerService); - - Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backup enable"); - userBackupManagerService.initializeBackupEnableState(); - Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); - } - - /** Stops the backup service for user {@code userId} when the user is stopped. */ - @VisibleForTesting - protected void stopServiceForUser(int userId) { - UserBackupManagerService userBackupManagerService = mUserServices.removeReturnOld(userId); - - if (userBackupManagerService != null) { - userBackupManagerService.tearDownService(); - - KeyValueBackupJob.cancel(userId, mContext); - FullBackupJob.cancel(userId, mContext); - } - } - - /** - * Returns a list of users currently unlocked that have a {@link UserBackupManagerService} - * registered. - * - * Warning: Do NOT modify returned object as it's used inside. - * - * TODO: Return a copy or only expose read-only information through other means. - */ - @VisibleForTesting - SparseArray<UserBackupManagerService> getUserServices() { - return mUserServices; - } - - /** - * Called from {@link BackupManagerService.Lifecycle} when a user {@code userId} is stopped. - * Offloads work onto the handler thread {@link #mHandlerThread} to keep stopping time low. - */ - void onStopUser(int userId) { - postToHandler( - () -> { - if (!mGlobalDisable) { - Slog.i(TAG, "Stopping service for user: " + userId); - stopServiceForUser(userId); - } - }); - } - - /** Returns {@link UserBackupManagerService} for user {@code userId}. */ - @Nullable - public UserBackupManagerService getUserService(int userId) { - return mUserServices.get(userId); - } - - /** - * The system user and managed profiles can only be acted on by callers in the system or root - * processes. Other users can be acted on by callers who have both android.permission.BACKUP and - * android.permission.INTERACT_ACROSS_USERS_FULL permissions. - */ - private void enforcePermissionsOnUser(int userId) throws SecurityException { - boolean isRestrictedUser = - userId == UserHandle.USER_SYSTEM - || getUserManager().getUserInfo(userId).isManagedProfile(); - - if (isRestrictedUser) { - int caller = binderGetCallingUid(); - if (caller != Process.SYSTEM_UID && caller != Process.ROOT_UID) { - throw new SecurityException("No permission to configure backup activity"); - } - } else { - mContext.enforceCallingOrSelfPermission( - Manifest.permission.BACKUP, "No permission to configure backup activity"); - mContext.enforceCallingOrSelfPermission( - Manifest.permission.INTERACT_ACROSS_USERS_FULL, - "No permission to configure backup activity"); - } - } - - /** - * Only privileged callers should be changing the backup state. Deactivating backup in the - * system user also deactivates backup in all users. We are not guaranteed that {@code userId} - * is unlocked at this point yet, so handle both cases. - */ - public void setBackupServiceActive(int userId, boolean makeActive) { - enforcePermissionsOnUser(userId); - - // In Q, backup is OFF by default for non-system users. In the future, we will change that - // to ON unless backup was explicitly deactivated with a (permissioned) call to - // setBackupServiceActive. - // Therefore, remember this for use in the future. Basically the default in the future will - // be: rememberFile.exists() ? rememberFile.value() : ON - // Note that this has to be done right after the permission checks and before any other - // action since we need to remember that a permissioned call was made irrespective of - // whether the call changes the state or not. - if (userId != UserHandle.USER_SYSTEM) { - try { - File rememberFile = getRememberActivatedFileForNonSystemUser(userId); - createFile(rememberFile); - RandomAccessFileUtils.writeBoolean(rememberFile, makeActive); - } catch (IOException e) { - Slog.e(TAG, "Unable to persist backup service activity", e); - } - } - - if (mGlobalDisable) { - Slog.i(TAG, "Backup service not supported"); - return; - } - - synchronized (mStateLock) { - Slog.i(TAG, "Making backup " + (makeActive ? "" : "in") + "active"); - if (makeActive) { - try { - activateBackupForUserLocked(userId); - } catch (IOException e) { - Slog.e(TAG, "Unable to persist backup service activity"); - } - - // If the user is unlocked, we can start the backup service for it. Otherwise we - // will start the service when the user is unlocked as part of its unlock callback. - if (getUserManager().isUserUnlocked(userId)) { - // Clear calling identity as initialization enforces the system identity but we - // can be coming from shell. - long oldId = Binder.clearCallingIdentity(); - try { - startServiceForUser(userId); - } finally { - Binder.restoreCallingIdentity(oldId); - } - } - } else { - try { - //TODO(b/121198006): what if this throws an exception? - deactivateBackupForUserLocked(userId); - } catch (IOException e) { - Slog.e(TAG, "Unable to persist backup service inactivity"); - } - //TODO(b/121198006): loop through active users that have work profile and - // stop them as well. - onStopUser(userId); - } - } - } - - // IBackupManager binder API - - /** - * Querying activity state of backup service. - * - * @param userId The user in which the activity state of backup service is queried. - * @return true if the service is active. - */ - @Override - public boolean isBackupServiceActive(int userId) { - synchronized (mStateLock) { - return !mGlobalDisable && isBackupActivatedForUser(userId); - } - } - - @Override - public void dataChangedForUser(int userId, String packageName) throws RemoteException { - if (isUserReadyForBackup(userId)) { - dataChanged(userId, packageName); - } - } - - @Override - public void dataChanged(String packageName) throws RemoteException { - dataChangedForUser(binderGetCallingUserId(), packageName); - } - - /** - * An app's backup agent calls this method to let the service know that there's new data to - * backup for their app {@code packageName}. Only used for apps participating in key-value - * backup. - */ - public void dataChanged(@UserIdInt int userId, String packageName) { - UserBackupManagerService userBackupManagerService = - getServiceForUserIfCallerHasPermission(userId, "dataChanged()"); - - if (userBackupManagerService != null) { - userBackupManagerService.dataChanged(packageName); - } - } - - // --------------------------------------------- - // TRANSPORT OPERATIONS - // --------------------------------------------- - - @Override - public void initializeTransportsForUser( - int userId, String[] transportNames, IBackupObserver observer) throws RemoteException { - if (isUserReadyForBackup(userId)) { - initializeTransports(userId, transportNames, observer); - } - } - - /** Run an initialize operation for the given transports {@code transportNames}. */ - public void initializeTransports( - @UserIdInt int userId, String[] transportNames, IBackupObserver observer) { - UserBackupManagerService userBackupManagerService = - getServiceForUserIfCallerHasPermission(userId, "initializeTransports()"); - - if (userBackupManagerService != null) { - userBackupManagerService.initializeTransports(transportNames, observer); - } - } - - @Override - public void clearBackupDataForUser(int userId, String transportName, String packageName) - throws RemoteException { - if (isUserReadyForBackup(userId)) { - clearBackupData(userId, transportName, packageName); - } - } - - /** - * Clear the given package {@code packageName}'s backup data from the transport {@code - * transportName}. - */ - public void clearBackupData(@UserIdInt int userId, String transportName, String packageName) { - UserBackupManagerService userBackupManagerService = - getServiceForUserIfCallerHasPermission(userId, "clearBackupData()"); - - if (userBackupManagerService != null) { - userBackupManagerService.clearBackupData(transportName, packageName); - } - } - - @Override - public void clearBackupData(String transportName, String packageName) - throws RemoteException { - clearBackupDataForUser(binderGetCallingUserId(), transportName, packageName); - } - - @Override - public void agentConnectedForUser(int userId, String packageName, IBinder agent) - throws RemoteException { - if (isUserReadyForBackup(userId)) { - agentConnected(userId, packageName, agent); - } - } - - @Override - public void agentConnected(String packageName, IBinder agent) throws RemoteException { - agentConnectedForUser(binderGetCallingUserId(), packageName, agent); - } - - /** - * Callback: a requested backup agent has been instantiated. This should only be called from the - * {@link ActivityManager}. - */ - public void agentConnected(@UserIdInt int userId, String packageName, IBinder agentBinder) { - UserBackupManagerService userBackupManagerService = - getServiceForUserIfCallerHasPermission(userId, "agentConnected()"); - - if (userBackupManagerService != null) { - userBackupManagerService.agentConnected(packageName, agentBinder); - } - } - - @Override - public void agentDisconnectedForUser(int userId, String packageName) throws RemoteException { - if (isUserReadyForBackup(userId)) { - agentDisconnected(userId, packageName); - } - } - - @Override - public void agentDisconnected(String packageName) throws RemoteException { - agentDisconnectedForUser(binderGetCallingUserId(), packageName); - } - - /** - * Callback: a backup agent has failed to come up, or has unexpectedly quit. This should only be - * called from the {@link ActivityManager}. - */ - public void agentDisconnected(@UserIdInt int userId, String packageName) { - UserBackupManagerService userBackupManagerService = - getServiceForUserIfCallerHasPermission(userId, "agentDisconnected()"); - - if (userBackupManagerService != null) { - userBackupManagerService.agentDisconnected(packageName); - } - } - - @Override - public void restoreAtInstallForUser(int userId, String packageName, int token) - throws RemoteException { - if (isUserReadyForBackup(userId)) { - restoreAtInstall(userId, packageName, token); - } - } - - @Override - public void restoreAtInstall(String packageName, int token) throws RemoteException { - restoreAtInstallForUser(binderGetCallingUserId(), packageName, token); - } - - /** - * Used to run a restore pass for an application that is being installed. This should only be - * called from the {@link PackageManager}. - */ - public void restoreAtInstall(@UserIdInt int userId, String packageName, int token) { - UserBackupManagerService userBackupManagerService = - getServiceForUserIfCallerHasPermission(userId, "restoreAtInstall()"); - - if (userBackupManagerService != null) { - userBackupManagerService.restoreAtInstall(packageName, token); - } - } - - @Override - public void setBackupEnabledForUser(@UserIdInt int userId, boolean isEnabled) - throws RemoteException { - if (isUserReadyForBackup(userId)) { - setBackupEnabled(userId, isEnabled); - } - } - - @Override - public void setBackupEnabled(boolean isEnabled) throws RemoteException { - setBackupEnabledForUser(binderGetCallingUserId(), isEnabled); - } - - /** Enable/disable the backup service. This is user-configurable via backup settings. */ - public void setBackupEnabled(@UserIdInt int userId, boolean enable) { - UserBackupManagerService userBackupManagerService = - getServiceForUserIfCallerHasPermission(userId, "setBackupEnabled()"); - - if (userBackupManagerService != null) { - userBackupManagerService.setBackupEnabled(enable); - } - } - - @Override - public void setAutoRestoreForUser(int userId, boolean doAutoRestore) throws RemoteException { - if (isUserReadyForBackup(userId)) { - setAutoRestore(userId, doAutoRestore); - } - } - - @Override - public void setAutoRestore(boolean doAutoRestore) throws RemoteException { - setAutoRestoreForUser(binderGetCallingUserId(), doAutoRestore); - } - - /** Enable/disable automatic restore of app data at install time. */ - public void setAutoRestore(@UserIdInt int userId, boolean autoRestore) { - UserBackupManagerService userBackupManagerService = - getServiceForUserIfCallerHasPermission(userId, "setAutoRestore()"); - - if (userBackupManagerService != null) { - userBackupManagerService.setAutoRestore(autoRestore); - } - } - - @Override - public boolean isBackupEnabledForUser(@UserIdInt int userId) throws RemoteException { - return isUserReadyForBackup(userId) && isBackupEnabled(userId); - } - - @Override - public boolean isBackupEnabled() throws RemoteException { - return isBackupEnabledForUser(binderGetCallingUserId()); - } - - /** - * Return {@code true} if the backup mechanism is currently enabled, else returns {@code false}. - */ - public boolean isBackupEnabled(@UserIdInt int userId) { - UserBackupManagerService userBackupManagerService = - getServiceForUserIfCallerHasPermission(userId, "isBackupEnabled()"); - - return userBackupManagerService != null && userBackupManagerService.isBackupEnabled(); - } - - /** Sets the backup password used when running adb backup. */ - @Override - public boolean setBackupPassword(String currentPassword, String newPassword) { - int userId = binderGetCallingUserId(); - 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(); - if (!isUserReadyForBackup(userId)) { - return false; - } - UserBackupManagerService userBackupManagerService = - getServiceForUserIfCallerHasPermission( - UserHandle.USER_SYSTEM, "hasBackupPassword()"); - - return userBackupManagerService != null && userBackupManagerService.hasBackupPassword(); - } - - @Override - public void backupNowForUser(@UserIdInt int userId) throws RemoteException { - if (isUserReadyForBackup(userId)) { - backupNow(userId); - } - } - - @Override - public void backupNow() throws RemoteException { - backupNowForUser(binderGetCallingUserId()); - } - - /** - * Run a backup pass immediately for any key-value backup applications that have declared that - * they have pending updates. - */ - public void backupNow(@UserIdInt int userId) { - UserBackupManagerService userBackupManagerService = - getServiceForUserIfCallerHasPermission(userId, "backupNow()"); - - if (userBackupManagerService != null) { - userBackupManagerService.backupNow(); - } - } - - /** - * 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); - } - } - - @Override - public void fullTransportBackupForUser(int userId, String[] packageNames) - throws RemoteException { - if (isUserReadyForBackup(userId)) { - fullTransportBackup(userId, packageNames); - } - } - - /** - * Run a full backup pass for the given packages {@code packageNames}. Used by 'adb shell bmgr'. - */ - public void fullTransportBackup(@UserIdInt int userId, String[] packageNames) { - UserBackupManagerService userBackupManagerService = - getServiceForUserIfCallerHasPermission(userId, "fullTransportBackup()"); - - if (userBackupManagerService != null) { - userBackupManagerService.fullTransportBackup(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. - */ - @Override - public void adbRestore(@UserIdInt int userId, ParcelFileDescriptor fd) { - if (!isUserReadyForBackup(userId)) { - return; - } - UserBackupManagerService userBackupManagerService = - getServiceForUserIfCallerHasPermission(userId, "adbRestore()"); - - if (userBackupManagerService != null) { - userBackupManagerService.adbRestore(fd); - } - } - - @Override - public void acknowledgeFullBackupOrRestoreForUser( - int userId, - int token, - boolean allow, - String curPassword, - String encryptionPassword, - IFullBackupRestoreObserver observer) - throws RemoteException { - if (isUserReadyForBackup(userId)) { - 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) - throws RemoteException { - acknowledgeFullBackupOrRestoreForUser( - binderGetCallingUserId(), token, allow, curPassword, encryptionPassword, observer); - } - - - @Override - public String getCurrentTransportForUser(int userId) throws RemoteException { - return (isUserReadyForBackup(userId)) ? getCurrentTransport(userId) : null; - } - - @Override - public String getCurrentTransport() throws RemoteException { - return getCurrentTransportForUser(binderGetCallingUserId()); - } - - /** Return the name of the currently active transport. */ - @Nullable - public String getCurrentTransport(@UserIdInt int userId) { - UserBackupManagerService userBackupManagerService = - getServiceForUserIfCallerHasPermission(userId, "getCurrentTransport()"); - - return userBackupManagerService == null - ? null - : userBackupManagerService.getCurrentTransport(); - } - - /** - * Returns the {@link ComponentName} of the host service of the selected transport or - * {@code null} if no transport selected or if the transport selected is not registered. - */ - @Override - @Nullable - public ComponentName getCurrentTransportComponentForUser(int userId) { - return (isUserReadyForBackup(userId)) ? getCurrentTransportComponent(userId) : null; - } - - /** - * Returns the {@link ComponentName} of the host service of the selected transport or {@code - * null} if no transport selected or if the transport selected is not registered. - */ - @Nullable - public ComponentName getCurrentTransportComponent(@UserIdInt int userId) { - UserBackupManagerService userBackupManagerService = - getServiceForUserIfCallerHasPermission(userId, "getCurrentTransportComponent()"); - - return userBackupManagerService == null - ? null - : userBackupManagerService.getCurrentTransportComponent(); - } - - @Override - public String[] listAllTransportsForUser(int userId) throws RemoteException { - return (isUserReadyForBackup(userId)) ? listAllTransports(userId) : null; - } - - /** Report all known, available backup transports by name. */ - @Nullable - public String[] listAllTransports(@UserIdInt int userId) { - UserBackupManagerService userBackupManagerService = - getServiceForUserIfCallerHasPermission(userId, "listAllTransports()"); - - return userBackupManagerService == null - ? null - : userBackupManagerService.listAllTransports(); - } - - @Override - public String[] listAllTransports() throws RemoteException { - return listAllTransportsForUser(binderGetCallingUserId()); - } - - @Override - public ComponentName[] listAllTransportComponentsForUser(int userId) throws RemoteException { - return (isUserReadyForBackup(userId)) - ? listAllTransportComponents(userId) : null; - } - - /** Report all known, available backup transports by {@link ComponentName}. */ - @Nullable - public ComponentName[] listAllTransportComponents(@UserIdInt int userId) { - UserBackupManagerService userBackupManagerService = - getServiceForUserIfCallerHasPermission(userId, "listAllTransportComponents()"); - - return userBackupManagerService == null - ? null - : userBackupManagerService.listAllTransportComponents(); - } - - @Override - public String[] getTransportWhitelist() { - int userId = binderGetCallingUserId(); - if (!isUserReadyForBackup(userId)) { - return null; - } - // No permission check, intentionally. - String[] whitelistedTransports = new String[mTransportWhitelist.size()]; - int i = 0; - for (ComponentName component : mTransportWhitelist) { - whitelistedTransports[i] = component.flattenToShortString(); - i++; - } - return whitelistedTransports; - } - - @Override - public void updateTransportAttributesForUser( - int userId, - ComponentName transportComponent, - String name, - @Nullable Intent configurationIntent, - String currentDestinationString, - @Nullable Intent dataManagementIntent, - CharSequence dataManagementLabel) { - if (isUserReadyForBackup(userId)) { - updateTransportAttributes( - userId, - transportComponent, - name, - configurationIntent, - currentDestinationString, - dataManagementIntent, - dataManagementLabel); - } - } - - /** - * Update the attributes of the transport identified by {@code transportComponent}. If the - * specified transport has not been bound at least once (for registration), this call will be - * ignored. Only the host process of the transport can change its description, otherwise a - * {@link SecurityException} will be thrown. - * - * @param transportComponent The identity of the transport being described. - * @param name A {@link String} with the new name for the transport. This is NOT for - * identification. MUST NOT be {@code null}. - * @param configurationIntent An {@link Intent} that can be passed to {@link - * Context#startActivity} in order to launch the transport's configuration UI. It may be - * {@code null} if the transport does not offer any user-facing configuration UI. - * @param currentDestinationString A {@link String} describing the destination to which the - * transport is currently sending data. MUST NOT be {@code null}. - * @param dataManagementIntent An {@link Intent} that can be passed to {@link - * Context#startActivity} in order to launch the transport's data-management UI. It may be - * {@code null} if the transport does not offer any user-facing data management UI. - * @param dataManagementLabel A {@link CharSequence} to be used as the label for the transport's - * data management affordance. This MUST be {@code null} when dataManagementIntent is {@code - * null} and MUST NOT be {@code null} when dataManagementIntent is not {@code null}. - * @throws SecurityException If the UID of the calling process differs from the package UID of - * {@code transportComponent} or if the caller does NOT have BACKUP permission. - */ - public void updateTransportAttributes( - @UserIdInt int userId, - ComponentName transportComponent, - String name, - @Nullable Intent configurationIntent, - String currentDestinationString, - @Nullable Intent dataManagementIntent, - CharSequence dataManagementLabel) { - UserBackupManagerService userBackupManagerService = - getServiceForUserIfCallerHasPermission(userId, "updateTransportAttributes()"); - - if (userBackupManagerService != null) { - userBackupManagerService.updateTransportAttributes( - transportComponent, - name, - configurationIntent, - currentDestinationString, - dataManagementIntent, - dataManagementLabel); - } - } - - @Override - public String selectBackupTransportForUser(int userId, String transport) - throws RemoteException { - return (isUserReadyForBackup(userId)) - ? selectBackupTransport(userId, transport) : null; - } - - @Override - public String selectBackupTransport(String transport) throws RemoteException { - return selectBackupTransportForUser(binderGetCallingUserId(), transport); - } - - /** - * Selects transport {@code transportName} and returns the previously selected transport. - * - * @deprecated Use {@link #selectBackupTransportAsync(ComponentName, - * ISelectBackupTransportCallback)} instead. - */ - @Deprecated - @Nullable - public String selectBackupTransport(@UserIdInt int userId, String transportName) { - UserBackupManagerService userBackupManagerService = - getServiceForUserIfCallerHasPermission(userId, "selectBackupTransport()"); - - return userBackupManagerService == null - ? null - : userBackupManagerService.selectBackupTransport(transportName); - } - - @Override - public void selectBackupTransportAsyncForUser(int userId, ComponentName transport, - ISelectBackupTransportCallback listener) throws RemoteException { - if (isUserReadyForBackup(userId)) { - selectBackupTransportAsync(userId, transport, listener); - } else { - if (listener != null) { - try { - listener.onFailure(BackupManager.ERROR_BACKUP_NOT_ALLOWED); - } catch (RemoteException ex) { - // ignore - } - } - } - } - - /** - * Selects transport {@code transportComponent} asynchronously and notifies {@code listener} - * with the result upon completion. - */ - public void selectBackupTransportAsync( - @UserIdInt int userId, - ComponentName transportComponent, - ISelectBackupTransportCallback listener) { - UserBackupManagerService userBackupManagerService = - getServiceForUserIfCallerHasPermission(userId, "selectBackupTransportAsync()"); - - if (userBackupManagerService != null) { - userBackupManagerService.selectBackupTransportAsync(transportComponent, listener); - } - } - - @Override - public Intent getConfigurationIntentForUser(int userId, String transport) - throws RemoteException { - return isUserReadyForBackup(userId) ? getConfigurationIntent(userId, transport) - : null; - } - - @Override - public Intent getConfigurationIntent(String transport) - throws RemoteException { - return getConfigurationIntentForUser(binderGetCallingUserId(), transport); - } - - /** - * Supply the configuration intent for the given transport. If the name is not one of the - * available transports, or if the transport does not supply any configuration UI, the method - * returns {@code null}. - */ - @Nullable - public Intent getConfigurationIntent(@UserIdInt int userId, String transportName) { - UserBackupManagerService userBackupManagerService = - getServiceForUserIfCallerHasPermission(userId, "getConfigurationIntent()"); - - return userBackupManagerService == null - ? null - : userBackupManagerService.getConfigurationIntent(transportName); - } - - @Override - public String getDestinationStringForUser(int userId, String transport) throws RemoteException { - return isUserReadyForBackup(userId) ? getDestinationString(userId, transport) - : null; - } - - @Override - public String getDestinationString(String transport) throws RemoteException { - return getDestinationStringForUser(binderGetCallingUserId(), transport); - } - - /** - * Supply the current destination string for the given transport. If the name is not one of the - * registered transports the method will return null. - * - * <p>This string is used VERBATIM as the summary text of the relevant Settings item. - * - * @param transportName The name of the registered transport. - * @return The current destination string or null if the transport is not registered. - */ - @Nullable - public String getDestinationString(@UserIdInt int userId, String transportName) { - UserBackupManagerService userBackupManagerService = - getServiceForUserIfCallerHasPermission(userId, "getDestinationString()"); - - return userBackupManagerService == null - ? null - : userBackupManagerService.getDestinationString(transportName); - } - - @Override - public Intent getDataManagementIntentForUser(int userId, String transport) - throws RemoteException { - return isUserReadyForBackup(userId) - ? getDataManagementIntent(userId, transport) : null; - } - - @Override - public Intent getDataManagementIntent(String transport) - throws RemoteException { - return getDataManagementIntentForUser(binderGetCallingUserId(), transport); - } - - /** Supply the manage-data intent for the given transport. */ - @Nullable - public Intent getDataManagementIntent(@UserIdInt int userId, String transportName) { - UserBackupManagerService userBackupManagerService = - getServiceForUserIfCallerHasPermission(userId, "getDataManagementIntent()"); - - return userBackupManagerService == null - ? null - : userBackupManagerService.getDataManagementIntent(transportName); - } - - @Override - public CharSequence getDataManagementLabelForUser(int userId, String transport) - throws RemoteException { - return isUserReadyForBackup(userId) ? getDataManagementLabel(userId, transport) - : null; - } - - /** - * Supply the menu label for affordances that fire the manage-data intent for the given - * transport. - */ - @Nullable - public CharSequence getDataManagementLabel(@UserIdInt int userId, String transportName) { - UserBackupManagerService userBackupManagerService = - getServiceForUserIfCallerHasPermission(userId, "getDataManagementLabel()"); - - return userBackupManagerService == null - ? null - : userBackupManagerService.getDataManagementLabel(transportName); - } - - @Override - public IRestoreSession beginRestoreSessionForUser( - int userId, String packageName, String transportID) throws RemoteException { - return isUserReadyForBackup(userId) - ? beginRestoreSession(userId, packageName, transportID) : null; - } - - /** - * Begin a restore for the specified package {@code packageName} using the specified transport - * {@code transportName}. - */ - @Nullable - public IRestoreSession beginRestoreSession( - @UserIdInt int userId, String packageName, String transportName) { - UserBackupManagerService userBackupManagerService = - getServiceForUserIfCallerHasPermission(userId, "beginRestoreSession()"); - - return userBackupManagerService == null - ? null - : userBackupManagerService.beginRestoreSession(packageName, transportName); - } - - @Override - public void opCompleteForUser(int userId, int token, long result) throws RemoteException { - if (isUserReadyForBackup(userId)) { - opComplete(userId, token, result); - } - } - - @Override - public void opComplete(int token, long result) throws RemoteException { - opCompleteForUser(binderGetCallingUserId(), token, result); - } - - /** - * Used by a currently-active backup agent to notify the service that it has completed its given - * outstanding asynchronous backup/restore operation. - */ - public void opComplete(@UserIdInt int userId, int token, long result) { - UserBackupManagerService userBackupManagerService = - getServiceForUserIfCallerHasPermission(userId, "opComplete()"); - - if (userBackupManagerService != null) { - userBackupManagerService.opComplete(token, result); - } - } - - @Override - public long getAvailableRestoreTokenForUser(int userId, String packageName) { - return isUserReadyForBackup(userId) ? getAvailableRestoreToken(userId, packageName) : 0; - } - - /** - * Get the restore-set token for the best-available restore set for this {@code packageName}: - * the active set if possible, else the ancestral one. Returns zero if none available. - */ - public long getAvailableRestoreToken(@UserIdInt int userId, String packageName) { - UserBackupManagerService userBackupManagerService = - getServiceForUserIfCallerHasPermission(userId, "getAvailableRestoreToken()"); - - return userBackupManagerService == null - ? 0 - : userBackupManagerService.getAvailableRestoreToken(packageName); - } - - @Override - public boolean isAppEligibleForBackupForUser(int userId, String packageName) { - return isUserReadyForBackup(userId) && isAppEligibleForBackup(userId, - packageName); - } - - /** Checks if the given package {@code packageName} is eligible for backup. */ - public boolean isAppEligibleForBackup(@UserIdInt int userId, String packageName) { - UserBackupManagerService userBackupManagerService = - getServiceForUserIfCallerHasPermission(userId, "isAppEligibleForBackup()"); - - return userBackupManagerService != null - && userBackupManagerService.isAppEligibleForBackup(packageName); - } - - @Override - public String[] filterAppsEligibleForBackupForUser(int userId, String[] packages) { - return isUserReadyForBackup(userId) ? filterAppsEligibleForBackup(userId, packages) : null; - } - - /** - * Returns from the inputted packages {@code packages}, the ones that are eligible for backup. - */ - @Nullable - public String[] filterAppsEligibleForBackup(@UserIdInt int userId, String[] packages) { - UserBackupManagerService userBackupManagerService = - getServiceForUserIfCallerHasPermission(userId, "filterAppsEligibleForBackup()"); - - return userBackupManagerService == null - ? null - : userBackupManagerService.filterAppsEligibleForBackup(packages); - } - - @Override - public int requestBackupForUser(@UserIdInt int userId, String[] packages, IBackupObserver - observer, IBackupManagerMonitor monitor, int flags) throws RemoteException { - if (!isUserReadyForBackup(userId)) { - return BackupManager.ERROR_BACKUP_NOT_ALLOWED; - } - return 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); - } - - /** - * Requests a backup for the inputted {@code packages} with a specified callback {@link - * IBackupManagerMonitor} for receiving events during the operation. - */ - public int requestBackup( - @UserIdInt int userId, - String[] packages, - IBackupObserver observer, - IBackupManagerMonitor monitor, - int flags) { - UserBackupManagerService userBackupManagerService = - getServiceForUserIfCallerHasPermission(userId, "requestBackup()"); - - return userBackupManagerService == null - ? BackupManager.ERROR_BACKUP_NOT_ALLOWED - : userBackupManagerService.requestBackup(packages, observer, monitor, flags); - } - - @Override - public void cancelBackupsForUser(@UserIdInt int userId) throws RemoteException { - if (isUserReadyForBackup(userId)) { - cancelBackups(userId); - } - } - - @Override - public void cancelBackups() throws RemoteException { - cancelBackupsForUser(binderGetCallingUserId()); - } - - /** Cancel all running backup operations. */ - public void cancelBackups(@UserIdInt int userId) { - UserBackupManagerService userBackupManagerService = - getServiceForUserIfCallerHasPermission(userId, "cancelBackups()"); - - if (userBackupManagerService != null) { - userBackupManagerService.cancelBackups(); - } - } - - /** - * Returns a {@link UserHandle} for the user that has {@code ancestralSerialNumber} as the - * serial number of its ancestral work profile or null if there is no {@link - * UserBackupManagerService} associated with that user. - * - * <p> The ancestral work profile is set by {@link #setAncestralSerialNumber(long)} - * and it corresponds to the profile that was used to restore to the callers profile. - */ - @Override - @Nullable - public UserHandle getUserForAncestralSerialNumber(long ancestralSerialNumber) { - if (mGlobalDisable) { - return null; - } - int callingUserId = Binder.getCallingUserHandle().getIdentifier(); - long oldId = Binder.clearCallingIdentity(); - final int[] userIds; - try { - userIds = - mContext - .getSystemService(UserManager.class) - .getProfileIds(callingUserId, false); - } finally { - Binder.restoreCallingIdentity(oldId); - } - - for (int userId : userIds) { - UserBackupManagerService userBackupManagerService = mUserServices.get(userId); - if (userBackupManagerService != null) { - if (userBackupManagerService.getAncestralSerialNumber() == ancestralSerialNumber) { - return UserHandle.of(userId); - } - } - } - - return null; - } - - /** - * Sets the ancestral work profile for the calling user. - * - * <p> The ancestral work profile corresponds to the profile that was used to restore to the - * callers profile. - */ - @Override - public void setAncestralSerialNumber(long ancestralSerialNumber) { - if (mGlobalDisable) { - return; - } - UserBackupManagerService userBackupManagerService = - getServiceForUserIfCallerHasPermission( - Binder.getCallingUserHandle().getIdentifier(), - "setAncestralSerialNumber()"); - - if (userBackupManagerService != null) { - userBackupManagerService.setAncestralSerialNumber(ancestralSerialNumber); - } - } - - @Override - public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { - if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) { - return; - } - int userId = binderGetCallingUserId(); - if (!isUserReadyForBackup(userId)) { - pw.println("Inactive"); - return; - } - - if (args != null) { - for (String arg : args) { - if ("users".equals(arg.toLowerCase())) { - pw.print(DUMP_RUNNING_USERS_MESSAGE); - for (int i = 0; i < mUserServices.size(); i++) { - pw.print(" " + mUserServices.keyAt(i)); - } - pw.println(); - return; - } - } - } - - UserBackupManagerService userBackupManagerService = - getServiceForUserIfCallerHasPermission(UserHandle.USER_SYSTEM, "dump()"); - - if (userBackupManagerService != null) { - userBackupManagerService.dump(fd, pw, args); - } - } - - /** - * Used by the {@link JobScheduler} to run a full backup when conditions are right. The model we - * use is to perform one app backup per scheduled job execution, and to reschedule the job with - * zero latency as long as conditions remain right and we still have work to do. - * - * @return Whether ongoing work will continue. The return value here will be passed along as the - * return value to the callback {@link JobService#onStartJob(JobParameters)}. - */ - public boolean beginFullBackup(@UserIdInt int userId, FullBackupJob scheduledJob) { - if (!isUserReadyForBackup(userId)) { - return false; - } - UserBackupManagerService userBackupManagerService = - getServiceForUserIfCallerHasPermission(userId, "beginFullBackup()"); - - return userBackupManagerService != null - && userBackupManagerService.beginFullBackup(scheduledJob); - } - - /** - * Used by the {@link JobScheduler} to end the current full backup task when conditions are no - * longer met for running the full backup job. - */ - public void endFullBackup(@UserIdInt int userId) { - if (!isUserReadyForBackup(userId)) { - return; - } - UserBackupManagerService userBackupManagerService = - getServiceForUserIfCallerHasPermission(userId, "endFullBackup()"); - - if (userBackupManagerService != null) { - userBackupManagerService.endFullBackup(); - } - } - - /** - * Returns the {@link UserBackupManagerService} instance for the specified user {@code userId}. - * If the user is not registered with the service (either the user is locked or not eligible for - * the backup service) then return {@code null}. - * - * @param userId The id of the user to retrieve its instance of {@link - * UserBackupManagerService}. - * @param caller A {@link String} identifying the caller for logging purposes. - * @throws SecurityException if {@code userId} is different from the calling user id and the - * caller does NOT have the android.permission.INTERACT_ACROSS_USERS_FULL permission. - */ - @Nullable - @VisibleForTesting - UserBackupManagerService getServiceForUserIfCallerHasPermission( - @UserIdInt int userId, String caller) { - enforceCallingPermissionOnUserId(userId, caller); - UserBackupManagerService userBackupManagerService = mUserServices.get(userId); - if (userBackupManagerService == null) { - Slog.w(TAG, "Called " + caller + " for unknown user: " + userId); - } - return userBackupManagerService; - } - - /** - * 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. - */ - void enforceCallingPermissionOnUserId(@UserIdInt int userId, String message) { - if (Binder.getCallingUserHandle().getIdentifier() != userId) { - mContext.enforceCallingOrSelfPermission( - Manifest.permission.INTERACT_ACROSS_USERS_FULL, message); - } - } -} diff --git a/services/backup/java/com/android/server/backup/UserBackupManagerService.java b/services/backup/java/com/android/server/backup/UserBackupManagerService.java index 0e81e077652e..77888db416a5 100644 --- a/services/backup/java/com/android/server/backup/UserBackupManagerService.java +++ b/services/backup/java/com/android/server/backup/UserBackupManagerService.java @@ -421,13 +421,13 @@ public class UserBackupManagerService { * Creates an instance of {@link UserBackupManagerService} and initializes state for it. This * includes setting up the directories where we keep our bookkeeping and transport management. * - * @see #createAndInitializeService(int, Context, Trampoline, HandlerThread, File, File, - * TransportManager) + * @see #createAndInitializeService(int, Context, BackupManagerService, HandlerThread, File, + * File, TransportManager) */ static UserBackupManagerService createAndInitializeService( @UserIdInt int userId, Context context, - Trampoline trampoline, + BackupManagerService backupManagerService, Set<ComponentName> transportWhitelist) { String currentTransport = Settings.Secure.getStringForUser( @@ -455,7 +455,7 @@ public class UserBackupManagerService { return createAndInitializeService( userId, context, - trampoline, + backupManagerService, userBackupThread, baseStateDir, dataDir, @@ -467,7 +467,7 @@ public class UserBackupManagerService { * * @param userId The user which this service is for. * @param context The system server context. - * @param trampoline A reference to the proxy to {@link BackupManagerService}. + * @param backupManagerService A reference to the proxy to {@link BackupManagerService}. * @param userBackupThread The thread running backup/restore operations for the user. * @param baseStateDir The directory we store the user's persistent bookkeeping data. * @param dataDir The directory we store the user's temporary staging data. @@ -478,7 +478,7 @@ public class UserBackupManagerService { public static UserBackupManagerService createAndInitializeService( @UserIdInt int userId, Context context, - Trampoline trampoline, + BackupManagerService backupManagerService, HandlerThread userBackupThread, File baseStateDir, File dataDir, @@ -486,7 +486,7 @@ public class UserBackupManagerService { return new UserBackupManagerService( userId, context, - trampoline, + backupManagerService, userBackupThread, baseStateDir, dataDir, @@ -509,7 +509,7 @@ public class UserBackupManagerService { private UserBackupManagerService( @UserIdInt int userId, Context context, - Trampoline parent, + BackupManagerService parent, HandlerThread userBackupThread, File baseStateDir, File dataDir, @@ -525,8 +525,8 @@ public class UserBackupManagerService { mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE); mStorageManager = IStorageManager.Stub.asInterface(ServiceManager.getService("mount")); - checkNotNull(parent, "trampoline cannot be null"); - mBackupManagerBinder = Trampoline.asInterface(parent.asBinder()); + checkNotNull(parent, "parent cannot be null"); + mBackupManagerBinder = BackupManagerService.asInterface(parent.asBinder()); mAgentTimeoutParameters = new BackupAgentTimeoutParameters(Handler.getMain(), mContext.getContentResolver()); diff --git a/services/robotests/backup/src/com/android/server/backup/TrampolineRoboTest.java b/services/robotests/backup/src/com/android/server/backup/BackupManagerServiceRoboTest.java index f0a5d3749a13..a1bfcdf4bdfa 100644 --- a/services/robotests/backup/src/com/android/server/backup/TrampolineRoboTest.java +++ b/services/robotests/backup/src/com/android/server/backup/BackupManagerServiceRoboTest.java @@ -26,8 +26,12 @@ import static com.android.server.backup.testing.TransportData.backupTransport; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.robolectric.Shadows.shadowOf; import static org.testng.Assert.expectThrows; @@ -72,7 +76,7 @@ import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; -/** Tests for {@link com.android.server.backup.Trampoline}. */ +/** Tests for {@link BackupManagerService}. */ @RunWith(RobolectricTestRunner.class) @Config( shadows = { @@ -83,7 +87,7 @@ import java.io.StringWriter; ShadowSystemServiceRegistry.class }) @Presubmit -public class TrampolineRoboTest { +public class BackupManagerServiceRoboTest { private static final String TEST_PACKAGE = "package"; private static final String TEST_TRANSPORT = "transport"; private static final String[] ADB_TEST_PACKAGES = {TEST_PACKAGE}; @@ -121,7 +125,7 @@ public class TrampolineRoboTest { /** Test that the service registers users. */ @Test public void testStartServiceForUser_registersUser() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); backupManagerService.setBackupServiceActive(mUserOneId, true); backupManagerService.startServiceForUser(mUserOneId); @@ -134,7 +138,7 @@ public class TrampolineRoboTest { /** Test that the service registers users. */ @Test public void testStartServiceForUser_withServiceInstance_registersUser() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); backupManagerService.setBackupServiceActive(mUserOneId, true); backupManagerService.startServiceForUser(mUserOneId, mUserOneService); @@ -147,7 +151,7 @@ public class TrampolineRoboTest { /** Test that the service unregisters users when stopped. */ @Test public void testStopServiceForUser_forRegisteredUser_unregistersCorrectUser() throws Exception { - Trampoline backupManagerService = + BackupManagerService backupManagerService = createServiceAndRegisterUser(mUserOneId, mUserOneService); backupManagerService.startServiceForUser(mUserTwoId, mUserTwoService); ShadowBinder.setCallingUid(Process.SYSTEM_UID); @@ -163,7 +167,7 @@ public class TrampolineRoboTest { /** Test that the service unregisters users when stopped. */ @Test public void testStopServiceForUser_forRegisteredUser_tearsDownCorrectUser() throws Exception { - Trampoline backupManagerService = + BackupManagerService backupManagerService = createServiceAndRegisterUser(mUserOneId, mUserOneService); backupManagerService.setBackupServiceActive(mUserTwoId, true); backupManagerService.startServiceForUser(mUserTwoId, mUserTwoService); @@ -177,7 +181,7 @@ public class TrampolineRoboTest { /** Test that the service unregisters users when stopped. */ @Test public void testStopServiceForUser_forUnknownUser_doesNothing() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); backupManagerService.setBackupServiceActive(mUserOneId, true); ShadowBinder.setCallingUid(Process.SYSTEM_UID); @@ -194,7 +198,7 @@ public class TrampolineRoboTest { /** Test that the backup service routes methods correctly to the user that requests it. */ @Test public void testDataChanged_onRegisteredUser_callsMethodForUser() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); setCallerAndGrantInteractUserPermission(mUserOneId, /* shouldGrantPermission */ false); @@ -206,7 +210,7 @@ public class TrampolineRoboTest { /** Test that the backup service does not route methods for non-registered users. */ @Test public void testDataChanged_onUnknownUser_doesNotPropagateCall() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); setCallerAndGrantInteractUserPermission(mUserTwoId, /* shouldGrantPermission */ false); @@ -218,7 +222,7 @@ public class TrampolineRoboTest { /** Test that the backup service routes methods correctly to the user that requests it. */ @Test public void testAgentConnected_onRegisteredUser_callsMethodForUser() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); setCallerAndGrantInteractUserPermission(mUserOneId, /* shouldGrantPermission */ false); IBinder agentBinder = mock(IBinder.class); @@ -231,7 +235,7 @@ public class TrampolineRoboTest { /** Test that the backup service does not route methods for non-registered users. */ @Test public void testAgentConnected_onUnknownUser_doesNotPropagateCall() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); setCallerAndGrantInteractUserPermission(mUserTwoId, /* shouldGrantPermission */ false); IBinder agentBinder = mock(IBinder.class); @@ -244,7 +248,7 @@ public class TrampolineRoboTest { /** Test that the backup service routes methods correctly to the user that requests it. */ @Test public void testOpComplete_onRegisteredUser_callsMethodForUser() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); setCallerAndGrantInteractUserPermission(mUserOneId, /* shouldGrantPermission */ false); @@ -256,7 +260,7 @@ public class TrampolineRoboTest { /** Test that the backup service does not route methods for non-registered users. */ @Test public void testOpComplete_onUnknownUser_doesNotPropagateCall() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); setCallerAndGrantInteractUserPermission(mUserTwoId, /* shouldGrantPermission */ false); @@ -272,7 +276,7 @@ public class TrampolineRoboTest { /** Test that the backup service routes methods correctly to the user that requests it. */ @Test public void testInitializeTransports_onRegisteredUser_callsMethodForUser() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); setCallerAndGrantInteractUserPermission(mUserOneId, /* shouldGrantPermission */ false); String[] transports = {TEST_TRANSPORT}; @@ -285,7 +289,7 @@ public class TrampolineRoboTest { /** Test that the backup service does not route methods for non-registered users. */ @Test public void testInitializeTransports_onUnknownUser_doesNotPropagateCall() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); setCallerAndGrantInteractUserPermission(mUserTwoId, /* shouldGrantPermission */ false); String[] transports = {TEST_TRANSPORT}; @@ -298,7 +302,7 @@ public class TrampolineRoboTest { /** Test that the backup service routes methods correctly to the user that requests it. */ @Test public void testClearBackupData_onRegisteredUser_callsMethodForUser() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); setCallerAndGrantInteractUserPermission(mUserOneId, /* shouldGrantPermission */ false); @@ -310,7 +314,7 @@ public class TrampolineRoboTest { /** Test that the backup service does not route methods for non-registered users. */ @Test public void testClearBackupData_onUnknownUser_doesNotPropagateCall() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); setCallerAndGrantInteractUserPermission(mUserTwoId, /* shouldGrantPermission */ false); @@ -322,7 +326,7 @@ public class TrampolineRoboTest { /** Test that the backup service routes methods correctly to the user that requests it. */ @Test public void testGetCurrentTransport_onRegisteredUser_callsMethodForUser() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); setCallerAndGrantInteractUserPermission(mUserOneId, /* shouldGrantPermission */ false); @@ -334,7 +338,7 @@ public class TrampolineRoboTest { /** Test that the backup service does not route methods for non-registered users. */ @Test public void testGetCurrentTransport_onUnknownUser_doesNotPropagateCall() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); setCallerAndGrantInteractUserPermission(mUserTwoId, /* shouldGrantPermission */ false); @@ -347,7 +351,7 @@ public class TrampolineRoboTest { @Test public void testGetCurrentTransportComponent_onRegisteredUser_callsMethodForUser() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); setCallerAndGrantInteractUserPermission(mUserOneId, /* shouldGrantPermission */ false); @@ -360,7 +364,7 @@ public class TrampolineRoboTest { @Test public void testGetCurrentTransportComponent_onUnknownUser_doesNotPropagateCall() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); setCallerAndGrantInteractUserPermission(mUserTwoId, /* shouldGrantPermission */ false); @@ -372,7 +376,7 @@ public class TrampolineRoboTest { /** Test that the backup service routes methods correctly to the user that requests it. */ @Test public void testListAllTransports_onRegisteredUser_callsMethodForUser() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); setCallerAndGrantInteractUserPermission(mUserOneId, /* shouldGrantPermission */ false); @@ -384,7 +388,7 @@ public class TrampolineRoboTest { /** Test that the backup service does not route methods for non-registered users. */ @Test public void testListAllTransports_onUnknownUser_doesNotPropagateCall() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); setCallerAndGrantInteractUserPermission(mUserTwoId, /* shouldGrantPermission */ false); @@ -397,7 +401,7 @@ public class TrampolineRoboTest { @Test public void testListAllTransportComponents_onRegisteredUser_callsMethodForUser() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); setCallerAndGrantInteractUserPermission(mUserOneId, /* shouldGrantPermission */ false); @@ -410,7 +414,7 @@ public class TrampolineRoboTest { @Test public void testListAllTransportComponents_onUnknownUser_doesNotPropagateCall() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); setCallerAndGrantInteractUserPermission(mUserTwoId, /* shouldGrantPermission */ false); @@ -422,7 +426,7 @@ public class TrampolineRoboTest { /** Test that the backup service routes methods correctly to the user that requests it. */ @Test public void testSelectBackupTransport_onRegisteredUser_callsMethodForUser() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); setCallerAndGrantInteractUserPermission(mUserOneId, /* shouldGrantPermission */ false); @@ -434,7 +438,7 @@ public class TrampolineRoboTest { /** Test that the backup service does not route methods for non-registered users. */ @Test public void testSelectBackupTransport_onUnknownUser_doesNotPropagateCall() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); setCallerAndGrantInteractUserPermission(mUserTwoId, /* shouldGrantPermission */ false); @@ -446,7 +450,7 @@ public class TrampolineRoboTest { /** Test that the backup service routes methods correctly to the user that requests it. */ @Test public void testSelectTransportAsync_onRegisteredUser_callsMethodForUser() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); setCallerAndGrantInteractUserPermission(mUserOneId, /* shouldGrantPermission */ false); TransportData transport = backupTransport(); @@ -463,7 +467,7 @@ public class TrampolineRoboTest { @Test public void testSelectBackupTransportAsync_onUnknownUser_doesNotPropagateCall() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); setCallerAndGrantInteractUserPermission(mUserTwoId, /* shouldGrantPermission */ false); TransportData transport = backupTransport(); @@ -479,7 +483,7 @@ public class TrampolineRoboTest { /** Test that the backup service routes methods correctly to the user that requests it. */ @Test public void testGetConfigurationIntent_onRegisteredUser_callsMethodForUser() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); setCallerAndGrantInteractUserPermission(mUserOneId, /* shouldGrantPermission */ false); @@ -491,7 +495,7 @@ public class TrampolineRoboTest { /** Test that the backup service does not route methods for non-registered users. */ @Test public void testGetConfigurationIntent_onUnknownUser_doesNotPropagateCall() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); setCallerAndGrantInteractUserPermission(mUserTwoId, /* shouldGrantPermission */ false); @@ -503,7 +507,7 @@ public class TrampolineRoboTest { /** Test that the backup service routes methods correctly to the user that requests it. */ @Test public void testGetDestinationString_onRegisteredUser_callsMethodForUser() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); setCallerAndGrantInteractUserPermission(mUserOneId, /* shouldGrantPermission */ false); @@ -515,7 +519,7 @@ public class TrampolineRoboTest { /** Test that the backup service does not route methods for non-registered users. */ @Test public void testGetDestinationString_onUnknownUser_doesNotPropagateCall() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); setCallerAndGrantInteractUserPermission(mUserTwoId, /* shouldGrantPermission */ false); @@ -527,7 +531,7 @@ public class TrampolineRoboTest { /** Test that the backup service routes methods correctly to the user that requests it. */ @Test public void testGetDataManagementIntent_onRegisteredUser_callsMethodForUser() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); setCallerAndGrantInteractUserPermission(mUserOneId, /* shouldGrantPermission */ false); @@ -539,7 +543,7 @@ public class TrampolineRoboTest { /** Test that the backup service does not route methods for non-registered users. */ @Test public void testGetDataManagementIntent_onUnknownUser_doesNotPropagateCall() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); setCallerAndGrantInteractUserPermission(mUserTwoId, /* shouldGrantPermission */ false); @@ -551,7 +555,7 @@ public class TrampolineRoboTest { /** Test that the backup service routes methods correctly to the user that requests it. */ @Test public void testGetDataManagementLabel_onRegisteredUser_callsMethodForUser() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); setCallerAndGrantInteractUserPermission(mUserOneId, /* shouldGrantPermission */ false); @@ -563,7 +567,7 @@ public class TrampolineRoboTest { /** Test that the backup service does not route methods for non-registered users. */ @Test public void testGetDataManagementLabel_onUnknownUser_doesNotPropagateCall() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); setCallerAndGrantInteractUserPermission(mUserTwoId, /* shouldGrantPermission */ false); @@ -576,7 +580,7 @@ public class TrampolineRoboTest { @Test public void testUpdateTransportAttributes_onRegisteredUser_callsMethodForUser() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); setCallerAndGrantInteractUserPermission(mUserOneId, /* shouldGrantPermission */ false); TransportData transport = backupTransport(); @@ -606,7 +610,7 @@ public class TrampolineRoboTest { @Test public void testUpdateTransportAttributes_onUnknownUser_doesNotPropagateCall() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); setCallerAndGrantInteractUserPermission(mUserTwoId, /* shouldGrantPermission */ false); TransportData transport = backupTransport(); @@ -642,7 +646,7 @@ public class TrampolineRoboTest { */ @Test public void testSetBackupEnabled_withoutPermission_throwsSecurityExceptionForNonCallingUser() { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); setCallerAndGrantInteractUserPermission(mUserOneId, /* shouldGrantPermission */ false); @@ -657,7 +661,7 @@ public class TrampolineRoboTest { */ @Test public void testSetBackupEnabled_withPermission_propagatesForNonCallingUser() { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); registerUser(backupManagerService, mUserTwoId, mUserTwoService); @@ -671,7 +675,7 @@ public class TrampolineRoboTest { /** Test that the backup service routes methods correctly to the user that requests it. */ @Test public void testSetBackupEnabled_onRegisteredUser_callsMethodForUser() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); setCallerAndGrantInteractUserPermission(mUserOneId, /* shouldGrantPermission */ false); @@ -683,7 +687,7 @@ public class TrampolineRoboTest { /** Test that the backup service does not route methods for non-registered users. */ @Test public void testSetBackupEnabled_onUnknownUser_doesNotPropagateCall() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); setCallerAndGrantInteractUserPermission(mUserTwoId, /* shouldGrantPermission */ false); @@ -695,7 +699,7 @@ public class TrampolineRoboTest { /** Test that the backup service routes methods correctly to the user that requests it. */ @Test public void testSetAutoRestore_onRegisteredUser_callsMethodForUser() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); setCallerAndGrantInteractUserPermission(mUserOneId, /* shouldGrantPermission */ false); @@ -707,7 +711,7 @@ public class TrampolineRoboTest { /** Test that the backup service does not route methods for non-registered users. */ @Test public void testSetAutoRestore_onUnknownUser_doesNotPropagateCall() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); setCallerAndGrantInteractUserPermission(mUserTwoId, /* shouldGrantPermission */ false); @@ -719,7 +723,7 @@ public class TrampolineRoboTest { /** Test that the backup service routes methods correctly to the user that requests it. */ @Test public void testIsBackupEnabled_onRegisteredUser_callsMethodForUser() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); setCallerAndGrantInteractUserPermission(mUserOneId, /* shouldGrantPermission */ false); @@ -731,7 +735,7 @@ public class TrampolineRoboTest { /** Test that the backup service does not route methods for non-registered users. */ @Test public void testIsBackupEnabled_onUnknownUser_doesNotPropagateCall() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); setCallerAndGrantInteractUserPermission(mUserTwoId, /* shouldGrantPermission */ false); @@ -747,7 +751,7 @@ public class TrampolineRoboTest { /** Test that the backup service routes methods correctly to the user that requests it. */ @Test public void testIsAppEligibleForBackup_onRegisteredUser_callsMethodForUser() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); setCallerAndGrantInteractUserPermission(mUserOneId, /* shouldGrantPermission */ false); @@ -759,7 +763,7 @@ public class TrampolineRoboTest { /** Test that the backup service does not route methods for non-registered users. */ @Test public void testIsAppEligibleForBackup_onUnknownUser_doesNotPropagateCall() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); setCallerAndGrantInteractUserPermission(mUserTwoId, /* shouldGrantPermission */ false); @@ -772,7 +776,7 @@ public class TrampolineRoboTest { @Test public void testFilterAppsEligibleForBackup_onRegisteredUser_callsMethodForUser() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); setCallerAndGrantInteractUserPermission(mUserOneId, /* shouldGrantPermission */ false); String[] packages = {TEST_PACKAGE}; @@ -786,7 +790,7 @@ public class TrampolineRoboTest { @Test public void testFilterAppsEligibleForBackup_onUnknownUser_doesNotPropagateCall() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); setCallerAndGrantInteractUserPermission(mUserTwoId, /* shouldGrantPermission */ false); String[] packages = {TEST_PACKAGE}; @@ -802,7 +806,7 @@ public class TrampolineRoboTest { */ @Test public void testBackupNow_withoutPermission_throwsSecurityExceptionForNonCallingUser() { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); setCallerAndGrantInteractUserPermission(mUserOneId, /* shouldGrantPermission */ false); @@ -815,7 +819,7 @@ public class TrampolineRoboTest { */ @Test public void testBackupNow_withPermission_propagatesForNonCallingUser() { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); registerUser(backupManagerService, mUserTwoId, mUserTwoService); @@ -829,7 +833,7 @@ public class TrampolineRoboTest { /** Test that the backup service routes methods correctly to the user that requests it. */ @Test public void testBackupNow_onRegisteredUser_callsMethodForUser() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); setCallerAndGrantInteractUserPermission(mUserOneId, /* shouldGrantPermission */ false); @@ -841,7 +845,7 @@ public class TrampolineRoboTest { /** Test that the backup service does not route methods for non-registered users. */ @Test public void testBackupNow_onUnknownUser_doesNotPropagateCall() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); setCallerAndGrantInteractUserPermission(mUserTwoId, /* shouldGrantPermission */ false); @@ -856,7 +860,7 @@ public class TrampolineRoboTest { */ @Test public void testRequestBackup_withoutPermission_throwsSecurityExceptionForNonCallingUser() { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); setCallerAndGrantInteractUserPermission(mUserOneId, /* shouldGrantPermission */ false); String[] packages = {TEST_PACKAGE}; @@ -876,7 +880,7 @@ public class TrampolineRoboTest { */ @Test public void testRequestBackup_withPermission_propagatesForNonCallingUser() { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); registerUser(backupManagerService, mUserTwoId, mUserTwoService); @@ -893,7 +897,7 @@ public class TrampolineRoboTest { /** Test that the backup service routes methods correctly to the user that requests it. */ @Test public void testRequestBackup_onRegisteredUser_callsMethodForUser() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); String[] packages = {TEST_PACKAGE}; IBackupObserver observer = mock(IBackupObserver.class); @@ -908,7 +912,7 @@ public class TrampolineRoboTest { /** Test that the backup service routes methods correctly to the user that requests it. */ @Test public void testRequestBackup_onUnknownUser_doesNotPropagateCall() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); String[] packages = {TEST_PACKAGE}; IBackupObserver observer = mock(IBackupObserver.class); @@ -926,7 +930,7 @@ public class TrampolineRoboTest { */ @Test public void testCancelBackups_withoutPermission_throwsSecurityExceptionForNonCallingUser() { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); setCallerAndGrantInteractUserPermission(mUserOneId, /* shouldGrantPermission */ false); @@ -939,7 +943,7 @@ public class TrampolineRoboTest { */ @Test public void testCancelBackups_withPermission_propagatesForNonCallingUser() { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); registerUser(backupManagerService, mUserTwoId, mUserTwoService); setCallerAndGrantInteractUserPermission(mUserOneId, /* shouldGrantPermission */ true); @@ -952,7 +956,7 @@ public class TrampolineRoboTest { /** Test that the backup service routes methods correctly to the user that requests it. */ @Test public void testCancelBackups_onRegisteredUser_callsMethodForUser() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); setCallerAndGrantInteractUserPermission(mUserOneId, /* shouldGrantPermission */ false); @@ -964,7 +968,7 @@ public class TrampolineRoboTest { /** Test that the backup service does not route methods for non-registered users. */ @Test public void testCancelBackups_onUnknownUser_doesNotPropagateCall() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); setCallerAndGrantInteractUserPermission(mUserTwoId, /* shouldGrantPermission */ false); @@ -976,7 +980,7 @@ public class TrampolineRoboTest { /** Test that the backup service routes methods correctly to the user that requests it. */ @Test public void testBeginFullBackup_onRegisteredUser_callsMethodForUser() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, UserHandle.USER_SYSTEM, mUserOneService); FullBackupJob job = new FullBackupJob(); @@ -988,7 +992,7 @@ public class TrampolineRoboTest { /** Test that the backup service does not route methods for non-registered users. */ @Test public void testBeginFullBackup_onUnknownUser_doesNotPropagateCall() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); FullBackupJob job = new FullBackupJob(); backupManagerService.beginFullBackup(UserHandle.USER_SYSTEM, job); @@ -999,7 +1003,7 @@ public class TrampolineRoboTest { /** Test that the backup service routes methods correctly to the user that requests it. */ @Test public void testEndFullBackup_onRegisteredUser_callsMethodForUser() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, UserHandle.USER_SYSTEM, mUserOneService); backupManagerService.endFullBackup(UserHandle.USER_SYSTEM); @@ -1010,7 +1014,7 @@ public class TrampolineRoboTest { /** Test that the backup service does not route methods for non-registered users. */ @Test public void testEndFullBackup_onUnknownUser_doesNotPropagateCall() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); backupManagerService.endFullBackup(UserHandle.USER_SYSTEM); @@ -1020,7 +1024,7 @@ public class TrampolineRoboTest { /** Test that the backup service routes methods correctly to the user that requests it. */ @Test public void testFullTransportBackup_onRegisteredUser_callsMethodForUser() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); setCallerAndGrantInteractUserPermission(mUserOneId, /* shouldGrantPermission */ false); String[] packages = {TEST_PACKAGE}; @@ -1033,7 +1037,7 @@ public class TrampolineRoboTest { /** Test that the backup service does not route methods for non-registered users. */ @Test public void testFullTransportBackup_onUnknownUser_doesNotPropagateCall() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); setCallerAndGrantInteractUserPermission(mUserTwoId, /* shouldGrantPermission */ false); String[] packages = {TEST_PACKAGE}; @@ -1050,7 +1054,7 @@ public class TrampolineRoboTest { /** Test that the backup service routes methods correctly to the user that requests it. */ @Test public void testRestoreAtInstall_onRegisteredUser_callsMethodForUser() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); setCallerAndGrantInteractUserPermission(mUserOneId, /* shouldGrantPermission */ false); @@ -1062,7 +1066,7 @@ public class TrampolineRoboTest { /** Test that the backup service does not route methods for non-registered users. */ @Test public void testRestoreAtInstall_onUnknownUser_doesNotPropagateCall() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); setCallerAndGrantInteractUserPermission(mUserTwoId, /* shouldGrantPermission */ false); @@ -1074,7 +1078,7 @@ public class TrampolineRoboTest { /** Test that the backup service routes methods correctly to the user that requests it. */ @Test public void testBeginRestoreSession_onRegisteredUser_callsMethodForUser() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); setCallerAndGrantInteractUserPermission(mUserOneId, /* shouldGrantPermission */ false); @@ -1086,7 +1090,7 @@ public class TrampolineRoboTest { /** Test that the backup service does not route methods for non-registered users. */ @Test public void testBeginRestoreSession_onUnknownUser_doesNotPropagateCall() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); setCallerAndGrantInteractUserPermission(mUserTwoId, /* shouldGrantPermission */ false); @@ -1099,7 +1103,7 @@ public class TrampolineRoboTest { @Test public void testGetAvailableRestoreToken_onRegisteredUser_callsMethodForUser() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); setCallerAndGrantInteractUserPermission(mUserOneId, /* shouldGrantPermission */ false); @@ -1111,7 +1115,7 @@ public class TrampolineRoboTest { /** Test that the backup service does not route methods for non-registered users. */ @Test public void testGetAvailableRestoreToken_onUnknownUser_doesNotPropagateCall() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); setCallerAndGrantInteractUserPermission(mUserTwoId, /* shouldGrantPermission */ false); @@ -1127,7 +1131,7 @@ public class TrampolineRoboTest { /** 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(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, UserHandle.USER_SYSTEM, mUserOneService); ShadowBinder.setCallingUserHandle(UserHandle.of(UserHandle.USER_SYSTEM)); @@ -1139,7 +1143,7 @@ public class TrampolineRoboTest { /** 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 backupManagerService = createService(); backupManagerService.setBackupPassword("currentPassword", "newPassword"); @@ -1149,7 +1153,7 @@ public class TrampolineRoboTest { /** 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(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, UserHandle.USER_SYSTEM, mUserOneService); ShadowBinder.setCallingUserHandle(UserHandle.of(UserHandle.USER_SYSTEM)); @@ -1161,7 +1165,7 @@ public class TrampolineRoboTest { /** 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 backupManagerService = createService(); backupManagerService.hasBackupPassword(); @@ -1174,7 +1178,7 @@ public class TrampolineRoboTest { */ @Test public void testAdbBackup_withoutPermission_throwsSecurityExceptionForNonCallingUser() { - Trampoline backupManagerService = createSystemRegisteredService(); + BackupManagerService backupManagerService = createSystemRegisteredService(); registerUser(backupManagerService, mUserOneId, mUserOneService); registerUser(backupManagerService, mUserTwoId, mUserTwoService); setCallerAndGrantInteractUserPermission(mUserOneId, /* shouldGrantPermission */ false); @@ -1202,7 +1206,7 @@ public class TrampolineRoboTest { */ @Test public void testAdbBackup_withPermission_propagatesForNonCallingUser() throws Exception { - Trampoline backupManagerService = createSystemRegisteredService(); + BackupManagerService backupManagerService = createSystemRegisteredService(); registerUser(backupManagerService, mUserOneId, mUserOneService); registerUser(backupManagerService, mUserTwoId, mUserTwoService); @@ -1239,7 +1243,7 @@ public class TrampolineRoboTest { /** 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(); + BackupManagerService backupManagerService = createSystemRegisteredService(); registerUser(backupManagerService, mUserOneId, mUserOneService); ParcelFileDescriptor parcelFileDescriptor = getFileDescriptorForAdbTest(); setCallerAndGrantInteractUserPermission(mUserOneId, /* shouldGrantPermission */ false); @@ -1274,7 +1278,7 @@ public class TrampolineRoboTest { /** Test that the backup service does not route methods for non-registered users. */ @Test public void testAdbBackup_onUnknownUser_doesNotPropagateCall() throws Exception { - Trampoline backupManagerService = createSystemRegisteredService(); + BackupManagerService backupManagerService = createSystemRegisteredService(); registerUser(backupManagerService, mUserOneId, mUserOneService); ParcelFileDescriptor parcelFileDescriptor = getFileDescriptorForAdbTest(); setCallerAndGrantInteractUserPermission(mUserTwoId, /* shouldGrantPermission */ false); @@ -1312,7 +1316,7 @@ public class TrampolineRoboTest { */ @Test public void testAdbRestore_withoutPermission_throwsSecurityExceptionForNonCallingUser() { - Trampoline backupManagerService = createSystemRegisteredService(); + BackupManagerService backupManagerService = createSystemRegisteredService(); registerUser(backupManagerService, mUserOneId, mUserOneService); registerUser(backupManagerService, mUserTwoId, mUserTwoService); setCallerAndGrantInteractUserPermission(mUserOneId, /* shouldGrantPermission */ false); @@ -1327,7 +1331,7 @@ public class TrampolineRoboTest { */ @Test public void testAdbRestore_withPermission_propagatesForNonCallingUser() throws Exception { - Trampoline backupManagerService = createSystemRegisteredService(); + BackupManagerService backupManagerService = createSystemRegisteredService(); registerUser(backupManagerService, mUserOneId, mUserOneService); registerUser(backupManagerService, mUserTwoId, mUserTwoService); ParcelFileDescriptor parcelFileDescriptor = getFileDescriptorForAdbTest(); @@ -1341,7 +1345,7 @@ public class TrampolineRoboTest { /** 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(); + BackupManagerService backupManagerService = createSystemRegisteredService(); registerUser(backupManagerService, mUserOneId, mUserOneService); ParcelFileDescriptor parcelFileDescriptor = getFileDescriptorForAdbTest(); setCallerAndGrantInteractUserPermission(mUserOneId, /* shouldGrantPermission */ false); @@ -1354,7 +1358,7 @@ public class TrampolineRoboTest { /** Test that the backup service does not route methods for non-registered users. */ @Test public void testAdbRestore_onUnknownUser_doesNotPropagateCall() throws Exception { - Trampoline backupManagerService = createSystemRegisteredService(); + BackupManagerService backupManagerService = createSystemRegisteredService(); registerUser(backupManagerService, mUserOneId, mUserOneService); ParcelFileDescriptor parcelFileDescriptor = getFileDescriptorForAdbTest(); setCallerAndGrantInteractUserPermission(mUserTwoId, /* shouldGrantPermission */ false); @@ -1374,7 +1378,7 @@ public class TrampolineRoboTest { @Test public void testAcknowledgeAdbBackupOrRestore_onRegisteredUser_callsMethodForUser() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); setCallerAndGrantInteractUserPermission(mUserOneId, /* shouldGrantPermission */ false); IFullBackupRestoreObserver observer = mock(IFullBackupRestoreObserver.class); @@ -1400,7 +1404,7 @@ public class TrampolineRoboTest { @Test public void testAcknowledgeAdbBackupOrRestore_onUnknownUser_doesNotPropagateCall() throws Exception { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); setCallerAndGrantInteractUserPermission(mUserTwoId, /* shouldGrantPermission */ false); IFullBackupRestoreObserver observer = mock(IFullBackupRestoreObserver.class); @@ -1430,7 +1434,7 @@ public class TrampolineRoboTest { @Test public void testDump_onRegisteredUser_callsMethodForUser() throws Exception { grantDumpPermissions(); - Trampoline backupManagerService = createSystemRegisteredService(); + BackupManagerService backupManagerService = createSystemRegisteredService(); File testFile = createTestFile(); FileDescriptor fileDescriptor = new FileDescriptor(); PrintWriter printWriter = new PrintWriter(testFile); @@ -1446,7 +1450,7 @@ public class TrampolineRoboTest { @Test public void testDump_onUnknownUser_doesNotPropagateCall() throws Exception { grantDumpPermissions(); - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); File testFile = createTestFile(); FileDescriptor fileDescriptor = new FileDescriptor(); PrintWriter printWriter = new PrintWriter(testFile); @@ -1461,7 +1465,7 @@ public class TrampolineRoboTest { @Test public void testDump_users_dumpsListOfRegisteredUsers() { grantDumpPermissions(); - Trampoline backupManagerService = createSystemRegisteredService(); + BackupManagerService backupManagerService = createSystemRegisteredService(); registerUser(backupManagerService, mUserOneId, mUserOneService); StringWriter out = new StringWriter(); PrintWriter writer = new PrintWriter(out); @@ -1471,7 +1475,7 @@ public class TrampolineRoboTest { writer.flush(); assertEquals( - String.format("%s %d %d\n", Trampoline.DUMP_RUNNING_USERS_MESSAGE, + String.format("%s %d %d\n", BackupManagerService.DUMP_RUNNING_USERS_MESSAGE, UserHandle.USER_SYSTEM, mUserOneId), out.toString()); } @@ -1493,7 +1497,7 @@ public class TrampolineRoboTest { */ @Test public void testGetServiceForUser_withoutPermission_throwsSecurityExceptionForNonCallingUser() { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); setCallerAndGrantInteractUserPermission(mUserTwoId, /* shouldGrantPermission */ false); @@ -1510,7 +1514,7 @@ public class TrampolineRoboTest { */ @Test public void testGetServiceForUserIfCallerHasPermission_withPermission_worksForNonCallingUser() { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); setCallerAndGrantInteractUserPermission(mUserTwoId, /* shouldGrantPermission */ true); @@ -1525,7 +1529,7 @@ public class TrampolineRoboTest { */ @Test public void testGetServiceForUserIfCallerHasPermission_withoutPermission_worksForCallingUser() { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); registerUser(backupManagerService, mUserOneId, mUserOneService); setCallerAndGrantInteractUserPermission(mUserOneId, /* shouldGrantPermission */ false); @@ -1534,25 +1538,98 @@ public class TrampolineRoboTest { backupManagerService.getServiceForUserIfCallerHasPermission(mUserOneId, "test")); } - private Trampoline createService() { - return new Trampoline(mContext); + /** + * Test verifying that {@link BackupManagerService#MORE_DEBUG} is set to {@code false}. This is + * specifically to prevent overloading the logs in production. + */ + @Test + public void testMoreDebug_isFalse() throws Exception { + boolean moreDebug = BackupManagerService.MORE_DEBUG; + + assertThat(moreDebug).isFalse(); + } + + /** Test that the constructor handles {@code null} parameters. */ + @Test + public void testConstructor_withNullContext_throws() throws Exception { + expectThrows( + NullPointerException.class, + () -> + new BackupManagerService( + /* context */ null, + new SparseArray<>())); } - private Trampoline createSystemRegisteredService() { - Trampoline trampoline = createService(); - registerUser(trampoline, UserHandle.USER_SYSTEM, mUserSystemService); - return trampoline; + /** Test that the constructor does not create {@link UserBackupManagerService} instances. */ + @Test + public void testConstructor_doesNotRegisterUsers() throws Exception { + BackupManagerService backupManagerService = createService(); + + assertThat(backupManagerService.getUserServices().size()).isEqualTo(0); + } + + // --------------------------------------------- + // Lifecycle tests + // --------------------------------------------- + + /** testOnStart_publishesService */ + @Test + public void testOnStart_publishesService() { + BackupManagerService backupManagerService = mock(BackupManagerService.class); + BackupManagerService.Lifecycle lifecycle = + spy(new BackupManagerService.Lifecycle(mContext, backupManagerService)); + doNothing().when(lifecycle).publishService(anyString(), any()); + + lifecycle.onStart(); + + 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.onUnlockUser(UserHandle.USER_SYSTEM); + + verify(backupManagerService).onUnlockUser(UserHandle.USER_SYSTEM); + } + + /** testOnStopUser_forwards */ + @Test + public void testOnStopUser_forwards() { + BackupManagerService backupManagerService = mock(BackupManagerService.class); + BackupManagerService.Lifecycle lifecycle = + new BackupManagerService.Lifecycle(mContext, backupManagerService); + + lifecycle.onStopUser(UserHandle.USER_SYSTEM); + + verify(backupManagerService).onStopUser(UserHandle.USER_SYSTEM); + } + + private BackupManagerService createService() { + return new BackupManagerService(mContext); + } + + private BackupManagerService createSystemRegisteredService() { + BackupManagerService backupManagerService = createService(); + registerUser(backupManagerService, UserHandle.USER_SYSTEM, mUserSystemService); + return backupManagerService; } private void registerUser( - Trampoline trampoline, int userId, UserBackupManagerService userBackupManagerService) { - trampoline.setBackupServiceActive(userId, true); - trampoline.startServiceForUser(userId, userBackupManagerService); + BackupManagerService backupManagerService, + int userId, + UserBackupManagerService userBackupManagerService) { + backupManagerService.setBackupServiceActive(userId, true); + backupManagerService.startServiceForUser(userId, userBackupManagerService); } - private Trampoline createServiceAndRegisterUser( + private BackupManagerService createServiceAndRegisterUser( int userId, UserBackupManagerService userBackupManagerService) { - Trampoline backupManagerService = createService(); + BackupManagerService backupManagerService = createService(); backupManagerService.setBackupServiceActive(userBackupManagerService.getUserId(), true); backupManagerService.startServiceForUser(userId, userBackupManagerService); return backupManagerService; diff --git a/services/robotests/backup/src/com/android/server/backup/BackupManagerServiceTest.java b/services/robotests/backup/src/com/android/server/backup/BackupManagerServiceTest.java deleted file mode 100644 index a034474837a5..000000000000 --- a/services/robotests/backup/src/com/android/server/backup/BackupManagerServiceTest.java +++ /dev/null @@ -1,231 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.backup; - -import static android.Manifest.permission.BACKUP; -import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; - -import static com.google.common.truth.Truth.assertThat; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -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.content.Context; -import android.os.ParcelFileDescriptor; -import android.os.Process; -import android.os.UserHandle; -import android.os.UserManager; -import android.platform.test.annotations.Presubmit; -import android.util.SparseArray; - -import com.android.server.testing.shadows.ShadowApplicationPackageManager; -import com.android.server.testing.shadows.ShadowBinder; -import com.android.server.testing.shadows.ShadowEnvironment; -import com.android.server.testing.shadows.ShadowSystemServiceRegistry; -import com.android.server.testing.shadows.ShadowUserManager; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; -import org.robolectric.annotation.Config; -import org.robolectric.shadow.api.Shadow; -import org.robolectric.shadows.ShadowContextWrapper; - -import java.io.File; - -/** Tests for the user-aware backup/restore system service {@link BackupManagerService}. */ -@RunWith(RobolectricTestRunner.class) -@Config( - shadows = { - ShadowApplicationPackageManager.class, - ShadowBinder.class, - ShadowEnvironment.class, - ShadowSystemServiceRegistry.class, - ShadowUserManager.class, - }) -@Presubmit -public class BackupManagerServiceTest { - private static final String TEST_PACKAGE = "package"; - private static final String TEST_TRANSPORT = "transport"; - private static final String[] ADB_TEST_PACKAGES = {TEST_PACKAGE}; - - private ShadowContextWrapper mShadowContext; - private ShadowUserManager mShadowUserManager; - private Context mContext; - private Trampoline mTrampoline; - @UserIdInt private int mUserOneId; - @UserIdInt private int mUserTwoId; - @Mock private UserBackupManagerService mUserOneService; - @Mock private UserBackupManagerService mUserTwoService; - - /** Initialize {@link BackupManagerService}. */ - @Before - public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - - Application application = RuntimeEnvironment.application; - mContext = application; - mShadowContext = shadowOf(application); - mShadowUserManager = Shadow.extract(UserManager.get(application)); - - mUserOneId = UserHandle.USER_SYSTEM + 1; - mUserTwoId = mUserOneId + 1; - mShadowUserManager.addUser(mUserOneId, "mUserOneId", 0); - mShadowUserManager.addUser(mUserTwoId, "mUserTwoId", 0); - - mShadowContext.grantPermissions(BACKUP); - mShadowContext.grantPermissions(INTERACT_ACROSS_USERS_FULL); - - mTrampoline = new Trampoline(mContext); - ShadowBinder.setCallingUid(Process.SYSTEM_UID); - } - - /** - * 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. - */ - @Test - public void testMoreDebug_isFalse() throws Exception { - boolean moreDebug = BackupManagerService.MORE_DEBUG; - - assertThat(moreDebug).isFalse(); - } - - /** Test that the constructor does not create {@link UserBackupManagerService} instances. */ - @Test - public void testConstructor_doesNotRegisterUsers() throws Exception { - BackupManagerService backupManagerService = createService(); - - assertThat(mTrampoline.getUserServices().size()).isEqualTo(0); - } - - /** Test that the constructor handles {@code null} parameters. */ - @Test - public void testConstructor_withNullContext_throws() throws Exception { - expectThrows( - NullPointerException.class, - () -> - new BackupManagerService( - /* context */ null, - new Trampoline(mContext), - new SparseArray<>())); - } - - /** Test that the constructor handles {@code null} parameters. */ - @Test - public void testConstructor_withNullTrampoline_throws() throws Exception { - expectThrows( - NullPointerException.class, - () -> - new BackupManagerService( - mContext, /* trampoline */ null, new SparseArray<>())); - } - - // --------------------------------------------- - // Lifecycle tests - // --------------------------------------------- - - /** testOnStart_publishesService */ - @Test - public void testOnStart_publishesService() { - Trampoline trampoline = mock(Trampoline.class); - BackupManagerService.Lifecycle lifecycle = - spy(new BackupManagerService.Lifecycle(mContext, trampoline)); - doNothing().when(lifecycle).publishService(anyString(), any()); - - lifecycle.onStart(); - - verify(lifecycle).publishService(Context.BACKUP_SERVICE, trampoline); - } - - /** testOnUnlockUser_forwards */ - @Test - public void testOnUnlockUser_forwards() { - Trampoline trampoline = mock(Trampoline.class); - BackupManagerService.Lifecycle lifecycle = - new BackupManagerService.Lifecycle(mContext, trampoline); - - lifecycle.onUnlockUser(UserHandle.USER_SYSTEM); - - verify(trampoline).onUnlockUser(UserHandle.USER_SYSTEM); - } - - /** testOnStopUser_forwards */ - @Test - public void testOnStopUser_forwards() { - Trampoline trampoline = mock(Trampoline.class); - BackupManagerService.Lifecycle lifecycle = - new BackupManagerService.Lifecycle(mContext, trampoline); - - lifecycle.onStopUser(UserHandle.USER_SYSTEM); - - verify(trampoline).onStopUser(UserHandle.USER_SYSTEM); - } - - private BackupManagerService createService() { - mShadowContext.grantPermissions(BACKUP); - return new BackupManagerService(mContext, mTrampoline, mTrampoline.getUserServices()); - } - - private void registerUser(int userId, UserBackupManagerService userBackupManagerService) { - mTrampoline.setBackupServiceActive(userId, true); - mTrampoline.startServiceForUser(userId, userBackupManagerService); - } - - /** - * Sets the calling user to {@code userId} and grants the permission INTERACT_ACROSS_USERS_FULL - * to the caller if {@code shouldGrantPermission} is {@code true}, else it denies the - * permission. - */ - private void setCallerAndGrantInteractUserPermission( - @UserIdInt int userId, boolean shouldGrantPermission) { - ShadowBinder.setCallingUserHandle(UserHandle.of(userId)); - if (shouldGrantPermission) { - mShadowContext.grantPermissions(INTERACT_ACROSS_USERS_FULL); - } else { - mShadowContext.denyPermissions(INTERACT_ACROSS_USERS_FULL); - } - } - - private ParcelFileDescriptor getFileDescriptorForAdbTest() throws Exception { - File testFile = new File(mContext.getFilesDir(), "test"); - testFile.createNewFile(); - return ParcelFileDescriptor.open(testFile, ParcelFileDescriptor.MODE_READ_WRITE); - } -} diff --git a/services/robotests/backup/src/com/android/server/backup/UserBackupManagerServiceTest.java b/services/robotests/backup/src/com/android/server/backup/UserBackupManagerServiceTest.java index 84e810dbb325..8632ca4c2898 100644 --- a/services/robotests/backup/src/com/android/server/backup/UserBackupManagerServiceTest.java +++ b/services/robotests/backup/src/com/android/server/backup/UserBackupManagerServiceTest.java @@ -1005,7 +1005,7 @@ public class UserBackupManagerServiceTest { UserBackupManagerService.createAndInitializeService( USER_ID, mContext, - new Trampoline(mContext), + new BackupManagerService(mContext), mBackupThread, mBaseStateDir, mDataDir, @@ -1026,7 +1026,7 @@ public class UserBackupManagerServiceTest { UserBackupManagerService.createAndInitializeService( USER_ID, mContext, - new Trampoline(mContext), + new BackupManagerService(mContext), mBackupThread, mBaseStateDir, mDataDir, @@ -1045,7 +1045,7 @@ public class UserBackupManagerServiceTest { UserBackupManagerService.createAndInitializeService( USER_ID, /* context */ null, - new Trampoline(mContext), + new BackupManagerService(mContext), mBackupThread, mBaseStateDir, mDataDir, @@ -1077,7 +1077,7 @@ public class UserBackupManagerServiceTest { UserBackupManagerService.createAndInitializeService( USER_ID, mContext, - new Trampoline(mContext), + new BackupManagerService(mContext), /* backupThread */ null, mBaseStateDir, mDataDir, @@ -1093,7 +1093,7 @@ public class UserBackupManagerServiceTest { UserBackupManagerService.createAndInitializeService( USER_ID, mContext, - new Trampoline(mContext), + new BackupManagerService(mContext), mBackupThread, /* baseStateDir */ null, mDataDir, @@ -1102,8 +1102,8 @@ public class UserBackupManagerServiceTest { /** * Test checking non-null argument on {@link - * UserBackupManagerService#createAndInitializeService(int, Context, Trampoline, HandlerThread, - * File, File, TransportManager)}. + * UserBackupManagerService#createAndInitializeService(int, Context, BackupManagerService, + * HandlerThread, File, File, TransportManager)}. */ @Test public void testCreateAndInitializeService_withNullDataDir_throws() { @@ -1113,7 +1113,7 @@ public class UserBackupManagerServiceTest { UserBackupManagerService.createAndInitializeService( USER_ID, mContext, - new Trampoline(mContext), + new BackupManagerService(mContext), mBackupThread, mBaseStateDir, /* dataDir */ null, @@ -1122,8 +1122,8 @@ public class UserBackupManagerServiceTest { /** * Test checking non-null argument on {@link - * UserBackupManagerService#createAndInitializeService(int, Context, Trampoline, HandlerThread, - * File, File, TransportManager)}. + * UserBackupManagerService#createAndInitializeService(int, Context, BackupManagerService, + * HandlerThread, File, File, TransportManager)}. */ @Test public void testCreateAndInitializeService_withNullTransportManager_throws() { @@ -1133,7 +1133,7 @@ public class UserBackupManagerServiceTest { UserBackupManagerService.createAndInitializeService( USER_ID, mContext, - new Trampoline(mContext), + new BackupManagerService(mContext), mBackupThread, mBaseStateDir, mDataDir, @@ -1151,7 +1151,7 @@ public class UserBackupManagerServiceTest { UserBackupManagerService service = UserBackupManagerService.createAndInitializeService( USER_ID, contextSpy, - new Trampoline(mContext), + new BackupManagerService(mContext), mBackupThread, mBaseStateDir, mDataDir, diff --git a/services/robotests/backup/src/com/android/server/backup/testing/BackupManagerServiceTestUtils.java b/services/robotests/backup/src/com/android/server/backup/testing/BackupManagerServiceTestUtils.java index 392d182328a5..84421ef178c9 100644 --- a/services/robotests/backup/src/com/android/server/backup/testing/BackupManagerServiceTestUtils.java +++ b/services/robotests/backup/src/com/android/server/backup/testing/BackupManagerServiceTestUtils.java @@ -37,7 +37,7 @@ import android.os.Process; import android.util.Log; import com.android.server.backup.BackupAgentTimeoutParameters; -import com.android.server.backup.Trampoline; +import com.android.server.backup.BackupManagerService; import com.android.server.backup.TransportManager; import com.android.server.backup.UserBackupManagerService; @@ -89,7 +89,7 @@ public class BackupManagerServiceTestUtils { UserBackupManagerService.createAndInitializeService( userId, context, - new Trampoline(context), + new BackupManagerService(context), backupThread, baseStateDir, dataDir, diff --git a/services/tests/servicestests/src/com/android/server/backup/TrampolineTest.java b/services/tests/servicestests/src/com/android/server/backup/BackupManagerServiceTest.java index 848ef4545034..68b413ff976c 100644 --- a/services/tests/servicestests/src/com/android/server/backup/TrampolineTest.java +++ b/services/tests/servicestests/src/com/android/server/backup/BackupManagerServiceTest.java @@ -11,7 +11,7 @@ * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and - * limitations under the License + * limitations under the License. */ package com.android.server.backup; @@ -76,7 +76,7 @@ import java.util.concurrent.TimeUnit; @SmallTest @Presubmit @RunWith(AndroidJUnit4.class) -public class TrampolineTest { +public class BackupManagerServiceTest { private static final String PACKAGE_NAME = "some.package.name"; private static final String TRANSPORT_NAME = "some.transport.name"; private static final String CURRENT_PASSWORD = "current_password"; @@ -100,8 +100,6 @@ public class TrampolineTest { @UserIdInt private int mUserId; @Mock - private BackupManagerService mBackupManagerServiceMock; - @Mock private UserBackupManagerService mUserBackupManagerService; @Mock private Context mContextMock; @@ -124,7 +122,7 @@ public class TrampolineTest { private FileDescriptor mFileDescriptorStub = new FileDescriptor(); - private TrampolineTestable mTrampoline; + private BackupManagerServiceTestable mService; private File mTestDir; private File mSuppressFile; private SparseArray<UserBackupManagerService> mUserServices; @@ -142,38 +140,37 @@ public class TrampolineTest { when(mUserManagerMock.getUserInfo(NON_USER_SYSTEM)).thenReturn(mUserInfoMock); when(mUserManagerMock.getUserInfo(UNSTARTED_NON_USER_SYSTEM)).thenReturn(mUserInfoMock); - TrampolineTestable.sBackupManagerServiceMock = mBackupManagerServiceMock; - TrampolineTestable.sCallingUserId = UserHandle.USER_SYSTEM; - TrampolineTestable.sCallingUid = Process.SYSTEM_UID; - TrampolineTestable.sBackupDisabled = false; - TrampolineTestable.sUserManagerMock = mUserManagerMock; + BackupManagerServiceTestable.sCallingUserId = UserHandle.USER_SYSTEM; + BackupManagerServiceTestable.sCallingUid = Process.SYSTEM_UID; + BackupManagerServiceTestable.sBackupDisabled = false; + BackupManagerServiceTestable.sUserManagerMock = mUserManagerMock; mTestDir = InstrumentationRegistry.getContext().getFilesDir(); mTestDir.mkdirs(); mSuppressFile = new File(mTestDir, "suppress"); - TrampolineTestable.sSuppressFile = mSuppressFile; + BackupManagerServiceTestable.sSuppressFile = mSuppressFile; setUpStateFilesForNonSystemUser(NON_USER_SYSTEM); setUpStateFilesForNonSystemUser(UNSTARTED_NON_USER_SYSTEM); when(mContextMock.getSystemService(Context.JOB_SCHEDULER_SERVICE)) .thenReturn(mock(JobScheduler.class)); - mTrampoline = new TrampolineTestable(mContextMock, mUserServices); + mService = new BackupManagerServiceTestable(mContextMock, mUserServices); } private void setUpStateFilesForNonSystemUser(int userId) { File activatedFile = new File(mTestDir, "activate-" + userId); - TrampolineTestable.sActivatedFiles.append(userId, activatedFile); + BackupManagerServiceTestable.sActivatedFiles.append(userId, activatedFile); File rememberActivatedFile = new File(mTestDir, "rem-activate-" + userId); - TrampolineTestable.sRememberActivatedFiles.append(userId, rememberActivatedFile); + BackupManagerServiceTestable.sRememberActivatedFiles.append(userId, rememberActivatedFile); } @After public void tearDown() throws Exception { mSuppressFile.delete(); - deleteFiles(TrampolineTestable.sActivatedFiles); - deleteFiles(TrampolineTestable.sRememberActivatedFiles); + deleteFiles(BackupManagerServiceTestable.sActivatedFiles); + deleteFiles(BackupManagerServiceTestable.sRememberActivatedFiles); } private void deleteFiles(SparseArray<File> files) { @@ -185,144 +182,149 @@ public class TrampolineTest { @Test public void testIsBackupServiceActive_whenBackupsNotDisabledAndSuppressFileDoesNotExist() { - assertTrue(mTrampoline.isBackupServiceActive(UserHandle.USER_SYSTEM)); + assertTrue(mService.isBackupServiceActive(UserHandle.USER_SYSTEM)); } @Test public void testOnUnlockUser_forNonSystemUserWhenBackupsDisabled_doesNotStartUser() { - TrampolineTestable.sBackupDisabled = true; - TrampolineTestable trampoline = new TrampolineTestable(mContextMock, new SparseArray<>()); + BackupManagerServiceTestable.sBackupDisabled = true; + BackupManagerServiceTestable service = + new BackupManagerServiceTestable(mContextMock, new SparseArray<>()); ConditionVariable unlocked = new ConditionVariable(false); - trampoline.onUnlockUser(NON_USER_SYSTEM); + service.onUnlockUser(NON_USER_SYSTEM); - trampoline.getBackupHandler().post(unlocked::open); + service.getBackupHandler().post(unlocked::open); unlocked.block(); - assertNull(trampoline.getUserService(NON_USER_SYSTEM)); + assertNull(service.getUserService(NON_USER_SYSTEM)); } @Test public void testOnUnlockUser_forSystemUserWhenBackupsDisabled_doesNotStartUser() { - TrampolineTestable.sBackupDisabled = true; - TrampolineTestable trampoline = new TrampolineTestable(mContextMock, new SparseArray<>()); + BackupManagerServiceTestable.sBackupDisabled = true; + BackupManagerServiceTestable service = + new BackupManagerServiceTestable(mContextMock, new SparseArray<>()); ConditionVariable unlocked = new ConditionVariable(false); - trampoline.onUnlockUser(UserHandle.USER_SYSTEM); + service.onUnlockUser(UserHandle.USER_SYSTEM); - trampoline.getBackupHandler().post(unlocked::open); + service.getBackupHandler().post(unlocked::open); unlocked.block(); - assertNull(trampoline.getUserService(UserHandle.USER_SYSTEM)); + assertNull(service.getUserService(UserHandle.USER_SYSTEM)); } @Test public void testOnUnlockUser_whenBackupNotActivated_doesNotStartUser() { - TrampolineTestable.sBackupDisabled = false; - TrampolineTestable trampoline = new TrampolineTestable(mContextMock, new SparseArray<>()); - trampoline.setBackupServiceActive(NON_USER_SYSTEM, false); + BackupManagerServiceTestable.sBackupDisabled = false; + BackupManagerServiceTestable service = + new BackupManagerServiceTestable(mContextMock, new SparseArray<>()); + service.setBackupServiceActive(NON_USER_SYSTEM, false); ConditionVariable unlocked = new ConditionVariable(false); - trampoline.onUnlockUser(NON_USER_SYSTEM); + service.onUnlockUser(NON_USER_SYSTEM); - trampoline.getBackupHandler().post(unlocked::open); + service.getBackupHandler().post(unlocked::open); unlocked.block(); - assertNull(trampoline.getUserService(NON_USER_SYSTEM)); + assertNull(service.getUserService(NON_USER_SYSTEM)); } @Test public void testIsBackupServiceActive_forSystemUserWhenBackupDisabled_returnsTrue() throws Exception { - TrampolineTestable.sBackupDisabled = true; - Trampoline trampoline = new TrampolineTestable(mContextMock, mUserServices); - trampoline.setBackupServiceActive(UserHandle.USER_SYSTEM, true); + BackupManagerServiceTestable.sBackupDisabled = true; + BackupManagerService backupManagerService = + new BackupManagerServiceTestable(mContextMock, mUserServices); + backupManagerService.setBackupServiceActive(UserHandle.USER_SYSTEM, true); - assertFalse(trampoline.isBackupServiceActive(UserHandle.USER_SYSTEM)); + assertFalse(backupManagerService.isBackupServiceActive(UserHandle.USER_SYSTEM)); } @Test public void testIsBackupServiceActive_forNonSystemUserWhenBackupDisabled_returnsTrue() throws Exception { - TrampolineTestable.sBackupDisabled = true; - Trampoline trampoline = new TrampolineTestable(mContextMock, mUserServices); - trampoline.setBackupServiceActive(NON_USER_SYSTEM, true); + BackupManagerServiceTestable.sBackupDisabled = true; + BackupManagerService backupManagerService = + new BackupManagerServiceTestable(mContextMock, mUserServices); + backupManagerService.setBackupServiceActive(NON_USER_SYSTEM, true); - assertFalse(trampoline.isBackupServiceActive(NON_USER_SYSTEM)); + assertFalse(backupManagerService.isBackupServiceActive(NON_USER_SYSTEM)); } @Test public void isBackupServiceActive_forSystemUser_returnsTrueWhenActivated() throws Exception { - mTrampoline.setBackupServiceActive(UserHandle.USER_SYSTEM, true); + mService.setBackupServiceActive(UserHandle.USER_SYSTEM, true); - assertTrue(mTrampoline.isBackupServiceActive(UserHandle.USER_SYSTEM)); + assertTrue(mService.isBackupServiceActive(UserHandle.USER_SYSTEM)); } @Test public void isBackupServiceActive_forSystemUser_returnsFalseWhenDeactivated() throws Exception { - mTrampoline.setBackupServiceActive(UserHandle.USER_SYSTEM, false); + mService.setBackupServiceActive(UserHandle.USER_SYSTEM, false); - assertFalse(mTrampoline.isBackupServiceActive(UserHandle.USER_SYSTEM)); + assertFalse(mService.isBackupServiceActive(UserHandle.USER_SYSTEM)); } @Test public void isBackupServiceActive_forNonSystemUser_returnsFalseWhenSystemUserDeactivated() throws Exception { - mTrampoline.setBackupServiceActive(UserHandle.USER_SYSTEM, false); - mTrampoline.setBackupServiceActive(NON_USER_SYSTEM, true); + mService.setBackupServiceActive(UserHandle.USER_SYSTEM, false); + mService.setBackupServiceActive(NON_USER_SYSTEM, true); - assertFalse(mTrampoline.isBackupServiceActive(NON_USER_SYSTEM)); + assertFalse(mService.isBackupServiceActive(NON_USER_SYSTEM)); } @Test public void isBackupServiceActive_forNonSystemUser_returnsFalseWhenNonSystemUserDeactivated() throws Exception { - mTrampoline.setBackupServiceActive(UserHandle.USER_SYSTEM, true); + mService.setBackupServiceActive(UserHandle.USER_SYSTEM, true); // Don't activate non-system user. - assertFalse(mTrampoline.isBackupServiceActive(NON_USER_SYSTEM)); + assertFalse(mService.isBackupServiceActive(NON_USER_SYSTEM)); } @Test public void isBackupServiceActive_forNonSystemUser_returnsTrueWhenSystemAndNonSystemUserActivated() - throws Exception { - mTrampoline.setBackupServiceActive(UserHandle.USER_SYSTEM, true); - mTrampoline.setBackupServiceActive(NON_USER_SYSTEM, true); + throws Exception { + mService.setBackupServiceActive(UserHandle.USER_SYSTEM, true); + mService.setBackupServiceActive(NON_USER_SYSTEM, true); - assertTrue(mTrampoline.isBackupServiceActive(NON_USER_SYSTEM)); + assertTrue(mService.isBackupServiceActive(NON_USER_SYSTEM)); } @Test public void isBackupServiceActive_forUnstartedNonSystemUser_returnsTrueWhenSystemAndUserActivated() throws Exception { - mTrampoline.setBackupServiceActive(UNSTARTED_NON_USER_SYSTEM, true); + mService.setBackupServiceActive(UNSTARTED_NON_USER_SYSTEM, true); - assertTrue(mTrampoline.isBackupServiceActive(UNSTARTED_NON_USER_SYSTEM)); + assertTrue(mService.isBackupServiceActive(UNSTARTED_NON_USER_SYSTEM)); } @Test public void setBackupServiceActive_forSystemUserAndCallerSystemUid_serviceCreated() { - TrampolineTestable.sCallingUid = Process.SYSTEM_UID; + BackupManagerServiceTestable.sCallingUid = Process.SYSTEM_UID; - mTrampoline.setBackupServiceActive(UserHandle.USER_SYSTEM, true); + mService.setBackupServiceActive(UserHandle.USER_SYSTEM, true); - assertTrue(mTrampoline.isBackupServiceActive(UserHandle.USER_SYSTEM)); + assertTrue(mService.isBackupServiceActive(UserHandle.USER_SYSTEM)); } @Test public void setBackupServiceActive_forSystemUserAndCallerRootUid_serviceCreated() { - TrampolineTestable.sCallingUid = Process.ROOT_UID; + BackupManagerServiceTestable.sCallingUid = Process.ROOT_UID; - mTrampoline.setBackupServiceActive(UserHandle.USER_SYSTEM, true); + mService.setBackupServiceActive(UserHandle.USER_SYSTEM, true); - assertTrue(mTrampoline.isBackupServiceActive(UserHandle.USER_SYSTEM)); + assertTrue(mService.isBackupServiceActive(UserHandle.USER_SYSTEM)); } @Test public void setBackupServiceActive_forSystemUserAndCallerNonRootNonSystem_throws() { - TrampolineTestable.sCallingUid = Process.FIRST_APPLICATION_UID; + BackupManagerServiceTestable.sCallingUid = Process.FIRST_APPLICATION_UID; try { - mTrampoline.setBackupServiceActive(UserHandle.USER_SYSTEM, true); + mService.setBackupServiceActive(UserHandle.USER_SYSTEM, true); fail(); } catch (SecurityException expected) { } @@ -331,30 +333,30 @@ public class TrampolineTest { @Test public void setBackupServiceActive_forManagedProfileAndCallerSystemUid_serviceCreated() { when(mUserInfoMock.isManagedProfile()).thenReturn(true); - TrampolineTestable.sCallingUid = Process.SYSTEM_UID; + BackupManagerServiceTestable.sCallingUid = Process.SYSTEM_UID; - mTrampoline.setBackupServiceActive(NON_USER_SYSTEM, true); + mService.setBackupServiceActive(NON_USER_SYSTEM, true); - assertTrue(mTrampoline.isBackupServiceActive(NON_USER_SYSTEM)); + assertTrue(mService.isBackupServiceActive(NON_USER_SYSTEM)); } @Test public void setBackupServiceActive_forManagedProfileAndCallerRootUid_serviceCreated() { when(mUserInfoMock.isManagedProfile()).thenReturn(true); - TrampolineTestable.sCallingUid = Process.ROOT_UID; + BackupManagerServiceTestable.sCallingUid = Process.ROOT_UID; - mTrampoline.setBackupServiceActive(NON_USER_SYSTEM, true); + mService.setBackupServiceActive(NON_USER_SYSTEM, true); - assertTrue(mTrampoline.isBackupServiceActive(NON_USER_SYSTEM)); + assertTrue(mService.isBackupServiceActive(NON_USER_SYSTEM)); } @Test public void setBackupServiceActive_forManagedProfileAndCallerNonRootNonSystem_throws() { when(mUserInfoMock.isManagedProfile()).thenReturn(true); - TrampolineTestable.sCallingUid = Process.FIRST_APPLICATION_UID; + BackupManagerServiceTestable.sCallingUid = Process.FIRST_APPLICATION_UID; try { - mTrampoline.setBackupServiceActive(NON_USER_SYSTEM, true); + mService.setBackupServiceActive(NON_USER_SYSTEM, true); fail(); } catch (SecurityException expected) { } @@ -367,7 +369,7 @@ public class TrampolineTest { .enforceCallingOrSelfPermission(eq(Manifest.permission.BACKUP), anyString()); try { - mTrampoline.setBackupServiceActive(NON_USER_SYSTEM, true); + mService.setBackupServiceActive(NON_USER_SYSTEM, true); fail(); } catch (SecurityException expected) { } @@ -381,7 +383,7 @@ public class TrampolineTest { eq(Manifest.permission.INTERACT_ACROSS_USERS_FULL), anyString()); try { - mTrampoline.setBackupServiceActive(NON_USER_SYSTEM, true); + mService.setBackupServiceActive(NON_USER_SYSTEM, true); fail(); } catch (SecurityException expected) { } @@ -389,95 +391,96 @@ public class TrampolineTest { @Test public void setBackupServiceActive_backupDisabled_ignored() { - TrampolineTestable.sBackupDisabled = true; - TrampolineTestable trampoline = new TrampolineTestable(mContextMock, mUserServices); + BackupManagerServiceTestable.sBackupDisabled = true; + BackupManagerServiceTestable service = + new BackupManagerServiceTestable(mContextMock, mUserServices); - trampoline.setBackupServiceActive(UserHandle.USER_SYSTEM, true); + service.setBackupServiceActive(UserHandle.USER_SYSTEM, true); - assertFalse(trampoline.isBackupServiceActive(UserHandle.USER_SYSTEM)); + assertFalse(service.isBackupServiceActive(UserHandle.USER_SYSTEM)); } @Test public void setBackupServiceActive_alreadyActive_ignored() { - mTrampoline.setBackupServiceActive(UserHandle.USER_SYSTEM, true); - assertTrue(mTrampoline.isBackupServiceActive(UserHandle.USER_SYSTEM)); + mService.setBackupServiceActive(UserHandle.USER_SYSTEM, true); + assertTrue(mService.isBackupServiceActive(UserHandle.USER_SYSTEM)); - mTrampoline.setBackupServiceActive(UserHandle.USER_SYSTEM, true); - assertTrue(mTrampoline.isBackupServiceActive(UserHandle.USER_SYSTEM)); + mService.setBackupServiceActive(UserHandle.USER_SYSTEM, true); + assertTrue(mService.isBackupServiceActive(UserHandle.USER_SYSTEM)); } @Test public void setBackupServiceActive_makeNonActive_alreadyNonActive_ignored() { - mTrampoline.setBackupServiceActive(UserHandle.USER_SYSTEM, false); - mTrampoline.setBackupServiceActive(UserHandle.USER_SYSTEM, false); + mService.setBackupServiceActive(UserHandle.USER_SYSTEM, false); + mService.setBackupServiceActive(UserHandle.USER_SYSTEM, false); - assertFalse(mTrampoline.isBackupServiceActive(UserHandle.USER_SYSTEM)); + assertFalse(mService.isBackupServiceActive(UserHandle.USER_SYSTEM)); } @Test public void setBackupServiceActive_makeActive_serviceCreatedAndSuppressFileDeleted() { - mTrampoline.setBackupServiceActive(UserHandle.USER_SYSTEM, true); + mService.setBackupServiceActive(UserHandle.USER_SYSTEM, true); - assertTrue(mTrampoline.isBackupServiceActive(UserHandle.USER_SYSTEM)); + assertTrue(mService.isBackupServiceActive(UserHandle.USER_SYSTEM)); } @Test public void setBackupServiceActive_makeNonActive_serviceDeletedAndSuppressFileCreated() throws IOException { - assertTrue(mTrampoline.isBackupServiceActive(UserHandle.USER_SYSTEM)); + assertTrue(mService.isBackupServiceActive(UserHandle.USER_SYSTEM)); - mTrampoline.setBackupServiceActive(UserHandle.USER_SYSTEM, false); + mService.setBackupServiceActive(UserHandle.USER_SYSTEM, false); - assertFalse(mTrampoline.isBackupServiceActive(UserHandle.USER_SYSTEM)); + assertFalse(mService.isBackupServiceActive(UserHandle.USER_SYSTEM)); } @Test public void setBackupActive_nonSystemUser_disabledForSystemUser_ignored() { - mTrampoline.setBackupServiceActive(UserHandle.USER_SYSTEM, false); - mTrampoline.setBackupServiceActive(NON_USER_SYSTEM, true); + mService.setBackupServiceActive(UserHandle.USER_SYSTEM, false); + mService.setBackupServiceActive(NON_USER_SYSTEM, true); - assertFalse(mTrampoline.isBackupServiceActive(NON_USER_SYSTEM)); + assertFalse(mService.isBackupServiceActive(NON_USER_SYSTEM)); } @Test public void setBackupServiceActive_forOneNonSystemUser_doesNotActivateForAllNonSystemUsers() { int otherUser = NON_USER_SYSTEM + 1; File activateFile = new File(mTestDir, "activate-" + otherUser); - TrampolineTestable.sActivatedFiles.append(otherUser, activateFile); - mTrampoline.setBackupServiceActive(UserHandle.USER_SYSTEM, true); + BackupManagerServiceTestable.sActivatedFiles.append(otherUser, activateFile); + mService.setBackupServiceActive(UserHandle.USER_SYSTEM, true); - mTrampoline.setBackupServiceActive(NON_USER_SYSTEM, true); + mService.setBackupServiceActive(NON_USER_SYSTEM, true); - assertTrue(mTrampoline.isBackupServiceActive(NON_USER_SYSTEM)); - assertFalse(mTrampoline.isBackupServiceActive(otherUser)); + assertTrue(mService.isBackupServiceActive(NON_USER_SYSTEM)); + assertFalse(mService.isBackupServiceActive(otherUser)); activateFile.delete(); } @Test public void setBackupServiceActive_forNonSystemUser_remembersActivated() { - mTrampoline.setBackupServiceActive(NON_USER_SYSTEM, true); + mService.setBackupServiceActive(NON_USER_SYSTEM, true); assertTrue(RandomAccessFileUtils.readBoolean( - TrampolineTestable.sRememberActivatedFiles.get(NON_USER_SYSTEM), false)); + BackupManagerServiceTestable.sRememberActivatedFiles.get(NON_USER_SYSTEM), false)); } @Test public void setBackupServiceActiveFalse_forNonSystemUser_remembersActivated() { - mTrampoline.setBackupServiceActive(NON_USER_SYSTEM, false); + mService.setBackupServiceActive(NON_USER_SYSTEM, false); assertFalse(RandomAccessFileUtils.readBoolean( - TrampolineTestable.sRememberActivatedFiles.get(NON_USER_SYSTEM), true)); + BackupManagerServiceTestable.sRememberActivatedFiles.get(NON_USER_SYSTEM), true)); } @Test public void setBackupServiceActiveTwice_forNonSystemUser_remembersLastActivated() { - mTrampoline.setBackupServiceActive(NON_USER_SYSTEM, true); - mTrampoline.setBackupServiceActive(NON_USER_SYSTEM, false); + mService.setBackupServiceActive(NON_USER_SYSTEM, true); + mService.setBackupServiceActive(NON_USER_SYSTEM, false); assertFalse(RandomAccessFileUtils.readBoolean( - TrampolineTestable.sRememberActivatedFiles.get(NON_USER_SYSTEM), true)); + BackupManagerServiceTestable.sRememberActivatedFiles.get(NON_USER_SYSTEM), true)); } @Test @@ -497,7 +500,7 @@ public class TrampolineTest { } }; - mTrampoline.selectBackupTransportAsyncForUser(mUserId, TRANSPORT_COMPONENT_NAME, listener); + mService.selectBackupTransportAsyncForUser(mUserId, TRANSPORT_COMPONENT_NAME, listener); assertEquals(BackupManager.ERROR_BACKUP_NOT_ALLOWED, (int) future.get(5, TimeUnit.SECONDS)); } @@ -505,14 +508,14 @@ public class TrampolineTest { @Test public void selectBackupTransportAsyncForUser_beforeUserUnlockedWithNullListener_doesNotThrow() throws Exception { - mTrampoline.selectBackupTransportAsyncForUser(mUserId, TRANSPORT_COMPONENT_NAME, null); + mService.selectBackupTransportAsyncForUser(mUserId, TRANSPORT_COMPONENT_NAME, null); // No crash. } @Test public void - selectBackupTransportAsyncForUser_beforeUserUnlockedWithThrowingListener_doesNotThrow() + selectBackupTransportAsyncForUser_beforeUserUnlockedListenerThrowing_doesNotThrow() throws Exception { ISelectBackupTransportCallback.Stub listener = new ISelectBackupTransportCallback.Stub() { @@ -524,7 +527,7 @@ public class TrampolineTest { } }; - mTrampoline.selectBackupTransportAsyncForUser(mUserId, TRANSPORT_COMPONENT_NAME, listener); + mService.selectBackupTransportAsyncForUser(mUserId, TRANSPORT_COMPONENT_NAME, listener); // No crash. } @@ -535,44 +538,45 @@ public class TrampolineTest { android.Manifest.permission.DUMP)).thenReturn( PackageManager.PERMISSION_DENIED); - mTrampoline.dump(mFileDescriptorStub, mPrintWriterMock, new String[0]); + mService.dump(mFileDescriptorStub, mPrintWriterMock, new String[0]); - verifyNoMoreInteractions(mBackupManagerServiceMock); + verifyNoMoreInteractions(mUserBackupManagerService); } public void testGetUserForAncestralSerialNumber() { - TrampolineTestable.sBackupDisabled = false; - Trampoline trampoline = new TrampolineTestable(mContextMock, mUserServices); + BackupManagerServiceTestable.sBackupDisabled = false; + BackupManagerService backupManagerService = + new BackupManagerServiceTestable(mContextMock, mUserServices); when(mUserBackupManagerService.getAncestralSerialNumber()).thenReturn(11L); - UserHandle user = trampoline.getUserForAncestralSerialNumber(11L); + UserHandle user = backupManagerService.getUserForAncestralSerialNumber(11L); assertThat(user).isEqualTo(UserHandle.of(1)); } public void testGetUserForAncestralSerialNumber_whenDisabled() { - TrampolineTestable.sBackupDisabled = true; - Trampoline trampoline = new TrampolineTestable(mContextMock, mUserServices); + BackupManagerServiceTestable.sBackupDisabled = true; + BackupManagerService backupManagerService = + new BackupManagerServiceTestable(mContextMock, mUserServices); when(mUserBackupManagerService.getAncestralSerialNumber()).thenReturn(11L); - UserHandle user = trampoline.getUserForAncestralSerialNumber(11L); + UserHandle user = backupManagerService.getUserForAncestralSerialNumber(11L); assertThat(user).isNull(); } - private static class TrampolineTestable extends Trampoline { + private static class BackupManagerServiceTestable extends BackupManagerService { static boolean sBackupDisabled = false; static int sCallingUserId = -1; static int sCallingUid = -1; - static BackupManagerService sBackupManagerServiceMock = null; static File sSuppressFile = null; static SparseArray<File> sActivatedFiles = new SparseArray<>(); static SparseArray<File> sRememberActivatedFiles = new SparseArray<>(); static UserManager sUserManagerMock = null; - TrampolineTestable(Context context, SparseArray<UserBackupManagerService> userServices) { + BackupManagerServiceTestable( + Context context, SparseArray<UserBackupManagerService> userServices) { super(context, userServices); - mService = sBackupManagerServiceMock; } @Override |