From 2e40d115ca4332d88424d1b591fdd8d5f78d1831 Mon Sep 17 00:00:00 2001 From: Christopher Tate Date: Tue, 15 Jul 2014 12:37:38 -0700 Subject: Add BackupAgent.onRestoreFinished() callback The agent's onRestoreFinished() method is called after all available data has been delivered to the app, whether via the key/value restore API or the full-data file-at-a-time API. This gives the app a stable opportunity to do any postprocessing that might be appropriate. Also fixes a lingering bug in the framework's handling of backup agent lifetimes. In cases where an existing agent instances was being rebound, the framework was forgetting to notify the dependent that the agent was available. This was causing timeouts and restore failure. Bug 16241004 Change-Id: I3f52b299312d30d38b0cba63a2cfaeb934991ef2 --- core/java/android/app/backup/BackupAgent.java | 37 ++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) (limited to 'core/java/android/app/backup') diff --git a/core/java/android/app/backup/BackupAgent.java b/core/java/android/app/backup/BackupAgent.java index e2a86e8..87d785a 100644 --- a/core/java/android/app/backup/BackupAgent.java +++ b/core/java/android/app/backup/BackupAgent.java @@ -209,7 +209,7 @@ public abstract class BackupAgent extends ContextWrapper { * output stream. */ public abstract void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data, - ParcelFileDescriptor newState) throws IOException; + ParcelFileDescriptor newState) throws IOException; /** * The application is being restored from backup and should replace any @@ -243,8 +243,7 @@ public abstract class BackupAgent extends ContextWrapper { * When a full-backup dataset is being restored, this will be null. */ public abstract void onRestore(BackupDataInput data, int appVersionCode, - ParcelFileDescriptor newState) - throws IOException; + ParcelFileDescriptor newState) throws IOException; /** * The application is having its entire file system contents backed up. {@code data} @@ -575,6 +574,20 @@ public abstract class BackupAgent extends ContextWrapper { FullBackup.restoreFile(data, size, type, mode, mtime, null); } + /** + * The application's restore operation has completed. This method is called after + * all available data has been delivered to the application for restore (via either + * the {@link #onRestore(BackupDataInput, int, ParcelFileDescriptor) onRestore()} or + * {@link #onRestoreFile(ParcelFileDescriptor, long, File, int, long, long) onRestoreFile()} + * callbacks). This provides the app with a stable end-of-restore opportunity to + * perform any appropriate post-processing on the data that was just delivered. + * + * @see #onRestore(BackupDataInput, int, ParcelFileDescriptor) + * @see #onRestoreFile(ParcelFileDescriptor, long, File, int, long, long) + */ + public void onRestoreFinished() { + } + // ----- Core implementation ----- /** @hide */ @@ -723,6 +736,24 @@ public abstract class BackupAgent extends ContextWrapper { } @Override + public void doRestoreFinished(int token, IBackupManager callbackBinder) { + long ident = Binder.clearCallingIdentity(); + try { + BackupAgent.this.onRestoreFinished(); + } finally { + // Ensure that any side-effect SharedPreferences writes have landed + waitForSharedPrefs(); + + Binder.restoreCallingIdentity(ident); + try { + callbackBinder.opComplete(token); + } catch (RemoteException e) { + // we'll time out anyway, so we're safe + } + } + } + + @Override public void fail(String message) { getHandler().post(new FailRunnable(message)); } -- cgit v1.1