1 /* 2 * Copyright (C) 2018 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 com.android.internal.util.Preconditions.checkNotNull; 20 21 import android.Manifest; 22 import android.annotation.Nullable; 23 import android.annotation.UserIdInt; 24 import android.app.ActivityManager; 25 import android.app.backup.BackupManager; 26 import android.app.backup.IBackupManagerMonitor; 27 import android.app.backup.IBackupObserver; 28 import android.app.backup.IFullBackupRestoreObserver; 29 import android.app.backup.IRestoreSession; 30 import android.app.backup.ISelectBackupTransportCallback; 31 import android.app.job.JobParameters; 32 import android.app.job.JobScheduler; 33 import android.app.job.JobService; 34 import android.content.BroadcastReceiver; 35 import android.content.ComponentName; 36 import android.content.Context; 37 import android.content.Intent; 38 import android.content.IntentFilter; 39 import android.content.pm.PackageManager; 40 import android.os.Binder; 41 import android.os.FileUtils; 42 import android.os.HandlerThread; 43 import android.os.IBinder; 44 import android.os.ParcelFileDescriptor; 45 import android.os.Trace; 46 import android.os.UserHandle; 47 import android.os.UserManager; 48 import android.util.Slog; 49 import android.util.SparseArray; 50 51 import com.android.internal.annotations.VisibleForTesting; 52 import com.android.internal.util.DumpUtils; 53 import com.android.server.SystemConfig; 54 import com.android.server.SystemService; 55 56 import java.io.File; 57 import java.io.FileDescriptor; 58 import java.io.PrintWriter; 59 import java.util.Collections; 60 import java.util.Set; 61 62 /** 63 * Definition of the system service that performs backup/restore operations. 64 * 65 * <p>This class is responsible for handling user-aware operations and acts as a delegator, routing 66 * incoming calls to the appropriate per-user {@link UserBackupManagerService} to handle the 67 * corresponding backup/restore operation. 68 */ 69 public class BackupManagerService { 70 public static final String TAG = "BackupManagerService"; 71 public static final boolean DEBUG = true; 72 public static final boolean MORE_DEBUG = false; 73 public static final boolean DEBUG_SCHEDULING = true; 74 75 @VisibleForTesting 76 static final String DUMP_RUNNING_USERS_MESSAGE = "Backup Manager is running for users:"; 77 78 // The published binder is a singleton Trampoline object that calls through to the proper code. 79 // This indirection lets us turn down the heavy implementation object on the fly without 80 // disturbing binders that have been cached elsewhere in the system. 81 private static Trampoline sInstance; 82 getInstance()83 static Trampoline getInstance() { 84 // Always constructed during system bring up, so no need to lazy-init. 85 return sInstance; 86 } 87 88 private final Context mContext; 89 private final Trampoline mTrampoline; 90 private final HandlerThread mBackupThread; 91 92 // Keeps track of all unlocked users registered with this service. Indexed by user id. 93 private final SparseArray<UserBackupManagerService> mServiceUsers = new SparseArray<>(); 94 95 private Set<ComponentName> mTransportWhitelist; 96 97 private final BroadcastReceiver mUserRemovedReceiver = new BroadcastReceiver() { 98 @Override 99 public void onReceive(Context context, Intent intent) { 100 if (Intent.ACTION_USER_REMOVED.equals(intent.getAction())) { 101 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL); 102 if (userId > 0) { // for only non system users 103 onRemovedNonSystemUser(userId); 104 } 105 } 106 } 107 }; 108 109 /** Instantiate a new instance of {@link BackupManagerService}. */ BackupManagerService( Context context, Trampoline trampoline, HandlerThread backupThread)110 public BackupManagerService( 111 Context context, Trampoline trampoline, HandlerThread backupThread) { 112 mContext = checkNotNull(context); 113 mTrampoline = checkNotNull(trampoline); 114 mBackupThread = checkNotNull(backupThread); 115 116 // Set up our transport options. 117 SystemConfig systemConfig = SystemConfig.getInstance(); 118 mTransportWhitelist = systemConfig.getBackupTransportWhitelist(); 119 if (mTransportWhitelist == null) { 120 mTransportWhitelist = Collections.emptySet(); 121 } 122 123 mContext.registerReceiver(mUserRemovedReceiver, 124 new IntentFilter(Intent.ACTION_USER_REMOVED)); 125 } 126 127 /** 128 * Remove backup state for non system {@code userId} when the user is removed from the device. 129 * For non system users, backup state is stored in both the user's own dir and the system dir. 130 * When the user is removed, the user's own dir gets removed by the OS. This method ensures that 131 * the part of the user backup state which is in the system dir also gets removed. 132 */ onRemovedNonSystemUser(int userId)133 private void onRemovedNonSystemUser(int userId) { 134 Slog.i(TAG, "Removing state for non system user " + userId); 135 File dir = UserBackupManagerFiles.getStateDirInSystemDir(userId); 136 if (!FileUtils.deleteContentsAndDir(dir)) { 137 Slog.w(TAG, "Failed to delete state dir for removed user: " + userId); 138 } 139 } 140 141 /** 142 * If {@code userId} is different from the calling user id, then the caller must hold the 143 * android.permission.INTERACT_ACROSS_USERS_FULL permission. 144 * 145 * @param userId User id on which the backup operation is being requested. 146 * @param message A message to include in the exception if it is thrown. 147 */ enforceCallingPermissionOnUserId(@serIdInt int userId, String message)148 private void enforceCallingPermissionOnUserId(@UserIdInt int userId, String message) { 149 if (Binder.getCallingUserHandle().getIdentifier() != userId) { 150 mContext.enforceCallingOrSelfPermission( 151 Manifest.permission.INTERACT_ACROSS_USERS_FULL, message); 152 } 153 } 154 155 // --------------------------------------------- 156 // USER LIFECYCLE CALLBACKS 157 // --------------------------------------------- 158 159 /** 160 * Starts the backup service for user {@code userId} by creating a new instance of {@link 161 * UserBackupManagerService} and registering it with this service. 162 */ 163 @VisibleForTesting startServiceForUser(int userId)164 protected void startServiceForUser(int userId) { 165 if (mServiceUsers.get(userId) != null) { 166 Slog.i(TAG, "userId " + userId + " already started, so not starting again"); 167 return; 168 } 169 170 UserBackupManagerService userBackupManagerService = 171 UserBackupManagerService.createAndInitializeService( 172 userId, mContext, mTrampoline, mTransportWhitelist); 173 startServiceForUser(userId, userBackupManagerService); 174 } 175 176 /** 177 * Starts the backup service for user {@code userId} by registering its instance of {@link 178 * UserBackupManagerService} with this service and setting enabled state. 179 */ startServiceForUser(int userId, UserBackupManagerService userBackupManagerService)180 void startServiceForUser(int userId, UserBackupManagerService userBackupManagerService) { 181 mServiceUsers.put(userId, userBackupManagerService); 182 183 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backup enable"); 184 userBackupManagerService.initializeBackupEnableState(); 185 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 186 } 187 188 /** Stops the backup service for user {@code userId} when the user is stopped. */ 189 @VisibleForTesting stopServiceForUser(int userId)190 protected void stopServiceForUser(int userId) { 191 UserBackupManagerService userBackupManagerService = mServiceUsers.removeReturnOld(userId); 192 193 if (userBackupManagerService != null) { 194 userBackupManagerService.tearDownService(); 195 196 KeyValueBackupJob.cancel(userId, mContext); 197 FullBackupJob.cancel(userId, mContext); 198 } 199 } 200 201 /** 202 * Returns a lst of users currently unlocked that have a 203 * {@link UserBackupManagerService} registered. 204 */ 205 @VisibleForTesting getServiceUsers()206 public SparseArray<UserBackupManagerService> getServiceUsers() { 207 return mServiceUsers; 208 } 209 210 /** 211 * Returns the {@link UserBackupManagerService} instance for the specified user {@code userId}. 212 * If the user is not registered with the service (either the user is locked or not eligible for 213 * the backup service) then return {@code null}. 214 * 215 * @param userId The id of the user to retrieve its instance of {@link 216 * UserBackupManagerService}. 217 * @param caller A {@link String} identifying the caller for logging purposes. 218 * @throws SecurityException if {@code userId} is different from the calling user id and the 219 * caller does NOT have the android.permission.INTERACT_ACROSS_USERS_FULL permission. 220 */ 221 @Nullable 222 @VisibleForTesting getServiceForUserIfCallerHasPermission( @serIdInt int userId, String caller)223 UserBackupManagerService getServiceForUserIfCallerHasPermission( 224 @UserIdInt int userId, String caller) { 225 enforceCallingPermissionOnUserId(userId, caller); 226 UserBackupManagerService userBackupManagerService = mServiceUsers.get(userId); 227 if (userBackupManagerService == null) { 228 Slog.w(TAG, "Called " + caller + " for unknown user: " + userId); 229 } 230 return userBackupManagerService; 231 } 232 233 /* 234 * The following methods are implementations of IBackupManager methods called from Trampoline. 235 * They delegate to the appropriate per-user instance of UserBackupManagerService to perform the 236 * action on the passed in user. Currently this is a straight redirection (see TODO). 237 */ 238 // TODO (b/118520567): Stop hardcoding system user when we pass in user id as a parameter 239 240 // --------------------------------------------- 241 // BACKUP AGENT OPERATIONS 242 // --------------------------------------------- 243 244 /** 245 * An app's backup agent calls this method to let the service know that there's new data to 246 * backup for their app {@code packageName}. Only used for apps participating in key-value 247 * backup. 248 */ dataChanged(@serIdInt int userId, String packageName)249 public void dataChanged(@UserIdInt int userId, String packageName) { 250 UserBackupManagerService userBackupManagerService = 251 getServiceForUserIfCallerHasPermission(userId, "dataChanged()"); 252 253 if (userBackupManagerService != null) { 254 userBackupManagerService.dataChanged(packageName); 255 } 256 } 257 258 /** 259 * Callback: a requested backup agent has been instantiated. This should only be called from the 260 * {@link ActivityManager}. 261 */ agentConnected(@serIdInt int userId, String packageName, IBinder agentBinder)262 public void agentConnected(@UserIdInt int userId, String packageName, IBinder agentBinder) { 263 UserBackupManagerService userBackupManagerService = 264 getServiceForUserIfCallerHasPermission(userId, "agentConnected()"); 265 266 if (userBackupManagerService != null) { 267 userBackupManagerService.agentConnected(packageName, agentBinder); 268 } 269 } 270 271 /** 272 * Callback: a backup agent has failed to come up, or has unexpectedly quit. This should only be 273 * called from the {@link ActivityManager}. 274 */ agentDisconnected(@serIdInt int userId, String packageName)275 public void agentDisconnected(@UserIdInt int userId, String packageName) { 276 UserBackupManagerService userBackupManagerService = 277 getServiceForUserIfCallerHasPermission(userId, "agentDisconnected()"); 278 279 if (userBackupManagerService != null) { 280 userBackupManagerService.agentDisconnected(packageName); 281 } 282 } 283 284 /** 285 * Used by a currently-active backup agent to notify the service that it has completed its given 286 * outstanding asynchronous backup/restore operation. 287 */ opComplete(@serIdInt int userId, int token, long result)288 public void opComplete(@UserIdInt int userId, int token, long result) { 289 UserBackupManagerService userBackupManagerService = 290 getServiceForUserIfCallerHasPermission(userId, "opComplete()"); 291 292 if (userBackupManagerService != null) { 293 userBackupManagerService.opComplete(token, result); 294 } 295 } 296 297 // --------------------------------------------- 298 // TRANSPORT OPERATIONS 299 // --------------------------------------------- 300 301 /** Run an initialize operation for the given transports {@code transportNames}. */ initializeTransports( @serIdInt int userId, String[] transportNames, IBackupObserver observer)302 public void initializeTransports( 303 @UserIdInt int userId, String[] transportNames, IBackupObserver observer) { 304 UserBackupManagerService userBackupManagerService = 305 getServiceForUserIfCallerHasPermission(userId, "initializeTransports()"); 306 307 if (userBackupManagerService != null) { 308 userBackupManagerService.initializeTransports(transportNames, observer); 309 } 310 } 311 312 /** 313 * Clear the given package {@code packageName}'s backup data from the transport {@code 314 * transportName}. 315 */ clearBackupData(@serIdInt int userId, String transportName, String packageName)316 public void clearBackupData(@UserIdInt int userId, String transportName, String packageName) { 317 UserBackupManagerService userBackupManagerService = 318 getServiceForUserIfCallerHasPermission(userId, "clearBackupData()"); 319 320 if (userBackupManagerService != null) { 321 userBackupManagerService.clearBackupData(transportName, packageName); 322 } 323 } 324 325 /** Return the name of the currently active transport. */ 326 @Nullable getCurrentTransport(@serIdInt int userId)327 public String getCurrentTransport(@UserIdInt int userId) { 328 UserBackupManagerService userBackupManagerService = 329 getServiceForUserIfCallerHasPermission(userId, "getCurrentTransport()"); 330 331 return userBackupManagerService == null 332 ? null 333 : userBackupManagerService.getCurrentTransport(); 334 } 335 336 /** 337 * Returns the {@link ComponentName} of the host service of the selected transport or {@code 338 * null} if no transport selected or if the transport selected is not registered. 339 */ 340 @Nullable getCurrentTransportComponent(@serIdInt int userId)341 public ComponentName getCurrentTransportComponent(@UserIdInt int userId) { 342 UserBackupManagerService userBackupManagerService = 343 getServiceForUserIfCallerHasPermission(userId, "getCurrentTransportComponent()"); 344 345 return userBackupManagerService == null 346 ? null 347 : userBackupManagerService.getCurrentTransportComponent(); 348 } 349 350 /** Report all known, available backup transports by name. */ 351 @Nullable listAllTransports(@serIdInt int userId)352 public String[] listAllTransports(@UserIdInt int userId) { 353 UserBackupManagerService userBackupManagerService = 354 getServiceForUserIfCallerHasPermission(userId, "listAllTransports()"); 355 356 return userBackupManagerService == null 357 ? null 358 : userBackupManagerService.listAllTransports(); 359 } 360 361 /** Report all known, available backup transports by {@link ComponentName}. */ 362 @Nullable listAllTransportComponents(@serIdInt int userId)363 public ComponentName[] listAllTransportComponents(@UserIdInt int userId) { 364 UserBackupManagerService userBackupManagerService = 365 getServiceForUserIfCallerHasPermission(userId, "listAllTransportComponents()"); 366 367 return userBackupManagerService == null 368 ? null 369 : userBackupManagerService.listAllTransportComponents(); 370 } 371 372 /** Report all system whitelisted transports. */ 373 @Nullable getTransportWhitelist()374 public String[] getTransportWhitelist() { 375 // No permission check, intentionally. 376 String[] whitelistedTransports = new String[mTransportWhitelist.size()]; 377 int i = 0; 378 for (ComponentName component : mTransportWhitelist) { 379 whitelistedTransports[i] = component.flattenToShortString(); 380 i++; 381 } 382 return whitelistedTransports; 383 } 384 385 /** 386 * Update the attributes of the transport identified by {@code transportComponent}. If the 387 * specified transport has not been bound at least once (for registration), this call will be 388 * ignored. Only the host process of the transport can change its description, otherwise a 389 * {@link SecurityException} will be thrown. 390 * 391 * @param transportComponent The identity of the transport being described. 392 * @param name A {@link String} with the new name for the transport. This is NOT for 393 * identification. MUST NOT be {@code null}. 394 * @param configurationIntent An {@link Intent} that can be passed to {@link 395 * Context#startActivity} in order to launch the transport's configuration UI. It may be 396 * {@code null} if the transport does not offer any user-facing configuration UI. 397 * @param currentDestinationString A {@link String} describing the destination to which the 398 * transport is currently sending data. MUST NOT be {@code null}. 399 * @param dataManagementIntent An {@link Intent} that can be passed to {@link 400 * Context#startActivity} in order to launch the transport's data-management UI. It may be 401 * {@code null} if the transport does not offer any user-facing data management UI. 402 * @param dataManagementLabel A {@link CharSequence} to be used as the label for the transport's 403 * data management affordance. This MUST be {@code null} when dataManagementIntent is {@code 404 * null} and MUST NOT be {@code null} when dataManagementIntent is not {@code null}. 405 * @throws SecurityException If the UID of the calling process differs from the package UID of 406 * {@code transportComponent} or if the caller does NOT have BACKUP permission. 407 */ updateTransportAttributes( @serIdInt int userId, ComponentName transportComponent, String name, @Nullable Intent configurationIntent, String currentDestinationString, @Nullable Intent dataManagementIntent, CharSequence dataManagementLabel)408 public void updateTransportAttributes( 409 @UserIdInt int userId, 410 ComponentName transportComponent, 411 String name, 412 @Nullable Intent configurationIntent, 413 String currentDestinationString, 414 @Nullable Intent dataManagementIntent, 415 CharSequence dataManagementLabel) { 416 UserBackupManagerService userBackupManagerService = 417 getServiceForUserIfCallerHasPermission(userId, "updateTransportAttributes()"); 418 419 if (userBackupManagerService != null) { 420 userBackupManagerService.updateTransportAttributes( 421 transportComponent, 422 name, 423 configurationIntent, 424 currentDestinationString, 425 dataManagementIntent, 426 dataManagementLabel); 427 } 428 } 429 430 /** 431 * Selects transport {@code transportName} and returns the previously selected transport. 432 * 433 * @deprecated Use {@link #selectBackupTransportAsync(ComponentName, 434 * ISelectBackupTransportCallback)} instead. 435 */ 436 @Deprecated 437 @Nullable selectBackupTransport(@serIdInt int userId, String transportName)438 public String selectBackupTransport(@UserIdInt int userId, String transportName) { 439 UserBackupManagerService userBackupManagerService = 440 getServiceForUserIfCallerHasPermission(userId, "selectBackupTransport()"); 441 442 return userBackupManagerService == null 443 ? null 444 : userBackupManagerService.selectBackupTransport(transportName); 445 } 446 447 /** 448 * Selects transport {@code transportComponent} asynchronously and notifies {@code listener} 449 * with the result upon completion. 450 */ selectBackupTransportAsync( @serIdInt int userId, ComponentName transportComponent, ISelectBackupTransportCallback listener)451 public void selectBackupTransportAsync( 452 @UserIdInt int userId, 453 ComponentName transportComponent, 454 ISelectBackupTransportCallback listener) { 455 UserBackupManagerService userBackupManagerService = 456 getServiceForUserIfCallerHasPermission(userId, "selectBackupTransportAsync()"); 457 458 if (userBackupManagerService != null) { 459 userBackupManagerService.selectBackupTransportAsync(transportComponent, listener); 460 } 461 } 462 463 /** 464 * Supply the configuration intent for the given transport. If the name is not one of the 465 * available transports, or if the transport does not supply any configuration UI, the method 466 * returns {@code null}. 467 */ 468 @Nullable getConfigurationIntent(@serIdInt int userId, String transportName)469 public Intent getConfigurationIntent(@UserIdInt int userId, String transportName) { 470 UserBackupManagerService userBackupManagerService = 471 getServiceForUserIfCallerHasPermission(userId, "getConfigurationIntent()"); 472 473 return userBackupManagerService == null 474 ? null 475 : userBackupManagerService.getConfigurationIntent(transportName); 476 } 477 478 /** 479 * Sets the ancestral work profile for the calling user. 480 * 481 * <p> The ancestral work profile corresponds to the profile that was used to restore to the 482 * callers profile. 483 */ setAncestralSerialNumber(long ancestralSerialNumber)484 public void setAncestralSerialNumber(long ancestralSerialNumber) { 485 UserBackupManagerService userBackupManagerService = 486 getServiceForUserIfCallerHasPermission( 487 Binder.getCallingUserHandle().getIdentifier(), 488 "setAncestralSerialNumber()"); 489 490 if (userBackupManagerService != null) { 491 userBackupManagerService.setAncestralSerialNumber(ancestralSerialNumber); 492 } 493 } 494 495 /** 496 * Returns a {@link UserHandle} for the user that has {@code ancestralSerialNumber} as the 497 * serial number of the its ancestral work profile. 498 * 499 * <p> The ancestral work profile is set by {@link #setAncestralSerialNumber(long)} 500 * and it corresponds to the profile that was used to restore to the callers profile. 501 */ 502 @Nullable getUserForAncestralSerialNumber(long ancestralSerialNumber)503 public UserHandle getUserForAncestralSerialNumber(long ancestralSerialNumber) { 504 int callingUserId = Binder.getCallingUserHandle().getIdentifier(); 505 long oldId = Binder.clearCallingIdentity(); 506 int[] userIds; 507 try { 508 userIds = mContext.getSystemService(UserManager.class).getProfileIds(callingUserId, 509 false); 510 } finally { 511 Binder.restoreCallingIdentity(oldId); 512 } 513 514 for (int userId : userIds) { 515 UserBackupManagerService userBackupManagerService = getServiceUsers().get(userId); 516 if (userBackupManagerService != null) { 517 if (userBackupManagerService.getAncestralSerialNumber() == ancestralSerialNumber) { 518 return UserHandle.of(userId); 519 } 520 } 521 } 522 523 return null; 524 } 525 526 /** 527 * Supply the current destination string for the given transport. If the name is not one of the 528 * registered transports the method will return null. 529 * 530 * <p>This string is used VERBATIM as the summary text of the relevant Settings item. 531 * 532 * @param transportName The name of the registered transport. 533 * @return The current destination string or null if the transport is not registered. 534 */ 535 @Nullable getDestinationString(@serIdInt int userId, String transportName)536 public String getDestinationString(@UserIdInt int userId, String transportName) { 537 UserBackupManagerService userBackupManagerService = 538 getServiceForUserIfCallerHasPermission(userId, "getDestinationString()"); 539 540 return userBackupManagerService == null 541 ? null 542 : userBackupManagerService.getDestinationString(transportName); 543 } 544 545 /** Supply the manage-data intent for the given transport. */ 546 @Nullable getDataManagementIntent(@serIdInt int userId, String transportName)547 public Intent getDataManagementIntent(@UserIdInt int userId, String transportName) { 548 UserBackupManagerService userBackupManagerService = 549 getServiceForUserIfCallerHasPermission(userId, "getDataManagementIntent()"); 550 551 return userBackupManagerService == null 552 ? null 553 : userBackupManagerService.getDataManagementIntent(transportName); 554 } 555 556 /** 557 * Supply the menu label for affordances that fire the manage-data intent for the given 558 * transport. 559 */ 560 @Nullable getDataManagementLabel(@serIdInt int userId, String transportName)561 public CharSequence getDataManagementLabel(@UserIdInt int userId, String transportName) { 562 UserBackupManagerService userBackupManagerService = 563 getServiceForUserIfCallerHasPermission(userId, "getDataManagementLabel()"); 564 565 return userBackupManagerService == null 566 ? null 567 : userBackupManagerService.getDataManagementLabel(transportName); 568 } 569 570 // --------------------------------------------- 571 // SETTINGS OPERATIONS 572 // --------------------------------------------- 573 574 /** Enable/disable the backup service. This is user-configurable via backup settings. */ setBackupEnabled(@serIdInt int userId, boolean enable)575 public void setBackupEnabled(@UserIdInt int userId, boolean enable) { 576 UserBackupManagerService userBackupManagerService = 577 getServiceForUserIfCallerHasPermission(userId, "setBackupEnabled()"); 578 579 if (userBackupManagerService != null) { 580 userBackupManagerService.setBackupEnabled(enable); 581 } 582 } 583 584 /** Enable/disable automatic restore of app data at install time. */ setAutoRestore(@serIdInt int userId, boolean autoRestore)585 public void setAutoRestore(@UserIdInt int userId, boolean autoRestore) { 586 UserBackupManagerService userBackupManagerService = 587 getServiceForUserIfCallerHasPermission(userId, "setAutoRestore()"); 588 589 if (userBackupManagerService != null) { 590 userBackupManagerService.setAutoRestore(autoRestore); 591 } 592 } 593 594 /** 595 * Return {@code true} if the backup mechanism is currently enabled, else returns {@code false}. 596 */ isBackupEnabled(@serIdInt int userId)597 public boolean isBackupEnabled(@UserIdInt int userId) { 598 UserBackupManagerService userBackupManagerService = 599 getServiceForUserIfCallerHasPermission(userId, "isBackupEnabled()"); 600 601 return userBackupManagerService != null && userBackupManagerService.isBackupEnabled(); 602 } 603 604 // --------------------------------------------- 605 // BACKUP OPERATIONS 606 // --------------------------------------------- 607 608 /** Checks if the given package {@code packageName} is eligible for backup. */ isAppEligibleForBackup(@serIdInt int userId, String packageName)609 public boolean isAppEligibleForBackup(@UserIdInt int userId, String packageName) { 610 UserBackupManagerService userBackupManagerService = 611 getServiceForUserIfCallerHasPermission(userId, "isAppEligibleForBackup()"); 612 613 return userBackupManagerService != null 614 && userBackupManagerService.isAppEligibleForBackup(packageName); 615 } 616 617 /** 618 * Returns from the inputted packages {@code packages}, the ones that are eligible for backup. 619 */ 620 @Nullable filterAppsEligibleForBackup(@serIdInt int userId, String[] packages)621 public String[] filterAppsEligibleForBackup(@UserIdInt int userId, String[] packages) { 622 UserBackupManagerService userBackupManagerService = 623 getServiceForUserIfCallerHasPermission(userId, "filterAppsEligibleForBackup()"); 624 625 return userBackupManagerService == null 626 ? null 627 : userBackupManagerService.filterAppsEligibleForBackup(packages); 628 } 629 630 /** 631 * Run a backup pass immediately for any key-value backup applications that have declared that 632 * they have pending updates. 633 */ backupNow(@serIdInt int userId)634 public void backupNow(@UserIdInt int userId) { 635 UserBackupManagerService userBackupManagerService = 636 getServiceForUserIfCallerHasPermission(userId, "backupNow()"); 637 638 if (userBackupManagerService != null) { 639 userBackupManagerService.backupNow(); 640 } 641 } 642 643 /** 644 * Requests a backup for the inputted {@code packages} with a specified callback {@link 645 * IBackupManagerMonitor} for receiving events during the operation. 646 */ requestBackup( @serIdInt int userId, String[] packages, IBackupObserver observer, IBackupManagerMonitor monitor, int flags)647 public int requestBackup( 648 @UserIdInt int userId, 649 String[] packages, 650 IBackupObserver observer, 651 IBackupManagerMonitor monitor, 652 int flags) { 653 UserBackupManagerService userBackupManagerService = 654 getServiceForUserIfCallerHasPermission(userId, "requestBackup()"); 655 656 return userBackupManagerService == null 657 ? BackupManager.ERROR_BACKUP_NOT_ALLOWED 658 : userBackupManagerService.requestBackup(packages, observer, monitor, flags); 659 } 660 661 /** Cancel all running backup operations. */ cancelBackups(@serIdInt int userId)662 public void cancelBackups(@UserIdInt int userId) { 663 UserBackupManagerService userBackupManagerService = 664 getServiceForUserIfCallerHasPermission(userId, "cancelBackups()"); 665 666 if (userBackupManagerService != null) { 667 userBackupManagerService.cancelBackups(); 668 } 669 } 670 671 /** 672 * Used by the {@link JobScheduler} to run a full backup when conditions are right. The model we 673 * use is to perform one app backup per scheduled job execution, and to reschedule the job with 674 * zero latency as long as conditions remain right and we still have work to do. 675 * 676 * @return Whether ongoing work will continue. The return value here will be passed along as the 677 * return value to the callback {@link JobService#onStartJob(JobParameters)}. 678 */ beginFullBackup(@serIdInt int userId, FullBackupJob scheduledJob)679 public boolean beginFullBackup(@UserIdInt int userId, FullBackupJob scheduledJob) { 680 UserBackupManagerService userBackupManagerService = 681 getServiceForUserIfCallerHasPermission(userId, "beginFullBackup()"); 682 683 return userBackupManagerService != null 684 && userBackupManagerService.beginFullBackup(scheduledJob); 685 } 686 687 /** 688 * Used by the {@link JobScheduler} to end the current full backup task when conditions are no 689 * longer met for running the full backup job. 690 */ endFullBackup(@serIdInt int userId)691 public void endFullBackup(@UserIdInt int userId) { 692 UserBackupManagerService userBackupManagerService = 693 getServiceForUserIfCallerHasPermission(userId, "endFullBackup()"); 694 695 if (userBackupManagerService != null) { 696 userBackupManagerService.endFullBackup(); 697 } 698 } 699 700 /** 701 * Run a full backup pass for the given packages {@code packageNames}. Used by 'adb shell bmgr'. 702 */ fullTransportBackup(@serIdInt int userId, String[] packageNames)703 public void fullTransportBackup(@UserIdInt int userId, String[] packageNames) { 704 UserBackupManagerService userBackupManagerService = 705 getServiceForUserIfCallerHasPermission(userId, "fullTransportBackup()"); 706 707 if (userBackupManagerService != null) { 708 userBackupManagerService.fullTransportBackup(packageNames); 709 } 710 } 711 712 // --------------------------------------------- 713 // RESTORE OPERATIONS 714 // --------------------------------------------- 715 716 /** 717 * Used to run a restore pass for an application that is being installed. This should only be 718 * called from the {@link PackageManager}. 719 */ restoreAtInstall(@serIdInt int userId, String packageName, int token)720 public void restoreAtInstall(@UserIdInt int userId, String packageName, int token) { 721 UserBackupManagerService userBackupManagerService = 722 getServiceForUserIfCallerHasPermission(userId, "restoreAtInstall()"); 723 724 if (userBackupManagerService != null) { 725 userBackupManagerService.restoreAtInstall(packageName, token); 726 } 727 } 728 729 /** 730 * Begin a restore for the specified package {@code packageName} using the specified transport 731 * {@code transportName}. 732 */ 733 @Nullable beginRestoreSession( @serIdInt int userId, String packageName, String transportName)734 public IRestoreSession beginRestoreSession( 735 @UserIdInt int userId, String packageName, String transportName) { 736 UserBackupManagerService userBackupManagerService = 737 getServiceForUserIfCallerHasPermission(userId, "beginRestoreSession()"); 738 739 return userBackupManagerService == null 740 ? null 741 : userBackupManagerService.beginRestoreSession(packageName, transportName); 742 } 743 744 /** 745 * Get the restore-set token for the best-available restore set for this {@code packageName}: 746 * the active set if possible, else the ancestral one. Returns zero if none available. 747 */ getAvailableRestoreToken(@serIdInt int userId, String packageName)748 public long getAvailableRestoreToken(@UserIdInt int userId, String packageName) { 749 UserBackupManagerService userBackupManagerService = 750 getServiceForUserIfCallerHasPermission(userId, "getAvailableRestoreToken()"); 751 752 return userBackupManagerService == null 753 ? 0 754 : userBackupManagerService.getAvailableRestoreToken(packageName); 755 } 756 757 // --------------------------------------------- 758 // ADB BACKUP/RESTORE OPERATIONS 759 // --------------------------------------------- 760 761 /** Sets the backup password used when running adb backup. */ setBackupPassword(String currentPassword, String newPassword)762 public boolean setBackupPassword(String currentPassword, String newPassword) { 763 UserBackupManagerService userBackupManagerService = 764 getServiceForUserIfCallerHasPermission( 765 UserHandle.USER_SYSTEM, "setBackupPassword()"); 766 767 return userBackupManagerService != null 768 && userBackupManagerService.setBackupPassword(currentPassword, newPassword); 769 } 770 771 /** Returns {@code true} if adb backup was run with a password, else returns {@code false}. */ hasBackupPassword()772 public boolean hasBackupPassword() { 773 UserBackupManagerService userBackupManagerService = 774 getServiceForUserIfCallerHasPermission( 775 UserHandle.USER_SYSTEM, "hasBackupPassword()"); 776 777 return userBackupManagerService != null && userBackupManagerService.hasBackupPassword(); 778 } 779 780 /** 781 * Used by 'adb backup' to run a backup pass for packages {@code packageNames} supplied via the 782 * command line, writing the resulting data stream to the supplied {@code fd}. This method is 783 * synchronous and does not return to the caller until the backup has been completed. It 784 * requires on-screen confirmation by the user. 785 */ adbBackup( @serIdInt int userId, ParcelFileDescriptor fd, boolean includeApks, boolean includeObbs, boolean includeShared, boolean doWidgets, boolean doAllApps, boolean includeSystem, boolean doCompress, boolean doKeyValue, String[] packageNames)786 public void adbBackup( 787 @UserIdInt int userId, 788 ParcelFileDescriptor fd, 789 boolean includeApks, 790 boolean includeObbs, 791 boolean includeShared, 792 boolean doWidgets, 793 boolean doAllApps, 794 boolean includeSystem, 795 boolean doCompress, 796 boolean doKeyValue, 797 String[] packageNames) { 798 UserBackupManagerService userBackupManagerService = 799 getServiceForUserIfCallerHasPermission(userId, "adbBackup()"); 800 801 if (userBackupManagerService != null) { 802 userBackupManagerService.adbBackup( 803 fd, 804 includeApks, 805 includeObbs, 806 includeShared, 807 doWidgets, 808 doAllApps, 809 includeSystem, 810 doCompress, 811 doKeyValue, 812 packageNames); 813 } 814 } 815 816 /** 817 * Used by 'adb restore' to run a restore pass reading from the supplied {@code fd}. This method 818 * is synchronous and does not return to the caller until the restore has been completed. It 819 * requires on-screen confirmation by the user. 820 */ adbRestore(@serIdInt int userId, ParcelFileDescriptor fd)821 public void adbRestore(@UserIdInt int userId, ParcelFileDescriptor fd) { 822 UserBackupManagerService userBackupManagerService = 823 getServiceForUserIfCallerHasPermission(userId, "adbRestore()"); 824 825 if (userBackupManagerService != null) { 826 userBackupManagerService.adbRestore(fd); 827 } 828 } 829 830 /** 831 * Confirm that the previously requested adb backup/restore operation can proceed. This is used 832 * to require a user-facing disclosure about the operation. 833 */ acknowledgeAdbBackupOrRestore( @serIdInt int userId, int token, boolean allow, String currentPassword, String encryptionPassword, IFullBackupRestoreObserver observer)834 public void acknowledgeAdbBackupOrRestore( 835 @UserIdInt int userId, 836 int token, 837 boolean allow, 838 String currentPassword, 839 String encryptionPassword, 840 IFullBackupRestoreObserver observer) { 841 UserBackupManagerService userBackupManagerService = 842 getServiceForUserIfCallerHasPermission(userId, "acknowledgeAdbBackupOrRestore()"); 843 844 if (userBackupManagerService != null) { 845 userBackupManagerService.acknowledgeAdbBackupOrRestore( 846 token, allow, currentPassword, encryptionPassword, observer); 847 } 848 } 849 850 // --------------------------------------------- 851 // SERVICE OPERATIONS 852 // --------------------------------------------- 853 854 /** Prints service state for 'dumpsys backup'. */ dump(FileDescriptor fd, PrintWriter pw, String[] args)855 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 856 if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) { 857 return; 858 } 859 860 if (args != null) { 861 for (String arg : args) { 862 if ("users".equals(arg.toLowerCase())) { 863 pw.print(DUMP_RUNNING_USERS_MESSAGE); 864 for (int i = 0; i < mServiceUsers.size(); i++) { 865 pw.print(" " + mServiceUsers.keyAt(i)); 866 } 867 pw.println(); 868 return; 869 } 870 } 871 } 872 873 UserBackupManagerService userBackupManagerService = 874 getServiceForUserIfCallerHasPermission(UserHandle.USER_SYSTEM, "dump()"); 875 876 if (userBackupManagerService != null) { 877 userBackupManagerService.dump(fd, pw, args); 878 } 879 } 880 881 /** Implementation to receive lifecycle event callbacks for system services. */ 882 public static final class Lifecycle extends SystemService { Lifecycle(Context context)883 public Lifecycle(Context context) { 884 super(context); 885 sInstance = new Trampoline(context); 886 } 887 888 @Override onStart()889 public void onStart() { 890 publishBinderService(Context.BACKUP_SERVICE, sInstance); 891 } 892 893 @Override onUnlockUser(int userId)894 public void onUnlockUser(int userId) { 895 if (userId == UserHandle.USER_SYSTEM) { 896 sInstance.initializeService(); 897 } 898 sInstance.unlockUser(userId); 899 } 900 901 @Override onStopUser(int userId)902 public void onStopUser(int userId) { 903 sInstance.stopUser(userId); 904 } 905 } 906 } 907