Loading cmds/bu/src/com/android/commands/bu/Backup.java +15 −9 Original line number Diff line number Diff line Loading @@ -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."); } Loading @@ -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; } Loading @@ -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 + "'"); } } Loading @@ -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; } Loading @@ -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; } Loading @@ -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() { Loading core/java/android/app/ActivityThread.java +14 −8 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 Loading Loading @@ -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); Loading @@ -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); Loading core/java/android/app/IApplicationThread.java +1 −0 Original line number Diff line number Diff line Loading @@ -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) Loading core/java/android/app/IBackupAgent.aidl +19 −0 Original line number Diff line number Diff line Loading @@ -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); } core/java/android/app/backup/BackupAgent.java +31 −1 Original line number Diff line number Diff line Loading @@ -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 ----- Loading @@ -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, Loading Loading @@ -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 { Loading @@ -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
cmds/bu/src/com/android/commands/bu/Backup.java +15 −9 Original line number Diff line number Diff line Loading @@ -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."); } Loading @@ -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; } Loading @@ -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 + "'"); } } Loading @@ -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; } Loading @@ -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; } Loading @@ -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() { Loading
core/java/android/app/ActivityThread.java +14 −8 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 Loading Loading @@ -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); Loading @@ -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); Loading
core/java/android/app/IApplicationThread.java +1 −0 Original line number Diff line number Diff line Loading @@ -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) Loading
core/java/android/app/IBackupAgent.aidl +19 −0 Original line number Diff line number Diff line Loading @@ -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); }
core/java/android/app/backup/BackupAgent.java +31 −1 Original line number Diff line number Diff line Loading @@ -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 ----- Loading @@ -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, Loading Loading @@ -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 { Loading @@ -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 } } } } }