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

Commit 1a536e64 authored by Christopher Tate's avatar Christopher Tate Committed by Android (Google) Code Review
Browse files

Merge "Restore from a previous full backup's tarfile"

parents cb0975b3 75a99709
Loading
Loading
Loading
Loading
+15 −9
Original line number Diff line number Diff line
@@ -34,11 +34,12 @@ public final class Backup {
    IBackupManager mBackupManager;

    public static void main(String[] args) {
        Log.d(TAG, "Beginning: " + args[0]);
        mArgs = args;
        try {
            new Backup().run();
        } catch (Exception e) {
            Log.e(TAG, "Error running backup", e);
            Log.e(TAG, "Error running backup/restore", e);
        }
        Log.d(TAG, "Finished.");
    }
@@ -46,7 +47,7 @@ public final class Backup {
    public void run() {
        mBackupManager = IBackupManager.Stub.asInterface(ServiceManager.getService("backup"));
        if (mBackupManager == null) {
            System.err.println("ERROR: could not contact backup manager");
            Log.e(TAG, "Can't obtain Backup Manager binder");
            return;
        }

@@ -56,7 +57,7 @@ public final class Backup {
        } else if (arg.equals("restore")) {
            doFullRestore();
        } else {
            System.err.println("ERROR: invalid operation '" + arg + "'");
            Log.e(TAG, "Invalid operation '" + arg + "'");
        }
    }

@@ -80,7 +81,6 @@ public final class Backup {
                } else if ("-all".equals(arg)) {
                    doEverything = true;
                } else {
                    System.err.println("WARNING: unknown backup flag " + arg);
                    Log.w(TAG, "Unknown backup flag " + arg);
                    continue;
                }
@@ -91,13 +91,10 @@ public final class Backup {
        }

        if (doEverything && packages.size() > 0) {
            System.err.println("WARNING: -all used with explicit backup package set");
            Log.w(TAG, "-all passed for backup along with specific package names");
        }

        if (!doEverything && !saveShared && packages.size() == 0) {
            System.err.println(
                    "ERROR: no packages supplied for backup and neither -shared nor -all given");
            Log.e(TAG, "no backup packages supplied and neither -shared nor -all given");
            return;
        }
@@ -108,13 +105,22 @@ public final class Backup {
            mBackupManager.fullBackup(fd, saveApks, saveShared, doEverything,
                    packages.toArray(packArray));
        } catch (IOException e) {
            System.err.println("ERROR: cannot dup System.out");
            Log.e(TAG, "Can't dup out");
        } catch (RemoteException e) {
            System.err.println("ERROR: unable to invoke backup manager service");
            Log.e(TAG, "Unable to invoke backup manager for backup");
        }
    }

    private void doFullRestore() {
        // No arguments to restore
        try {
            ParcelFileDescriptor fd = ParcelFileDescriptor.dup(FileDescriptor.in);
            mBackupManager.fullRestore(fd);
        } catch (IOException e) {
            Log.e(TAG, "Can't dup System.in");
        } catch (RemoteException e) {
            Log.e(TAG, "Unable to invoke backup manager for restore");
        }
    }

    private String nextArg() {
+14 −8
Original line number Diff line number Diff line
@@ -1980,7 +1980,8 @@ public final class ActivityThread {
        BackupAgent agent = null;
        String classname = data.appInfo.backupAgentName;

        if (data.backupMode == IApplicationThread.BACKUP_MODE_FULL) {
        if (data.backupMode == IApplicationThread.BACKUP_MODE_FULL
                || data.backupMode == IApplicationThread.BACKUP_MODE_RESTORE_FULL) {
            classname = "android.app.backup.FullBackupAgent";
            if ((data.appInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
                // system packages can supply their own full-backup agent
@@ -2011,7 +2012,8 @@ public final class ActivityThread {
                // If this is during restore, fail silently; otherwise go
                // ahead and let the user see the crash.
                Slog.e(TAG, "Agent threw during creation: " + e);
                if (data.backupMode != IApplicationThread.BACKUP_MODE_RESTORE) {
                if (data.backupMode != IApplicationThread.BACKUP_MODE_RESTORE
                        && data.backupMode != IApplicationThread.BACKUP_MODE_RESTORE_FULL) {
                    throw e;
                }
                // falling through with 'binder' still null
@@ -3658,6 +3660,9 @@ public final class ActivityThread {
        Application app = data.info.makeApplication(data.restrictedBackupMode, null);
        mInitialApplication = app;

        // don't bring up providers in restricted mode; they may depend on the
        // app's custom Application class
        if (!data.restrictedBackupMode){ 
            List<ProviderInfo> providers = data.providers;
            if (providers != null) {
                installContentProviders(app, providers);
@@ -3665,6 +3670,7 @@ public final class ActivityThread {
                // ensure that the JIT is enabled "at some point".
                mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);
            }
        }

        try {
            mInstrumentation.callApplicationOnCreate(app);
+1 −0
Original line number Diff line number Diff line
@@ -68,6 +68,7 @@ public interface IApplicationThread extends IInterface {
    static final int BACKUP_MODE_INCREMENTAL = 0;
    static final int BACKUP_MODE_FULL = 1;
    static final int BACKUP_MODE_RESTORE = 2;
    static final int BACKUP_MODE_RESTORE_FULL = 3;
    void scheduleCreateBackupAgent(ApplicationInfo app, CompatibilityInfo compatInfo,
            int backupMode) throws RemoteException;
    void scheduleDestroyBackupAgent(ApplicationInfo app, CompatibilityInfo compatInfo)
+19 −0
Original line number Diff line number Diff line
@@ -79,4 +79,23 @@ oneway interface IBackupAgent {
     */
    void doRestore(in ParcelFileDescriptor data, int appVersionCode,
            in ParcelFileDescriptor newState, int token, IBackupManager callbackBinder);

    /**
     * Restore a single "file" to the application.  The file was typically obtained from
     * a full-backup dataset.  The agent reads 'size' bytes of file content
     * from the provided file descriptor.
     *
     * @param data Read-only pipe delivering the file content itself.
     *
     * @param size Size of the file being restored.
     * @param type Type of file system entity, e.g. FullBackup.TYPE_DIRECTORY.
     * @param domain Name of the file's semantic domain to which the 'path' argument is a
     *        relative path.  e.g. FullBackup.DATABASE_TREE_TOKEN.
     * @param path Relative path of the file within its semantic domain.
     * @param mode Access mode of the file system entity, e.g. 0660.
     * @param mtime Last modification time of the file system entity.
     */
    void doRestoreFile(in ParcelFileDescriptor data, long size,
            int type, String domain, String path, long mode, long mtime,
            int token, IBackupManager callbackBinder);
}
+31 −1
Original line number Diff line number Diff line
@@ -178,11 +178,19 @@ public abstract class BackupAgent extends ContextWrapper {
            ParcelFileDescriptor newState)
            throws IOException;

    /**
     * @hide
     */
    public void onRestoreFile(ParcelFileDescriptor data, long size,
            int type, String domain, String path, long mode, long mtime)
            throws IOException {
        // empty stub implementation
    }

    /**
     * Package-private, used only for dispatching an extra step during full backup
     */
    void onSaveApk(BackupDataOutput data) {
        if (DEBUG) Log.v(TAG, "--- base onSaveApk() ---");
    }

    // ----- Core implementation -----
@@ -203,6 +211,7 @@ public abstract class BackupAgent extends ContextWrapper {
    private class BackupServiceBinder extends IBackupAgent.Stub {
        private static final String TAG = "BackupServiceBinder";

        @Override
        public void doBackup(ParcelFileDescriptor oldState,
                ParcelFileDescriptor data,
                ParcelFileDescriptor newState,
@@ -236,6 +245,7 @@ public abstract class BackupAgent extends ContextWrapper {
            }
        }

        @Override
        public void doRestore(ParcelFileDescriptor data, int appVersionCode,
                ParcelFileDescriptor newState,
                int token, IBackupManager callbackBinder) throws RemoteException {
@@ -261,5 +271,25 @@ public abstract class BackupAgent extends ContextWrapper {
                }
            }
        }

        @Override
        public void doRestoreFile(ParcelFileDescriptor data, long size,
                int type, String domain, String path, long mode, long mtime,
                int token, IBackupManager callbackBinder) throws RemoteException {
            long ident = Binder.clearCallingIdentity();
            try {
Log.d(TAG, "doRestoreFile() => onRestoreFile()");
                BackupAgent.this.onRestoreFile(data, size, type, domain, path, mode, mtime);
            } catch (IOException e) {
                throw new RuntimeException(e);
            } finally {
                Binder.restoreCallingIdentity(ident);
                try {
                    callbackBinder.opComplete(token);
                } catch (RemoteException e) {
                    // we'll time out anyway, so we're safe
                }
            }
        }
    }
}
Loading