API CHANGE: expose backup/restore to the SDK
The core backup/restore classes [BackupManager, BackupAgent, RestoreSession, and RestoreObserver] are now published for 3rd party developers, as well as the suite of helper classes that exist so far to aid authorship of backup/restore agents. In conjunction with the API change, the restore-time automatic data wipe has now been removed: applications are responsible for managing the logic of wipe vs merge themselves. If the app's agent onRestore() callback throws, the data is presumed to be incoherent and a wipe is issued via the Activity Manager; otherwise, no automatic action is ever taken. Change-Id: I0b3418b829d4689b58b88be3d9c4ace37a8583a9
This commit is contained in:
686
api/current.xml
686
api/current.xml
@@ -19850,6 +19850,83 @@
|
||||
>
|
||||
</method>
|
||||
</class>
|
||||
<class name="BackupAgent"
|
||||
extends="android.content.ContextWrapper"
|
||||
abstract="true"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<constructor name="BackupAgent"
|
||||
type="android.app.BackupAgent"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
</constructor>
|
||||
<method name="onBackup"
|
||||
return="void"
|
||||
abstract="true"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="oldState" type="android.os.ParcelFileDescriptor">
|
||||
</parameter>
|
||||
<parameter name="data" type="android.backup.BackupDataOutput">
|
||||
</parameter>
|
||||
<parameter name="newState" type="android.os.ParcelFileDescriptor">
|
||||
</parameter>
|
||||
<exception name="IOException" type="java.io.IOException">
|
||||
</exception>
|
||||
</method>
|
||||
<method name="onCreate"
|
||||
return="void"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
</method>
|
||||
<method name="onDestroy"
|
||||
return="void"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
</method>
|
||||
<method name="onRestore"
|
||||
return="void"
|
||||
abstract="true"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="data" type="android.backup.BackupDataInput">
|
||||
</parameter>
|
||||
<parameter name="appVersionCode" type="int">
|
||||
</parameter>
|
||||
<parameter name="newState" type="android.os.ParcelFileDescriptor">
|
||||
</parameter>
|
||||
<exception name="IOException" type="java.io.IOException">
|
||||
</exception>
|
||||
</method>
|
||||
</class>
|
||||
<class name="DatePickerDialog"
|
||||
extends="android.app.AlertDialog"
|
||||
abstract="false"
|
||||
@@ -27399,6 +27476,615 @@
|
||||
</field>
|
||||
</class>
|
||||
</package>
|
||||
<package name="android.backup"
|
||||
>
|
||||
<class name="AbsoluteFileBackupHelper"
|
||||
extends="android.backup.FileBackupHelperBase"
|
||||
abstract="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<implements name="android.backup.BackupHelper">
|
||||
</implements>
|
||||
<constructor name="AbsoluteFileBackupHelper"
|
||||
type="android.backup.AbsoluteFileBackupHelper"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="context" type="android.content.Context">
|
||||
</parameter>
|
||||
<parameter name="files" type="java.lang.String...">
|
||||
</parameter>
|
||||
</constructor>
|
||||
<method name="performBackup"
|
||||
return="void"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="oldState" type="android.os.ParcelFileDescriptor">
|
||||
</parameter>
|
||||
<parameter name="data" type="android.backup.BackupDataOutput">
|
||||
</parameter>
|
||||
<parameter name="newState" type="android.os.ParcelFileDescriptor">
|
||||
</parameter>
|
||||
</method>
|
||||
<method name="restoreEntity"
|
||||
return="void"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="data" type="android.backup.BackupDataInputStream">
|
||||
</parameter>
|
||||
</method>
|
||||
</class>
|
||||
<class name="BackupDataInput"
|
||||
extends="java.lang.Object"
|
||||
abstract="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<method name="getDataSize"
|
||||
return="int"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
</method>
|
||||
<method name="getKey"
|
||||
return="java.lang.String"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
</method>
|
||||
<method name="readEntityData"
|
||||
return="int"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="data" type="byte[]">
|
||||
</parameter>
|
||||
<parameter name="offset" type="int">
|
||||
</parameter>
|
||||
<parameter name="size" type="int">
|
||||
</parameter>
|
||||
<exception name="IOException" type="java.io.IOException">
|
||||
</exception>
|
||||
</method>
|
||||
<method name="readNextHeader"
|
||||
return="boolean"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<exception name="IOException" type="java.io.IOException">
|
||||
</exception>
|
||||
</method>
|
||||
<method name="skipEntityData"
|
||||
return="void"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<exception name="IOException" type="java.io.IOException">
|
||||
</exception>
|
||||
</method>
|
||||
</class>
|
||||
<class name="BackupDataInputStream"
|
||||
extends="java.io.InputStream"
|
||||
abstract="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<method name="getKey"
|
||||
return="java.lang.String"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
</method>
|
||||
<method name="read"
|
||||
return="int"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<exception name="IOException" type="java.io.IOException">
|
||||
</exception>
|
||||
</method>
|
||||
<method name="size"
|
||||
return="int"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
</method>
|
||||
</class>
|
||||
<class name="BackupDataOutput"
|
||||
extends="java.lang.Object"
|
||||
abstract="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<method name="setKeyPrefix"
|
||||
return="void"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="keyPrefix" type="java.lang.String">
|
||||
</parameter>
|
||||
</method>
|
||||
<method name="writeEntityData"
|
||||
return="int"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="data" type="byte[]">
|
||||
</parameter>
|
||||
<parameter name="size" type="int">
|
||||
</parameter>
|
||||
<exception name="IOException" type="java.io.IOException">
|
||||
</exception>
|
||||
</method>
|
||||
<method name="writeEntityHeader"
|
||||
return="int"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="key" type="java.lang.String">
|
||||
</parameter>
|
||||
<parameter name="dataSize" type="int">
|
||||
</parameter>
|
||||
<exception name="IOException" type="java.io.IOException">
|
||||
</exception>
|
||||
</method>
|
||||
<field name="OP_DELETE"
|
||||
type="int"
|
||||
transient="false"
|
||||
volatile="false"
|
||||
value="2"
|
||||
static="true"
|
||||
final="true"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
</field>
|
||||
<field name="OP_UPDATE"
|
||||
type="int"
|
||||
transient="false"
|
||||
volatile="false"
|
||||
value="1"
|
||||
static="true"
|
||||
final="true"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
</field>
|
||||
</class>
|
||||
<interface name="BackupHelper"
|
||||
abstract="true"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<method name="performBackup"
|
||||
return="void"
|
||||
abstract="true"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="oldState" type="android.os.ParcelFileDescriptor">
|
||||
</parameter>
|
||||
<parameter name="data" type="android.backup.BackupDataOutput">
|
||||
</parameter>
|
||||
<parameter name="newState" type="android.os.ParcelFileDescriptor">
|
||||
</parameter>
|
||||
</method>
|
||||
<method name="restoreEntity"
|
||||
return="void"
|
||||
abstract="true"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="data" type="android.backup.BackupDataInputStream">
|
||||
</parameter>
|
||||
</method>
|
||||
<method name="writeRestoreSnapshot"
|
||||
return="void"
|
||||
abstract="true"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="fd" type="android.os.ParcelFileDescriptor">
|
||||
</parameter>
|
||||
</method>
|
||||
</interface>
|
||||
<class name="BackupHelperAgent"
|
||||
extends="android.app.BackupAgent"
|
||||
abstract="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<constructor name="BackupHelperAgent"
|
||||
type="android.backup.BackupHelperAgent"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
</constructor>
|
||||
<method name="addHelper"
|
||||
return="void"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="keyPrefix" type="java.lang.String">
|
||||
</parameter>
|
||||
<parameter name="helper" type="android.backup.BackupHelper">
|
||||
</parameter>
|
||||
</method>
|
||||
<method name="onBackup"
|
||||
return="void"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="oldState" type="android.os.ParcelFileDescriptor">
|
||||
</parameter>
|
||||
<parameter name="data" type="android.backup.BackupDataOutput">
|
||||
</parameter>
|
||||
<parameter name="newState" type="android.os.ParcelFileDescriptor">
|
||||
</parameter>
|
||||
<exception name="IOException" type="java.io.IOException">
|
||||
</exception>
|
||||
</method>
|
||||
<method name="onRestore"
|
||||
return="void"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="data" type="android.backup.BackupDataInput">
|
||||
</parameter>
|
||||
<parameter name="appVersionCode" type="int">
|
||||
</parameter>
|
||||
<parameter name="newState" type="android.os.ParcelFileDescriptor">
|
||||
</parameter>
|
||||
<exception name="IOException" type="java.io.IOException">
|
||||
</exception>
|
||||
</method>
|
||||
</class>
|
||||
<class name="BackupManager"
|
||||
extends="java.lang.Object"
|
||||
abstract="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<constructor name="BackupManager"
|
||||
type="android.backup.BackupManager"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="context" type="android.content.Context">
|
||||
</parameter>
|
||||
</constructor>
|
||||
<method name="beginRestoreSession"
|
||||
return="android.backup.RestoreSession"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
</method>
|
||||
<method name="dataChanged"
|
||||
return="void"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
</method>
|
||||
<method name="dataChanged"
|
||||
return="void"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="true"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="packageName" type="java.lang.String">
|
||||
</parameter>
|
||||
</method>
|
||||
</class>
|
||||
<class name="FileBackupHelper"
|
||||
extends="android.backup.FileBackupHelperBase"
|
||||
abstract="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<implements name="android.backup.BackupHelper">
|
||||
</implements>
|
||||
<constructor name="FileBackupHelper"
|
||||
type="android.backup.FileBackupHelper"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="context" type="android.content.Context">
|
||||
</parameter>
|
||||
<parameter name="files" type="java.lang.String...">
|
||||
</parameter>
|
||||
</constructor>
|
||||
<method name="performBackup"
|
||||
return="void"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="oldState" type="android.os.ParcelFileDescriptor">
|
||||
</parameter>
|
||||
<parameter name="data" type="android.backup.BackupDataOutput">
|
||||
</parameter>
|
||||
<parameter name="newState" type="android.os.ParcelFileDescriptor">
|
||||
</parameter>
|
||||
</method>
|
||||
<method name="restoreEntity"
|
||||
return="void"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="data" type="android.backup.BackupDataInputStream">
|
||||
</parameter>
|
||||
</method>
|
||||
</class>
|
||||
<class name="FileBackupHelperBase"
|
||||
extends="java.lang.Object"
|
||||
abstract="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility=""
|
||||
>
|
||||
<method name="writeRestoreSnapshot"
|
||||
return="void"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="fd" type="android.os.ParcelFileDescriptor">
|
||||
</parameter>
|
||||
</method>
|
||||
</class>
|
||||
<class name="RestoreObserver"
|
||||
extends="java.lang.Object"
|
||||
abstract="true"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<constructor name="RestoreObserver"
|
||||
type="android.backup.RestoreObserver"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
</constructor>
|
||||
</class>
|
||||
<class name="RestoreSession"
|
||||
extends="java.lang.Object"
|
||||
abstract="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<method name="endRestoreSession"
|
||||
return="void"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
</method>
|
||||
<method name="restorePackage"
|
||||
return="int"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="packageName" type="java.lang.String">
|
||||
</parameter>
|
||||
<parameter name="observer" type="android.backup.RestoreObserver">
|
||||
</parameter>
|
||||
</method>
|
||||
</class>
|
||||
<class name="SharedPreferencesBackupHelper"
|
||||
extends="android.backup.FileBackupHelperBase"
|
||||
abstract="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<implements name="android.backup.BackupHelper">
|
||||
</implements>
|
||||
<constructor name="SharedPreferencesBackupHelper"
|
||||
type="android.backup.SharedPreferencesBackupHelper"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="context" type="android.content.Context">
|
||||
</parameter>
|
||||
<parameter name="prefGroups" type="java.lang.String...">
|
||||
</parameter>
|
||||
</constructor>
|
||||
<method name="performBackup"
|
||||
return="void"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="oldState" type="android.os.ParcelFileDescriptor">
|
||||
</parameter>
|
||||
<parameter name="data" type="android.backup.BackupDataOutput">
|
||||
</parameter>
|
||||
<parameter name="newState" type="android.os.ParcelFileDescriptor">
|
||||
</parameter>
|
||||
</method>
|
||||
<method name="restoreEntity"
|
||||
return="void"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="data" type="android.backup.BackupDataInputStream">
|
||||
</parameter>
|
||||
</method>
|
||||
</class>
|
||||
</package>
|
||||
<package name="android.bluetooth"
|
||||
>
|
||||
<class name="BluetoothAdapter"
|
||||
|
||||
@@ -33,8 +33,8 @@ import java.io.IOException;
|
||||
/**
|
||||
* This is the central interface between an application and Android's
|
||||
* settings backup mechanism.
|
||||
*
|
||||
* @hide pending API solidification
|
||||
*
|
||||
* <p>STOPSHIP write more documentation about the backup process here.
|
||||
*/
|
||||
public abstract class BackupAgent extends ContextWrapper {
|
||||
private static final String TAG = "BackupAgent";
|
||||
@@ -62,9 +62,9 @@ public abstract class BackupAgent extends ContextWrapper {
|
||||
* state provided by the application. May be null, in which
|
||||
* case no prior state is being provided and the application should
|
||||
* perform a full backup.
|
||||
* @param data An open, read/write ParcelFileDescriptor pointing to the backup data
|
||||
* destination. Typically the application will use backup helper
|
||||
* classes to write to this file.
|
||||
* @param data A structured wrapper around an open, read/write ParcelFileDescriptor
|
||||
* pointing to the backup data destination. Typically the application will use
|
||||
* backup helper classes to write to this file.
|
||||
* @param newState An open, read/write ParcelFileDescriptor pointing to an empty
|
||||
* file. The application should record the final backup state
|
||||
* here after writing the requested data to dataFd.
|
||||
@@ -77,10 +77,18 @@ public abstract class BackupAgent extends ContextWrapper {
|
||||
* existing data with the contents of the backup. The backup data is
|
||||
* provided in the file pointed to by the dataFd file descriptor. Once
|
||||
* the restore is finished, the application should write a representation
|
||||
* of the final state to the newStateFd file descriptor,
|
||||
* of the final state to the newStateFd file descriptor,
|
||||
*
|
||||
* @param data An open, read-only ParcelFileDescriptor pointing to a full snapshot
|
||||
* of the application's data.
|
||||
* <p>The application is responsible for properly erasing its old data and
|
||||
* replacing it with the data supplied to this method. No "clear user data"
|
||||
* operation will be performed automatically by the operating system. The
|
||||
* exception to this is in the case of a failed restore attempt: if onRestore()
|
||||
* throws an exception, the OS will assume that the application's data may now
|
||||
* be in an incoherent state, and will clear it before proceeding.
|
||||
*
|
||||
* @param data A structured wrapper around an open, read-only ParcelFileDescriptor
|
||||
* pointing to a full snapshot of the application's data. Typically the
|
||||
* application will use helper classes to read this data.
|
||||
* @param appVersionCode The android:versionCode value of the application that backed
|
||||
* up this particular data set. This makes it easier for an application's
|
||||
* agent to distinguish among several possible older data versions when
|
||||
|
||||
@@ -27,7 +27,7 @@ import java.io.FileDescriptor;
|
||||
* Like FileBackupHelper, but takes absolute paths for the files instead of
|
||||
* subpaths of getFilesDir()
|
||||
*
|
||||
* @hide
|
||||
* STOPSHIP: document!
|
||||
*/
|
||||
public class AbsoluteFileBackupHelper extends FileBackupHelperBase implements BackupHelper {
|
||||
private static final String TAG = "AbsoluteFileBackupHelper";
|
||||
@@ -36,6 +36,13 @@ public class AbsoluteFileBackupHelper extends FileBackupHelperBase implements Ba
|
||||
Context mContext;
|
||||
String[] mFiles;
|
||||
|
||||
/**
|
||||
* Construct a helper for backing up / restoring the files at the given absolute locations
|
||||
* within the file system.
|
||||
*
|
||||
* @param context
|
||||
* @param files
|
||||
*/
|
||||
public AbsoluteFileBackupHelper(Context context, String... files) {
|
||||
super(context);
|
||||
|
||||
@@ -54,6 +61,9 @@ public class AbsoluteFileBackupHelper extends FileBackupHelperBase implements Ba
|
||||
performBackup_checked(oldState, data, newState, mFiles, mFiles);
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore one absolute file entity from the restore stream
|
||||
*/
|
||||
public void restoreEntity(BackupDataInputStream data) {
|
||||
if (DEBUG) Log.d(TAG, "got entity '" + data.getKey() + "' size=" + data.size());
|
||||
String key = data.getKey();
|
||||
|
||||
@@ -21,7 +21,9 @@ import android.content.Context;
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.IOException;
|
||||
|
||||
/** @hide */
|
||||
/**
|
||||
* STOPSHIP: document!
|
||||
*/
|
||||
public class BackupDataInput {
|
||||
int mBackupReader;
|
||||
|
||||
@@ -33,6 +35,7 @@ public class BackupDataInput {
|
||||
int dataSize;
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public BackupDataInput(FileDescriptor fd) {
|
||||
if (fd == null) throw new NullPointerException();
|
||||
mBackupReader = ctor(fd);
|
||||
@@ -41,6 +44,7 @@ public class BackupDataInput {
|
||||
}
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
protected void finalize() throws Throwable {
|
||||
try {
|
||||
dtor(mBackupReader);
|
||||
@@ -49,6 +53,13 @@ public class BackupDataInput {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Consumes the next header from the restore stream.
|
||||
*
|
||||
* @return true when there is an entity ready for consumption from the restore stream,
|
||||
* false if the restore stream has been fully consumed.
|
||||
* @throws IOException if an error occurred while reading the restore stream
|
||||
*/
|
||||
public boolean readNextHeader() throws IOException {
|
||||
int result = readNextHeader_native(mBackupReader, mHeader);
|
||||
if (result == 0) {
|
||||
@@ -66,6 +77,11 @@ public class BackupDataInput {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Report the key associated with the current record in the restore stream
|
||||
* @return the current record's key string
|
||||
* @throws IllegalStateException if the next record header has not yet been read
|
||||
*/
|
||||
public String getKey() {
|
||||
if (mHeaderReady) {
|
||||
return mHeader.key;
|
||||
@@ -74,6 +90,13 @@ public class BackupDataInput {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Report the size in bytes of the data associated with the current record in the
|
||||
* restore stream.
|
||||
*
|
||||
* @return The size of the record's raw data, in bytes
|
||||
* @throws IllegalStateException if the next record header has not yet been read
|
||||
*/
|
||||
public int getDataSize() {
|
||||
if (mHeaderReady) {
|
||||
return mHeader.dataSize;
|
||||
@@ -82,6 +105,19 @@ public class BackupDataInput {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a record's raw data from the restore stream. The record's header must first
|
||||
* have been processed by the {@link #readNextHeader()} method. Multiple calls to
|
||||
* this method may be made in order to process the data in chunks; not all of it
|
||||
* must be read in a single call.
|
||||
*
|
||||
* @param data An allocated byte array of at least 'size' bytes
|
||||
* @param offset Offset within the 'data' array at which the data will be placed
|
||||
* when read from the stream.
|
||||
* @param size The number of bytes to read in this pass.
|
||||
* @return The number of bytes of data read
|
||||
* @throws IOException if an error occurred when trying to read the restore data stream
|
||||
*/
|
||||
public int readEntityData(byte[] data, int offset, int size) throws IOException {
|
||||
if (mHeaderReady) {
|
||||
int result = readEntityData_native(mBackupReader, data, offset, size);
|
||||
@@ -95,6 +131,14 @@ public class BackupDataInput {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Consume the current record's data without actually reading it into a buffer
|
||||
* for further processing. This allows a {@link android.backup.BackupAgent} to
|
||||
* efficiently discard obsolete or otherwise uninteresting records during the
|
||||
* restore operation.
|
||||
*
|
||||
* @throws IOException if an error occurred when trying to read the restore data stream
|
||||
*/
|
||||
public void skipEntityData() throws IOException {
|
||||
if (mHeaderReady) {
|
||||
skipEntityData_native(mBackupReader);
|
||||
|
||||
@@ -16,12 +16,11 @@
|
||||
|
||||
package android.backup;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
/** @hide */
|
||||
/**
|
||||
* STOPSHIP: document */
|
||||
public class BackupDataInputStream extends InputStream {
|
||||
|
||||
String key;
|
||||
@@ -30,6 +29,7 @@ public class BackupDataInputStream extends InputStream {
|
||||
BackupDataInput mData;
|
||||
byte[] mOneByte;
|
||||
|
||||
/** @hide */
|
||||
BackupDataInputStream(BackupDataInput data) {
|
||||
mData = data;
|
||||
}
|
||||
|
||||
@@ -21,13 +21,16 @@ import android.content.Context;
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.IOException;
|
||||
|
||||
/** @hide */
|
||||
/**
|
||||
* STOPSHIP: document
|
||||
*/
|
||||
public class BackupDataOutput {
|
||||
int mBackupWriter;
|
||||
|
||||
public static final int OP_UPDATE = 1;
|
||||
public static final int OP_DELETE = 2;
|
||||
|
||||
/** @hide */
|
||||
public BackupDataOutput(FileDescriptor fd) {
|
||||
if (fd == null) throw new NullPointerException();
|
||||
mBackupWriter = ctor(fd);
|
||||
@@ -36,7 +39,15 @@ public class BackupDataOutput {
|
||||
}
|
||||
}
|
||||
|
||||
// A dataSize of -1 indicates that the record under this key should be deleted
|
||||
/**
|
||||
* Mark the beginning of one record in the backup data stream.
|
||||
*
|
||||
* @param key
|
||||
* @param dataSize The size in bytes of this record's data. Passing a dataSize
|
||||
* of -1 indicates that the record under this key should be deleted.
|
||||
* @return The number of bytes written to the backup stream
|
||||
* @throws IOException if the write failed
|
||||
*/
|
||||
public int writeEntityHeader(String key, int dataSize) throws IOException {
|
||||
int result = writeEntityHeader_native(mBackupWriter, key, dataSize);
|
||||
if (result >= 0) {
|
||||
@@ -46,6 +57,13 @@ public class BackupDataOutput {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a chunk of data under the current entity to the backup transport.
|
||||
* @param data A raw data buffer to send
|
||||
* @param size The number of bytes to be sent in this chunk
|
||||
* @return the number of bytes written
|
||||
* @throws IOException if the write failed
|
||||
*/
|
||||
public int writeEntityData(byte[] data, int size) throws IOException {
|
||||
int result = writeEntityData_native(mBackupWriter, data, size);
|
||||
if (result >= 0) {
|
||||
@@ -59,6 +77,7 @@ public class BackupDataOutput {
|
||||
setKeyPrefix_native(mBackupWriter, keyPrefix);
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
protected void finalize() throws Throwable {
|
||||
try {
|
||||
dtor(mBackupWriter);
|
||||
|
||||
@@ -20,7 +20,9 @@ import android.os.ParcelFileDescriptor;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
/** @hide */
|
||||
/**
|
||||
* STOPSHIP: document!
|
||||
*/
|
||||
public interface BackupHelper {
|
||||
/**
|
||||
* Based on oldState, determine which of the files from the application's data directory
|
||||
@@ -31,16 +33,18 @@ public interface BackupHelper {
|
||||
ParcelFileDescriptor newState);
|
||||
|
||||
/**
|
||||
* Called by BackupHelperDispatcher to dispatch one entity of data.
|
||||
* Called by BackupHelperAgent to restore one entity from the restore dataset.
|
||||
* <p class=note>
|
||||
* Do not close the <code>data</code> stream. Do not read more than
|
||||
* <code>dataSize</code> bytes from <code>data</code>.
|
||||
* <code>data.size()</code> bytes from <code>data</code>.
|
||||
*/
|
||||
public void restoreEntity(BackupDataInputStream data);
|
||||
|
||||
/**
|
||||
*
|
||||
* Called by BackupHelperAgent to write the new backup state file corresponding to
|
||||
* the current state of the app's data at the time the backup operation was
|
||||
* performed.
|
||||
*/
|
||||
public void writeRestoreSnapshot(ParcelFileDescriptor fd);
|
||||
public void writeNewStateDescription(ParcelFileDescriptor fd);
|
||||
}
|
||||
|
||||
|
||||
@@ -26,28 +26,54 @@ import android.util.Log;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/** @hide */
|
||||
/**
|
||||
* A convenient BackupAgent wrapper class that automatically manages heterogeneous
|
||||
* data sets within the backup data, each identified by a unique key prefix. An
|
||||
* application will typically extend this class in their own backup agent. Then,
|
||||
* within the agent's onBackup() and onRestore() methods, it will call
|
||||
* {@link #addHelper(String, BackupHelper)} one or more times to specify the data
|
||||
* sets, then invoke super.onBackup() or super.onRestore() to have the BackupHelperAgent
|
||||
* implementation process the data.
|
||||
*
|
||||
* STOPSHIP: document!
|
||||
*/
|
||||
public class BackupHelperAgent extends BackupAgent {
|
||||
static final String TAG = "BackupHelperAgent";
|
||||
|
||||
BackupHelperDispatcher mDispatcher = new BackupHelperDispatcher();
|
||||
|
||||
/**
|
||||
* Run the backup process on each of the configured handlers.
|
||||
*/
|
||||
@Override
|
||||
public void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
|
||||
ParcelFileDescriptor newState) throws IOException {
|
||||
mDispatcher.performBackup(oldState, data, newState);
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the restore process on each of the configured handlers.
|
||||
*/
|
||||
@Override
|
||||
public void onRestore(BackupDataInput data, int appVersionCode, ParcelFileDescriptor newState)
|
||||
throws IOException {
|
||||
mDispatcher.performRestore(data, appVersionCode, newState);
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public BackupHelperDispatcher getDispatcher() {
|
||||
return mDispatcher;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a helper for a given data subset to the agent's configuration. Each helper
|
||||
* must have a prefix string that is unique within this backup agent's set of
|
||||
* helpers.
|
||||
*
|
||||
* @param keyPrefix A string used to disambiguate the various helpers within this agent
|
||||
* @param helper A backup/restore helper object to be invoked during backup and restore
|
||||
* operations.
|
||||
*/
|
||||
public void addHelper(String keyPrefix, BackupHelper helper) {
|
||||
mDispatcher.addHelper(keyPrefix, helper);
|
||||
}
|
||||
|
||||
@@ -138,7 +138,7 @@ public class BackupHelperDispatcher {
|
||||
|
||||
// Write out the state files -- mHelpers is a TreeMap, so the order is well defined.
|
||||
for (BackupHelper helper: mHelpers.values()) {
|
||||
helper.writeRestoreSnapshot(newState);
|
||||
helper.writeNewStateDescription(newState);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,11 @@ import android.util.Log;
|
||||
* documentation for {@link android.app.BackupAgent} for a detailed description
|
||||
* of how the backup then proceeds.
|
||||
*
|
||||
* @hide pending API solidification
|
||||
* <p>STOPSHIP more documentation here! Include the attributes:
|
||||
* android:backupAgent
|
||||
* android:allowBackup
|
||||
* android:restoreNeedsApplication
|
||||
* android:killAfterRestore
|
||||
*/
|
||||
public class BackupManager {
|
||||
private static final String TAG = "BackupManager";
|
||||
@@ -110,11 +114,8 @@ public class BackupManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Begin the process of restoring system data from backup. This method requires
|
||||
* that the application hold the "android.permission.BACKUP" permission, and is
|
||||
* not public.
|
||||
*
|
||||
* {@hide}
|
||||
* Begin the process of restoring data from backup. See the
|
||||
* {@link android.backup.RestoreSession} class for documentation on that process.
|
||||
*/
|
||||
public RestoreSession beginRestoreSession() {
|
||||
if (!EVEN_THINK_ABOUT_DOING_RESTORE) {
|
||||
@@ -128,7 +129,7 @@ public class BackupManager {
|
||||
IRestoreSession binder = sService.beginRestoreSession(transport);
|
||||
session = new RestoreSession(mContext, binder);
|
||||
} catch (RemoteException e) {
|
||||
Log.d(TAG, "beginRestoreSession() couldn't connect");
|
||||
Log.w(TAG, "beginRestoreSession() couldn't connect");
|
||||
}
|
||||
}
|
||||
return session;
|
||||
|
||||
@@ -23,7 +23,9 @@ import android.util.Log;
|
||||
import java.io.File;
|
||||
import java.io.FileDescriptor;
|
||||
|
||||
/** @hide */
|
||||
/**
|
||||
* STOPSHIP: document! [manages backup of a set of files; restore is totally opaque]
|
||||
*/
|
||||
public class FileBackupHelper extends FileBackupHelperBase implements BackupHelper {
|
||||
private static final String TAG = "FileBackupHelper";
|
||||
private static final boolean DEBUG = false;
|
||||
@@ -32,6 +34,13 @@ public class FileBackupHelper extends FileBackupHelperBase implements BackupHelp
|
||||
File mFilesDir;
|
||||
String[] mFiles;
|
||||
|
||||
/**
|
||||
* Construct a helper to manage backup/restore of entire files within the
|
||||
* application's data directory hierarchy.
|
||||
*
|
||||
* @param context The backup agent's Context object
|
||||
* @param files A list of the files to be backed up or restored.
|
||||
*/
|
||||
public FileBackupHelper(Context context, String... files) {
|
||||
super(context);
|
||||
|
||||
@@ -60,6 +69,9 @@ public class FileBackupHelper extends FileBackupHelperBase implements BackupHelp
|
||||
performBackup_checked(oldState, data, newState, fullPaths, files);
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore one record [representing a single file] from the restore dataset.
|
||||
*/
|
||||
public void restoreEntity(BackupDataInputStream data) {
|
||||
if (DEBUG) Log.d(TAG, "got entity '" + data.getKey() + "' size=" + data.size());
|
||||
String key = data.getKey();
|
||||
|
||||
@@ -20,7 +20,6 @@ import android.content.Context;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.FileOutputStream;
|
||||
@@ -80,18 +79,14 @@ class FileBackupHelperBase {
|
||||
}
|
||||
}
|
||||
|
||||
void writeFile(File f, InputStream in) {
|
||||
if (!(in instanceof BackupDataInputStream)) {
|
||||
throw new IllegalStateException("input stream must be a BackupDataInputStream");
|
||||
}
|
||||
void writeFile(File f, BackupDataInputStream in) {
|
||||
int result = -1;
|
||||
|
||||
// Create the enclosing directory.
|
||||
File parent = f.getParentFile();
|
||||
parent.mkdirs();
|
||||
|
||||
result = writeFile_native(mPtr, f.getAbsolutePath(),
|
||||
((BackupDataInputStream)in).mData.mBackupReader);
|
||||
result = writeFile_native(mPtr, f.getAbsolutePath(), in.mData.mBackupReader);
|
||||
if (result != 0) {
|
||||
// Bail on this entity. Only log one failure per helper object.
|
||||
if (!mExceptionLogged) {
|
||||
@@ -103,7 +98,7 @@ class FileBackupHelperBase {
|
||||
}
|
||||
}
|
||||
|
||||
public void writeRestoreSnapshot(ParcelFileDescriptor fd) {
|
||||
public void writeNewStateDescription(ParcelFileDescriptor fd) {
|
||||
int result = writeSnapshot_native(mPtr, fd.getFileDescriptor());
|
||||
// TODO: Do something with the error.
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@ package android.backup;
|
||||
/**
|
||||
* Callback class for receiving progress reports during a restore operation. These
|
||||
* methods will all be called on your application's main thread.
|
||||
* @hide
|
||||
*/
|
||||
public abstract class RestoreObserver {
|
||||
/**
|
||||
|
||||
@@ -27,7 +27,6 @@ import android.util.Log;
|
||||
|
||||
/**
|
||||
* Interface for applications to use when managing a restore session.
|
||||
* @hide
|
||||
*/
|
||||
public class RestoreSession {
|
||||
static final String TAG = "RestoreSession";
|
||||
@@ -44,6 +43,8 @@ public class RestoreSession {
|
||||
* and a String array under the key "names" whose entries are the user-meaningful
|
||||
* text corresponding to the backup sets at each index in the tokens array.
|
||||
* On error, returns null.
|
||||
*
|
||||
* {@hide}
|
||||
*/
|
||||
public RestoreSet[] getAvailableRestoreSets() {
|
||||
try {
|
||||
@@ -66,6 +67,8 @@ public class RestoreSession {
|
||||
* the restore set that should be used.
|
||||
* @param observer If non-null, this binder points to an object that will receive
|
||||
* progress callbacks during the restore operation.
|
||||
*
|
||||
* {@hide}
|
||||
*/
|
||||
public int restoreAll(long token, RestoreObserver observer) {
|
||||
int err = -1;
|
||||
|
||||
@@ -23,7 +23,9 @@ import android.util.Log;
|
||||
import java.io.File;
|
||||
import java.io.FileDescriptor;
|
||||
|
||||
/** @hide */
|
||||
/**
|
||||
* STOPSHIP: document!
|
||||
*/
|
||||
public class SharedPreferencesBackupHelper extends FileBackupHelperBase implements BackupHelper {
|
||||
private static final String TAG = "SharedPreferencesBackupHelper";
|
||||
private static final boolean DEBUG = false;
|
||||
@@ -31,6 +33,13 @@ public class SharedPreferencesBackupHelper extends FileBackupHelperBase implemen
|
||||
private Context mContext;
|
||||
private String[] mPrefGroups;
|
||||
|
||||
/**
|
||||
* Construct a helper for backing up and restoring the
|
||||
* {@link android.content.SharedPreferences} under the given names.
|
||||
*
|
||||
* @param context
|
||||
* @param prefGroups
|
||||
*/
|
||||
public SharedPreferencesBackupHelper(Context context, String... prefGroups) {
|
||||
super(context);
|
||||
|
||||
@@ -38,6 +47,9 @@ public class SharedPreferencesBackupHelper extends FileBackupHelperBase implemen
|
||||
mPrefGroups = prefGroups;
|
||||
}
|
||||
|
||||
/**
|
||||
* Backs up the configured SharedPreferences groups
|
||||
*/
|
||||
public void performBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
|
||||
ParcelFileDescriptor newState) {
|
||||
Context context = mContext;
|
||||
@@ -54,6 +66,10 @@ public class SharedPreferencesBackupHelper extends FileBackupHelperBase implemen
|
||||
performBackup_checked(oldState, data, newState, files, prefGroups);
|
||||
}
|
||||
|
||||
/**
|
||||
* Restores one entity from the restore data stream to its proper shared
|
||||
* preferences file store.
|
||||
*/
|
||||
public void restoreEntity(BackupDataInputStream data) {
|
||||
Context context = mContext;
|
||||
|
||||
|
||||
@@ -1083,15 +1083,11 @@ class BackupManagerService extends IBackupManager.Stub {
|
||||
|
||||
synchronized(mClearDataLock) {
|
||||
mClearingData = true;
|
||||
/* This is causing some critical processes to be killed during setup.
|
||||
Temporarily revert this change until we find a better solution.
|
||||
try {
|
||||
mActivityManager.clearApplicationUserData(packageName, observer);
|
||||
} catch (RemoteException e) {
|
||||
// can't happen because the activity manager is in this process
|
||||
}
|
||||
*/
|
||||
mPackageManager.clearApplicationUserData(packageName, observer);
|
||||
|
||||
// only wait 10 seconds for the clear data to happen
|
||||
long timeoutMark = System.currentTimeMillis() + TIMEOUT_INTERVAL;
|
||||
@@ -1660,10 +1656,6 @@ class BackupManagerService extends IBackupManager.Stub {
|
||||
+ "] is compatible with installed version ["
|
||||
+ packageInfo.versionCode + "]");
|
||||
|
||||
// Now perform the actual restore: first clear the app's data
|
||||
// if appropriate
|
||||
clearApplicationDataSynchronous(packageName);
|
||||
|
||||
// Then set up and bind the agent (with a restricted Application object
|
||||
// unless the application says otherwise)
|
||||
boolean useRealApp = (packageInfo.applicationInfo.flags
|
||||
|
||||
Reference in New Issue
Block a user