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

Commit 3cbab32a authored by Christopher Tate's avatar Christopher Tate Committed by The Android Open Source Project
Browse files

am 22b8787e: Squashed commit of the following:

Merge commit '22b8787e'

* commit '22b8787e':
  Squashed commit of the following:
parents 545ac3a0 22b8787e
Loading
Loading
Loading
Loading
+30 −25
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.app.Service;
import android.backup.IBackupService;
import android.content.Intent;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.util.Log;

@@ -59,23 +60,25 @@ public abstract class BackupService extends Service {
     * The application is being asked to write any data changed since the
     * last time it performed a backup operation.  The state data recorded
     * during the last backup pass is provided in the oldStateFd file descriptor.
     * If oldStateFd is negative, no old state is available and the application
     * should perform a full backup.  In both cases, a representation of the
     * final backup state after this pass should be written to the file pointed
     * If oldState.getStatSize() is zero or negative, no old state is available
     * and the application should perform a full backup.  In both cases, a representation
     * of the final backup state after this pass should be written to the file pointed
     * to by the newStateFd file descriptor.
     *
     * @param oldStateFd An open, read-only file descriptor pointing to the last
     *                   backup state provided by the application.  May be negative,
     *                   in which case no prior state is being provided and the
     *                   application should perform a full backup.
     * @param dataFd An open, read/write file descriptor pointing to the backup data
     * @param oldState An open, read-only ParcelFileDescriptor pointing to the last backup
     *                 state provided by the application.  May be empty or invalid, 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 newStateFd An open, read/write file descriptor pointing to an empty
     * @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.
     */
    public abstract void onBackup(int oldStateFd, int dataFd, int newStateFd);
    public abstract void onBackup(ParcelFileDescriptor oldState,
            ParcelFileDescriptor data,
            ParcelFileDescriptor newState);
    
    /**
     * The application is being restored from backup, and should replace any
@@ -84,13 +87,13 @@ public abstract class BackupService extends Service {
     * the restore is finished, the application should write a representation
     * of the final state to the newStateFd file descriptor, 
     *
     * @param dataFd An open, read-only file descriptor pointing to a full snapshot
     * @param data An open, read-only ParcelFileDescriptor pointing to a full snapshot
     *             of the application's data.
     * @param newStateFd An open, read/write file descriptor pointing to an empty
     * @param newState An open, read/write ParcelFileDescriptor pointing to an empty
     *                 file.  The application should record the final backup state
     *                 here after restoring its data from dataFd.
     */
    public abstract void onRestore(int dataFd, int newStateFd);
    public abstract void onRestore(ParcelFileDescriptor data, ParcelFileDescriptor newState);


    // ----- Core implementation -----
@@ -110,17 +113,19 @@ public abstract class BackupService extends Service {

    // ----- IBackupService binder interface -----
    private class BackupServiceBinder extends IBackupService.Stub {
        public void doBackup(int oldStateFd, int dataFd, int newStateFd)
                throws RemoteException {
        public void doBackup(ParcelFileDescriptor oldState,
                ParcelFileDescriptor data,
                ParcelFileDescriptor newState) throws RemoteException {
            // !!! TODO - real implementation; for now just invoke the callbacks directly
            Log.v("BackupServiceBinder", "doBackup() invoked");
            BackupService.this.onBackup(oldStateFd, dataFd, newStateFd);
            BackupService.this.onBackup(oldState, data, newState);
        }

        public void doRestore(int dataFd, int newStateFd) throws RemoteException {
        public void doRestore(ParcelFileDescriptor data,
                ParcelFileDescriptor newState) throws RemoteException {
            // !!! TODO - real implementation; for now just invoke the callbacks directly
            Log.v("BackupServiceBinder", "doRestore() invoked");
            BackupService.this.onRestore(dataFd, newStateFd);
            BackupService.this.onRestore(data, newState);
        }
    }
}
+14 −8
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package android.backup;

import android.os.ParcelFileDescriptor;
 
/**
 * Interface presented by applications being asked to participate in the
 * backup & restore mechanism.  End user code does not typically implement
@@ -27,27 +29,31 @@ interface IBackupService {
    /**
     * Request that the app perform an incremental backup.
     *
     * @param oldStateFd Read-only file containing the description blob of the
     * @param oldState Read-only file containing the description blob of the
     *        app's data state as of the last backup operation's completion.
     *        This file is empty or invalid when a full backup is being
     *        requested.
     *
     * @param dataFd Read-write file, empty when onBackup() is called, that
     * @param data Read-write file, empty when onBackup() is called, that
     *        is the data destination for this backup pass's incrementals.
     *
     * @param newStateFd Read-write file, empty when onBackup() is called,
     * @param newState Read-write file, empty when onBackup() is called,
     *        where the new state blob is to be recorded.
     */
    void doBackup(int oldStateFd, int dataFd, int newStateFd);
    void doBackup(in ParcelFileDescriptor oldState,
            in ParcelFileDescriptor data,
            in ParcelFileDescriptor newState);

    /**
     * Restore an entire data snapshot to the application.
     *
     * @param dataFd Read-only file containing the full data snapshot of the
     * @param data Read-only file containing the full data snapshot of the
     *        app's backup.  This is to be a <i>replacement</i> of the app's
     *        current data, not to be merged into it.
     *
     * @param newStateFd Read-write file, empty when onRestore() is called,
     * @param newState Read-write file, empty when onRestore() is called,
     *        that is to be written with the state description that holds after
     *        the restore has been completed.
     */
    void doRestore(int dataFd, int newStateFd);
    void doRestore(in ParcelFileDescriptor data, in ParcelFileDescriptor newState);
}
+41 −2
Original line number Diff line number Diff line
@@ -26,15 +26,19 @@ import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.os.Binder;
import android.os.Environment;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.util.Log;
import android.util.SparseArray;

import android.backup.IBackupManager;

import java.io.File;
import java.io.FileNotFoundException;
import java.lang.String;
import java.util.HashSet;
import java.util.List;
@@ -57,6 +61,7 @@ class BackupManagerService extends IBackupManager.Stub {
    private HashSet<ServiceInfo> mPendingBackups = new HashSet<ServiceInfo>();
    private final Object mQueueLock = new Object();

    private File mStateDir;
    
    // ----- Handler that runs the actual backup process asynchronously -----

@@ -99,12 +104,41 @@ class BackupManagerService extends IBackupManager.Stub {
                        if (mTargetService != null) {
                            try {
                                Log.d(TAG, "invoking doBackup() on " + backupIntent);
                                // !!! TODO: set up files
                                mTargetService.doBackup(-1, -1, -1);

                                File savedStateName = new File(mStateDir, service.packageName);
                                File backupDataName = new File(mStateDir, service.packageName + ".data");
                                File newStateName = new File(mStateDir, service.packageName + ".new");
                                
                                ParcelFileDescriptor savedState =
                                        ParcelFileDescriptor.open(savedStateName,
                                                ParcelFileDescriptor.MODE_READ_ONLY |
                                                ParcelFileDescriptor.MODE_CREATE);
                                ParcelFileDescriptor backupData =
                                        ParcelFileDescriptor.open(backupDataName,
                                                ParcelFileDescriptor.MODE_READ_WRITE |
                                                ParcelFileDescriptor.MODE_CREATE);
                                ParcelFileDescriptor newState =
                                        ParcelFileDescriptor.open(newStateName,
                                                ParcelFileDescriptor.MODE_READ_WRITE |
                                                ParcelFileDescriptor.MODE_CREATE);

                                mTargetService.doBackup(savedState, backupData, newState);

                                // !!! TODO: Now propagate the newly-backed-up data to the transport
                                
                                // !!! TODO: After successful transport, juggle the files so that
                                // next time the new state is used as the old state
                                
                            } catch (FileNotFoundException fnf) {
                                Log.d(TAG, "File not found on backup: ");
                                fnf.printStackTrace();
                            } catch (RemoteException e) {
                                Log.d(TAG, "Remote target " + backupIntent
                                        + " threw during backup:");
                                e.printStackTrace();
                            } catch (Exception e) {
                                Log.w(TAG, "Final exception guard in backup: ");
                                e.printStackTrace();
                            }
                            mContext.unbindService(this);
                        }
@@ -138,6 +172,11 @@ class BackupManagerService extends IBackupManager.Stub {
        mContext = context;
        mPackageManager = context.getPackageManager();

        // Set up our bookkeeping
        File dataDir = Environment.getDataDirectory();
        mStateDir = new File(dataDir, "backup");
        mStateDir.mkdirs();
        
        // Identify the backup participants
        // !!! TODO: also watch package-install to keep this up to date
        List<ResolveInfo> services = mPackageManager.queryIntentServices(