1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.backup; 18 19 import static java.util.Collections.emptySet; 20 21 import android.Manifest; 22 import android.annotation.NonNull; 23 import android.annotation.Nullable; 24 import android.annotation.UserIdInt; 25 import android.app.ActivityManager; 26 import android.app.admin.DevicePolicyManager; 27 import android.app.backup.BackupManager; 28 import android.app.backup.BackupRestoreEventLogger.DataTypeResult; 29 import android.app.backup.IBackupManager; 30 import android.app.backup.IBackupManagerMonitor; 31 import android.app.backup.IBackupObserver; 32 import android.app.backup.IFullBackupRestoreObserver; 33 import android.app.backup.IRestoreSession; 34 import android.app.backup.ISelectBackupTransportCallback; 35 import android.app.compat.CompatChanges; 36 import android.app.job.JobParameters; 37 import android.app.job.JobScheduler; 38 import android.app.job.JobService; 39 import android.content.BroadcastReceiver; 40 import android.content.ComponentName; 41 import android.content.Context; 42 import android.content.Intent; 43 import android.content.IntentFilter; 44 import android.content.pm.PackageManager; 45 import android.os.Binder; 46 import android.os.FileUtils; 47 import android.os.Handler; 48 import android.os.HandlerThread; 49 import android.os.IBinder; 50 import android.os.ParcelFileDescriptor; 51 import android.os.Process; 52 import android.os.RemoteException; 53 import android.os.SystemProperties; 54 import android.os.Trace; 55 import android.os.UserHandle; 56 import android.os.UserManager; 57 import android.util.Slog; 58 import android.util.SparseArray; 59 60 import com.android.internal.annotations.GuardedBy; 61 import com.android.internal.annotations.VisibleForTesting; 62 import com.android.internal.util.DumpUtils; 63 import com.android.server.SystemConfig; 64 import com.android.server.SystemService; 65 import com.android.server.backup.utils.RandomAccessFileUtils; 66 67 import java.io.File; 68 import java.io.FileDescriptor; 69 import java.io.IOException; 70 import java.io.PrintWriter; 71 import java.util.List; 72 import java.util.Objects; 73 import java.util.Set; 74 75 /** 76 * Definition of the system service that performs backup/restore operations. 77 * 78 * <p>This class is responsible for handling user-aware operations and acts as a delegator, routing 79 * incoming calls to the appropriate per-user {@link UserBackupManagerService} to handle the 80 * corresponding backup/restore operation. 81 * 82 * <p>It also determines whether the backup service is available. It can be disabled in the 83 * following two ways: 84 * 85 * <ul> 86 * <li>Temporary - call {@link #setBackupServiceActive(int, boolean)}, or 87 * <li>Permanent - set the system property {@link #BACKUP_DISABLE_PROPERTY} to true. 88 * </ul> 89 * 90 * Temporary disabling is controlled by {@link #setBackupServiceActive(int, boolean)} through 91 * privileged callers (currently {@link DevicePolicyManager}). If called on {@link 92 * UserHandle#USER_SYSTEM}, backup is disabled for all users. 93 */ 94 public class BackupManagerService extends IBackupManager.Stub { 95 public static final String TAG = "BackupManagerService"; 96 public static final boolean DEBUG = true; 97 public static final boolean MORE_DEBUG = false; 98 public static final boolean DEBUG_SCHEDULING = true; 99 100 @VisibleForTesting 101 static final String DUMP_RUNNING_USERS_MESSAGE = "Backup Manager is running for users:"; 102 103 /** 104 * Name of file that disables the backup service. If this file exists, then backup is disabled 105 * for all users. 106 */ 107 private static final String BACKUP_SUPPRESS_FILENAME = "backup-suppress"; 108 109 /** 110 * Name of file for non-system users that enables the backup service for the user. Backup is 111 * disabled by default in non-system users. 112 */ 113 private static final String BACKUP_ACTIVATED_FILENAME = "backup-activated"; 114 115 /** 116 * Name of file for non-system users that remembers whether backup was explicitly activated or 117 * deactivated with a call to setBackupServiceActive. 118 */ 119 private static final String REMEMBER_ACTIVATED_FILENAME = "backup-remember-activated"; 120 121 // Product-level suppression of backup/restore. 122 private static final String BACKUP_DISABLE_PROPERTY = "ro.backup.disable"; 123 124 private static final String BACKUP_THREAD = "backup"; 125 126 static BackupManagerService sInstance; 127 getInstance()128 static BackupManagerService getInstance() { 129 return Objects.requireNonNull(sInstance); 130 } 131 132 private final Context mContext; 133 private final UserManager mUserManager; 134 135 private final boolean mGlobalDisable; 136 // Lock to write backup suppress files. 137 // TODD(b/121198006): remove this object and synchronized all methods on "this". 138 private final Object mStateLock = new Object(); 139 140 private final Handler mHandler; 141 private final Set<ComponentName> mTransportWhitelist; 142 143 /** Keeps track of all unlocked users registered with this service. Indexed by user id. */ 144 private final SparseArray<UserBackupManagerService> mUserServices; 145 146 private final BroadcastReceiver mUserRemovedReceiver = new BroadcastReceiver() { 147 @Override 148 public void onReceive(Context context, Intent intent) { 149 if (Intent.ACTION_USER_REMOVED.equals(intent.getAction())) { 150 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL); 151 if (userId > 0) { // for only non system users 152 mHandler.post(() -> onRemovedNonSystemUser(userId)); 153 } 154 } 155 } 156 }; 157 158 /** 159 * The user that the backup is activated by default for. 160 * 161 * <p>If there is a {@link UserManager#getMainUser()}, this will be that user. If not, it will 162 * be {@link UserHandle#USER_SYSTEM}. 163 * 164 * <p>Note: on the first ever boot of a new device, this might change once the first user is 165 * unlocked. See {@link #updateDefaultBackupUserIdIfNeeded()}. 166 * 167 * @see #isBackupActivatedForUser(int) 168 */ 169 @UserIdInt private int mDefaultBackupUserId; 170 171 private boolean mHasFirstUserUnlockedSinceBoot = false; 172 BackupManagerService(Context context)173 public BackupManagerService(Context context) { 174 mContext = context; 175 mGlobalDisable = isBackupDisabled(); 176 HandlerThread handlerThread = 177 new HandlerThread(BACKUP_THREAD, Process.THREAD_PRIORITY_BACKGROUND); 178 handlerThread.start(); 179 mHandler = new Handler(handlerThread.getLooper()); 180 mUserManager = UserManager.get(context); 181 mUserServices = new SparseArray<>(); 182 Set<ComponentName> transportWhitelist = 183 SystemConfig.getInstance().getBackupTransportWhitelist(); 184 mTransportWhitelist = (transportWhitelist == null) ? emptySet() : transportWhitelist; 185 mContext.registerReceiver( 186 mUserRemovedReceiver, new IntentFilter(Intent.ACTION_USER_REMOVED)); 187 UserHandle mainUser = getUserManager().getMainUser(); 188 mDefaultBackupUserId = mainUser == null ? UserHandle.USER_SYSTEM : mainUser.getIdentifier(); 189 if (DEBUG) { 190 Slog.d(TAG, "Default backup user id = " + mDefaultBackupUserId); 191 } 192 } 193 194 // TODO: Remove this when we implement DI by injecting in the construtor. 195 @VisibleForTesting getBackupHandler()196 Handler getBackupHandler() { 197 return mHandler; 198 } 199 200 @VisibleForTesting isBackupDisabled()201 protected boolean isBackupDisabled() { 202 return SystemProperties.getBoolean(BACKUP_DISABLE_PROPERTY, false); 203 } 204 205 @VisibleForTesting binderGetCallingUserId()206 protected int binderGetCallingUserId() { 207 return Binder.getCallingUserHandle().getIdentifier(); 208 } 209 210 @VisibleForTesting binderGetCallingUid()211 protected int binderGetCallingUid() { 212 return Binder.getCallingUid(); 213 } 214 215 @VisibleForTesting getSuppressFileForUser(@serIdInt int userId)216 protected File getSuppressFileForUser(@UserIdInt int userId) { 217 return new File(UserBackupManagerFiles.getBaseStateDir(userId), BACKUP_SUPPRESS_FILENAME); 218 } 219 220 /** Stored in the system user's directory and the file is indexed by the user it refers to. */ 221 @VisibleForTesting getRememberActivatedFileForNonSystemUser(int userId)222 protected File getRememberActivatedFileForNonSystemUser(int userId) { 223 return UserBackupManagerFiles.getStateFileInSystemDir(REMEMBER_ACTIVATED_FILENAME, userId); 224 } 225 226 /** Stored in the system user's directory and the file is indexed by the user it refers to. */ 227 @VisibleForTesting getActivatedFileForUser(int userId)228 protected File getActivatedFileForUser(int userId) { 229 return UserBackupManagerFiles.getStateFileInSystemDir(BACKUP_ACTIVATED_FILENAME, userId); 230 } 231 232 /** 233 * Remove backup state for non system {@code userId} when the user is removed from the device. 234 * For non system users, backup state is stored in both the user's own dir and the system dir. 235 * When the user is removed, the user's own dir gets removed by the OS. This method ensures that 236 * the part of the user backup state which is in the system dir also gets removed. 237 */ onRemovedNonSystemUser(int userId)238 private void onRemovedNonSystemUser(int userId) { 239 Slog.i(TAG, "Removing state for non system user " + userId); 240 File dir = UserBackupManagerFiles.getStateDirInSystemDir(userId); 241 if (!FileUtils.deleteContentsAndDir(dir)) { 242 Slog.w(TAG, "Failed to delete state dir for removed user: " + userId); 243 } 244 } 245 246 // TODO (b/124359804) move to util method in FileUtils createFile(File file)247 private void createFile(File file) throws IOException { 248 if (file.exists()) { 249 return; 250 } 251 252 file.getParentFile().mkdirs(); 253 if (!file.createNewFile()) { 254 Slog.w(TAG, "Failed to create file " + file.getPath()); 255 } 256 } 257 258 // TODO (b/124359804) move to util method in FileUtils deleteFile(File file)259 private void deleteFile(File file) { 260 if (!file.exists()) { 261 return; 262 } 263 264 if (!file.delete()) { 265 Slog.w(TAG, "Failed to delete file " + file.getPath()); 266 } 267 } 268 269 /** 270 * Deactivates the backup service for user {@code userId}. 271 * 272 * If this is the system user or the {@link #mDefaultBackupUserId} user, it creates a "suppress" 273 * file for this user. 274 * 275 * Otherwise, it deleties the user's "activated" file. 276 * 277 * Note that if backup is deactivated for the system user, it will be deactivated for ALL 278 * users until it is reactivated for the system user, at which point the per-user activation 279 * status will be the source of truth. 280 */ 281 @GuardedBy("mStateLock") deactivateBackupForUserLocked(int userId)282 private void deactivateBackupForUserLocked(int userId) throws IOException { 283 if (userId == UserHandle.USER_SYSTEM || userId == mDefaultBackupUserId) { 284 createFile(getSuppressFileForUser(userId)); 285 } else { 286 deleteFile(getActivatedFileForUser(userId)); 287 } 288 } 289 290 /** 291 * Activates the backup service for user {@code userId}. 292 * 293 * If this is the system user or the {@link #mDefaultBackupUserId} user, it deletes its 294 * "suppress" file. 295 * 296 * Otherwise, it creates the user's "activated" file. 297 */ 298 @GuardedBy("mStateLock") activateBackupForUserLocked(int userId)299 private void activateBackupForUserLocked(int userId) throws IOException { 300 if (userId == UserHandle.USER_SYSTEM || userId == mDefaultBackupUserId) { 301 deleteFile(getSuppressFileForUser(userId)); 302 } else { 303 createFile(getActivatedFileForUser(userId)); 304 } 305 } 306 307 /** 308 * This method should not perform any I/O (e.g. do not call isBackupActivatedForUser), 309 * it's used in multiple places where I/O waits would cause system lock-ups. 310 * @param userId User id for which this operation should be performed. 311 * @return true if the user is ready for backup and false otherwise. 312 */ 313 @Override isUserReadyForBackup(int userId)314 public boolean isUserReadyForBackup(int userId) { 315 enforceCallingPermissionOnUserId(userId, "isUserReadyForBackup()"); 316 return mUserServices.get(userId) != null; 317 } 318 319 /** 320 * If there is a "suppress" file for the system user, backup is inactive for ALL users. 321 * 322 * Otherwise, the below logic applies: 323 * 324 * For the {@link #mDefaultBackupUserId}, backup is active by default. Backup is only 325 * deactivated if there exists a "suppress" file for the user, which can be created by calling 326 * {@link #setBackupServiceActive}. 327 * 328 * For non-main users, backup is only active if there exists an "activated" file for the user, 329 * which can also be created by calling {@link #setBackupServiceActive}. 330 */ isBackupActivatedForUser(int userId)331 private boolean isBackupActivatedForUser(int userId) { 332 if (getSuppressFileForUser(UserHandle.USER_SYSTEM).exists()) { 333 return false; 334 } 335 336 boolean isDefaultUser = userId == mDefaultBackupUserId; 337 338 // If the default user is not the system user, we are in headless mode and the system user 339 // doesn't have an actual human user associated with it. 340 if ((userId == UserHandle.USER_SYSTEM) && !isDefaultUser) { 341 return false; 342 } 343 344 if (isDefaultUser && getSuppressFileForUser(userId).exists()) { 345 return false; 346 } 347 348 return isDefaultUser || getActivatedFileForUser(userId).exists(); 349 } 350 351 @VisibleForTesting getContext()352 protected Context getContext() { 353 return mContext; 354 } 355 356 @VisibleForTesting getUserManager()357 protected UserManager getUserManager() { 358 return mUserManager; 359 } 360 361 @VisibleForTesting postToHandler(Runnable runnable)362 protected void postToHandler(Runnable runnable) { 363 mHandler.post(runnable); 364 } 365 366 /** 367 * Starts the backup service for user {@code userId} by creating a new instance of {@link 368 * UserBackupManagerService} and registering it with this service. 369 */ 370 @VisibleForTesting startServiceForUser(int userId)371 void startServiceForUser(int userId) { 372 // We know that the user is unlocked here because it is called from setBackupServiceActive 373 // and unlockUser which have these guarantees. So we can check if the file exists. 374 if (mGlobalDisable) { 375 Slog.i(TAG, "Backup service not supported"); 376 return; 377 } 378 if (!isBackupActivatedForUser(userId)) { 379 Slog.i(TAG, "Backup not activated for user " + userId); 380 return; 381 } 382 if (mUserServices.get(userId) != null) { 383 Slog.i(TAG, "userId " + userId + " already started, so not starting again"); 384 return; 385 } 386 Slog.i(TAG, "Starting service for user: " + userId); 387 UserBackupManagerService userBackupManagerService = 388 UserBackupManagerService.createAndInitializeService( 389 userId, mContext, this, mTransportWhitelist); 390 startServiceForUser(userId, userBackupManagerService); 391 } 392 393 /** 394 * Starts the backup service for user {@code userId} by registering its instance of {@link 395 * UserBackupManagerService} with this service and setting enabled state. 396 */ 397 @VisibleForTesting startServiceForUser(int userId, UserBackupManagerService userBackupManagerService)398 void startServiceForUser(int userId, UserBackupManagerService userBackupManagerService) { 399 mUserServices.put(userId, userBackupManagerService); 400 401 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backup enable"); 402 userBackupManagerService.initializeBackupEnableState(); 403 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 404 } 405 406 /** Stops the backup service for user {@code userId} when the user is stopped. */ 407 @VisibleForTesting stopServiceForUser(int userId)408 protected void stopServiceForUser(int userId) { 409 UserBackupManagerService userBackupManagerService = mUserServices.removeReturnOld(userId); 410 411 if (userBackupManagerService != null) { 412 userBackupManagerService.tearDownService(); 413 414 KeyValueBackupJob.cancel(userId, mContext); 415 FullBackupJob.cancel(userId, mContext); 416 } 417 } 418 419 /** 420 * Returns a list of users currently unlocked that have a {@link UserBackupManagerService} 421 * registered. 422 * 423 * Warning: Do NOT modify returned object as it's used inside. 424 * 425 * TODO: Return a copy or only expose read-only information through other means. 426 */ 427 @VisibleForTesting getUserServices()428 SparseArray<UserBackupManagerService> getUserServices() { 429 return mUserServices; 430 } 431 432 /** 433 * Called from {@link BackupManagerService.Lifecycle} when a user {@code userId} is stopped. 434 * Offloads work onto the handler thread {@link #mHandlerThread} to keep stopping time low. 435 */ onStopUser(int userId)436 void onStopUser(int userId) { 437 postToHandler( 438 () -> { 439 if (!mGlobalDisable) { 440 Slog.i(TAG, "Stopping service for user: " + userId); 441 stopServiceForUser(userId); 442 } 443 }); 444 } 445 446 /** Returns {@link UserBackupManagerService} for user {@code userId}. */ 447 @Nullable getUserService(int userId)448 public UserBackupManagerService getUserService(int userId) { 449 return mUserServices.get(userId); 450 } 451 452 /** 453 * The system user and managed profiles can only be acted on by callers in the system or root 454 * processes. Other users can be acted on by callers who have both android.permission.BACKUP and 455 * android.permission.INTERACT_ACROSS_USERS_FULL permissions. 456 */ enforcePermissionsOnUser(int userId)457 private void enforcePermissionsOnUser(int userId) throws SecurityException { 458 boolean isRestrictedUser = 459 userId == UserHandle.USER_SYSTEM 460 || getUserManager().getUserInfo(userId).isManagedProfile(); 461 462 if (isRestrictedUser) { 463 int caller = binderGetCallingUid(); 464 if (caller != Process.SYSTEM_UID && caller != Process.ROOT_UID) { 465 throw new SecurityException("No permission to configure backup activity"); 466 } 467 } else { 468 mContext.enforceCallingOrSelfPermission( 469 Manifest.permission.BACKUP, "No permission to configure backup activity"); 470 mContext.enforceCallingOrSelfPermission( 471 Manifest.permission.INTERACT_ACROSS_USERS_FULL, 472 "No permission to configure backup activity"); 473 } 474 } 475 476 /** 477 * Only privileged callers should be changing the backup state. Deactivating backup in the 478 * system user also deactivates backup in all users. We are not guaranteed that {@code userId} 479 * is unlocked at this point yet, so handle both cases. 480 */ setBackupServiceActive(int userId, boolean makeActive)481 public void setBackupServiceActive(int userId, boolean makeActive) { 482 enforcePermissionsOnUser(userId); 483 484 // In Q, backup is OFF by default for non-system users. In the future, we will change that 485 // to ON unless backup was explicitly deactivated with a (permissioned) call to 486 // setBackupServiceActive. 487 // Therefore, remember this for use in the future. Basically the default in the future will 488 // be: rememberFile.exists() ? rememberFile.value() : ON 489 // Note that this has to be done right after the permission checks and before any other 490 // action since we need to remember that a permissioned call was made irrespective of 491 // whether the call changes the state or not. 492 if (userId != UserHandle.USER_SYSTEM) { 493 try { 494 File rememberFile = getRememberActivatedFileForNonSystemUser(userId); 495 createFile(rememberFile); 496 RandomAccessFileUtils.writeBoolean(rememberFile, makeActive); 497 } catch (IOException e) { 498 Slog.e(TAG, "Unable to persist backup service activity", e); 499 } 500 } 501 502 if (mGlobalDisable) { 503 Slog.i(TAG, "Backup service not supported"); 504 return; 505 } 506 507 synchronized (mStateLock) { 508 Slog.i(TAG, "Making backup " + (makeActive ? "" : "in") + "active"); 509 if (makeActive) { 510 try { 511 activateBackupForUserLocked(userId); 512 } catch (IOException e) { 513 Slog.e(TAG, "Unable to persist backup service activity"); 514 } 515 516 // If the user is unlocked, we can start the backup service for it. Otherwise we 517 // will start the service when the user is unlocked as part of its unlock callback. 518 if (getUserManager().isUserUnlocked(userId)) { 519 // Clear calling identity as initialization enforces the system identity but we 520 // can be coming from shell. 521 final long oldId = Binder.clearCallingIdentity(); 522 try { 523 startServiceForUser(userId); 524 } finally { 525 Binder.restoreCallingIdentity(oldId); 526 } 527 } 528 } else { 529 try { 530 //TODO(b/121198006): what if this throws an exception? 531 deactivateBackupForUserLocked(userId); 532 } catch (IOException e) { 533 Slog.e(TAG, "Unable to persist backup service inactivity"); 534 } 535 //TODO(b/121198006): loop through active users that have work profile and 536 // stop them as well. 537 onStopUser(userId); 538 } 539 } 540 } 541 542 // IBackupManager binder API 543 544 /** 545 * Querying activity state of backup service. 546 * 547 * @param userId The user in which the activity state of backup service is queried. 548 * @return true if the service is active. 549 */ 550 @Override isBackupServiceActive(int userId)551 public boolean isBackupServiceActive(int userId) { 552 int callingUid = Binder.getCallingUid(); 553 if (CompatChanges.isChangeEnabled( 554 BackupManager.IS_BACKUP_SERVICE_ACTIVE_ENFORCE_PERMISSION_IN_SERVICE, callingUid)) { 555 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP, 556 "isBackupServiceActive"); 557 } 558 synchronized (mStateLock) { 559 return !mGlobalDisable && isBackupActivatedForUser(userId); 560 } 561 } 562 563 @Override dataChangedForUser(int userId, String packageName)564 public void dataChangedForUser(int userId, String packageName) throws RemoteException { 565 if (isUserReadyForBackup(userId)) { 566 dataChanged(userId, packageName); 567 } 568 } 569 570 @Override dataChanged(String packageName)571 public void dataChanged(String packageName) throws RemoteException { 572 dataChangedForUser(binderGetCallingUserId(), packageName); 573 } 574 575 /** 576 * An app's backup agent calls this method to let the service know that there's new data to 577 * backup for their app {@code packageName}. Only used for apps participating in key-value 578 * backup. 579 */ dataChanged(@serIdInt int userId, String packageName)580 public void dataChanged(@UserIdInt int userId, String packageName) { 581 UserBackupManagerService userBackupManagerService = 582 getServiceForUserIfCallerHasPermission(userId, "dataChanged()"); 583 584 if (userBackupManagerService != null) { 585 userBackupManagerService.dataChanged(packageName); 586 } 587 } 588 589 // --------------------------------------------- 590 // TRANSPORT OPERATIONS 591 // --------------------------------------------- 592 593 @Override initializeTransportsForUser( int userId, String[] transportNames, IBackupObserver observer)594 public void initializeTransportsForUser( 595 int userId, String[] transportNames, IBackupObserver observer) throws RemoteException { 596 if (isUserReadyForBackup(userId)) { 597 initializeTransports(userId, transportNames, observer); 598 } 599 } 600 601 /** Run an initialize operation for the given transports {@code transportNames}. */ initializeTransports( @serIdInt int userId, String[] transportNames, IBackupObserver observer)602 public void initializeTransports( 603 @UserIdInt int userId, String[] transportNames, IBackupObserver observer) { 604 UserBackupManagerService userBackupManagerService = 605 getServiceForUserIfCallerHasPermission(userId, "initializeTransports()"); 606 607 if (userBackupManagerService != null) { 608 userBackupManagerService.initializeTransports(transportNames, observer); 609 } 610 } 611 612 @Override clearBackupDataForUser(int userId, String transportName, String packageName)613 public void clearBackupDataForUser(int userId, String transportName, String packageName) 614 throws RemoteException { 615 if (isUserReadyForBackup(userId)) { 616 clearBackupData(userId, transportName, packageName); 617 } 618 } 619 620 /** 621 * Clear the given package {@code packageName}'s backup data from the transport {@code 622 * transportName}. 623 */ clearBackupData(@serIdInt int userId, String transportName, String packageName)624 public void clearBackupData(@UserIdInt int userId, String transportName, String packageName) { 625 UserBackupManagerService userBackupManagerService = 626 getServiceForUserIfCallerHasPermission(userId, "clearBackupData()"); 627 628 if (userBackupManagerService != null) { 629 userBackupManagerService.clearBackupData(transportName, packageName); 630 } 631 } 632 633 @Override clearBackupData(String transportName, String packageName)634 public void clearBackupData(String transportName, String packageName) 635 throws RemoteException { 636 clearBackupDataForUser(binderGetCallingUserId(), transportName, packageName); 637 } 638 639 @Override agentConnectedForUser(int userId, String packageName, IBinder agent)640 public void agentConnectedForUser(int userId, String packageName, IBinder agent) 641 throws RemoteException { 642 if (isUserReadyForBackup(userId)) { 643 agentConnected(userId, packageName, agent); 644 } 645 } 646 647 @Override agentConnected(String packageName, IBinder agent)648 public void agentConnected(String packageName, IBinder agent) throws RemoteException { 649 agentConnectedForUser(binderGetCallingUserId(), packageName, agent); 650 } 651 652 /** 653 * Callback: a requested backup agent has been instantiated. This should only be called from the 654 * {@link ActivityManager}. 655 */ agentConnected(@serIdInt int userId, String packageName, IBinder agentBinder)656 public void agentConnected(@UserIdInt int userId, String packageName, IBinder agentBinder) { 657 UserBackupManagerService userBackupManagerService = 658 getServiceForUserIfCallerHasPermission(userId, "agentConnected()"); 659 660 if (userBackupManagerService != null) { 661 userBackupManagerService.agentConnected(packageName, agentBinder); 662 } 663 } 664 665 @Override agentDisconnectedForUser(int userId, String packageName)666 public void agentDisconnectedForUser(int userId, String packageName) throws RemoteException { 667 if (isUserReadyForBackup(userId)) { 668 agentDisconnected(userId, packageName); 669 } 670 } 671 672 @Override agentDisconnected(String packageName)673 public void agentDisconnected(String packageName) throws RemoteException { 674 agentDisconnectedForUser(binderGetCallingUserId(), packageName); 675 } 676 677 /** 678 * Callback: a backup agent has failed to come up, or has unexpectedly quit. This should only be 679 * called from the {@link ActivityManager}. 680 */ agentDisconnected(@serIdInt int userId, String packageName)681 public void agentDisconnected(@UserIdInt int userId, String packageName) { 682 UserBackupManagerService userBackupManagerService = 683 getServiceForUserIfCallerHasPermission(userId, "agentDisconnected()"); 684 685 if (userBackupManagerService != null) { 686 userBackupManagerService.agentDisconnected(packageName); 687 } 688 } 689 690 @Override restoreAtInstallForUser(int userId, String packageName, int token)691 public void restoreAtInstallForUser(int userId, String packageName, int token) 692 throws RemoteException { 693 if (isUserReadyForBackup(userId)) { 694 restoreAtInstall(userId, packageName, token); 695 } 696 } 697 698 @Override restoreAtInstall(String packageName, int token)699 public void restoreAtInstall(String packageName, int token) throws RemoteException { 700 restoreAtInstallForUser(binderGetCallingUserId(), packageName, token); 701 } 702 703 /** 704 * Used to run a restore pass for an application that is being installed. This should only be 705 * called from the {@link PackageManager}. 706 */ restoreAtInstall(@serIdInt int userId, String packageName, int token)707 public void restoreAtInstall(@UserIdInt int userId, String packageName, int token) { 708 UserBackupManagerService userBackupManagerService = 709 getServiceForUserIfCallerHasPermission(userId, "restoreAtInstall()"); 710 711 if (userBackupManagerService != null) { 712 userBackupManagerService.restoreAtInstall(packageName, token); 713 } 714 } 715 716 @Override setFrameworkSchedulingEnabledForUser(int userId, boolean isEnabled)717 public void setFrameworkSchedulingEnabledForUser(int userId, boolean isEnabled) { 718 UserBackupManagerService userBackupManagerService = 719 getServiceForUserIfCallerHasPermission(userId, 720 "setFrameworkSchedulingEnabledForUser()"); 721 722 if (userBackupManagerService != null) { 723 userBackupManagerService.setFrameworkSchedulingEnabled(isEnabled); 724 } 725 } 726 727 @Override setBackupEnabledForUser(@serIdInt int userId, boolean isEnabled)728 public void setBackupEnabledForUser(@UserIdInt int userId, boolean isEnabled) 729 throws RemoteException { 730 if (isUserReadyForBackup(userId)) { 731 setBackupEnabled(userId, isEnabled); 732 } 733 } 734 735 @Override setBackupEnabled(boolean isEnabled)736 public void setBackupEnabled(boolean isEnabled) throws RemoteException { 737 setBackupEnabledForUser(binderGetCallingUserId(), isEnabled); 738 } 739 740 /** Enable/disable the backup service. This is user-configurable via backup settings. */ setBackupEnabled(@serIdInt int userId, boolean enable)741 public void setBackupEnabled(@UserIdInt int userId, boolean enable) { 742 UserBackupManagerService userBackupManagerService = 743 getServiceForUserIfCallerHasPermission(userId, "setBackupEnabled()"); 744 745 if (userBackupManagerService != null) { 746 userBackupManagerService.setBackupEnabled(enable); 747 } 748 } 749 750 @Override setAutoRestoreForUser(int userId, boolean doAutoRestore)751 public void setAutoRestoreForUser(int userId, boolean doAutoRestore) throws RemoteException { 752 if (isUserReadyForBackup(userId)) { 753 setAutoRestore(userId, doAutoRestore); 754 } 755 } 756 757 @Override setAutoRestore(boolean doAutoRestore)758 public void setAutoRestore(boolean doAutoRestore) throws RemoteException { 759 setAutoRestoreForUser(binderGetCallingUserId(), doAutoRestore); 760 } 761 762 /** Enable/disable automatic restore of app data at install time. */ setAutoRestore(@serIdInt int userId, boolean autoRestore)763 public void setAutoRestore(@UserIdInt int userId, boolean autoRestore) { 764 UserBackupManagerService userBackupManagerService = 765 getServiceForUserIfCallerHasPermission(userId, "setAutoRestore()"); 766 767 if (userBackupManagerService != null) { 768 userBackupManagerService.setAutoRestore(autoRestore); 769 } 770 } 771 772 @Override isBackupEnabledForUser(@serIdInt int userId)773 public boolean isBackupEnabledForUser(@UserIdInt int userId) throws RemoteException { 774 return isUserReadyForBackup(userId) && isBackupEnabled(userId); 775 } 776 777 @Override isBackupEnabled()778 public boolean isBackupEnabled() throws RemoteException { 779 return isBackupEnabledForUser(binderGetCallingUserId()); 780 } 781 782 /** 783 * Return {@code true} if the backup mechanism is currently enabled, else returns {@code false}. 784 */ isBackupEnabled(@serIdInt int userId)785 public boolean isBackupEnabled(@UserIdInt int userId) { 786 UserBackupManagerService userBackupManagerService = 787 getServiceForUserIfCallerHasPermission(userId, "isBackupEnabled()"); 788 789 return userBackupManagerService != null && userBackupManagerService.isBackupEnabled(); 790 } 791 792 /** Sets the backup password used when running adb backup. */ 793 @Override setBackupPassword(String currentPassword, String newPassword)794 public boolean setBackupPassword(String currentPassword, String newPassword) { 795 int userId = binderGetCallingUserId(); 796 if (!isUserReadyForBackup(userId)) { 797 return false; 798 } 799 UserBackupManagerService userBackupManagerService = 800 getServiceForUserIfCallerHasPermission( 801 UserHandle.USER_SYSTEM, "setBackupPassword()"); 802 803 return userBackupManagerService != null 804 && userBackupManagerService.setBackupPassword(currentPassword, newPassword); 805 } 806 807 /** Returns {@code true} if adb backup was run with a password, else returns {@code false}. */ 808 @Override hasBackupPassword()809 public boolean hasBackupPassword() throws RemoteException { 810 int userId = binderGetCallingUserId(); 811 if (!isUserReadyForBackup(userId)) { 812 return false; 813 } 814 UserBackupManagerService userBackupManagerService = 815 getServiceForUserIfCallerHasPermission( 816 UserHandle.USER_SYSTEM, "hasBackupPassword()"); 817 818 return userBackupManagerService != null && userBackupManagerService.hasBackupPassword(); 819 } 820 821 @Override backupNowForUser(@serIdInt int userId)822 public void backupNowForUser(@UserIdInt int userId) throws RemoteException { 823 if (isUserReadyForBackup(userId)) { 824 backupNow(userId); 825 } 826 } 827 828 @Override backupNow()829 public void backupNow() throws RemoteException { 830 backupNowForUser(binderGetCallingUserId()); 831 } 832 833 /** 834 * Run a backup pass immediately for any key-value backup applications that have declared that 835 * they have pending updates. 836 */ backupNow(@serIdInt int userId)837 public void backupNow(@UserIdInt int userId) { 838 UserBackupManagerService userBackupManagerService = 839 getServiceForUserIfCallerHasPermission(userId, "backupNow()"); 840 841 if (userBackupManagerService != null) { 842 userBackupManagerService.backupNow(); 843 } 844 } 845 846 /** 847 * Used by 'adb backup' to run a backup pass for packages {@code packageNames} supplied via the 848 * command line, writing the resulting data stream to the supplied {@code fd}. This method is 849 * synchronous and does not return to the caller until the backup has been completed. It 850 * requires on-screen confirmation by the user. 851 */ 852 @Override adbBackup( @serIdInt int userId, ParcelFileDescriptor fd, boolean includeApks, boolean includeObbs, boolean includeShared, boolean doWidgets, boolean doAllApps, boolean includeSystem, boolean doCompress, boolean doKeyValue, String[] packageNames)853 public void adbBackup( 854 @UserIdInt int userId, 855 ParcelFileDescriptor fd, 856 boolean includeApks, 857 boolean includeObbs, 858 boolean includeShared, 859 boolean doWidgets, 860 boolean doAllApps, 861 boolean includeSystem, 862 boolean doCompress, 863 boolean doKeyValue, 864 String[] packageNames) { 865 if (!isUserReadyForBackup(userId)) { 866 return; 867 } 868 UserBackupManagerService userBackupManagerService = 869 getServiceForUserIfCallerHasPermission(userId, "adbBackup()"); 870 871 if (userBackupManagerService != null) { 872 userBackupManagerService.adbBackup( 873 fd, 874 includeApks, 875 includeObbs, 876 includeShared, 877 doWidgets, 878 doAllApps, 879 includeSystem, 880 doCompress, 881 doKeyValue, 882 packageNames); 883 } 884 } 885 886 @Override fullTransportBackupForUser(int userId, String[] packageNames)887 public void fullTransportBackupForUser(int userId, String[] packageNames) 888 throws RemoteException { 889 if (isUserReadyForBackup(userId)) { 890 fullTransportBackup(userId, packageNames); 891 } 892 } 893 894 /** 895 * Run a full backup pass for the given packages {@code packageNames}. Used by 'adb shell bmgr'. 896 */ fullTransportBackup(@serIdInt int userId, String[] packageNames)897 public void fullTransportBackup(@UserIdInt int userId, String[] packageNames) { 898 UserBackupManagerService userBackupManagerService = 899 getServiceForUserIfCallerHasPermission(userId, "fullTransportBackup()"); 900 901 if (userBackupManagerService != null) { 902 userBackupManagerService.fullTransportBackup(packageNames); 903 } 904 } 905 906 /** 907 * Used by 'adb restore' to run a restore pass reading from the supplied {@code fd}. This method 908 * is synchronous and does not return to the caller until the restore has been completed. It 909 * requires on-screen confirmation by the user. 910 */ 911 @Override adbRestore(@serIdInt int userId, ParcelFileDescriptor fd)912 public void adbRestore(@UserIdInt int userId, ParcelFileDescriptor fd) { 913 if (!isUserReadyForBackup(userId)) { 914 return; 915 } 916 UserBackupManagerService userBackupManagerService = 917 getServiceForUserIfCallerHasPermission(userId, "adbRestore()"); 918 919 if (userBackupManagerService != null) { 920 userBackupManagerService.adbRestore(fd); 921 } 922 } 923 924 @Override acknowledgeFullBackupOrRestoreForUser( int userId, int token, boolean allow, String curPassword, String encryptionPassword, IFullBackupRestoreObserver observer)925 public void acknowledgeFullBackupOrRestoreForUser( 926 int userId, 927 int token, 928 boolean allow, 929 String curPassword, 930 String encryptionPassword, 931 IFullBackupRestoreObserver observer) 932 throws RemoteException { 933 if (isUserReadyForBackup(userId)) { 934 acknowledgeAdbBackupOrRestore(userId, token, allow, 935 curPassword, encryptionPassword, observer); 936 } 937 } 938 939 /** 940 * Confirm that the previously requested adb backup/restore operation can proceed. This is used 941 * to require a user-facing disclosure about the operation. 942 */ acknowledgeAdbBackupOrRestore( @serIdInt int userId, int token, boolean allow, String currentPassword, String encryptionPassword, IFullBackupRestoreObserver observer)943 public void acknowledgeAdbBackupOrRestore( 944 @UserIdInt int userId, 945 int token, 946 boolean allow, 947 String currentPassword, 948 String encryptionPassword, 949 IFullBackupRestoreObserver observer) { 950 UserBackupManagerService userBackupManagerService = 951 getServiceForUserIfCallerHasPermission(userId, "acknowledgeAdbBackupOrRestore()"); 952 953 if (userBackupManagerService != null) { 954 userBackupManagerService.acknowledgeAdbBackupOrRestore( 955 token, allow, currentPassword, encryptionPassword, observer); 956 } 957 } 958 959 @Override acknowledgeFullBackupOrRestore(int token, boolean allow, String curPassword, String encryptionPassword, IFullBackupRestoreObserver observer)960 public void acknowledgeFullBackupOrRestore(int token, boolean allow, String curPassword, 961 String encryptionPassword, IFullBackupRestoreObserver observer) 962 throws RemoteException { 963 acknowledgeFullBackupOrRestoreForUser( 964 binderGetCallingUserId(), token, allow, curPassword, encryptionPassword, observer); 965 } 966 967 968 @Override getCurrentTransportForUser(int userId)969 public String getCurrentTransportForUser(int userId) throws RemoteException { 970 return (isUserReadyForBackup(userId)) ? getCurrentTransport(userId) : null; 971 } 972 973 @Override getCurrentTransport()974 public String getCurrentTransport() throws RemoteException { 975 return getCurrentTransportForUser(binderGetCallingUserId()); 976 } 977 978 /** Return the name of the currently active transport. */ 979 @Nullable getCurrentTransport(@serIdInt int userId)980 public String getCurrentTransport(@UserIdInt int userId) { 981 UserBackupManagerService userBackupManagerService = 982 getServiceForUserIfCallerHasPermission(userId, "getCurrentTransport()"); 983 984 return userBackupManagerService == null 985 ? null 986 : userBackupManagerService.getCurrentTransport(); 987 } 988 989 /** 990 * Returns the {@link ComponentName} of the host service of the selected transport or 991 * {@code null} if no transport selected or if the transport selected is not registered. 992 */ 993 @Override 994 @Nullable getCurrentTransportComponentForUser(int userId)995 public ComponentName getCurrentTransportComponentForUser(int userId) { 996 return (isUserReadyForBackup(userId)) ? getCurrentTransportComponent(userId) : null; 997 } 998 999 /** 1000 * Returns the {@link ComponentName} of the host service of the selected transport or {@code 1001 * null} if no transport selected or if the transport selected is not registered. 1002 */ 1003 @Nullable getCurrentTransportComponent(@serIdInt int userId)1004 public ComponentName getCurrentTransportComponent(@UserIdInt int userId) { 1005 UserBackupManagerService userBackupManagerService = 1006 getServiceForUserIfCallerHasPermission(userId, "getCurrentTransportComponent()"); 1007 1008 return userBackupManagerService == null 1009 ? null 1010 : userBackupManagerService.getCurrentTransportComponent(); 1011 } 1012 1013 @Override listAllTransportsForUser(int userId)1014 public String[] listAllTransportsForUser(int userId) throws RemoteException { 1015 return (isUserReadyForBackup(userId)) ? listAllTransports(userId) : null; 1016 } 1017 1018 /** Report all known, available backup transports by name. */ 1019 @Nullable listAllTransports(@serIdInt int userId)1020 public String[] listAllTransports(@UserIdInt int userId) { 1021 UserBackupManagerService userBackupManagerService = 1022 getServiceForUserIfCallerHasPermission(userId, "listAllTransports()"); 1023 1024 return userBackupManagerService == null 1025 ? null 1026 : userBackupManagerService.listAllTransports(); 1027 } 1028 1029 @Override listAllTransports()1030 public String[] listAllTransports() throws RemoteException { 1031 return listAllTransportsForUser(binderGetCallingUserId()); 1032 } 1033 1034 @Override listAllTransportComponentsForUser(int userId)1035 public ComponentName[] listAllTransportComponentsForUser(int userId) throws RemoteException { 1036 return (isUserReadyForBackup(userId)) 1037 ? listAllTransportComponents(userId) : null; 1038 } 1039 1040 /** Report all known, available backup transports by {@link ComponentName}. */ 1041 @Nullable listAllTransportComponents(@serIdInt int userId)1042 public ComponentName[] listAllTransportComponents(@UserIdInt int userId) { 1043 UserBackupManagerService userBackupManagerService = 1044 getServiceForUserIfCallerHasPermission(userId, "listAllTransportComponents()"); 1045 1046 return userBackupManagerService == null 1047 ? null 1048 : userBackupManagerService.listAllTransportComponents(); 1049 } 1050 1051 @Override getTransportWhitelist()1052 public String[] getTransportWhitelist() { 1053 int userId = binderGetCallingUserId(); 1054 if (!isUserReadyForBackup(userId)) { 1055 return null; 1056 } 1057 // No permission check, intentionally. 1058 String[] whitelistedTransports = new String[mTransportWhitelist.size()]; 1059 int i = 0; 1060 for (ComponentName component : mTransportWhitelist) { 1061 whitelistedTransports[i] = component.flattenToShortString(); 1062 i++; 1063 } 1064 return whitelistedTransports; 1065 } 1066 1067 @Override updateTransportAttributesForUser( int userId, ComponentName transportComponent, String name, @Nullable Intent configurationIntent, String currentDestinationString, @Nullable Intent dataManagementIntent, CharSequence dataManagementLabel)1068 public void updateTransportAttributesForUser( 1069 int userId, 1070 ComponentName transportComponent, 1071 String name, 1072 @Nullable Intent configurationIntent, 1073 String currentDestinationString, 1074 @Nullable Intent dataManagementIntent, 1075 CharSequence dataManagementLabel) { 1076 if (isUserReadyForBackup(userId)) { 1077 updateTransportAttributes( 1078 userId, 1079 transportComponent, 1080 name, 1081 configurationIntent, 1082 currentDestinationString, 1083 dataManagementIntent, 1084 dataManagementLabel); 1085 } 1086 } 1087 1088 /** 1089 * Update the attributes of the transport identified by {@code transportComponent}. If the 1090 * specified transport has not been bound at least once (for registration), this call will be 1091 * ignored. Only the host process of the transport can change its description, otherwise a 1092 * {@link SecurityException} will be thrown. 1093 * 1094 * @param transportComponent The identity of the transport being described. 1095 * @param name A {@link String} with the new name for the transport. This is NOT for 1096 * identification. MUST NOT be {@code null}. 1097 * @param configurationIntent An {@link Intent} that can be passed to {@link 1098 * Context#startActivity} in order to launch the transport's configuration UI. It may be 1099 * {@code null} if the transport does not offer any user-facing configuration UI. 1100 * @param currentDestinationString A {@link String} describing the destination to which the 1101 * transport is currently sending data. MUST NOT be {@code null}. 1102 * @param dataManagementIntent An {@link Intent} that can be passed to {@link 1103 * Context#startActivity} in order to launch the transport's data-management UI. It may be 1104 * {@code null} if the transport does not offer any user-facing data management UI. 1105 * @param dataManagementLabel A {@link CharSequence} to be used as the label for the transport's 1106 * data management affordance. This MUST be {@code null} when dataManagementIntent is {@code 1107 * null} and MUST NOT be {@code null} when dataManagementIntent is not {@code null}. 1108 * @throws SecurityException If the UID of the calling process differs from the package UID of 1109 * {@code transportComponent} or if the caller does NOT have BACKUP permission. 1110 */ updateTransportAttributes( @serIdInt int userId, ComponentName transportComponent, String name, @Nullable Intent configurationIntent, String currentDestinationString, @Nullable Intent dataManagementIntent, CharSequence dataManagementLabel)1111 public void updateTransportAttributes( 1112 @UserIdInt int userId, 1113 ComponentName transportComponent, 1114 String name, 1115 @Nullable Intent configurationIntent, 1116 String currentDestinationString, 1117 @Nullable Intent dataManagementIntent, 1118 CharSequence dataManagementLabel) { 1119 UserBackupManagerService userBackupManagerService = 1120 getServiceForUserIfCallerHasPermission(userId, "updateTransportAttributes()"); 1121 1122 if (userBackupManagerService != null) { 1123 userBackupManagerService.updateTransportAttributes( 1124 transportComponent, 1125 name, 1126 configurationIntent, 1127 currentDestinationString, 1128 dataManagementIntent, 1129 dataManagementLabel); 1130 } 1131 } 1132 1133 @Override selectBackupTransportForUser(int userId, String transport)1134 public String selectBackupTransportForUser(int userId, String transport) 1135 throws RemoteException { 1136 return (isUserReadyForBackup(userId)) 1137 ? selectBackupTransport(userId, transport) : null; 1138 } 1139 1140 @Override selectBackupTransport(String transport)1141 public String selectBackupTransport(String transport) throws RemoteException { 1142 return selectBackupTransportForUser(binderGetCallingUserId(), transport); 1143 } 1144 1145 /** 1146 * Selects transport {@code transportName} and returns the previously selected transport. 1147 * 1148 * @deprecated Use {@link #selectBackupTransportAsync(ComponentName, 1149 * ISelectBackupTransportCallback)} instead. 1150 */ 1151 @Deprecated 1152 @Nullable selectBackupTransport(@serIdInt int userId, String transportName)1153 public String selectBackupTransport(@UserIdInt int userId, String transportName) { 1154 UserBackupManagerService userBackupManagerService = 1155 getServiceForUserIfCallerHasPermission(userId, "selectBackupTransport()"); 1156 1157 return userBackupManagerService == null 1158 ? null 1159 : userBackupManagerService.selectBackupTransport(transportName); 1160 } 1161 1162 @Override selectBackupTransportAsyncForUser(int userId, ComponentName transport, ISelectBackupTransportCallback listener)1163 public void selectBackupTransportAsyncForUser(int userId, ComponentName transport, 1164 ISelectBackupTransportCallback listener) throws RemoteException { 1165 if (isUserReadyForBackup(userId)) { 1166 selectBackupTransportAsync(userId, transport, listener); 1167 } else { 1168 if (listener != null) { 1169 try { 1170 listener.onFailure(BackupManager.ERROR_BACKUP_NOT_ALLOWED); 1171 } catch (RemoteException ex) { 1172 // ignore 1173 } 1174 } 1175 } 1176 } 1177 1178 /** 1179 * Selects transport {@code transportComponent} asynchronously and notifies {@code listener} 1180 * with the result upon completion. 1181 */ selectBackupTransportAsync( @serIdInt int userId, ComponentName transportComponent, ISelectBackupTransportCallback listener)1182 public void selectBackupTransportAsync( 1183 @UserIdInt int userId, 1184 ComponentName transportComponent, 1185 ISelectBackupTransportCallback listener) { 1186 UserBackupManagerService userBackupManagerService = 1187 getServiceForUserIfCallerHasPermission(userId, "selectBackupTransportAsync()"); 1188 1189 if (userBackupManagerService != null) { 1190 userBackupManagerService.selectBackupTransportAsync(transportComponent, listener); 1191 } 1192 } 1193 1194 @Override getConfigurationIntentForUser(int userId, String transport)1195 public Intent getConfigurationIntentForUser(int userId, String transport) 1196 throws RemoteException { 1197 return isUserReadyForBackup(userId) ? getConfigurationIntent(userId, transport) 1198 : null; 1199 } 1200 1201 @Override getConfigurationIntent(String transport)1202 public Intent getConfigurationIntent(String transport) 1203 throws RemoteException { 1204 return getConfigurationIntentForUser(binderGetCallingUserId(), transport); 1205 } 1206 1207 /** 1208 * Supply the configuration intent for the given transport. If the name is not one of the 1209 * available transports, or if the transport does not supply any configuration UI, the method 1210 * returns {@code null}. 1211 */ 1212 @Nullable getConfigurationIntent(@serIdInt int userId, String transportName)1213 public Intent getConfigurationIntent(@UserIdInt int userId, String transportName) { 1214 UserBackupManagerService userBackupManagerService = 1215 getServiceForUserIfCallerHasPermission(userId, "getConfigurationIntent()"); 1216 1217 return userBackupManagerService == null 1218 ? null 1219 : userBackupManagerService.getConfigurationIntent(transportName); 1220 } 1221 1222 @Override getDestinationStringForUser(int userId, String transport)1223 public String getDestinationStringForUser(int userId, String transport) throws RemoteException { 1224 return isUserReadyForBackup(userId) ? getDestinationString(userId, transport) 1225 : null; 1226 } 1227 1228 @Override getDestinationString(String transport)1229 public String getDestinationString(String transport) throws RemoteException { 1230 return getDestinationStringForUser(binderGetCallingUserId(), transport); 1231 } 1232 1233 /** 1234 * Supply the current destination string for the given transport. If the name is not one of the 1235 * registered transports the method will return null. 1236 * 1237 * <p>This string is used VERBATIM as the summary text of the relevant Settings item. 1238 * 1239 * @param transportName The name of the registered transport. 1240 * @return The current destination string or null if the transport is not registered. 1241 */ 1242 @Nullable getDestinationString(@serIdInt int userId, String transportName)1243 public String getDestinationString(@UserIdInt int userId, String transportName) { 1244 UserBackupManagerService userBackupManagerService = 1245 getServiceForUserIfCallerHasPermission(userId, "getDestinationString()"); 1246 1247 return userBackupManagerService == null 1248 ? null 1249 : userBackupManagerService.getDestinationString(transportName); 1250 } 1251 1252 @Override getDataManagementIntentForUser(int userId, String transport)1253 public Intent getDataManagementIntentForUser(int userId, String transport) 1254 throws RemoteException { 1255 return isUserReadyForBackup(userId) 1256 ? getDataManagementIntent(userId, transport) : null; 1257 } 1258 1259 @Override getDataManagementIntent(String transport)1260 public Intent getDataManagementIntent(String transport) 1261 throws RemoteException { 1262 return getDataManagementIntentForUser(binderGetCallingUserId(), transport); 1263 } 1264 1265 /** Supply the manage-data intent for the given transport. */ 1266 @Nullable getDataManagementIntent(@serIdInt int userId, String transportName)1267 public Intent getDataManagementIntent(@UserIdInt int userId, String transportName) { 1268 UserBackupManagerService userBackupManagerService = 1269 getServiceForUserIfCallerHasPermission(userId, "getDataManagementIntent()"); 1270 1271 return userBackupManagerService == null 1272 ? null 1273 : userBackupManagerService.getDataManagementIntent(transportName); 1274 } 1275 1276 @Override getDataManagementLabelForUser(int userId, String transport)1277 public CharSequence getDataManagementLabelForUser(int userId, String transport) 1278 throws RemoteException { 1279 return isUserReadyForBackup(userId) ? getDataManagementLabel(userId, transport) 1280 : null; 1281 } 1282 1283 /** 1284 * Supply the menu label for affordances that fire the manage-data intent for the given 1285 * transport. 1286 */ 1287 @Nullable getDataManagementLabel(@serIdInt int userId, String transportName)1288 public CharSequence getDataManagementLabel(@UserIdInt int userId, String transportName) { 1289 UserBackupManagerService userBackupManagerService = 1290 getServiceForUserIfCallerHasPermission(userId, "getDataManagementLabel()"); 1291 1292 return userBackupManagerService == null 1293 ? null 1294 : userBackupManagerService.getDataManagementLabel(transportName); 1295 } 1296 1297 @Override beginRestoreSessionForUser( int userId, String packageName, String transportID)1298 public IRestoreSession beginRestoreSessionForUser( 1299 int userId, String packageName, String transportID) throws RemoteException { 1300 return isUserReadyForBackup(userId) 1301 ? beginRestoreSession(userId, packageName, transportID) : null; 1302 } 1303 1304 /** 1305 * Begin a restore for the specified package {@code packageName} using the specified transport 1306 * {@code transportName}. 1307 */ 1308 @Nullable beginRestoreSession( @serIdInt int userId, String packageName, String transportName)1309 public IRestoreSession beginRestoreSession( 1310 @UserIdInt int userId, String packageName, String transportName) { 1311 UserBackupManagerService userBackupManagerService = 1312 getServiceForUserIfCallerHasPermission(userId, "beginRestoreSession()"); 1313 1314 return userBackupManagerService == null 1315 ? null 1316 : userBackupManagerService.beginRestoreSession(packageName, transportName); 1317 } 1318 1319 @Override opCompleteForUser(int userId, int token, long result)1320 public void opCompleteForUser(int userId, int token, long result) throws RemoteException { 1321 if (isUserReadyForBackup(userId)) { 1322 opComplete(userId, token, result); 1323 } 1324 } 1325 1326 @Override opComplete(int token, long result)1327 public void opComplete(int token, long result) throws RemoteException { 1328 opCompleteForUser(binderGetCallingUserId(), token, result); 1329 } 1330 1331 /** 1332 * Used by a currently-active backup agent to notify the service that it has completed its given 1333 * outstanding asynchronous backup/restore operation. 1334 */ opComplete(@serIdInt int userId, int token, long result)1335 public void opComplete(@UserIdInt int userId, int token, long result) { 1336 UserBackupManagerService userBackupManagerService = 1337 getServiceForUserIfCallerHasPermission(userId, "opComplete()"); 1338 1339 if (userBackupManagerService != null) { 1340 userBackupManagerService.opComplete(token, result); 1341 } 1342 } 1343 1344 @Override getAvailableRestoreTokenForUser(int userId, String packageName)1345 public long getAvailableRestoreTokenForUser(int userId, String packageName) { 1346 return isUserReadyForBackup(userId) ? getAvailableRestoreToken(userId, packageName) : 0; 1347 } 1348 1349 /** 1350 * Get the restore-set token for the best-available restore set for this {@code packageName}: 1351 * the active set if possible, else the ancestral one. Returns zero if none available. 1352 */ getAvailableRestoreToken(@serIdInt int userId, String packageName)1353 public long getAvailableRestoreToken(@UserIdInt int userId, String packageName) { 1354 UserBackupManagerService userBackupManagerService = 1355 getServiceForUserIfCallerHasPermission(userId, "getAvailableRestoreToken()"); 1356 1357 return userBackupManagerService == null 1358 ? 0 1359 : userBackupManagerService.getAvailableRestoreToken(packageName); 1360 } 1361 1362 @Override isAppEligibleForBackupForUser(int userId, String packageName)1363 public boolean isAppEligibleForBackupForUser(int userId, String packageName) { 1364 return isUserReadyForBackup(userId) && isAppEligibleForBackup(userId, 1365 packageName); 1366 } 1367 1368 /** Checks if the given package {@code packageName} is eligible for backup. */ isAppEligibleForBackup(@serIdInt int userId, String packageName)1369 public boolean isAppEligibleForBackup(@UserIdInt int userId, String packageName) { 1370 UserBackupManagerService userBackupManagerService = 1371 getServiceForUserIfCallerHasPermission(userId, "isAppEligibleForBackup()"); 1372 1373 return userBackupManagerService != null 1374 && userBackupManagerService.isAppEligibleForBackup(packageName); 1375 } 1376 1377 @Override filterAppsEligibleForBackupForUser(int userId, String[] packages)1378 public String[] filterAppsEligibleForBackupForUser(int userId, String[] packages) { 1379 return isUserReadyForBackup(userId) ? filterAppsEligibleForBackup(userId, packages) : null; 1380 } 1381 1382 /** 1383 * Returns from the inputted packages {@code packages}, the ones that are eligible for backup. 1384 */ 1385 @Nullable filterAppsEligibleForBackup(@serIdInt int userId, String[] packages)1386 public String[] filterAppsEligibleForBackup(@UserIdInt int userId, String[] packages) { 1387 UserBackupManagerService userBackupManagerService = 1388 getServiceForUserIfCallerHasPermission(userId, "filterAppsEligibleForBackup()"); 1389 1390 return userBackupManagerService == null 1391 ? null 1392 : userBackupManagerService.filterAppsEligibleForBackup(packages); 1393 } 1394 1395 @Override requestBackupForUser(@serIdInt int userId, String[] packages, IBackupObserver observer, IBackupManagerMonitor monitor, int flags)1396 public int requestBackupForUser(@UserIdInt int userId, String[] packages, IBackupObserver 1397 observer, IBackupManagerMonitor monitor, int flags) throws RemoteException { 1398 if (!isUserReadyForBackup(userId)) { 1399 return BackupManager.ERROR_BACKUP_NOT_ALLOWED; 1400 } 1401 return requestBackup(userId, packages, observer, monitor, flags); 1402 } 1403 1404 @Override requestBackup(String[] packages, IBackupObserver observer, IBackupManagerMonitor monitor, int flags)1405 public int requestBackup(String[] packages, IBackupObserver observer, 1406 IBackupManagerMonitor monitor, int flags) 1407 throws RemoteException { 1408 return requestBackup(binderGetCallingUserId(), packages, 1409 observer, monitor, flags); 1410 } 1411 1412 /** 1413 * Requests a backup for the inputted {@code packages} with a specified callback {@link 1414 * IBackupManagerMonitor} for receiving events during the operation. 1415 */ requestBackup( @serIdInt int userId, String[] packages, IBackupObserver observer, IBackupManagerMonitor monitor, int flags)1416 public int requestBackup( 1417 @UserIdInt int userId, 1418 String[] packages, 1419 IBackupObserver observer, 1420 IBackupManagerMonitor monitor, 1421 int flags) { 1422 UserBackupManagerService userBackupManagerService = 1423 getServiceForUserIfCallerHasPermission(userId, "requestBackup()"); 1424 1425 return userBackupManagerService == null 1426 ? BackupManager.ERROR_BACKUP_NOT_ALLOWED 1427 : userBackupManagerService.requestBackup(packages, observer, monitor, flags); 1428 } 1429 1430 @Override cancelBackupsForUser(@serIdInt int userId)1431 public void cancelBackupsForUser(@UserIdInt int userId) throws RemoteException { 1432 if (isUserReadyForBackup(userId)) { 1433 cancelBackups(userId); 1434 } 1435 } 1436 1437 @Override cancelBackups()1438 public void cancelBackups() throws RemoteException { 1439 cancelBackupsForUser(binderGetCallingUserId()); 1440 } 1441 1442 /** Cancel all running backup operations. */ cancelBackups(@serIdInt int userId)1443 public void cancelBackups(@UserIdInt int userId) { 1444 UserBackupManagerService userBackupManagerService = 1445 getServiceForUserIfCallerHasPermission(userId, "cancelBackups()"); 1446 1447 if (userBackupManagerService != null) { 1448 userBackupManagerService.cancelBackups(); 1449 } 1450 } 1451 1452 /** 1453 * Returns a {@link UserHandle} for the user that has {@code ancestralSerialNumber} as the 1454 * serial number of its ancestral work profile or null if there is no {@link 1455 * UserBackupManagerService} associated with that user. 1456 * 1457 * <p> The ancestral work profile is set by {@link #setAncestralSerialNumber(long)} 1458 * and it corresponds to the profile that was used to restore to the callers profile. 1459 */ 1460 @Override 1461 @Nullable getUserForAncestralSerialNumber(long ancestralSerialNumber)1462 public UserHandle getUserForAncestralSerialNumber(long ancestralSerialNumber) { 1463 if (mGlobalDisable) { 1464 return null; 1465 } 1466 int callingUserId = Binder.getCallingUserHandle().getIdentifier(); 1467 final int[] userIds; 1468 final long oldId = Binder.clearCallingIdentity(); 1469 try { 1470 userIds = getUserManager().getProfileIds(callingUserId, false); 1471 } finally { 1472 Binder.restoreCallingIdentity(oldId); 1473 } 1474 1475 for (int userId : userIds) { 1476 UserBackupManagerService userBackupManagerService = mUserServices.get(userId); 1477 if (userBackupManagerService != null) { 1478 if (userBackupManagerService.getAncestralSerialNumber() == ancestralSerialNumber) { 1479 return UserHandle.of(userId); 1480 } 1481 } 1482 } 1483 1484 return null; 1485 } 1486 1487 /** 1488 * Sets the ancestral work profile for the calling user. 1489 * 1490 * <p> The ancestral work profile corresponds to the profile that was used to restore to the 1491 * callers profile. 1492 */ 1493 @Override setAncestralSerialNumber(long ancestralSerialNumber)1494 public void setAncestralSerialNumber(long ancestralSerialNumber) { 1495 if (mGlobalDisable) { 1496 return; 1497 } 1498 UserBackupManagerService userBackupManagerService = 1499 getServiceForUserIfCallerHasPermission( 1500 Binder.getCallingUserHandle().getIdentifier(), 1501 "setAncestralSerialNumber()"); 1502 1503 if (userBackupManagerService != null) { 1504 userBackupManagerService.setAncestralSerialNumber(ancestralSerialNumber); 1505 } 1506 } 1507 1508 @Override dump(FileDescriptor fd, PrintWriter pw, String[] args)1509 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1510 if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) { 1511 return; 1512 } 1513 1514 int argIndex = 0; 1515 1516 String op = nextArg(args, argIndex); 1517 argIndex++; 1518 1519 if ("--help".equals(op) || "-h".equals(op)) { 1520 showDumpUsage(pw); 1521 return; 1522 } 1523 if ("users".equals(op)) { 1524 pw.print(DUMP_RUNNING_USERS_MESSAGE); 1525 for (int i = 0; i < mUserServices.size(); i++) { 1526 UserBackupManagerService userBackupManagerService = 1527 getServiceForUserIfCallerHasPermission(mUserServices.keyAt(i), 1528 "dump()"); 1529 if (userBackupManagerService != null) { 1530 pw.print(" " + userBackupManagerService.getUserId()); 1531 } 1532 } 1533 pw.println(); 1534 return; 1535 } 1536 if ("--user".equals(op)) { 1537 String userArg = nextArg(args, argIndex); 1538 argIndex++; 1539 if (userArg == null) { 1540 showDumpUsage(pw); 1541 return; 1542 } 1543 int userId = UserHandle.parseUserArg(userArg); 1544 UserBackupManagerService userBackupManagerService = 1545 getServiceForUserIfCallerHasPermission(userId, "dump()"); 1546 if (userBackupManagerService != null) { 1547 userBackupManagerService.dump(fd, pw, args); 1548 } 1549 return; 1550 } 1551 1552 // We get here if we have no parameters or parameters unkonwn to us. 1553 // Print dumpsys info in either case: bug report creation passes some parameter to 1554 // dumpsys that we don't need to check. 1555 for (int i = 0; i < mUserServices.size(); i++) { 1556 UserBackupManagerService userBackupManagerService = 1557 getServiceForUserIfCallerHasPermission(mUserServices.keyAt(i), "dump()"); 1558 if (userBackupManagerService != null) { 1559 userBackupManagerService.dump(fd, pw, args); 1560 } 1561 } 1562 } 1563 nextArg(String[] args, int argIndex)1564 private String nextArg(String[] args, int argIndex) { 1565 if (argIndex >= args.length) { 1566 return null; 1567 } 1568 return args[argIndex]; 1569 } 1570 showDumpUsage(PrintWriter pw)1571 private static void showDumpUsage(PrintWriter pw) { 1572 pw.println("'dumpsys backup' optional arguments:"); 1573 pw.println(" --help : this help text"); 1574 pw.println(" a[gents] : dump information about defined backup agents"); 1575 pw.println(" transportclients : dump information about transport clients"); 1576 pw.println(" transportstats : dump transport stats"); 1577 pw.println(" users : dump the list of users for which backup service is running"); 1578 pw.println(" --user <userId> : dump information for user userId"); 1579 } 1580 1581 /** 1582 * Used by the {@link JobScheduler} to run a full backup when conditions are right. The model we 1583 * use is to perform one app backup per scheduled job execution, and to reschedule the job with 1584 * zero latency as long as conditions remain right and we still have work to do. 1585 * 1586 * @return Whether ongoing work will continue. The return value here will be passed along as the 1587 * return value to the callback {@link JobService#onStartJob(JobParameters)}. 1588 */ beginFullBackup(@serIdInt int userId, FullBackupJob scheduledJob)1589 public boolean beginFullBackup(@UserIdInt int userId, FullBackupJob scheduledJob) { 1590 if (!isUserReadyForBackup(userId)) { 1591 return false; 1592 } 1593 UserBackupManagerService userBackupManagerService = 1594 getServiceForUserIfCallerHasPermission(userId, "beginFullBackup()"); 1595 1596 return userBackupManagerService != null 1597 && userBackupManagerService.beginFullBackup(scheduledJob); 1598 } 1599 1600 /** 1601 * Used by the {@link JobScheduler} to end the current full backup task when conditions are no 1602 * longer met for running the full backup job. 1603 */ endFullBackup(@serIdInt int userId)1604 public void endFullBackup(@UserIdInt int userId) { 1605 if (!isUserReadyForBackup(userId)) { 1606 return; 1607 } 1608 UserBackupManagerService userBackupManagerService = 1609 getServiceForUserIfCallerHasPermission(userId, "endFullBackup()"); 1610 1611 if (userBackupManagerService != null) { 1612 userBackupManagerService.endFullBackup(); 1613 } 1614 } 1615 1616 /** 1617 * Excludes keys from KV restore for a given package. The corresponding data will be excluded 1618 * from the data set available the backup agent during restore. However, final list of keys 1619 * that have been excluded will be passed to the agent to make it aware of the exclusions. 1620 */ excludeKeysFromRestore(String packageName, List<String> keys)1621 public void excludeKeysFromRestore(String packageName, List<String> keys) { 1622 int userId = Binder.getCallingUserHandle().getIdentifier(); 1623 if (!isUserReadyForBackup(userId)) { 1624 Slog.w(TAG, "Returning from excludeKeysFromRestore as backup for user" + userId + 1625 " is not initialized yet"); 1626 return; 1627 } 1628 UserBackupManagerService userBackupManagerService = 1629 getServiceForUserIfCallerHasPermission(userId, "excludeKeysFromRestore()"); 1630 1631 if (userBackupManagerService != null) { 1632 userBackupManagerService.excludeKeysFromRestore(packageName, keys); 1633 } 1634 } 1635 reportDelayedRestoreResult(String packageName, List<DataTypeResult> results)1636 public void reportDelayedRestoreResult(String packageName, List<DataTypeResult> results) { 1637 int userId = Binder.getCallingUserHandle().getIdentifier(); 1638 if (!isUserReadyForBackup(userId)) { 1639 Slog.w(TAG, "Returning from reportDelayedRestoreResult as backup for user" + userId + 1640 " is not initialized yet"); 1641 return; 1642 } 1643 UserBackupManagerService userBackupManagerService = 1644 getServiceForUserIfCallerHasPermission(userId, 1645 /* caller */ "reportDelayedRestoreResult()"); 1646 1647 if (userBackupManagerService != null) { 1648 // Clear as the method binds to BackupTransport, which needs to happen from system 1649 // process. 1650 final long oldId = Binder.clearCallingIdentity(); 1651 try { 1652 userBackupManagerService.reportDelayedRestoreResult(packageName, results); 1653 } finally { 1654 Binder.restoreCallingIdentity(oldId); 1655 } 1656 } 1657 } 1658 1659 /** 1660 * Returns the {@link UserBackupManagerService} instance for the specified user {@code userId}. 1661 * If the user is not registered with the service (either the user is locked or not eligible for 1662 * the backup service) then return {@code null}. 1663 * 1664 * @param userId The id of the user to retrieve its instance of {@link 1665 * UserBackupManagerService}. 1666 * @param caller A {@link String} identifying the caller for logging purposes. 1667 * @throws SecurityException if {@code userId} is different from the calling user id and the 1668 * caller does NOT have the android.permission.INTERACT_ACROSS_USERS_FULL permission. 1669 */ 1670 @Nullable 1671 @VisibleForTesting getServiceForUserIfCallerHasPermission( @serIdInt int userId, String caller)1672 UserBackupManagerService getServiceForUserIfCallerHasPermission( 1673 @UserIdInt int userId, String caller) { 1674 enforceCallingPermissionOnUserId(userId, caller); 1675 UserBackupManagerService userBackupManagerService = mUserServices.get(userId); 1676 if (userBackupManagerService == null) { 1677 Slog.w(TAG, "Called " + caller + " for unknown user: " + userId); 1678 } 1679 return userBackupManagerService; 1680 } 1681 1682 /** 1683 * If {@code userId} is different from the calling user id, then the caller must hold the 1684 * android.permission.INTERACT_ACROSS_USERS_FULL permission. 1685 * 1686 * @param userId User id on which the backup operation is being requested. 1687 * @param message A message to include in the exception if it is thrown. 1688 */ enforceCallingPermissionOnUserId(@serIdInt int userId, String message)1689 void enforceCallingPermissionOnUserId(@UserIdInt int userId, String message) { 1690 if (binderGetCallingUserId() != userId) { 1691 mContext.enforceCallingOrSelfPermission( 1692 Manifest.permission.INTERACT_ACROSS_USERS_FULL, message); 1693 } 1694 } 1695 1696 /** Implementation to receive lifecycle event callbacks for system services. */ 1697 public static class Lifecycle extends SystemService { Lifecycle(Context context)1698 public Lifecycle(Context context) { 1699 this(context, new BackupManagerService(context)); 1700 } 1701 1702 @VisibleForTesting Lifecycle(Context context, BackupManagerService backupManagerService)1703 Lifecycle(Context context, BackupManagerService backupManagerService) { 1704 super(context); 1705 sInstance = backupManagerService; 1706 } 1707 1708 @Override onStart()1709 public void onStart() { 1710 publishService(Context.BACKUP_SERVICE, BackupManagerService.sInstance); 1711 } 1712 1713 @Override onUserUnlocking(@onNull TargetUser user)1714 public void onUserUnlocking(@NonNull TargetUser user) { 1715 // Starts the backup service for this user if backup is active for this user. Offloads 1716 // work onto the handler thread {@link #mHandlerThread} to keep unlock time low since 1717 // backup is not essential for device functioning. 1718 sInstance.postToHandler( 1719 () -> { 1720 sInstance.updateDefaultBackupUserIdIfNeeded(); 1721 sInstance.startServiceForUser(user.getUserIdentifier()); 1722 sInstance.mHasFirstUserUnlockedSinceBoot = true; 1723 }); 1724 } 1725 1726 @Override onUserStopping(@onNull TargetUser user)1727 public void onUserStopping(@NonNull TargetUser user) { 1728 sInstance.onStopUser(user.getUserIdentifier()); 1729 } 1730 1731 @VisibleForTesting publishService(String name, IBinder service)1732 void publishService(String name, IBinder service) { 1733 publishBinderService(name, service); 1734 } 1735 } 1736 1737 /** 1738 * On the first ever boot of a new device, the 'main' user might not exist for a short period of 1739 * time and be created after {@link BackupManagerService} is created. In this case the {@link 1740 * #mDefaultBackupUserId} will be the system user initially, but we need to change it to the 1741 * newly created {@link UserManager#getMainUser()} later. 1742 * 1743 * <p>{@link Lifecycle#onUserUnlocking(SystemService.TargetUser)} (for any user) is the earliest 1744 * point where we know that a main user (if there is going to be one) is created. 1745 */ updateDefaultBackupUserIdIfNeeded()1746 private void updateDefaultBackupUserIdIfNeeded() { 1747 // The default user can only change before any user unlocks since boot, and it will only 1748 // change from the system user to a non-system user. 1749 if (mHasFirstUserUnlockedSinceBoot || mDefaultBackupUserId != UserHandle.USER_SYSTEM) { 1750 return; 1751 } 1752 1753 UserHandle mainUser = getUserManager().getMainUser(); 1754 if (mainUser == null) { 1755 return; 1756 } 1757 1758 if (mDefaultBackupUserId != mainUser.getIdentifier()) { 1759 int oldDefaultBackupUserId = mDefaultBackupUserId; 1760 mDefaultBackupUserId = mainUser.getIdentifier(); 1761 // We don't expect the service to be started for the old default user but we attempt to 1762 // stop its service to be safe. 1763 if (!isBackupActivatedForUser(oldDefaultBackupUserId)) { 1764 stopServiceForUser(oldDefaultBackupUserId); 1765 } 1766 Slog.i( 1767 TAG, 1768 "Default backup user changed from " 1769 + oldDefaultBackupUserId 1770 + " to " 1771 + mDefaultBackupUserId); 1772 } 1773 } 1774 } 1775