From d1475e0375cbf1ebd5010c6ce96bbdc1de6c1b57 Mon Sep 17 00:00:00 2001 From: Christopher Tate Date: Thu, 9 Jul 2009 15:36:17 -0700 Subject: Don't crash the app when restore agent bringup throws Restore runs during the SetupWizard, before the phone is usable per se, so we want to avoid presenting the usual "Application whatever has crashed..." dialog to the user in the middle of that process. This change modifies the exception handling around agent bringup so that agent-originated exceptions are caught and a null agent binder reported to the backup manager. There are three points during this code sequence at which an exception can be thrown due to application-code error: + the app's manifest can name a nonexistent or malformed BackupAgent class, incurring a VM-level exception like ClassNotFound or BadCast. - the agent's onCreate() method could crash/throw. - the agent's onBind() method could crash/throw. The new code arrangement here puts a try/catch around all of these possible failure points. When the code is invoked for backup, any caught exception is merely rethrown. During restore, however, execution is allowed to proceed through reporting the app's agent binder back to the activity manager. If any exception was thrown, this reported binder will be null, i.e. a clean failure notification to the backup manager. What this code does *not* do at present is tear down the app when an exception has been thrown. This is happens if the exception is allowed to propagate. Doing so cleanly is problematic, however, in circumstances where mutiple apps and agents share a process. Leaving the background process around until it is torn down by the usual policies is probably the safer course at present. --- core/java/android/app/ActivityThread.java | 45 ++++++++++++++++++------------- 1 file changed, 26 insertions(+), 19 deletions(-) (limited to 'core/java/android/app') diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 5ee29ac..ec8d56b 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -2545,32 +2545,39 @@ public final class ActivityThread { classname = "android.app.FullBackupAgent"; } try { - java.lang.ClassLoader cl = packageInfo.getClassLoader(); - agent = (BackupAgent) cl.loadClass(data.appInfo.backupAgentName).newInstance(); - } catch (Exception e) { - throw new RuntimeException("Unable to instantiate backup agent " - + data.appInfo.backupAgentName + ": " + e.toString(), e); - } - - // set up the agent's context - try { - if (DEBUG_BACKUP) Log.v(TAG, "Initializing BackupAgent " - + data.appInfo.backupAgentName); - - ApplicationContext context = new ApplicationContext(); - context.init(packageInfo, null, this); - context.setOuterContext(agent); - agent.attach(context); - agent.onCreate(); + IBinder binder = null; + try { + java.lang.ClassLoader cl = packageInfo.getClassLoader(); + agent = (BackupAgent) cl.loadClass(data.appInfo.backupAgentName).newInstance(); + + // set up the agent's context + if (DEBUG_BACKUP) Log.v(TAG, "Initializing BackupAgent " + + data.appInfo.backupAgentName); + + ApplicationContext context = new ApplicationContext(); + context.init(packageInfo, null, this); + context.setOuterContext(agent); + agent.attach(context); + + agent.onCreate(); + binder = agent.onBind(); + mBackupAgents.put(packageName, agent); + } catch (Exception e) { + // If this is during restore, fail silently; otherwise go + // ahead and let the user see the crash. + Log.e(TAG, "Agent threw during creation: " + e); + if (data.backupMode != IApplicationThread.BACKUP_MODE_RESTORE) { + throw e; + } + // falling through with 'binder' still null + } // tell the OS that we're live now - IBinder binder = agent.onBind(); try { ActivityManagerNative.getDefault().backupAgentCreated(packageName, binder); } catch (RemoteException e) { // nothing to do. } - mBackupAgents.put(packageName, agent); } catch (Exception e) { throw new RuntimeException("Unable to create BackupAgent " + data.appInfo.backupAgentName + ": " + e.toString(), e); -- cgit v1.1