Simplify crash dialog
Remove "Reopen app" for background crashes, remove "Close"
for foreground crashes.
Make crash dialog cancelable with back / tapping outside.
Remove reset option for repeating crashes.
Change-Id: I3773ee6b6986efa35da30830fec223300cda5d75
Fixes: 28768481
Fixes: 28740658
diff --git a/core/res/res/layout/app_error_dialog.xml b/core/res/res/layout/app_error_dialog.xml
index 7147ea2..9a5bbd4 100644
--- a/core/res/res/layout/app_error_dialog.xml
+++ b/core/res/res/layout/app_error_dialog.xml
@@ -35,11 +35,11 @@
/>
<Button
- android:id="@+id/aerr_reset"
+ android:id="@+id/aerr_close"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:text="@string/aerr_reset"
- android:drawableStart="@drawable/ic_refresh"
+ android:text="@string/aerr_close"
+ android:drawableStart="@drawable/ic_close"
style="@style/aerr_list_item"
/>
@@ -53,15 +53,6 @@
/>
<Button
- android:id="@+id/aerr_close"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="@string/aerr_close"
- android:drawableStart="@drawable/ic_close"
- style="@style/aerr_list_item"
- />
-
- <Button
android:id="@+id/aerr_mute"
android:layout_width="match_parent"
android:layout_height="wrap_content"
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 737daed..9ab42a9 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2445,7 +2445,6 @@
<java-symbol type="id" name="work_widget_badge_icon" />
<java-symbol type="id" name="aerr_report" />
- <java-symbol type="id" name="aerr_reset" />
<java-symbol type="id" name="aerr_restart" />
<java-symbol type="id" name="aerr_close" />
<java-symbol type="id" name="aerr_mute" />
diff --git a/services/core/java/com/android/server/am/AppErrorDialog.java b/services/core/java/com/android/server/am/AppErrorDialog.java
index ddfab4d..e37feb2 100644
--- a/services/core/java/com/android/server/am/AppErrorDialog.java
+++ b/services/core/java/com/android/server/am/AppErrorDialog.java
@@ -18,13 +18,17 @@
import android.app.ActivityManagerInternal;
import android.app.ActivityOptions;
+import android.content.BroadcastReceiver;
import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
import android.content.pm.IPackageDataObserver;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
+import android.provider.Settings;
import android.text.BidiFormatter;
import android.util.Slog;
import android.view.LayoutInflater;
@@ -43,6 +47,7 @@
private final AppErrorResult mResult;
private final ProcessRecord mProc;
private final boolean mRepeating;
+ private final boolean mForeground;
private CharSequence mName;
@@ -54,9 +59,9 @@
static final int FORCE_QUIT = 1;
static final int FORCE_QUIT_AND_REPORT = 2;
static final int RESTART = 3;
- static final int RESET = 4;
static final int MUTE = 5;
static final int TIMEOUT = 6;
+ static final int CANCEL = 7;
// 5-minute timeout, then we automatically dismiss the crash dialog
static final long DISMISS_TIMEOUT = 1000 * 60 * 5;
@@ -69,6 +74,7 @@
mProc = data.proc;
mResult = data.result;
mRepeating = data.repeating;
+ mForeground = data.task != null;
BidiFormatter bidi = BidiFormatter.getInstance();
if ((mProc.pkgList.size() == 1) &&
@@ -86,7 +92,8 @@
bidi.unicodeWrap(mName.toString())));
}
- setCancelable(false);
+ setCancelable(true);
+ setCancelMessage(mHandler.obtainMessage(CANCEL));
WindowManager.LayoutParams attrs = getWindow().getAttributes();
attrs.setTitle("Application Error: " + mProc.info.processName);
@@ -111,25 +118,41 @@
LayoutInflater.from(context).inflate(
com.android.internal.R.layout.app_error_dialog, frame, true);
+ boolean hasRestart = !mRepeating && mForeground;
+ final boolean hasReceiver = mProc.errorReportReceiver != null;
+
final TextView restart = (TextView) findViewById(com.android.internal.R.id.aerr_restart);
restart.setOnClickListener(this);
- restart.setVisibility(!mRepeating ? View.VISIBLE : View.GONE);
- final TextView reset = (TextView) findViewById(com.android.internal.R.id.aerr_reset);
- reset.setOnClickListener(this);
- reset.setVisibility(mRepeating ? View.VISIBLE : View.GONE);
+ restart.setVisibility(hasRestart ? View.VISIBLE : View.GONE);
final TextView report = (TextView) findViewById(com.android.internal.R.id.aerr_report);
report.setOnClickListener(this);
- final boolean hasReceiver = mProc.errorReportReceiver != null;
report.setVisibility(hasReceiver ? View.VISIBLE : View.GONE);
final TextView close = (TextView) findViewById(com.android.internal.R.id.aerr_close);
+ close.setVisibility(!hasRestart ? View.VISIBLE : View.GONE);
close.setOnClickListener(this);
+
+ boolean showMute = !IS_USER_BUILD && Settings.Global.getInt(context.getContentResolver(),
+ Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) != 0;
final TextView mute = (TextView) findViewById(com.android.internal.R.id.aerr_mute);
mute.setOnClickListener(this);
- mute.setVisibility(!IS_USER_BUILD ? View.VISIBLE : View.GONE);
+ mute.setVisibility(showMute ? View.VISIBLE : View.GONE);
findViewById(com.android.internal.R.id.customPanel).setVisibility(View.VISIBLE);
}
+ @Override
+ public void onStart() {
+ super.onStart();
+ getContext().registerReceiver(mReceiver,
+ new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ getContext().unregisterReceiver(mReceiver);
+ }
+
private final Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
final int result = msg.what;
@@ -163,9 +186,6 @@
case com.android.internal.R.id.aerr_restart:
mHandler.obtainMessage(RESTART).sendToTarget();
break;
- case com.android.internal.R.id.aerr_reset:
- mHandler.obtainMessage(RESET).sendToTarget();
- break;
case com.android.internal.R.id.aerr_report:
mHandler.obtainMessage(FORCE_QUIT_AND_REPORT).sendToTarget();
break;
@@ -180,6 +200,15 @@
}
}
+ private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(intent.getAction())) {
+ cancel();
+ }
+ }
+ };
+
static class Data {
AppErrorResult result;
TaskRecord task;
diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java
index 3ed9969..49106f4 100644
--- a/services/core/java/com/android/server/am/AppErrors.java
+++ b/services/core/java/com/android/server/am/AppErrors.java
@@ -370,38 +370,9 @@
Intent appErrorIntent = null;
MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_APP_CRASH, res);
- if (res == AppErrorDialog.TIMEOUT) {
+ if (res == AppErrorDialog.TIMEOUT || res == AppErrorDialog.CANCEL) {
res = AppErrorDialog.FORCE_QUIT;
}
- if (res == AppErrorDialog.RESET) {
- String[] packageList = r.getPackageList();
- if (packageList != null) {
- PackageManager pm = mContext.getPackageManager();
- final Semaphore s = new Semaphore(0);
- for (int i = 0; i < packageList.length; i++) {
- if (i < packageList.length - 1) {
- pm.deleteApplicationCacheFiles(packageList[i], null);
- } else {
- pm.deleteApplicationCacheFiles(packageList[i],
- new IPackageDataObserver.Stub() {
- @Override
- public void onRemoveCompleted(String packageName,
- boolean succeeded) {
- s.release();
- }
- });
-
- // Wait until cache has been cleared before we restart.
- try {
- s.acquire();
- } catch (InterruptedException e) {
- }
- }
- }
- }
- // If there was nothing to reset, just restart;
- res = AppErrorDialog.RESTART;
- }
synchronized (mService) {
if (res == AppErrorDialog.MUTE) {
stopReportingCrashesLocked(r);