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