Merge "Simplify crash dialog" into nyc-dev

This commit is contained in:
Adrian Roos
2016-05-27 22:02:44 +00:00
committed by Android (Google) Code Review
4 changed files with 44 additions and 54 deletions

View File

@@ -35,11 +35,11 @@
/> />
<Button <Button
android:id="@+id/aerr_reset" android:id="@+id/aerr_close"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/aerr_reset" android:text="@string/aerr_close"
android:drawableStart="@drawable/ic_refresh" android:drawableStart="@drawable/ic_close"
style="@style/aerr_list_item" style="@style/aerr_list_item"
/> />
@@ -52,15 +52,6 @@
style="@style/aerr_list_item" style="@style/aerr_list_item"
/> />
<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 <Button
android:id="@+id/aerr_mute" android:id="@+id/aerr_mute"
android:layout_width="match_parent" android:layout_width="match_parent"

View File

@@ -2445,7 +2445,6 @@
<java-symbol type="id" name="work_widget_badge_icon" /> <java-symbol type="id" name="work_widget_badge_icon" />
<java-symbol type="id" name="aerr_report" /> <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_restart" />
<java-symbol type="id" name="aerr_close" /> <java-symbol type="id" name="aerr_close" />
<java-symbol type="id" name="aerr_mute" /> <java-symbol type="id" name="aerr_mute" />

View File

@@ -18,13 +18,17 @@ package com.android.server.am;
import android.app.ActivityManagerInternal; import android.app.ActivityManagerInternal;
import android.app.ActivityOptions; import android.app.ActivityOptions;
import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.IPackageDataObserver; import android.content.pm.IPackageDataObserver;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.content.res.Resources; import android.content.res.Resources;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.Message; import android.os.Message;
import android.provider.Settings;
import android.text.BidiFormatter; import android.text.BidiFormatter;
import android.util.Slog; import android.util.Slog;
import android.view.LayoutInflater; import android.view.LayoutInflater;
@@ -43,6 +47,7 @@ final class AppErrorDialog extends BaseErrorDialog implements View.OnClickListen
private final AppErrorResult mResult; private final AppErrorResult mResult;
private final ProcessRecord mProc; private final ProcessRecord mProc;
private final boolean mRepeating; private final boolean mRepeating;
private final boolean mForeground;
private CharSequence mName; private CharSequence mName;
@@ -54,9 +59,9 @@ final class AppErrorDialog extends BaseErrorDialog implements View.OnClickListen
static final int FORCE_QUIT = 1; static final int FORCE_QUIT = 1;
static final int FORCE_QUIT_AND_REPORT = 2; static final int FORCE_QUIT_AND_REPORT = 2;
static final int RESTART = 3; static final int RESTART = 3;
static final int RESET = 4;
static final int MUTE = 5; static final int MUTE = 5;
static final int TIMEOUT = 6; static final int TIMEOUT = 6;
static final int CANCEL = 7;
// 5-minute timeout, then we automatically dismiss the crash dialog // 5-minute timeout, then we automatically dismiss the crash dialog
static final long DISMISS_TIMEOUT = 1000 * 60 * 5; static final long DISMISS_TIMEOUT = 1000 * 60 * 5;
@@ -69,6 +74,7 @@ final class AppErrorDialog extends BaseErrorDialog implements View.OnClickListen
mProc = data.proc; mProc = data.proc;
mResult = data.result; mResult = data.result;
mRepeating = data.repeating; mRepeating = data.repeating;
mForeground = data.task != null;
BidiFormatter bidi = BidiFormatter.getInstance(); BidiFormatter bidi = BidiFormatter.getInstance();
if ((mProc.pkgList.size() == 1) && if ((mProc.pkgList.size() == 1) &&
@@ -86,7 +92,8 @@ final class AppErrorDialog extends BaseErrorDialog implements View.OnClickListen
bidi.unicodeWrap(mName.toString()))); bidi.unicodeWrap(mName.toString())));
} }
setCancelable(false); setCancelable(true);
setCancelMessage(mHandler.obtainMessage(CANCEL));
WindowManager.LayoutParams attrs = getWindow().getAttributes(); WindowManager.LayoutParams attrs = getWindow().getAttributes();
attrs.setTitle("Application Error: " + mProc.info.processName); attrs.setTitle("Application Error: " + mProc.info.processName);
@@ -111,25 +118,41 @@ final class AppErrorDialog extends BaseErrorDialog implements View.OnClickListen
LayoutInflater.from(context).inflate( LayoutInflater.from(context).inflate(
com.android.internal.R.layout.app_error_dialog, frame, true); 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); final TextView restart = (TextView) findViewById(com.android.internal.R.id.aerr_restart);
restart.setOnClickListener(this); restart.setOnClickListener(this);
restart.setVisibility(!mRepeating ? View.VISIBLE : View.GONE); restart.setVisibility(hasRestart ? 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);
final TextView report = (TextView) findViewById(com.android.internal.R.id.aerr_report); final TextView report = (TextView) findViewById(com.android.internal.R.id.aerr_report);
report.setOnClickListener(this); report.setOnClickListener(this);
final boolean hasReceiver = mProc.errorReportReceiver != null;
report.setVisibility(hasReceiver ? View.VISIBLE : View.GONE); report.setVisibility(hasReceiver ? View.VISIBLE : View.GONE);
final TextView close = (TextView) findViewById(com.android.internal.R.id.aerr_close); final TextView close = (TextView) findViewById(com.android.internal.R.id.aerr_close);
close.setVisibility(!hasRestart ? View.VISIBLE : View.GONE);
close.setOnClickListener(this); 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); final TextView mute = (TextView) findViewById(com.android.internal.R.id.aerr_mute);
mute.setOnClickListener(this); 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); 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() { private final Handler mHandler = new Handler() {
public void handleMessage(Message msg) { public void handleMessage(Message msg) {
final int result = msg.what; final int result = msg.what;
@@ -163,9 +186,6 @@ final class AppErrorDialog extends BaseErrorDialog implements View.OnClickListen
case com.android.internal.R.id.aerr_restart: case com.android.internal.R.id.aerr_restart:
mHandler.obtainMessage(RESTART).sendToTarget(); mHandler.obtainMessage(RESTART).sendToTarget();
break; break;
case com.android.internal.R.id.aerr_reset:
mHandler.obtainMessage(RESET).sendToTarget();
break;
case com.android.internal.R.id.aerr_report: case com.android.internal.R.id.aerr_report:
mHandler.obtainMessage(FORCE_QUIT_AND_REPORT).sendToTarget(); mHandler.obtainMessage(FORCE_QUIT_AND_REPORT).sendToTarget();
break; break;
@@ -180,6 +200,15 @@ final class AppErrorDialog extends BaseErrorDialog implements View.OnClickListen
} }
} }
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 { static class Data {
AppErrorResult result; AppErrorResult result;
TaskRecord task; TaskRecord task;

View File

@@ -370,38 +370,9 @@ class AppErrors {
Intent appErrorIntent = null; Intent appErrorIntent = null;
MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_APP_CRASH, res); MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_APP_CRASH, res);
if (res == AppErrorDialog.TIMEOUT) { if (res == AppErrorDialog.TIMEOUT || res == AppErrorDialog.CANCEL) {
res = AppErrorDialog.FORCE_QUIT; 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) { synchronized (mService) {
if (res == AppErrorDialog.MUTE) { if (res == AppErrorDialog.MUTE) {
stopReportingCrashesLocked(r); stopReportingCrashesLocked(r);