public class BackupTransport extends Object
Modifier and Type | Field and Description |
---|---|
static int |
AGENT_ERROR |
static int |
AGENT_UNKNOWN |
static int |
FLAG_USER_INITIATED |
static int |
NO_MORE_DATA |
static int |
TRANSPORT_ERROR |
static int |
TRANSPORT_NOT_INITIALIZED |
static int |
TRANSPORT_OK |
static int |
TRANSPORT_PACKAGE_REJECTED |
static int |
TRANSPORT_QUOTA_EXCEEDED |
Constructor and Description |
---|
BackupTransport() |
Modifier and Type | Method and Description |
---|---|
int |
abortFullRestore()
If the OS encounters an error while processing
RestoreDescription.TYPE_FULL_STREAM
data for restore, it will invoke this method to tell the transport that it should
abandon the data download for the current package. |
void |
cancelFullBackup()
Tells the transport to cancel the currently-ongoing full backup operation.
|
int |
checkFullBackupSize(long size)
Called after
performFullBackup(android.content.pm.PackageInfo, android.os.ParcelFileDescriptor, int) to make sure that the transport is willing to
handle a full-data backup operation of the specified size on the current package. |
int |
clearBackupData(PackageInfo packageInfo)
Erase the given application's data from the backup destination.
|
Intent |
configurationIntent()
Ask the transport for an Intent that can be used to launch any internal
configuration Activity that it wishes to present.
|
String |
currentDestinationString()
On demand, supply a one-line string that can be shown to the user that
describes the current backend destination.
|
Intent |
dataManagementIntent()
Ask the transport for an Intent that can be used to launch a more detailed
secondary data management activity.
|
String |
dataManagementLabel()
On demand, supply a short string that can be shown to the user as the label
on an overflow menu item used to invoked the data management UI.
|
int |
finishBackup()
Finish sending application data to the backup destination.
|
void |
finishRestore()
End a restore session (aborting any in-process data transfer as necessary),
freeing any resources and connections used during the restore process.
|
RestoreSet[] |
getAvailableRestoreSets()
Get the set of all backups currently available over this transport.
|
long |
getBackupQuota(String packageName,
boolean isFullBackup)
Ask the transport about current quota for backup size of the package.
|
IBinder |
getBinder() |
long |
getCurrentRestoreSet()
Get the identifying token of the backup set currently being stored from
this device.
|
int |
getNextFullRestoreDataChunk(ParcelFileDescriptor socket)
Ask the transport to provide data for the "current" package being restored.
|
int |
getRestoreData(ParcelFileDescriptor outFd)
Get the data for the application returned by
nextRestorePackage() , if that
method reported RestoreDescription.TYPE_KEY_VALUE as its delivery type. |
int |
initializeDevice()
Initialize the server side storage for this device, erasing all stored data.
|
boolean |
isAppEligibleForBackup(PackageInfo targetPackage,
boolean isFullBackup)
Ask the transport whether this app is eligible for backup.
|
String |
name()
Ask the transport for the name under which it should be registered.
|
RestoreDescription |
nextRestorePackage()
Get the package name of the next application with data in the backup store, plus
a description of the structure of the restored archive: either TYPE_KEY_VALUE for
an original-API key/value dataset, or TYPE_FULL_STREAM for a tarball-type archive stream.
|
int |
performBackup(PackageInfo packageInfo,
ParcelFileDescriptor inFd)
Legacy version of
performBackup(PackageInfo, ParcelFileDescriptor, int) that
doesn't use flags parameter. |
int |
performBackup(PackageInfo packageInfo,
ParcelFileDescriptor inFd,
int flags)
Send one application's key/value data update to the backup destination.
|
int |
performFullBackup(PackageInfo targetPackage,
ParcelFileDescriptor socket)
Legacy version of
performFullBackup(PackageInfo, ParcelFileDescriptor, int) that
doesn't use flags parameter. |
int |
performFullBackup(PackageInfo targetPackage,
ParcelFileDescriptor socket,
int flags)
Begin the process of sending an application's full-data archive to the backend.
|
long |
requestBackupTime()
Verify that this is a suitable time for a key/value backup pass.
|
long |
requestFullBackupTime()
Verify that this is a suitable time for a full-data backup pass.
|
int |
sendBackupData(int numBytes)
Tells the transport to read
numBytes bytes of data from the socket file
descriptor provided in the performFullBackup(PackageInfo, ParcelFileDescriptor)
call, and deliver those bytes to the datastore. |
int |
startRestore(long token,
PackageInfo[] packages)
Start restoring application data from backup.
|
String |
transportDirName()
Ask the transport where, on local device storage, to keep backup state blobs.
|
public static final int TRANSPORT_OK
public static final int NO_MORE_DATA
public static final int TRANSPORT_ERROR
public static final int TRANSPORT_NOT_INITIALIZED
public static final int TRANSPORT_PACKAGE_REJECTED
public static final int AGENT_ERROR
public static final int AGENT_UNKNOWN
public static final int TRANSPORT_QUOTA_EXCEEDED
public static final int FLAG_USER_INITIATED
public IBinder getBinder()
public String name()
public Intent configurationIntent()
If the transport does not supply any user-facing configuration UI, it should
return null
from this method.
null
if the transport does not offer any user-facing configuration UI.public String currentDestinationString()
public Intent dataManagementIntent()
In the Settings UI, the configuration intent will typically be invoked when the user taps on the preferences item labeled with the current destination string, and the management intent will be placed in an overflow menu labelled with the management label string.
If the transport does not supply any user-facing data management
UI, then it should return null
from this method.
null
if the transport does not offer any user-facing data
management UI.public String dataManagementLabel()
null
.public String transportDirName()
public int initializeDevice()
finishBackup()
will be called to ensure the request
is sent and received successfully.
If the transport returns anything other than TRANSPORT_OK from this method, the OS will halt the current initialize operation and schedule a retry in the near future. Even if the transport is in a state such that attempting to "initialize" the backend storage is meaningless -- for example, if there is no current live dataset at all, or there is no authenticated account under which to store the data remotely -- the transport should return TRANSPORT_OK here and treat the initializeDevice() / finishBackup() pair as a graceful no-op.
TRANSPORT_OK
(OK so far) or
TRANSPORT_ERROR
(to retry following network error
or other failure).public int clearBackupData(PackageInfo packageInfo)
finishBackup
must be called to ensure that the operation is recorded successfully.performBackup(android.content.pm.PackageInfo, android.os.ParcelFileDescriptor, int)
.public int finishBackup()
performBackup(android.content.pm.PackageInfo, android.os.ParcelFileDescriptor, int)
, performFullBackup(android.content.pm.PackageInfo, android.os.ParcelFileDescriptor, int)
, or clearBackupData
to ensure that all data is sent and the operation properly finalized. Only when this
method returns true can a backup be assumed to have succeeded.public long requestBackupTime()
performBackup(android.content.pm.PackageInfo, android.os.ParcelFileDescriptor, int)
/finishBackup()
pair.
If this is not a suitable time for a backup, the transport should return a backoff delay, in milliseconds, after which the Backup Manager should try again.
public int performBackup(PackageInfo packageInfo, ParcelFileDescriptor inFd, int flags)
TRANSPORT_OK
, finishBackup()
will then be called to ensure the data
is sent and recorded successfully.packageInfo
- The identity of the application whose data is being backed up.
This specifically includes the signature list for the package.inFd
- Descriptor of file with data that resulted from invoking the application's
BackupService.doBackup() method. This may be a pipe rather than a file on
persistent media, so it may not be seekable.flags
- FLAG_USER_INITIATED
or 0.TRANSPORT_OK
(OK so far),
TRANSPORT_PACKAGE_REJECTED
(to suppress backup of this
specific package, but allow others to proceed),
TRANSPORT_ERROR
(on network error or other failure), or
TRANSPORT_NOT_INITIALIZED
(if the backend dataset has
become lost due to inactivity purge or some other reason and needs re-initializing)public int performBackup(PackageInfo packageInfo, ParcelFileDescriptor inFd)
performBackup(PackageInfo, ParcelFileDescriptor, int)
that
doesn't use flags parameter.public RestoreSet[] getAvailableRestoreSets()
public long getCurrentRestoreSet()
startRestore(long, android.content.pm.PackageInfo[])
, or 0 if there
is no backup set available corresponding to the current device state.public int startRestore(long token, PackageInfo[] packages)
nextRestorePackage()
and #nextRestoreData
to walk through the actual application data.token
- A backup token as returned by getAvailableRestoreSets()
or getCurrentRestoreSet()
.packages
- List of applications to restore (if data is available).
Application data will be restored in the order given.TRANSPORT_OK
(OK so far, call
nextRestorePackage()
) or TRANSPORT_ERROR
(an error occurred, the restore should be aborted and rescheduled).public RestoreDescription nextRestorePackage()
If the package name in the returned RestoreDescription object is the singleton
RestoreDescription.NO_MORE_PACKAGES
, it indicates that no further data is available
in the current restore session: all packages described in startRestore() have been
processed.
If this method returns null
, it means that a transport-level error has
occurred and the entire restore operation should be abandoned.
The OS may call nextRestorePackage()
multiple times
before calling either getRestoreData()
or getNextFullRestoreDataChunk()
.
It does this when it has determined that it needs to skip restore of one or more
packages. The transport should not actually transfer any restore data for
the given package in response to nextRestorePackage()
, but rather wait
for an explicit request before doing so.
startRestore(long, android.content.pm.PackageInfo[])
plus an indicator of the data type of that
restore data; or RestoreDescription.NO_MORE_PACKAGES
to indicate that
no more packages can be restored in this session; or null
to indicate
a transport-level error.public int getRestoreData(ParcelFileDescriptor outFd)
nextRestorePackage()
, if that
method reported RestoreDescription.TYPE_KEY_VALUE
as its delivery type.
If the package has only TYPE_FULL_STREAM data, then this method will return an
error.data
- An open, writable file into which the key/value backup data should be stored.startRestore(long, android.content.pm.PackageInfo[])
.public void finishRestore()
public long requestFullBackupTime()
performFullBackup(android.content.pm.PackageInfo, android.os.ParcelFileDescriptor, int)
/finishBackup()
pair.
If this is not a suitable time for a backup, the transport should return a backoff delay, in milliseconds, after which the Backup Manager should try again.
requestBackupTime()
public int performFullBackup(PackageInfo targetPackage, ParcelFileDescriptor socket, int flags)
If the package is not eligible for backup, the transport should return
TRANSPORT_PACKAGE_REJECTED
. In this case the system will
simply proceed with the next candidate if any, or finish the full backup operation
if all apps have been processed.
After the transport returns TRANSPORT_OK
from this
method, the OS will proceed to call #sendBackupData()
one or more times
to deliver the application's data as a streamed tarball. The transport should not
read() from the socket except as instructed to via the sendBackupData(int)
method.
After all data has been delivered to the transport, the system will call
finishBackup()
. At this point the transport should commit the data to
its datastore, if appropriate, and close the socket that had been provided in
performFullBackup(PackageInfo, ParcelFileDescriptor)
.
If the transport returns TRANSPORT_OK from this method, then the
OS will always provide a matching call to finishBackup()
even if sending
data via sendBackupData(int)
failed at some point.
targetPackage
- The package whose data is to follow.socket
- The socket file descriptor through which the data will be provided.
If the transport returns TRANSPORT_PACKAGE_REJECTED
here, it must still
close this file descriptor now; otherwise it should be cached for use during
succeeding calls to sendBackupData(int)
, and closed in response to
finishBackup()
.flags
- FLAG_USER_INITIATED
or 0.public int performFullBackup(PackageInfo targetPackage, ParcelFileDescriptor socket)
performFullBackup(PackageInfo, ParcelFileDescriptor, int)
that
doesn't use flags parameter.public int checkFullBackupSize(long size)
performFullBackup(android.content.pm.PackageInfo, android.os.ParcelFileDescriptor, int)
to make sure that the transport is willing to
handle a full-data backup operation of the specified size on the current package.
If the transport returns anything other than TRANSPORT_OK, the package's backup
operation will be skipped (and invoked
with no data for that
package being passed to sendBackupData(int)
.
The platform does no size-based rejection of full backup attempts on
its own: it is always the responsibility of the transport to implement its own policy.
In particular, even if the preflighted payload size is zero, the platform will still call
this method and will proceed to back up an archive metadata header with no file content
if this method returns TRANSPORT_OK. To avoid storing such payloads the transport
must recognize this case and return TRANSPORT_PACKAGE_REJECTED.
Added in Build.VERSION_CODES.M
.
size
- The estimated size of the full-data payload for this app. This includes
manifest and archive format overhead, but is not guaranteed to be precise.public int sendBackupData(int numBytes)
numBytes
bytes of data from the socket file
descriptor provided in the performFullBackup(PackageInfo, ParcelFileDescriptor)
call, and deliver those bytes to the datastore.numBytes
- The number of bytes of tarball data available to be read from the
socket.public void cancelFullBackup()
#performFullBackup()
and finishBackup()
if the OS needs to abort the backup operation for any reason, such as a crash in
the application undergoing backup.
When it receives this call, the transport should discard any partial archive that it has stored so far. If possible it should also roll back to the previous known-good archive in its datastore.
If the transport receives this callback, it will not receive a
call to finishBackup()
. It needs to tear down any ongoing backup state
here.
public boolean isAppEligibleForBackup(PackageInfo targetPackage, boolean isFullBackup)
targetPackage
- The identity of the application.isFullBackup
- If set, transport should check if app is eligible for full data backup,
otherwise to check if eligible for key-value backup.public long getBackupQuota(String packageName, boolean isFullBackup)
packageName
- ID of package to provide the quota.isFullBackup
- If set, transport should return limit for full data backup, otherwise
for key-value backup.public int getNextFullRestoreDataChunk(ParcelFileDescriptor socket)
nextRestorePackage()
as having
RestoreDescription.TYPE_FULL_STREAM
data.
The transport writes some data to the socket supplied to this call, and returns
the number of bytes written. The system will then read that many bytes and
stream them to the application's agent for restore, then will call this method again
to receive the next chunk of the archive. This sequence will be repeated until the
transport returns zero indicating that all of the package's data has been delivered
(or returns a negative value indicating some sort of hard error condition at the
transport level).
After this method returns zero, the system will then call
nextRestorePackage()
to begin the restore process for the next
application, and the sequence begins again.
The transport should always close this socket when returning from this method. Do not cache this socket across multiple calls or you may leak file descriptors.
socket
- The file descriptor that the transport will use for delivering the
streamed archive. The transport must close this socket in all cases when returning
from this method.NO_MORE_DATA
when no more data for the current package is available.
A positive value indicates the presence of that many bytes to be delivered to the app.
A value of zero indicates that no data was deliverable at this time, but the restore
is still running and the caller should retry. TRANSPORT_PACKAGE_REJECTED
means that the current package's restore operation should be aborted, but that
the transport itself is still in a good state and so a multiple-package restore
sequence can still be continued. Any other negative return value is treated as a
fatal error condition that aborts all further restore operations on the current dataset.public int abortFullRestore()
RestoreDescription.TYPE_FULL_STREAM
data for restore, it will invoke this method to tell the transport that it should
abandon the data download for the current package. The OS will then either call
nextRestorePackage()
again to move on to restoring the next package in the
set being iterated over, or will call finishRestore()
to shut down the restore
operation.TRANSPORT_OK
if the transport was successful in shutting down the
current stream cleanly, or TRANSPORT_ERROR
to indicate a serious
transport-level failure. If the transport reports an error here, the entire restore
operation will immediately be finished with no further attempts to restore app data.