diff options
Diffstat (limited to 'src/com/android/browser/CrashRecoveryHandler.java')
-rw-r--r-- | src/com/android/browser/CrashRecoveryHandler.java | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/src/com/android/browser/CrashRecoveryHandler.java b/src/com/android/browser/CrashRecoveryHandler.java new file mode 100644 index 0000000..9e98e76 --- /dev/null +++ b/src/com/android/browser/CrashRecoveryHandler.java @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.browser; + +import android.app.AlertDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.DialogInterface.OnClickListener; +import android.content.Intent; +import android.os.Bundle; +import android.os.Debug; +import android.os.Parcel; +import android.util.Log; + +import java.io.ByteArrayOutputStream; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; + +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 Controller mController; + + public CrashRecoveryHandler(Controller controller) { + mController = controller; + } + + public void backupState() { + final Bundle state = new Bundle(); + mController.onSaveInstanceState(state); + 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 (Exception e) { + Log.i(LOGTAG, "Failed to save persistent state", e); + } finally { + p.recycle(); + } + } + }.start(); + } + + public void clearState() { + Context context = mController.getActivity(); + context.deleteFile(STATE_FILE); + } + + public void promptToRecover(final Bundle state, final Intent intent) { + new AlertDialog.Builder(mController.getActivity()) + .setTitle(R.string.recover_title) + .setMessage(R.string.recover_prompt) + .setPositiveButton(R.string.recover_yes, new OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + mController.doStart(state, intent); + } + }) + .setNegativeButton(R.string.recover_no, new OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + clearState(); + mController.doStart(null, intent); + } + }) + .show(); + } + + public void startRecovery(Intent intent) { + Parcel parcel = Parcel.obtain(); + try { + Context context = mController.getActivity(); + FileInputStream fin = context.openFileInput(STATE_FILE); + ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); + byte[] buffer = new byte[BUFFER_SIZE]; + int read; + while ((read = fin.read(buffer)) > 0) { + dataStream.write(buffer, 0, read); + } + byte[] data = dataStream.toByteArray(); + parcel.unmarshall(data, 0, data.length); + parcel.setDataPosition(0); + Bundle state = parcel.readBundle(); + promptToRecover(state, intent); + } catch (FileNotFoundException e) { + // No state to recover + mController.doStart(null, intent); + } catch (Exception e) { + Log.w(LOGTAG, "Failed to recover state!", e); + mController.doStart(null, intent); + } finally { + parcel.recycle(); + } + } +} |