diff options
Diffstat (limited to 'src/com')
-rw-r--r-- | src/com/android/browser/BrowserWebView.java | 9 | ||||
-rw-r--r-- | src/com/android/browser/Controller.java | 6 | ||||
-rw-r--r-- | src/com/android/browser/CrashRecoveryHandler.java | 96 |
3 files changed, 87 insertions, 24 deletions
diff --git a/src/com/android/browser/BrowserWebView.java b/src/com/android/browser/BrowserWebView.java index 5a40b3c..55dd24a 100644 --- a/src/com/android/browser/BrowserWebView.java +++ b/src/com/android/browser/BrowserWebView.java @@ -191,4 +191,13 @@ public class BrowserWebView extends WebView implements Runnable { } } + @Override + protected void updateCachedTextfield(String updatedText) { + super.updateCachedTextfield(updatedText); + CrashRecoveryHandler handler = CrashRecoveryHandler.getInstance(); + if (handler != null) { + handler.backupState(); + } + } + } diff --git a/src/com/android/browser/Controller.java b/src/com/android/browser/Controller.java index 986b617..5fb413b 100644 --- a/src/com/android/browser/Controller.java +++ b/src/com/android/browser/Controller.java @@ -226,7 +226,7 @@ public class Controller mDataController = DataController.getInstance(mActivity); mTabControl = new TabControl(this); mSettings.setController(this); - mCrashRecoveryHandler = new CrashRecoveryHandler(this); + mCrashRecoveryHandler = CrashRecoveryHandler.initialize(this); mUrlHandler = new UrlHandler(this); mIntentHandler = new IntentHandler(mActivity, this); @@ -262,7 +262,6 @@ public class Controller void start(final Bundle icicle, final Intent intent) { boolean noCrashRecovery = intent.getBooleanExtra(NO_CRASH_RECOVERY, false); if (icicle != null || noCrashRecovery) { - mCrashRecoveryHandler.clearState(); doStart(icicle, intent); } else { mCrashRecoveryHandler.startRecovery(intent); @@ -615,7 +614,7 @@ public class Controller mNetworkHandler.onPause(); WebView.disablePlatformNotifications(); - mCrashRecoveryHandler.clearState(); + mCrashRecoveryHandler.backupState(); } void onSaveInstanceState(Bundle outState, boolean saveImages) { @@ -2141,6 +2140,7 @@ public class Controller protected void removeTab(Tab tab) { mUi.removeTab(tab); mTabControl.removeTab(tab); + mCrashRecoveryHandler.backupState(); } @Override diff --git a/src/com/android/browser/CrashRecoveryHandler.java b/src/com/android/browser/CrashRecoveryHandler.java index 60e39da..7ee9cee 100644 --- a/src/com/android/browser/CrashRecoveryHandler.java +++ b/src/com/android/browser/CrashRecoveryHandler.java @@ -22,7 +22,10 @@ import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; import android.content.Intent; import android.os.Bundle; +import android.os.Handler; +import android.os.HandlerThread; import android.os.Parcel; +import android.os.Process; import android.util.Log; import java.io.ByteArrayOutputStream; @@ -35,37 +38,88 @@ public class CrashRecoveryHandler { private static final String LOGTAG = "BrowserCrashRecovery"; private static final String STATE_FILE = "browser_state.parcel"; private static final int BUFFER_SIZE = 4096; + private static final long BACKUP_DELAY = 500; // 500ms between writes + + private static CrashRecoveryHandler sInstance; private Controller mController; + private Handler mForegroundHandler; + private Handler mBackgroundHandler; - public CrashRecoveryHandler(Controller controller) { + public static CrashRecoveryHandler initialize(Controller controller) { + if (sInstance == null) { + sInstance = new CrashRecoveryHandler(controller); + } else { + sInstance.mController = controller; + } + return sInstance; + } + + public static CrashRecoveryHandler getInstance() { + return sInstance; + } + + private CrashRecoveryHandler(Controller controller) { mController = controller; + mForegroundHandler = new Handler(); + HandlerThread thread = new HandlerThread(LOGTAG, + Process.THREAD_PRIORITY_BACKGROUND); + thread.start(); + mBackgroundHandler = new Handler(thread.getLooper()); } public void backupState() { - final Bundle state = new Bundle(); - mController.onSaveInstanceState(state, false); - final Context context = mController.getActivity(); - new Thread() { - @Override - public void run() { - Parcel p = Parcel.obtain(); - try { - state.writeToParcel(p, 0); - FileOutputStream fout = context.openFileOutput(STATE_FILE, - Context.MODE_PRIVATE); - fout.write(p.marshall()); - fout.close(); - } catch (Throwable e) { - Log.i(LOGTAG, "Failed to save persistent state", e); - } finally { - p.recycle(); - } + mForegroundHandler.postDelayed(mCreateState, BACKUP_DELAY); + } + + private Runnable mCreateState = new Runnable() { + + @Override + public void run() { + try { + final Bundle state = new Bundle(); + mController.onSaveInstanceState(state, false); + Context context = mController.getActivity() + .getApplicationContext(); + mBackgroundHandler.post(new WriteState(context, state)); + // Remove any queued up saves + mForegroundHandler.removeCallbacks(mCreateState); + } catch (Throwable t) { + Log.w(LOGTAG, "Failed to save state", t); + return; } - }.start(); + } + + }; + + static class WriteState implements Runnable { + private Context mContext; + private Bundle mState; + + WriteState(Context context, Bundle state) { + mContext = context; + mState = state; + } + + @Override + public void run() { + Parcel p = Parcel.obtain(); + try { + mState.writeToParcel(p, 0); + FileOutputStream fout = mContext.openFileOutput(STATE_FILE, + Context.MODE_PRIVATE); + fout.write(p.marshall()); + fout.close(); + } catch (Throwable e) { + Log.i(LOGTAG, "Failed to save persistent state", e); + } finally { + p.recycle(); + } + } + } - public void clearState() { + private void clearState() { Context context = mController.getActivity(); context.deleteFile(STATE_FILE); } |