Home | History | Annotate | Download | only in backup
      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 
     53     IBackupTransport mBinderImpl = new TransportImpl();
     54 
     55     public IBinder getBinder() {
     56         return mBinderImpl.asBinder();
     57     }
     58 
     59     // ------------------------------------------------------------------------------------
     60     // Transport self-description and general configuration interfaces
     61     //
     62 
     63     /**
     64      * Ask the transport for the name under which it should be registered.  This will
     65      * typically be its host service's component name, but need not be.
     66      */
     67     public String name() {
     68         throw new UnsupportedOperationException("Transport name() not implemented");
     69     }
     70 
     71     /**
     72      * Ask the transport for an Intent that can be used to launch any internal
     73      * configuration Activity that it wishes to present.  For example, the transport
     74      * may offer a UI for allowing the user to supply login credentials for the
     75      * transport's off-device backend.
     76      *
     77      * <p>If the transport does not supply any user-facing configuration UI, it should
     78      * return {@code null} from this method.
     79      *
     80      * @return An Intent that can be passed to Context.startActivity() in order to
     81      *         launch the transport's configuration UI.  This method will return {@code null}
     82      *         if the transport does not offer any user-facing configuration UI.
     83      */
     84     public Intent configurationIntent() {
     85         return null;
     86     }
     87 
     88     /**
     89      * On demand, supply a one-line string that can be shown to the user that
     90      * describes the current backend destination.  For example, a transport that
     91      * can potentially associate backup data with arbitrary user accounts should
     92      * include the name of the currently-active account here.
     93      *
     94      * @return A string describing the destination to which the transport is currently
     95      *         sending data.  This method should not return null.
     96      */
     97     public String currentDestinationString() {
     98         throw new UnsupportedOperationException(
     99                 "Transport currentDestinationString() not implemented");
    100     }
    101 
    102     /**
    103      * Ask the transport for an Intent that can be used to launch a more detailed
    104      * secondary data management activity.  For example, the configuration intent might
    105      * be one for allowing the user to select which account they wish to associate
    106      * their backups with, and the management intent might be one which presents a
    107      * UI for managing the data on the backend.
    108      *
    109      * <p>In the Settings UI, the configuration intent will typically be invoked
    110      * when the user taps on the preferences item labeled with the current
    111      * destination string, and the management intent will be placed in an overflow
    112      * menu labelled with the management label string.
    113      *
    114      * <p>If the transport does not supply any user-facing data management
    115      * UI, then it should return {@code null} from this method.
    116      *
    117      * @return An intent that can be passed to Context.startActivity() in order to
    118      *         launch the transport's data-management UI.  This method will return
    119      *         {@code null} if the transport does not offer any user-facing data
    120      *         management UI.
    121      */
    122     public Intent dataManagementIntent() {
    123         return null;
    124     }
    125 
    126     /**
    127      * On demand, supply a short string that can be shown to the user as the label
    128      * on an overflow menu item used to invoked the data management UI.
    129      *
    130      * @return A string to be used as the label for the transport's data management
    131      *         affordance.  If the transport supplies a data management intent, this
    132      *         method must not return {@code null}.
    133      */
    134     public String dataManagementLabel() {
    135         throw new UnsupportedOperationException(
    136                 "Transport dataManagementLabel() not implemented");
    137     }
    138 
    139     /**
    140      * Ask the transport where, on local device storage, to keep backup state blobs.
    141      * This is per-transport so that mock transports used for testing can coexist with
    142      * "live" backup services without interfering with the live bookkeeping.  The
    143      * returned string should be a name that is expected to be unambiguous among all
    144      * available backup transports; the name of the class implementing the transport
    145      * is a good choice.
    146      *
    147      * @return A unique name, suitable for use as a file or directory name, that the
    148      *         Backup Manager could use to disambiguate state files associated with
    149      *         different backup transports.
    150      */
    151     public String transportDirName() {
    152         throw new UnsupportedOperationException(
    153                 "Transport transportDirName() not implemented");
    154     }
    155 
    156     // ------------------------------------------------------------------------------------
    157     // Device-level operations common to both key/value and full-data storage
    158 
    159     /**
    160      * Initialize the server side storage for this device, erasing all stored data.
    161      * The transport may send the request immediately, or may buffer it.  After
    162      * this is called, {@link #finishBackup} will be called to ensure the request
    163      * is sent and received successfully.
    164      *
    165      * @return One of {@link BackupTransport#TRANSPORT_OK} (OK so far) or
    166      *   {@link BackupTransport#TRANSPORT_ERROR} (on network error or other failure).
    167      */
    168     public int initializeDevice() {
    169         return BackupTransport.TRANSPORT_ERROR;
    170     }
    171 
    172     /**
    173      * Erase the given application's data from the backup destination.  This clears
    174      * out the given package's data from the current backup set, making it as though
    175      * the app had never yet been backed up.  After this is called, {@link finishBackup}
    176      * must be called to ensure that the operation is recorded successfully.
    177      *
    178      * @return the same error codes as {@link #performBackup}.
    179      */
    180     public int clearBackupData(PackageInfo packageInfo) {
    181         return BackupTransport.TRANSPORT_ERROR;
    182     }
    183 
    184     /**
    185      * Finish sending application data to the backup destination.  This must be
    186      * called after {@link #performBackup}, {@link #performFullBackup}, or {@link clearBackupData}
    187      * to ensure that all data is sent and the operation properly finalized.  Only when this
    188      * method returns true can a backup be assumed to have succeeded.
    189      *
    190      * @return the same error codes as {@link #performBackup} or {@link #performFullBackup}.
    191      */
    192     public int finishBackup() {
    193         return BackupTransport.TRANSPORT_ERROR;
    194     }
    195 
    196     // ------------------------------------------------------------------------------------
    197     // Key/value incremental backup support interfaces
    198 
    199     /**
    200      * Verify that this is a suitable time for a key/value backup pass.  This should return zero
    201      * if a backup is reasonable right now, some positive value otherwise.  This method
    202      * will be called outside of the {@link #performBackup}/{@link #finishBackup} pair.
    203      *
    204      * <p>If this is not a suitable time for a backup, the transport should return a
    205      * backoff delay, in milliseconds, after which the Backup Manager should try again.
    206      *
    207      * @return Zero if this is a suitable time for a backup pass, or a positive time delay
    208      *   in milliseconds to suggest deferring the backup pass for a while.
    209      */
    210     public long requestBackupTime() {
    211         return 0;
    212     }
    213 
    214     /**
    215      * Send one application's key/value data update to the backup destination.  The
    216      * transport may send the data immediately, or may buffer it.  If this method returns
    217      * {@link #TRANSPORT_OK}, {@link #finishBackup} will then be called to ensure the data
    218      * is sent and recorded successfully.
    219      *
    220      * @param packageInfo The identity of the application whose data is being backed up.
    221      *   This specifically includes the signature list for the package.
    222      * @param data The data stream that resulted from invoking the application's
    223      *   BackupService.doBackup() method.  This may be a pipe rather than a file on
    224      *   persistent media, so it may not be seekable.
    225      * @param wipeAllFirst When true, <i>all</i> backed-up data for the current device/account
    226      *   must be erased prior to the storage of the data provided here.  The purpose of this
    227      *   is to provide a guarantee that no stale data exists in the restore set when the
    228      *   device begins providing incremental backups.
    229      * @return one of {@link BackupTransport#TRANSPORT_OK} (OK so far),
    230      *  {@link BackupTransport#TRANSPORT_PACKAGE_REJECTED} (to suppress backup of this
    231      *  specific package, but allow others to proceed),
    232      *  {@link BackupTransport#TRANSPORT_ERROR} (on network error or other failure), or
    233      *  {@link BackupTransport#TRANSPORT_NOT_INITIALIZED} (if the backend dataset has
    234      *  become lost due to inactivity purge or some other reason and needs re-initializing)
    235      */
    236     public int performBackup(PackageInfo packageInfo, ParcelFileDescriptor inFd) {
    237         return BackupTransport.TRANSPORT_ERROR;
    238     }
    239 
    240     // ------------------------------------------------------------------------------------
    241     // Key/value dataset restore interfaces
    242 
    243     /**
    244      * Get the set of all backups currently available over this transport.
    245      *
    246      * @return Descriptions of the set of restore images available for this device,
    247      *   or null if an error occurred (the attempt should be rescheduled).
    248      **/
    249     public RestoreSet[] getAvailableRestoreSets() {
    250         return null;
    251     }
    252 
    253     /**
    254      * Get the identifying token of the backup set currently being stored from
    255      * this device.  This is used in the case of applications wishing to restore
    256      * their last-known-good data.
    257      *
    258      * @return A token that can be passed to {@link #startRestore}, or 0 if there
    259      *   is no backup set available corresponding to the current device state.
    260      */
    261     public long getCurrentRestoreSet() {
    262         return 0;
    263     }
    264 
    265     /**
    266      * Start restoring application data from backup.  After calling this function,
    267      * alternate calls to {@link #nextRestorePackage} and {@link #nextRestoreData}
    268      * to walk through the actual application data.
    269      *
    270      * @param token A backup token as returned by {@link #getAvailableRestoreSets}
    271      *   or {@link #getCurrentRestoreSet}.
    272      * @param packages List of applications to restore (if data is available).
    273      *   Application data will be restored in the order given.
    274      * @return One of {@link BackupTransport#TRANSPORT_OK} (OK so far, call
    275      *   {@link #nextRestorePackage}) or {@link BackupTransport#TRANSPORT_ERROR}
    276      *   (an error occurred, the restore should be aborted and rescheduled).
    277      */
    278     public int startRestore(long token, PackageInfo[] packages) {
    279         return BackupTransport.TRANSPORT_ERROR;
    280     }
    281 
    282     /**
    283      * Get the package name of the next application with data in the backup store, plus
    284      * a description of the structure of the restored archive: either TYPE_KEY_VALUE for
    285      * an original-API key/value dataset, or TYPE_FULL_STREAM for a tarball-type archive stream.
    286      *
    287      * <p>If the package name in the returned RestoreDescription object is the singleton
    288      * {@link RestoreDescription#NO_MORE_PACKAGES}, it indicates that no further data is available
    289      * in the current restore session: all packages described in startRestore() have been
    290      * processed.
    291      *
    292      * <p>If this method returns {@code null}, it means that a transport-level error has
    293      * occurred and the entire restore operation should be abandoned.
    294      *
    295      * <p class="note">The OS may call {@link #nextRestorePackage()} multiple times
    296      * before calling either {@link #getRestoreData(ParcelFileDescriptor) getRestoreData()}
    297      * or {@link #getNextFullRestoreDataChunk(ParcelFileDescriptor) getNextFullRestoreDataChunk()}.
    298      * It does this when it has determined that it needs to skip restore of one or more
    299      * packages.  The transport should not actually transfer any restore data for
    300      * the given package in response to {@link #nextRestorePackage()}, but rather wait
    301      * for an explicit request before doing so.
    302      *
    303      * @return A RestoreDescription object containing the name of one of the packages
    304      *   supplied to {@link #startRestore} plus an indicator of the data type of that
    305      *   restore data; or {@link RestoreDescription#NO_MORE_PACKAGES} to indicate that
    306      *   no more packages can be restored in this session; or {@code null} to indicate
    307      *   a transport-level error.
    308      */
    309     public RestoreDescription nextRestorePackage() {
    310         return null;
    311     }
    312 
    313     /**
    314      * Get the data for the application returned by {@link #nextRestorePackage}, if that
    315      * method reported {@link RestoreDescription#TYPE_KEY_VALUE} as its delivery type.
    316      * If the package has only TYPE_FULL_STREAM data, then this method will return an
    317      * error.
    318      *
    319      * @param data An open, writable file into which the key/value backup data should be stored.
    320      * @return the same error codes as {@link #startRestore}.
    321      */
    322     public int getRestoreData(ParcelFileDescriptor outFd) {
    323         return BackupTransport.TRANSPORT_ERROR;
    324     }
    325 
    326     /**
    327      * End a restore session (aborting any in-process data transfer as necessary),
    328      * freeing any resources and connections used during the restore process.
    329      */
    330     public void finishRestore() {
    331         throw new UnsupportedOperationException(
    332                 "Transport finishRestore() not implemented");
    333     }
    334 
    335     // ------------------------------------------------------------------------------------
    336     // Full backup interfaces
    337 
    338     /**
    339      * Verify that this is a suitable time for a full-data backup pass.  This should return zero
    340      * if a backup is reasonable right now, some positive value otherwise.  This method
    341      * will be called outside of the {@link #performFullBackup}/{@link #finishBackup} pair.
    342      *
    343      * <p>If this is not a suitable time for a backup, the transport should return a
    344      * backoff delay, in milliseconds, after which the Backup Manager should try again.
    345      *
    346      * @return Zero if this is a suitable time for a backup pass, or a positive time delay
    347      *   in milliseconds to suggest deferring the backup pass for a while.
    348      *
    349      * @see #requestBackupTime()
    350      */
    351     public long requestFullBackupTime() {
    352         return 0;
    353     }
    354 
    355     /**
    356      * Begin the process of sending an application's full-data archive to the backend.
    357      * The description of the package whose data will be delivered is provided, as well as
    358      * the socket file descriptor on which the transport will receive the data itself.
    359      *
    360      * <p>If the package is not eligible for backup, the transport should return
    361      * {@link BackupTransport#TRANSPORT_PACKAGE_REJECTED}.  In this case the system will
    362      * simply proceed with the next candidate if any, or finish the full backup operation
    363      * if all apps have been processed.
    364      *
    365      * <p>After the transport returns {@link BackupTransport#TRANSPORT_OK} from this
    366      * method, the OS will proceed to call {@link #sendBackupData()} one or more times
    367      * to deliver the application's data as a streamed tarball.  The transport should not
    368      * read() from the socket except as instructed to via the {@link #sendBackupData(int)}
    369      * method.
    370      *
    371      * <p>After all data has been delivered to the transport, the system will call
    372      * {@link #finishBackup()}.  At this point the transport should commit the data to
    373      * its datastore, if appropriate, and close the socket that had been provided in
    374      * {@link #performFullBackup(PackageInfo, ParcelFileDescriptor)}.
    375      *
    376      * <p class="note">If the transport returns TRANSPORT_OK from this method, then the
    377      * OS will always provide a matching call to {@link #finishBackup()} even if sending
    378      * data via {@link #sendBackupData(int)} failed at some point.
    379      *
    380      * @param targetPackage The package whose data is to follow.
    381      * @param socket The socket file descriptor through which the data will be provided.
    382      *    If the transport returns {@link #TRANSPORT_PACKAGE_REJECTED} here, it must still
    383      *    close this file descriptor now; otherwise it should be cached for use during
    384      *    succeeding calls to {@link #sendBackupData(int)}, and closed in response to
    385      *    {@link #finishBackup()}.
    386      * @return TRANSPORT_PACKAGE_REJECTED to indicate that the stated application is not
    387      *    to be backed up; TRANSPORT_OK to indicate that the OS may proceed with delivering
    388      *    backup data; TRANSPORT_ERROR to indicate a fatal error condition that precludes
    389      *    performing a backup at this time.
    390      */
    391     public int performFullBackup(PackageInfo targetPackage, ParcelFileDescriptor socket) {
    392         return BackupTransport.TRANSPORT_PACKAGE_REJECTED;
    393     }
    394 
    395     /**
    396      * Tells the transport to read {@code numBytes} bytes of data from the socket file
    397      * descriptor provided in the {@link #performFullBackup(PackageInfo, ParcelFileDescriptor)}
    398      * call, and deliver those bytes to the datastore.
    399      *
    400      * @param numBytes The number of bytes of tarball data available to be read from the
    401      *    socket.
    402      * @return TRANSPORT_OK on successful processing of the data; TRANSPORT_ERROR to
    403      *    indicate a fatal error situation.  If an error is returned, the system will
    404      *    call finishBackup() and stop attempting backups until after a backoff and retry
    405      *    interval.
    406      */
    407     public int sendBackupData(int numBytes) {
    408         return BackupTransport.TRANSPORT_ERROR;
    409     }
    410 
    411     /**
    412      * Tells the transport to cancel the currently-ongoing full backup operation.  This
    413      * will happen between {@link #performFullBackup()} and {@link #finishBackup()}
    414      * if the OS needs to abort the backup operation for any reason, such as a crash in
    415      * the application undergoing backup.
    416      *
    417      * <p>When it receives this call, the transport should discard any partial archive
    418      * that it has stored so far.  If possible it should also roll back to the previous
    419      * known-good archive in its datastore.
    420      *
    421      * <p>If the transport receives this callback, it will <em>not</em> receive a
    422      * call to {@link #finishBackup()}.  It needs to tear down any ongoing backup state
    423      * here.
    424      */
    425     public void cancelFullBackup() {
    426         throw new UnsupportedOperationException(
    427                 "Transport cancelFullBackup() not implemented");
    428     }
    429 
    430     // ------------------------------------------------------------------------------------
    431     // Full restore interfaces
    432 
    433     /**
    434      * Ask the transport to provide data for the "current" package being restored.  This
    435      * is the package that was just reported by {@link #nextRestorePackage()} as having
    436      * {@link RestoreDescription#TYPE_FULL_STREAM} data.
    437      *
    438      * The transport writes some data to the socket supplied to this call, and returns
    439      * the number of bytes written.  The system will then read that many bytes and
    440      * stream them to the application's agent for restore, then will call this method again
    441      * to receive the next chunk of the archive.  This sequence will be repeated until the
    442      * transport returns zero indicating that all of the package's data has been delivered
    443      * (or returns a negative value indicating some sort of hard error condition at the
    444      * transport level).
    445      *
    446      * <p>After this method returns zero, the system will then call
    447      * {@link #getNextFullRestorePackage()} to begin the restore process for the next
    448      * application, and the sequence begins again.
    449      *
    450      * <p>The transport should always close this socket when returning from this method.
    451      * Do not cache this socket across multiple calls or you may leak file descriptors.
    452      *
    453      * @param socket The file descriptor that the transport will use for delivering the
    454      *    streamed archive.  The transport must close this socket in all cases when returning
    455      *    from this method.
    456      * @return {@link #NO_MORE_DATA} when no more data for the current package is available.
    457      *    A positive value indicates the presence of that many bytes to be delivered to the app.
    458      *    A value of zero indicates that no data was deliverable at this time, but the restore
    459      *    is still running and the caller should retry.  {@link #TRANSPORT_PACKAGE_REJECTED}
    460      *    means that the current package's restore operation should be aborted, but that
    461      *    the transport itself is still in a good state and so a multiple-package restore
    462      *    sequence can still be continued.  Any other negative return value is treated as a
    463      *    fatal error condition that aborts all further restore operations on the current dataset.
    464      */
    465     public int getNextFullRestoreDataChunk(ParcelFileDescriptor socket) {
    466         return 0;
    467     }
    468 
    469     /**
    470      * If the OS encounters an error while processing {@link RestoreDescription#TYPE_FULL_STREAM}
    471      * data for restore, it will invoke this method to tell the transport that it should
    472      * abandon the data download for the current package.  The OS will then either call
    473      * {@link #nextRestorePackage()} again to move on to restoring the next package in the
    474      * set being iterated over, or will call {@link #finishRestore()} to shut down the restore
    475      * operation.
    476      *
    477      * @return {@link #TRANSPORT_OK} if the transport was successful in shutting down the
    478      *    current stream cleanly, or {@link #TRANSPORT_ERROR} to indicate a serious
    479      *    transport-level failure.  If the transport reports an error here, the entire restore
    480      *    operation will immediately be finished with no further attempts to restore app data.
    481      */
    482     public int abortFullRestore() {
    483         return BackupTransport.TRANSPORT_OK;
    484     }
    485 
    486     /**
    487      * Bridge between the actual IBackupTransport implementation and the stable API.  If the
    488      * binder interface needs to change, we use this layer to translate so that we can
    489      * (if appropriate) decouple those framework-side changes from the BackupTransport
    490      * implementations.
    491      */
    492     class TransportImpl extends IBackupTransport.Stub {
    493 
    494         @Override
    495         public String name() throws RemoteException {
    496             return BackupTransport.this.name();
    497         }
    498 
    499         @Override
    500         public Intent configurationIntent() throws RemoteException {
    501             return BackupTransport.this.configurationIntent();
    502         }
    503 
    504         @Override
    505         public String currentDestinationString() throws RemoteException {
    506             return BackupTransport.this.currentDestinationString();
    507         }
    508 
    509         @Override
    510         public Intent dataManagementIntent() {
    511             return BackupTransport.this.dataManagementIntent();
    512         }
    513 
    514         @Override
    515         public String dataManagementLabel() {
    516             return BackupTransport.this.dataManagementLabel();
    517         }
    518 
    519         @Override
    520         public String transportDirName() throws RemoteException {
    521             return BackupTransport.this.transportDirName();
    522         }
    523 
    524         @Override
    525         public long requestBackupTime() throws RemoteException {
    526             return BackupTransport.this.requestBackupTime();
    527         }
    528 
    529         @Override
    530         public int initializeDevice() throws RemoteException {
    531             return BackupTransport.this.initializeDevice();
    532         }
    533 
    534         @Override
    535         public int performBackup(PackageInfo packageInfo, ParcelFileDescriptor inFd)
    536                 throws RemoteException {
    537             return BackupTransport.this.performBackup(packageInfo, inFd);
    538         }
    539 
    540         @Override
    541         public int clearBackupData(PackageInfo packageInfo) throws RemoteException {
    542             return BackupTransport.this.clearBackupData(packageInfo);
    543         }
    544 
    545         @Override
    546         public int finishBackup() throws RemoteException {
    547             return BackupTransport.this.finishBackup();
    548         }
    549 
    550         @Override
    551         public RestoreSet[] getAvailableRestoreSets() throws RemoteException {
    552             return BackupTransport.this.getAvailableRestoreSets();
    553         }
    554 
    555         @Override
    556         public long getCurrentRestoreSet() throws RemoteException {
    557             return BackupTransport.this.getCurrentRestoreSet();
    558         }
    559 
    560         @Override
    561         public int startRestore(long token, PackageInfo[] packages) throws RemoteException {
    562             return BackupTransport.this.startRestore(token, packages);
    563         }
    564 
    565         @Override
    566         public RestoreDescription nextRestorePackage() throws RemoteException {
    567             return BackupTransport.this.nextRestorePackage();
    568         }
    569 
    570         @Override
    571         public int getRestoreData(ParcelFileDescriptor outFd) throws RemoteException {
    572             return BackupTransport.this.getRestoreData(outFd);
    573         }
    574 
    575         @Override
    576         public void finishRestore() throws RemoteException {
    577             BackupTransport.this.finishRestore();
    578         }
    579 
    580         @Override
    581         public long requestFullBackupTime() throws RemoteException {
    582             return BackupTransport.this.requestFullBackupTime();
    583         }
    584 
    585         @Override
    586         public int performFullBackup(PackageInfo targetPackage, ParcelFileDescriptor socket) throws RemoteException {
    587             return BackupTransport.this.performFullBackup(targetPackage, socket);
    588         }
    589 
    590         @Override
    591         public int sendBackupData(int numBytes) throws RemoteException {
    592             return BackupTransport.this.sendBackupData(numBytes);
    593         }
    594 
    595         @Override
    596         public void cancelFullBackup() throws RemoteException {
    597             BackupTransport.this.cancelFullBackup();
    598         }
    599 
    600         @Override
    601         public int getNextFullRestoreDataChunk(ParcelFileDescriptor socket) {
    602             return BackupTransport.this.getNextFullRestoreDataChunk(socket);
    603         }
    604 
    605         @Override
    606         public int abortFullRestore() {
    607             return BackupTransport.this.abortFullRestore();
    608         }
    609     }
    610 }
    611