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 android.app.backup; 18 19 import android.annotation.SystemApi; 20 import android.content.Intent; 21 import android.content.pm.PackageInfo; 22 import android.os.IBinder; 23 import android.os.ParcelFileDescriptor; 24 import android.os.RemoteException; 25 26 import com.android.internal.backup.IBackupTransport; 27 28 /** 29 * Concrete class that provides a stable-API bridge between IBackupTransport 30 * and its implementations. 31 * 32 * @hide 33 */ 34 @SystemApi 35 public class BackupTransport { 36 // Zero return always means things are okay. If returned from 37 // getNextFullRestoreDataChunk(), it means that no data could be delivered at 38 // this time, but the restore is still running and the caller should simply 39 // retry. 40 public static final int TRANSPORT_OK = 0; 41 42 // -1 is special; it is used in getNextFullRestoreDataChunk() to indicate that 43 // we've delivered the entire data stream for the current restore target. 44 public static final int NO_MORE_DATA = -1; 45 46 // Result codes that indicate real errors are negative and not -1 47 public static final int TRANSPORT_ERROR = -1000; 48 public static final int TRANSPORT_NOT_INITIALIZED = -1001; 49 public static final int TRANSPORT_PACKAGE_REJECTED = -1002; 50 public static final int AGENT_ERROR = -1003; 51 public static final int AGENT_UNKNOWN = -1004; 52 public static final int TRANSPORT_QUOTA_EXCEEDED = -1005; 53 54 /** 55 * Indicates that the transport cannot accept a diff backup for this package. 56 * 57 * <p>Backup manager should clear its state for this package and immediately retry a 58 * non-incremental backup. This might be used if the transport no longer has data for this 59 * package in its backing store. 60 * 61 * <p>This is only valid when backup manager called {@link 62 * #performBackup(PackageInfo, ParcelFileDescriptor, int)} with {@link #FLAG_INCREMENTAL}. 63 */ 64 public static final int TRANSPORT_NON_INCREMENTAL_BACKUP_REQUIRED = -1006; 65 66 // Indicates that operation was initiated by user, not a scheduled one. 67 // Transport should ignore its own moratoriums for call with this flag set. 68 public static final int FLAG_USER_INITIATED = 1; 69 70 /** 71 * For key value backup, indicates that the backup data is a diff from a previous backup. The 72 * transport must apply this diff to an existing backup to build the new backup set. 73 * 74 * @see #performBackup(PackageInfo, ParcelFileDescriptor, int) 75 */ 76 public static final int FLAG_INCREMENTAL = 1 << 1; 77 78 /** 79 * For key value backup, indicates that the backup data is a complete set, not a diff from a 80 * previous backup. The transport should clear any previous backup when storing this backup. 81 * 82 * @see #performBackup(PackageInfo, ParcelFileDescriptor, int) 83 */ 84 public static final int FLAG_NON_INCREMENTAL = 1 << 2; 85 86 /** 87 * Used as a boolean extra in the binding intent of transports. We pass {@code true} to 88 * notify transports that the current connection is used for registering the transport. 89 */ 90 public static final String EXTRA_TRANSPORT_REGISTRATION = 91 "android.app.backup.extra.TRANSPORT_REGISTRATION"; 92 93 IBackupTransport mBinderImpl = new TransportImpl(); 94 getBinder()95 public IBinder getBinder() { 96 return mBinderImpl.asBinder(); 97 } 98 99 // ------------------------------------------------------------------------------------ 100 // Transport self-description and general configuration interfaces 101 // 102 103 /** 104 * Ask the transport for the name under which it should be registered. This will 105 * typically be its host service's component name, but need not be. 106 */ name()107 public String name() { 108 throw new UnsupportedOperationException("Transport name() not implemented"); 109 } 110 111 /** 112 * Ask the transport for an Intent that can be used to launch any internal 113 * configuration Activity that it wishes to present. For example, the transport 114 * may offer a UI for allowing the user to supply login credentials for the 115 * transport's off-device backend. 116 * 117 * <p>If the transport does not supply any user-facing configuration UI, it should 118 * return {@code null} from this method. 119 * 120 * @return An Intent that can be passed to Context.startActivity() in order to 121 * launch the transport's configuration UI. This method will return {@code null} 122 * if the transport does not offer any user-facing configuration UI. 123 */ configurationIntent()124 public Intent configurationIntent() { 125 return null; 126 } 127 128 /** 129 * On demand, supply a one-line string that can be shown to the user that 130 * describes the current backend destination. For example, a transport that 131 * can potentially associate backup data with arbitrary user accounts should 132 * include the name of the currently-active account here. 133 * 134 * @return A string describing the destination to which the transport is currently 135 * sending data. This method should not return null. 136 */ currentDestinationString()137 public String currentDestinationString() { 138 throw new UnsupportedOperationException( 139 "Transport currentDestinationString() not implemented"); 140 } 141 142 /** 143 * Ask the transport for an Intent that can be used to launch a more detailed 144 * secondary data management activity. For example, the configuration intent might 145 * be one for allowing the user to select which account they wish to associate 146 * their backups with, and the management intent might be one which presents a 147 * UI for managing the data on the backend. 148 * 149 * <p>In the Settings UI, the configuration intent will typically be invoked 150 * when the user taps on the preferences item labeled with the current 151 * destination string, and the management intent will be placed in an overflow 152 * menu labelled with the management label string. 153 * 154 * <p>If the transport does not supply any user-facing data management 155 * UI, then it should return {@code null} from this method. 156 * 157 * @return An intent that can be passed to Context.startActivity() in order to 158 * launch the transport's data-management UI. This method will return 159 * {@code null} if the transport does not offer any user-facing data 160 * management UI. 161 */ dataManagementIntent()162 public Intent dataManagementIntent() { 163 return null; 164 } 165 166 /** 167 * On demand, supply a short string that can be shown to the user as the label 168 * on an overflow menu item used to invoked the data management UI. 169 * 170 * @return A string to be used as the label for the transport's data management 171 * affordance. If the transport supplies a data management intent, this 172 * method must not return {@code null}. 173 */ dataManagementLabel()174 public String dataManagementLabel() { 175 throw new UnsupportedOperationException( 176 "Transport dataManagementLabel() not implemented"); 177 } 178 179 /** 180 * Ask the transport where, on local device storage, to keep backup state blobs. 181 * This is per-transport so that mock transports used for testing can coexist with 182 * "live" backup services without interfering with the live bookkeeping. The 183 * returned string should be a name that is expected to be unambiguous among all 184 * available backup transports; the name of the class implementing the transport 185 * is a good choice. 186 * 187 * @return A unique name, suitable for use as a file or directory name, that the 188 * Backup Manager could use to disambiguate state files associated with 189 * different backup transports. 190 */ transportDirName()191 public String transportDirName() { 192 throw new UnsupportedOperationException( 193 "Transport transportDirName() not implemented"); 194 } 195 196 // ------------------------------------------------------------------------------------ 197 // Device-level operations common to both key/value and full-data storage 198 199 /** 200 * Initialize the server side storage for this device, erasing all stored data. 201 * The transport may send the request immediately, or may buffer it. After 202 * this is called, {@link #finishBackup} will be called to ensure the request 203 * is sent and received successfully. 204 * 205 * <p>If the transport returns anything other than TRANSPORT_OK from this method, 206 * the OS will halt the current initialize operation and schedule a retry in the 207 * near future. Even if the transport is in a state such that attempting to 208 * "initialize" the backend storage is meaningless -- for example, if there is 209 * no current live dataset at all, or there is no authenticated account under which 210 * to store the data remotely -- the transport should return TRANSPORT_OK here 211 * and treat the initializeDevice() / finishBackup() pair as a graceful no-op. 212 * 213 * @return One of {@link BackupTransport#TRANSPORT_OK} (OK so far) or 214 * {@link BackupTransport#TRANSPORT_ERROR} (to retry following network error 215 * or other failure). 216 */ initializeDevice()217 public int initializeDevice() { 218 return BackupTransport.TRANSPORT_ERROR; 219 } 220 221 /** 222 * Erase the given application's data from the backup destination. This clears 223 * out the given package's data from the current backup set, making it as though 224 * the app had never yet been backed up. After this is called, {@link finishBackup} 225 * must be called to ensure that the operation is recorded successfully. 226 * 227 * @return the same error codes as {@link #performBackup}. 228 */ clearBackupData(PackageInfo packageInfo)229 public int clearBackupData(PackageInfo packageInfo) { 230 return BackupTransport.TRANSPORT_ERROR; 231 } 232 233 /** 234 * Finish sending application data to the backup destination. This must be 235 * called after {@link #performBackup}, {@link #performFullBackup}, or {@link clearBackupData} 236 * to ensure that all data is sent and the operation properly finalized. Only when this 237 * method returns true can a backup be assumed to have succeeded. 238 * 239 * @return the same error codes as {@link #performBackup} or {@link #performFullBackup}. 240 */ finishBackup()241 public int finishBackup() { 242 return BackupTransport.TRANSPORT_ERROR; 243 } 244 245 // ------------------------------------------------------------------------------------ 246 // Key/value incremental backup support interfaces 247 248 /** 249 * Verify that this is a suitable time for a key/value backup pass. This should return zero 250 * if a backup is reasonable right now, some positive value otherwise. This method 251 * will be called outside of the {@link #performBackup}/{@link #finishBackup} pair. 252 * 253 * <p>If this is not a suitable time for a backup, the transport should return a 254 * backoff delay, in milliseconds, after which the Backup Manager should try again. 255 * 256 * @return Zero if this is a suitable time for a backup pass, or a positive time delay 257 * in milliseconds to suggest deferring the backup pass for a while. 258 */ requestBackupTime()259 public long requestBackupTime() { 260 return 0; 261 } 262 263 /** 264 * Send one application's key/value data update to the backup destination. The 265 * transport may send the data immediately, or may buffer it. If this method returns 266 * {@link #TRANSPORT_OK}, {@link #finishBackup} will then be called to ensure the data 267 * is sent and recorded successfully. 268 * 269 * If the backup data is a diff against the previous backup then the flag {@link 270 * BackupTransport#FLAG_INCREMENTAL} will be set. Otherwise, if the data is a complete backup 271 * set then {@link BackupTransport#FLAG_NON_INCREMENTAL} will be set. Before P neither flag will 272 * be set regardless of whether the backup is incremental or not. 273 * 274 * <p>If {@link BackupTransport#FLAG_INCREMENTAL} is set and the transport does not have data 275 * for this package in its storage backend then it cannot apply the incremental diff. Thus it 276 * should return {@link BackupTransport#TRANSPORT_NON_INCREMENTAL_BACKUP_REQUIRED} to indicate 277 * that backup manager should delete its state and retry the package as a non-incremental 278 * backup. Before P, or if this is a non-incremental backup, then this return code is equivalent 279 * to {@link BackupTransport#TRANSPORT_ERROR}. 280 * 281 * @param packageInfo The identity of the application whose data is being backed up. 282 * This specifically includes the signature list for the package. 283 * @param inFd Descriptor of file with data that resulted from invoking the application's 284 * BackupService.doBackup() method. This may be a pipe rather than a file on 285 * persistent media, so it may not be seekable. 286 * @param flags a combination of {@link BackupTransport#FLAG_USER_INITIATED}, {@link 287 * BackupTransport#FLAG_NON_INCREMENTAL}, {@link BackupTransport#FLAG_INCREMENTAL}, or 0. 288 * @return one of {@link BackupTransport#TRANSPORT_OK} (OK so far), 289 * {@link BackupTransport#TRANSPORT_PACKAGE_REJECTED} (to suppress backup of this 290 * specific package, but allow others to proceed), 291 * {@link BackupTransport#TRANSPORT_ERROR} (on network error or other failure), {@link 292 * BackupTransport#TRANSPORT_NON_INCREMENTAL_BACKUP_REQUIRED} (if the transport cannot accept 293 * an incremental backup for this package), or {@link 294 * BackupTransport#TRANSPORT_NOT_INITIALIZED} (if the backend dataset has become lost due to 295 * inactivity purge or some other reason and needs re-initializing) 296 */ performBackup(PackageInfo packageInfo, ParcelFileDescriptor inFd, int flags)297 public int performBackup(PackageInfo packageInfo, ParcelFileDescriptor inFd, int flags) { 298 return performBackup(packageInfo, inFd); 299 } 300 301 /** 302 * Legacy version of {@link #performBackup(PackageInfo, ParcelFileDescriptor, int)} that 303 * doesn't use flags parameter. 304 */ performBackup(PackageInfo packageInfo, ParcelFileDescriptor inFd)305 public int performBackup(PackageInfo packageInfo, ParcelFileDescriptor inFd) { 306 return BackupTransport.TRANSPORT_ERROR; 307 } 308 309 // ------------------------------------------------------------------------------------ 310 // Key/value dataset restore interfaces 311 312 /** 313 * Get the set of all backups currently available over this transport. 314 * 315 * @return Descriptions of the set of restore images available for this device, 316 * or null if an error occurred (the attempt should be rescheduled). 317 **/ getAvailableRestoreSets()318 public RestoreSet[] getAvailableRestoreSets() { 319 return null; 320 } 321 322 /** 323 * Get the identifying token of the backup set currently being stored from 324 * this device. This is used in the case of applications wishing to restore 325 * their last-known-good data. 326 * 327 * @return A token that can be passed to {@link #startRestore}, or 0 if there 328 * is no backup set available corresponding to the current device state. 329 */ getCurrentRestoreSet()330 public long getCurrentRestoreSet() { 331 return 0; 332 } 333 334 /** 335 * Start restoring application data from backup. After calling this function, 336 * alternate calls to {@link #nextRestorePackage} and {@link #nextRestoreData} 337 * to walk through the actual application data. 338 * 339 * @param token A backup token as returned by {@link #getAvailableRestoreSets} 340 * or {@link #getCurrentRestoreSet}. 341 * @param packages List of applications to restore (if data is available). 342 * Application data will be restored in the order given. 343 * @return One of {@link BackupTransport#TRANSPORT_OK} (OK so far, call 344 * {@link #nextRestorePackage}) or {@link BackupTransport#TRANSPORT_ERROR} 345 * (an error occurred, the restore should be aborted and rescheduled). 346 */ startRestore(long token, PackageInfo[] packages)347 public int startRestore(long token, PackageInfo[] packages) { 348 return BackupTransport.TRANSPORT_ERROR; 349 } 350 351 /** 352 * Get the package name of the next application with data in the backup store, plus 353 * a description of the structure of the restored archive: either TYPE_KEY_VALUE for 354 * an original-API key/value dataset, or TYPE_FULL_STREAM for a tarball-type archive stream. 355 * 356 * <p>If the package name in the returned RestoreDescription object is the singleton 357 * {@link RestoreDescription#NO_MORE_PACKAGES}, it indicates that no further data is available 358 * in the current restore session: all packages described in startRestore() have been 359 * processed. 360 * 361 * <p>If this method returns {@code null}, it means that a transport-level error has 362 * occurred and the entire restore operation should be abandoned. 363 * 364 * <p class="note">The OS may call {@link #nextRestorePackage()} multiple times 365 * before calling either {@link #getRestoreData(ParcelFileDescriptor) getRestoreData()} 366 * or {@link #getNextFullRestoreDataChunk(ParcelFileDescriptor) getNextFullRestoreDataChunk()}. 367 * It does this when it has determined that it needs to skip restore of one or more 368 * packages. The transport should not actually transfer any restore data for 369 * the given package in response to {@link #nextRestorePackage()}, but rather wait 370 * for an explicit request before doing so. 371 * 372 * @return A RestoreDescription object containing the name of one of the packages 373 * supplied to {@link #startRestore} plus an indicator of the data type of that 374 * restore data; or {@link RestoreDescription#NO_MORE_PACKAGES} to indicate that 375 * no more packages can be restored in this session; or {@code null} to indicate 376 * a transport-level error. 377 */ nextRestorePackage()378 public RestoreDescription nextRestorePackage() { 379 return null; 380 } 381 382 /** 383 * Get the data for the application returned by {@link #nextRestorePackage}, if that 384 * method reported {@link RestoreDescription#TYPE_KEY_VALUE} as its delivery type. 385 * If the package has only TYPE_FULL_STREAM data, then this method will return an 386 * error. 387 * 388 * @param data An open, writable file into which the key/value backup data should be stored. 389 * @return the same error codes as {@link #startRestore}. 390 */ getRestoreData(ParcelFileDescriptor outFd)391 public int getRestoreData(ParcelFileDescriptor outFd) { 392 return BackupTransport.TRANSPORT_ERROR; 393 } 394 395 /** 396 * End a restore session (aborting any in-process data transfer as necessary), 397 * freeing any resources and connections used during the restore process. 398 */ finishRestore()399 public void finishRestore() { 400 throw new UnsupportedOperationException( 401 "Transport finishRestore() not implemented"); 402 } 403 404 // ------------------------------------------------------------------------------------ 405 // Full backup interfaces 406 407 /** 408 * Verify that this is a suitable time for a full-data backup pass. This should return zero 409 * if a backup is reasonable right now, some positive value otherwise. This method 410 * will be called outside of the {@link #performFullBackup}/{@link #finishBackup} pair. 411 * 412 * <p>If this is not a suitable time for a backup, the transport should return a 413 * backoff delay, in milliseconds, after which the Backup Manager should try again. 414 * 415 * @return Zero if this is a suitable time for a backup pass, or a positive time delay 416 * in milliseconds to suggest deferring the backup pass for a while. 417 * 418 * @see #requestBackupTime() 419 */ requestFullBackupTime()420 public long requestFullBackupTime() { 421 return 0; 422 } 423 424 /** 425 * Begin the process of sending an application's full-data archive to the backend. 426 * The description of the package whose data will be delivered is provided, as well as 427 * the socket file descriptor on which the transport will receive the data itself. 428 * 429 * <p>If the package is not eligible for backup, the transport should return 430 * {@link BackupTransport#TRANSPORT_PACKAGE_REJECTED}. In this case the system will 431 * simply proceed with the next candidate if any, or finish the full backup operation 432 * if all apps have been processed. 433 * 434 * <p>After the transport returns {@link BackupTransport#TRANSPORT_OK} from this 435 * method, the OS will proceed to call {@link #sendBackupData()} one or more times 436 * to deliver the application's data as a streamed tarball. The transport should not 437 * read() from the socket except as instructed to via the {@link #sendBackupData(int)} 438 * method. 439 * 440 * <p>After all data has been delivered to the transport, the system will call 441 * {@link #finishBackup()}. At this point the transport should commit the data to 442 * its datastore, if appropriate, and close the socket that had been provided in 443 * {@link #performFullBackup(PackageInfo, ParcelFileDescriptor)}. 444 * 445 * <p class="note">If the transport returns TRANSPORT_OK from this method, then the 446 * OS will always provide a matching call to {@link #finishBackup()} even if sending 447 * data via {@link #sendBackupData(int)} failed at some point. 448 * 449 * @param targetPackage The package whose data is to follow. 450 * @param socket The socket file descriptor through which the data will be provided. 451 * If the transport returns {@link #TRANSPORT_PACKAGE_REJECTED} here, it must still 452 * close this file descriptor now; otherwise it should be cached for use during 453 * succeeding calls to {@link #sendBackupData(int)}, and closed in response to 454 * {@link #finishBackup()}. 455 * @param flags {@link BackupTransport#FLAG_USER_INITIATED} or 0. 456 * @return TRANSPORT_PACKAGE_REJECTED to indicate that the stated application is not 457 * to be backed up; TRANSPORT_OK to indicate that the OS may proceed with delivering 458 * backup data; TRANSPORT_ERROR to indicate a fatal error condition that precludes 459 * performing a backup at this time. 460 */ performFullBackup(PackageInfo targetPackage, ParcelFileDescriptor socket, int flags)461 public int performFullBackup(PackageInfo targetPackage, ParcelFileDescriptor socket, 462 int flags) { 463 return performFullBackup(targetPackage, socket); 464 } 465 466 /** 467 * Legacy version of {@link #performFullBackup(PackageInfo, ParcelFileDescriptor, int)} that 468 * doesn't use flags parameter. 469 */ performFullBackup(PackageInfo targetPackage, ParcelFileDescriptor socket)470 public int performFullBackup(PackageInfo targetPackage, ParcelFileDescriptor socket) { 471 return BackupTransport.TRANSPORT_PACKAGE_REJECTED; 472 } 473 474 /** 475 * Called after {@link #performFullBackup} to make sure that the transport is willing to 476 * handle a full-data backup operation of the specified size on the current package. 477 * If the transport returns anything other than TRANSPORT_OK, the package's backup 478 * operation will be skipped (and {@link #finishBackup() invoked} with no data for that 479 * package being passed to {@link #sendBackupData}. 480 * 481 * <p class="note">The platform does no size-based rejection of full backup attempts on 482 * its own: it is always the responsibility of the transport to implement its own policy. 483 * In particular, even if the preflighted payload size is zero, the platform will still call 484 * this method and will proceed to back up an archive metadata header with no file content 485 * if this method returns TRANSPORT_OK. To avoid storing such payloads the transport 486 * must recognize this case and return TRANSPORT_PACKAGE_REJECTED. 487 * 488 * Added in {@link android.os.Build.VERSION_CODES#M}. 489 * 490 * @param size The estimated size of the full-data payload for this app. This includes 491 * manifest and archive format overhead, but is not guaranteed to be precise. 492 * @return TRANSPORT_OK if the platform is to proceed with the full-data backup, 493 * TRANSPORT_PACKAGE_REJECTED if the proposed payload size is too large for 494 * the transport to handle, or TRANSPORT_ERROR to indicate a fatal error 495 * condition that means the platform cannot perform a backup at this time. 496 */ checkFullBackupSize(long size)497 public int checkFullBackupSize(long size) { 498 return BackupTransport.TRANSPORT_OK; 499 } 500 501 /** 502 * Tells the transport to read {@code numBytes} bytes of data from the socket file 503 * descriptor provided in the {@link #performFullBackup(PackageInfo, ParcelFileDescriptor)} 504 * call, and deliver those bytes to the datastore. 505 * 506 * @param numBytes The number of bytes of tarball data available to be read from the 507 * socket. 508 * @return TRANSPORT_OK on successful processing of the data; TRANSPORT_ERROR to 509 * indicate a fatal error situation. If an error is returned, the system will 510 * call finishBackup() and stop attempting backups until after a backoff and retry 511 * interval. 512 */ sendBackupData(int numBytes)513 public int sendBackupData(int numBytes) { 514 return BackupTransport.TRANSPORT_ERROR; 515 } 516 517 /** 518 * Tells the transport to cancel the currently-ongoing full backup operation. This 519 * will happen between {@link #performFullBackup()} and {@link #finishBackup()} 520 * if the OS needs to abort the backup operation for any reason, such as a crash in 521 * the application undergoing backup. 522 * 523 * <p>When it receives this call, the transport should discard any partial archive 524 * that it has stored so far. If possible it should also roll back to the previous 525 * known-good archive in its datastore. 526 * 527 * <p>If the transport receives this callback, it will <em>not</em> receive a 528 * call to {@link #finishBackup()}. It needs to tear down any ongoing backup state 529 * here. 530 */ cancelFullBackup()531 public void cancelFullBackup() { 532 throw new UnsupportedOperationException( 533 "Transport cancelFullBackup() not implemented"); 534 } 535 536 /** 537 * Ask the transport whether this app is eligible for backup. 538 * 539 * @param targetPackage The identity of the application. 540 * @param isFullBackup If set, transport should check if app is eligible for full data backup, 541 * otherwise to check if eligible for key-value backup. 542 * @return Whether this app is eligible for backup. 543 */ isAppEligibleForBackup(PackageInfo targetPackage, boolean isFullBackup)544 public boolean isAppEligibleForBackup(PackageInfo targetPackage, boolean isFullBackup) { 545 return true; 546 } 547 548 /** 549 * Ask the transport about current quota for backup size of the package. 550 * 551 * @param packageName ID of package to provide the quota. 552 * @param isFullBackup If set, transport should return limit for full data backup, otherwise 553 * for key-value backup. 554 * @return Current limit on backup size in bytes. 555 */ getBackupQuota(String packageName, boolean isFullBackup)556 public long getBackupQuota(String packageName, boolean isFullBackup) { 557 return Long.MAX_VALUE; 558 } 559 560 // ------------------------------------------------------------------------------------ 561 // Full restore interfaces 562 563 /** 564 * Ask the transport to provide data for the "current" package being restored. This 565 * is the package that was just reported by {@link #nextRestorePackage()} as having 566 * {@link RestoreDescription#TYPE_FULL_STREAM} data. 567 * 568 * The transport writes some data to the socket supplied to this call, and returns 569 * the number of bytes written. The system will then read that many bytes and 570 * stream them to the application's agent for restore, then will call this method again 571 * to receive the next chunk of the archive. This sequence will be repeated until the 572 * transport returns zero indicating that all of the package's data has been delivered 573 * (or returns a negative value indicating some sort of hard error condition at the 574 * transport level). 575 * 576 * <p>After this method returns zero, the system will then call 577 * {@link #nextRestorePackage()} to begin the restore process for the next 578 * application, and the sequence begins again. 579 * 580 * <p>The transport should always close this socket when returning from this method. 581 * Do not cache this socket across multiple calls or you may leak file descriptors. 582 * 583 * @param socket The file descriptor that the transport will use for delivering the 584 * streamed archive. The transport must close this socket in all cases when returning 585 * from this method. 586 * @return {@link #NO_MORE_DATA} when no more data for the current package is available. 587 * A positive value indicates the presence of that many bytes to be delivered to the app. 588 * A value of zero indicates that no data was deliverable at this time, but the restore 589 * is still running and the caller should retry. {@link #TRANSPORT_PACKAGE_REJECTED} 590 * means that the current package's restore operation should be aborted, but that 591 * the transport itself is still in a good state and so a multiple-package restore 592 * sequence can still be continued. Any other negative return value is treated as a 593 * fatal error condition that aborts all further restore operations on the current dataset. 594 */ getNextFullRestoreDataChunk(ParcelFileDescriptor socket)595 public int getNextFullRestoreDataChunk(ParcelFileDescriptor socket) { 596 return 0; 597 } 598 599 /** 600 * If the OS encounters an error while processing {@link RestoreDescription#TYPE_FULL_STREAM} 601 * data for restore, it will invoke this method to tell the transport that it should 602 * abandon the data download for the current package. The OS will then either call 603 * {@link #nextRestorePackage()} again to move on to restoring the next package in the 604 * set being iterated over, or will call {@link #finishRestore()} to shut down the restore 605 * operation. 606 * 607 * @return {@link #TRANSPORT_OK} if the transport was successful in shutting down the 608 * current stream cleanly, or {@link #TRANSPORT_ERROR} to indicate a serious 609 * transport-level failure. If the transport reports an error here, the entire restore 610 * operation will immediately be finished with no further attempts to restore app data. 611 */ abortFullRestore()612 public int abortFullRestore() { 613 return BackupTransport.TRANSPORT_OK; 614 } 615 616 /** 617 * Returns flags with additional information about the transport, which is accessible to the 618 * {@link android.app.backup.BackupAgent}. This allows the agent to decide what to do based on 619 * properties of the transport. 620 */ getTransportFlags()621 public int getTransportFlags() { 622 return 0; 623 } 624 625 /** 626 * Bridge between the actual IBackupTransport implementation and the stable API. If the 627 * binder interface needs to change, we use this layer to translate so that we can 628 * (if appropriate) decouple those framework-side changes from the BackupTransport 629 * implementations. 630 */ 631 class TransportImpl extends IBackupTransport.Stub { 632 633 @Override name()634 public String name() throws RemoteException { 635 return BackupTransport.this.name(); 636 } 637 638 @Override configurationIntent()639 public Intent configurationIntent() throws RemoteException { 640 return BackupTransport.this.configurationIntent(); 641 } 642 643 @Override currentDestinationString()644 public String currentDestinationString() throws RemoteException { 645 return BackupTransport.this.currentDestinationString(); 646 } 647 648 @Override dataManagementIntent()649 public Intent dataManagementIntent() { 650 return BackupTransport.this.dataManagementIntent(); 651 } 652 653 @Override dataManagementLabel()654 public String dataManagementLabel() { 655 return BackupTransport.this.dataManagementLabel(); 656 } 657 658 @Override transportDirName()659 public String transportDirName() throws RemoteException { 660 return BackupTransport.this.transportDirName(); 661 } 662 663 @Override requestBackupTime()664 public long requestBackupTime() throws RemoteException { 665 return BackupTransport.this.requestBackupTime(); 666 } 667 668 @Override initializeDevice()669 public int initializeDevice() throws RemoteException { 670 return BackupTransport.this.initializeDevice(); 671 } 672 673 @Override performBackup(PackageInfo packageInfo, ParcelFileDescriptor inFd, int flags)674 public int performBackup(PackageInfo packageInfo, ParcelFileDescriptor inFd, int flags) 675 throws RemoteException { 676 return BackupTransport.this.performBackup(packageInfo, inFd, flags); 677 } 678 679 @Override clearBackupData(PackageInfo packageInfo)680 public int clearBackupData(PackageInfo packageInfo) throws RemoteException { 681 return BackupTransport.this.clearBackupData(packageInfo); 682 } 683 684 @Override finishBackup()685 public int finishBackup() throws RemoteException { 686 return BackupTransport.this.finishBackup(); 687 } 688 689 @Override getAvailableRestoreSets()690 public RestoreSet[] getAvailableRestoreSets() throws RemoteException { 691 return BackupTransport.this.getAvailableRestoreSets(); 692 } 693 694 @Override getCurrentRestoreSet()695 public long getCurrentRestoreSet() throws RemoteException { 696 return BackupTransport.this.getCurrentRestoreSet(); 697 } 698 699 @Override startRestore(long token, PackageInfo[] packages)700 public int startRestore(long token, PackageInfo[] packages) throws RemoteException { 701 return BackupTransport.this.startRestore(token, packages); 702 } 703 704 @Override nextRestorePackage()705 public RestoreDescription nextRestorePackage() throws RemoteException { 706 return BackupTransport.this.nextRestorePackage(); 707 } 708 709 @Override getRestoreData(ParcelFileDescriptor outFd)710 public int getRestoreData(ParcelFileDescriptor outFd) throws RemoteException { 711 return BackupTransport.this.getRestoreData(outFd); 712 } 713 714 @Override finishRestore()715 public void finishRestore() throws RemoteException { 716 BackupTransport.this.finishRestore(); 717 } 718 719 @Override requestFullBackupTime()720 public long requestFullBackupTime() throws RemoteException { 721 return BackupTransport.this.requestFullBackupTime(); 722 } 723 724 @Override performFullBackup(PackageInfo targetPackage, ParcelFileDescriptor socket, int flags)725 public int performFullBackup(PackageInfo targetPackage, ParcelFileDescriptor socket, 726 int flags) throws RemoteException { 727 return BackupTransport.this.performFullBackup(targetPackage, socket, flags); 728 } 729 730 @Override checkFullBackupSize(long size)731 public int checkFullBackupSize(long size) { 732 return BackupTransport.this.checkFullBackupSize(size); 733 } 734 735 @Override sendBackupData(int numBytes)736 public int sendBackupData(int numBytes) throws RemoteException { 737 return BackupTransport.this.sendBackupData(numBytes); 738 } 739 740 @Override cancelFullBackup()741 public void cancelFullBackup() throws RemoteException { 742 BackupTransport.this.cancelFullBackup(); 743 } 744 745 @Override isAppEligibleForBackup(PackageInfo targetPackage, boolean isFullBackup)746 public boolean isAppEligibleForBackup(PackageInfo targetPackage, boolean isFullBackup) 747 throws RemoteException { 748 return BackupTransport.this.isAppEligibleForBackup(targetPackage, isFullBackup); 749 } 750 751 @Override getBackupQuota(String packageName, boolean isFullBackup)752 public long getBackupQuota(String packageName, boolean isFullBackup) { 753 return BackupTransport.this.getBackupQuota(packageName, isFullBackup); 754 } 755 756 @Override getTransportFlags()757 public int getTransportFlags() { 758 return BackupTransport.this.getTransportFlags(); 759 } 760 761 @Override getNextFullRestoreDataChunk(ParcelFileDescriptor socket)762 public int getNextFullRestoreDataChunk(ParcelFileDescriptor socket) { 763 return BackupTransport.this.getNextFullRestoreDataChunk(socket); 764 } 765 766 @Override abortFullRestore()767 public int abortFullRestore() { 768 return BackupTransport.this.abortFullRestore(); 769 } 770 } 771 } 772