OSDN Git Service

Add payload-size preflight stage to full transport backup
[android-x86/frameworks-base.git] / core / java / android / app / backup / BackupTransport.java
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      * Called after {@link #performFullBackup} to make sure that the transport is willing to
397      * handle a full-data backup operation of the specified size on the current package.
398      * If the transport returns anything other than TRANSPORT_OK, the package's backup
399      * operation will be skipped (and {@link #finishBackup() invoked} with no data for that
400      * package being passed to {@link #sendBackupData}.
401      *
402      * Added in MNC (API 23).
403      *
404      * @param size The estimated size of the full-data payload for this app.  This includes
405      *         manifest and archive format overhead, but is not guaranteed to be precise.
406      * @return TRANSPORT_OK if the platform is to proceed with the full-data backup,
407      *         TRANSPORT_PACKAGE_REJECTED if the proposed payload size is too large for
408      *         the transport to handle, or TRANSPORT_ERROR to indicate a fatal error
409      *         condition that means the platform cannot perform a backup at this time.
410      */
411     public int checkFullBackupSize(long size) {
412         return BackupTransport.TRANSPORT_OK;
413     }
414
415     /**
416      * Tells the transport to read {@code numBytes} bytes of data from the socket file
417      * descriptor provided in the {@link #performFullBackup(PackageInfo, ParcelFileDescriptor)}
418      * call, and deliver those bytes to the datastore.
419      *
420      * @param numBytes The number of bytes of tarball data available to be read from the
421      *    socket.
422      * @return TRANSPORT_OK on successful processing of the data; TRANSPORT_ERROR to
423      *    indicate a fatal error situation.  If an error is returned, the system will
424      *    call finishBackup() and stop attempting backups until after a backoff and retry
425      *    interval.
426      */
427     public int sendBackupData(int numBytes) {
428         return BackupTransport.TRANSPORT_ERROR;
429     }
430
431     /**
432      * Tells the transport to cancel the currently-ongoing full backup operation.  This
433      * will happen between {@link #performFullBackup()} and {@link #finishBackup()}
434      * if the OS needs to abort the backup operation for any reason, such as a crash in
435      * the application undergoing backup.
436      *
437      * <p>When it receives this call, the transport should discard any partial archive
438      * that it has stored so far.  If possible it should also roll back to the previous
439      * known-good archive in its datastore.
440      *
441      * <p>If the transport receives this callback, it will <em>not</em> receive a
442      * call to {@link #finishBackup()}.  It needs to tear down any ongoing backup state
443      * here.
444      */
445     public void cancelFullBackup() {
446         throw new UnsupportedOperationException(
447                 "Transport cancelFullBackup() not implemented");
448     }
449
450     // ------------------------------------------------------------------------------------
451     // Full restore interfaces
452
453     /**
454      * Ask the transport to provide data for the "current" package being restored.  This
455      * is the package that was just reported by {@link #nextRestorePackage()} as having
456      * {@link RestoreDescription#TYPE_FULL_STREAM} data.
457      *
458      * The transport writes some data to the socket supplied to this call, and returns
459      * the number of bytes written.  The system will then read that many bytes and
460      * stream them to the application's agent for restore, then will call this method again
461      * to receive the next chunk of the archive.  This sequence will be repeated until the
462      * transport returns zero indicating that all of the package's data has been delivered
463      * (or returns a negative value indicating some sort of hard error condition at the
464      * transport level).
465      *
466      * <p>After this method returns zero, the system will then call
467      * {@link #getNextFullRestorePackage()} to begin the restore process for the next
468      * application, and the sequence begins again.
469      *
470      * <p>The transport should always close this socket when returning from this method.
471      * Do not cache this socket across multiple calls or you may leak file descriptors.
472      *
473      * @param socket The file descriptor that the transport will use for delivering the
474      *    streamed archive.  The transport must close this socket in all cases when returning
475      *    from this method.
476      * @return {@link #NO_MORE_DATA} when no more data for the current package is available.
477      *    A positive value indicates the presence of that many bytes to be delivered to the app.
478      *    A value of zero indicates that no data was deliverable at this time, but the restore
479      *    is still running and the caller should retry.  {@link #TRANSPORT_PACKAGE_REJECTED}
480      *    means that the current package's restore operation should be aborted, but that
481      *    the transport itself is still in a good state and so a multiple-package restore
482      *    sequence can still be continued.  Any other negative return value is treated as a
483      *    fatal error condition that aborts all further restore operations on the current dataset.
484      */
485     public int getNextFullRestoreDataChunk(ParcelFileDescriptor socket) {
486         return 0;
487     }
488
489     /**
490      * If the OS encounters an error while processing {@link RestoreDescription#TYPE_FULL_STREAM}
491      * data for restore, it will invoke this method to tell the transport that it should
492      * abandon the data download for the current package.  The OS will then either call
493      * {@link #nextRestorePackage()} again to move on to restoring the next package in the
494      * set being iterated over, or will call {@link #finishRestore()} to shut down the restore
495      * operation.
496      *
497      * @return {@link #TRANSPORT_OK} if the transport was successful in shutting down the
498      *    current stream cleanly, or {@link #TRANSPORT_ERROR} to indicate a serious
499      *    transport-level failure.  If the transport reports an error here, the entire restore
500      *    operation will immediately be finished with no further attempts to restore app data.
501      */
502     public int abortFullRestore() {
503         return BackupTransport.TRANSPORT_OK;
504     }
505
506     /**
507      * Bridge between the actual IBackupTransport implementation and the stable API.  If the
508      * binder interface needs to change, we use this layer to translate so that we can
509      * (if appropriate) decouple those framework-side changes from the BackupTransport
510      * implementations.
511      */
512     class TransportImpl extends IBackupTransport.Stub {
513
514         @Override
515         public String name() throws RemoteException {
516             return BackupTransport.this.name();
517         }
518
519         @Override
520         public Intent configurationIntent() throws RemoteException {
521             return BackupTransport.this.configurationIntent();
522         }
523
524         @Override
525         public String currentDestinationString() throws RemoteException {
526             return BackupTransport.this.currentDestinationString();
527         }
528
529         @Override
530         public Intent dataManagementIntent() {
531             return BackupTransport.this.dataManagementIntent();
532         }
533
534         @Override
535         public String dataManagementLabel() {
536             return BackupTransport.this.dataManagementLabel();
537         }
538
539         @Override
540         public String transportDirName() throws RemoteException {
541             return BackupTransport.this.transportDirName();
542         }
543
544         @Override
545         public long requestBackupTime() throws RemoteException {
546             return BackupTransport.this.requestBackupTime();
547         }
548
549         @Override
550         public int initializeDevice() throws RemoteException {
551             return BackupTransport.this.initializeDevice();
552         }
553
554         @Override
555         public int performBackup(PackageInfo packageInfo, ParcelFileDescriptor inFd)
556                 throws RemoteException {
557             return BackupTransport.this.performBackup(packageInfo, inFd);
558         }
559
560         @Override
561         public int clearBackupData(PackageInfo packageInfo) throws RemoteException {
562             return BackupTransport.this.clearBackupData(packageInfo);
563         }
564
565         @Override
566         public int finishBackup() throws RemoteException {
567             return BackupTransport.this.finishBackup();
568         }
569
570         @Override
571         public RestoreSet[] getAvailableRestoreSets() throws RemoteException {
572             return BackupTransport.this.getAvailableRestoreSets();
573         }
574
575         @Override
576         public long getCurrentRestoreSet() throws RemoteException {
577             return BackupTransport.this.getCurrentRestoreSet();
578         }
579
580         @Override
581         public int startRestore(long token, PackageInfo[] packages) throws RemoteException {
582             return BackupTransport.this.startRestore(token, packages);
583         }
584
585         @Override
586         public RestoreDescription nextRestorePackage() throws RemoteException {
587             return BackupTransport.this.nextRestorePackage();
588         }
589
590         @Override
591         public int getRestoreData(ParcelFileDescriptor outFd) throws RemoteException {
592             return BackupTransport.this.getRestoreData(outFd);
593         }
594
595         @Override
596         public void finishRestore() throws RemoteException {
597             BackupTransport.this.finishRestore();
598         }
599
600         @Override
601         public long requestFullBackupTime() throws RemoteException {
602             return BackupTransport.this.requestFullBackupTime();
603         }
604
605         @Override
606         public int performFullBackup(PackageInfo targetPackage, ParcelFileDescriptor socket) throws RemoteException {
607             return BackupTransport.this.performFullBackup(targetPackage, socket);
608         }
609
610         @Override
611         public int checkFullBackupSize(long size) {
612             return BackupTransport.this.checkFullBackupSize(size);
613         }
614
615         @Override
616         public int sendBackupData(int numBytes) throws RemoteException {
617             return BackupTransport.this.sendBackupData(numBytes);
618         }
619
620         @Override
621         public void cancelFullBackup() throws RemoteException {
622             BackupTransport.this.cancelFullBackup();
623         }
624
625         @Override
626         public int getNextFullRestoreDataChunk(ParcelFileDescriptor socket) {
627             return BackupTransport.this.getNextFullRestoreDataChunk(socket);
628         }
629
630         @Override
631         public int abortFullRestore() {
632             return BackupTransport.this.abortFullRestore();
633         }
634     }
635 }