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