Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e28290e2 authored by Christopher Tate's avatar Christopher Tate
Browse files

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
parent bb9a5176
Loading
Loading
Loading
Loading
+686 −0
Original line number Diff line number Diff line
@@ -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"
+16 −8
Original line number Diff line number Diff line
@@ -34,7 +34,7 @@ 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.
@@ -79,8 +79,16 @@ public abstract class BackupAgent extends ContextWrapper {
     * the restore is finished, the application should write a representation
     * 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
+11 −1
Original line number Diff line number Diff line
@@ -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();
+45 −1
Original line number Diff line number Diff line
@@ -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);
+3 −3
Original line number Diff line number Diff line
@@ -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;
    }
Loading