summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author TreeHugger Robot <treehugger-gerrit@google.com> 2018-02-21 14:29:26 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2018-02-21 14:29:26 +0000
commit89c32b38a82dc7e810f53c44284fa7b60e7f10f0 (patch)
treec51197501c77c7f83c7cb0841dec1c497fafb893
parentbdc1e6218f6224972ac3f6c6a8d3025b57ab06d6 (diff)
parentc3a06e515666f999e6080ea71ca2a55a7d62338b (diff)
Merge "Fix crash in AppErrors and clean up code"
-rw-r--r--services/core/java/com/android/server/am/AppErrors.java59
-rw-r--r--services/core/java/com/android/server/am/AppNotRespondingDialog.java36
2 files changed, 55 insertions, 40 deletions
diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java
index 9776c4d2f947..ed098795d1d8 100644
--- a/services/core/java/com/android/server/am/AppErrors.java
+++ b/services/core/java/com/android/server/am/AppErrors.java
@@ -793,10 +793,20 @@ class AppErrors {
AppErrorDialog.Data data = (AppErrorDialog.Data) msg.obj;
boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
+
+ AppErrorDialog dialogToShow = null;
+ final String packageName;
+ final int userId;
synchronized (mService) {
- ProcessRecord proc = data.proc;
- AppErrorResult res = data.result;
- if (proc != null && proc.crashDialog != null) {
+ final ProcessRecord proc = data.proc;
+ final AppErrorResult res = data.result;
+ if (proc == null) {
+ Slog.e(TAG, "handleShowAppErrorUi: proc is null");
+ return;
+ }
+ packageName = proc.info.packageName;
+ userId = proc.userId;
+ if (proc.crashDialog != null) {
Slog.e(TAG, "App already has crash dialog: " + proc);
if (res != null) {
res.set(AppErrorDialog.ALREADY_SHOWING);
@@ -806,8 +816,8 @@ class AppErrors {
boolean isBackground = (UserHandle.getAppId(proc.uid)
>= Process.FIRST_APPLICATION_UID
&& proc.pid != MY_PID);
- for (int userId : mService.mUserController.getCurrentProfileIds()) {
- isBackground &= (proc.userId != userId);
+ for (int profileId : mService.mUserController.getCurrentProfileIds()) {
+ isBackground &= (userId != profileId);
}
if (isBackground && !showBackground) {
Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
@@ -828,7 +838,7 @@ class AppErrors {
mAppsNotReportingCrashes.contains(proc.info.packageName);
if ((mService.canShowErrorDialogs() || showBackground) && !crashSilenced
&& (showFirstCrash || showFirstCrashDevOption || data.repeating)) {
- proc.crashDialog = new AppErrorDialog(mContext, mService, data);
+ proc.crashDialog = dialogToShow = new AppErrorDialog(mContext, mService, data);
} else {
// The device is asleep, so just pretend that the user
// saw a crash dialog and hit "force quit".
@@ -838,10 +848,9 @@ class AppErrors {
}
}
// If we've created a crash dialog, show it without the lock held
- if(data.proc.crashDialog != null) {
- Slog.i(TAG, "Showing crash dialog for package " + data.proc.info.packageName
- + " u" + data.proc.userId);
- data.proc.crashDialog.show();
+ if (dialogToShow != null) {
+ Slog.i(TAG, "Showing crash dialog for package " + packageName + " u" + userId);
+ dialogToShow.show();
}
}
@@ -1071,14 +1080,8 @@ class AppErrors {
// Bring up the infamous App Not Responding dialog
Message msg = Message.obtain();
- HashMap<String, Object> map = new HashMap<String, Object>();
msg.what = ActivityManagerService.SHOW_NOT_RESPONDING_UI_MSG;
- msg.obj = map;
- msg.arg1 = aboveSystem ? 1 : 0;
- map.put("app", app);
- if (activity != null) {
- map.put("activity", activity);
- }
+ msg.obj = new AppNotRespondingDialog.Data(app, activity, aboveSystem);
mService.mUiHandler.sendMessage(msg);
}
@@ -1095,11 +1098,15 @@ class AppErrors {
}
void handleShowAnrUi(Message msg) {
- Dialog d = null;
+ Dialog dialogToShow = null;
synchronized (mService) {
- HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
- ProcessRecord proc = (ProcessRecord)data.get("app");
- if (proc != null && proc.anrDialog != null) {
+ AppNotRespondingDialog.Data data = (AppNotRespondingDialog.Data) msg.obj;
+ final ProcessRecord proc = data.proc;
+ if (proc == null) {
+ Slog.e(TAG, "handleShowAnrUi: proc is null");
+ return;
+ }
+ if (proc.anrDialog != null) {
Slog.e(TAG, "App already has anr dialog: " + proc);
MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_APP_ANR,
AppNotRespondingDialog.ALREADY_SHOWING);
@@ -1118,10 +1125,8 @@ class AppErrors {
boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
if (mService.canShowErrorDialogs() || showBackground) {
- d = new AppNotRespondingDialog(mService,
- mContext, proc, (ActivityRecord)data.get("activity"),
- msg.arg1 != 0);
- proc.anrDialog = d;
+ dialogToShow = new AppNotRespondingDialog(mService, mContext, data);
+ proc.anrDialog = dialogToShow;
} else {
MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_APP_ANR,
AppNotRespondingDialog.CANT_SHOW);
@@ -1130,8 +1135,8 @@ class AppErrors {
}
}
// If we've created a crash dialog, show it without the lock held
- if (d != null) {
- d.show();
+ if (dialogToShow != null) {
+ dialogToShow.show();
}
}
diff --git a/services/core/java/com/android/server/am/AppNotRespondingDialog.java b/services/core/java/com/android/server/am/AppNotRespondingDialog.java
index d9c6a3023903..8a88a69a7d82 100644
--- a/services/core/java/com/android/server/am/AppNotRespondingDialog.java
+++ b/services/core/java/com/android/server/am/AppNotRespondingDialog.java
@@ -21,7 +21,6 @@ import com.android.internal.logging.nano.MetricsProto;
import android.content.ActivityNotFoundException;
import android.content.Context;
-import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Resources;
import android.os.Bundle;
@@ -49,36 +48,35 @@ final class AppNotRespondingDialog extends BaseErrorDialog implements View.OnCli
private final ActivityManagerService mService;
private final ProcessRecord mProc;
- public AppNotRespondingDialog(ActivityManagerService service, Context context,
- ProcessRecord app, ActivityRecord activity, boolean aboveSystem) {
+ public AppNotRespondingDialog(ActivityManagerService service, Context context, Data data) {
super(context);
mService = service;
- mProc = app;
+ mProc = data.proc;
Resources res = context.getResources();
setCancelable(false);
int resid;
- CharSequence name1 = activity != null
- ? activity.info.loadLabel(context.getPackageManager())
+ CharSequence name1 = data.activity != null
+ ? data.activity.info.loadLabel(context.getPackageManager())
: null;
CharSequence name2 = null;
- if ((app.pkgList.size() == 1) &&
- (name2=context.getPackageManager().getApplicationLabel(app.info)) != null) {
+ if ((mProc.pkgList.size() == 1) &&
+ (name2=context.getPackageManager().getApplicationLabel(mProc.info)) != null) {
if (name1 != null) {
resid = com.android.internal.R.string.anr_activity_application;
} else {
name1 = name2;
- name2 = app.processName;
+ name2 = mProc.processName;
resid = com.android.internal.R.string.anr_application_process;
}
} else {
if (name1 != null) {
- name2 = app.processName;
+ name2 = mProc.processName;
resid = com.android.internal.R.string.anr_activity_process;
} else {
- name1 = app.processName;
+ name1 = mProc.processName;
resid = com.android.internal.R.string.anr_process;
}
}
@@ -89,11 +87,11 @@ final class AppNotRespondingDialog extends BaseErrorDialog implements View.OnCli
? res.getString(resid, bidi.unicodeWrap(name1.toString()), bidi.unicodeWrap(name2.toString()))
: res.getString(resid, bidi.unicodeWrap(name1.toString())));
- if (aboveSystem) {
+ if (data.aboveSystem) {
getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
}
WindowManager.LayoutParams attrs = getWindow().getAttributes();
- attrs.setTitle("Application Not Responding: " + app.info.processName);
+ attrs.setTitle("Application Not Responding: " + mProc.info.processName);
attrs.privateFlags = WindowManager.LayoutParams.PRIVATE_FLAG_SYSTEM_ERROR |
WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
getWindow().setAttributes(attrs);
@@ -180,4 +178,16 @@ final class AppNotRespondingDialog extends BaseErrorDialog implements View.OnCli
dismiss();
}
};
+
+ static class Data {
+ final ProcessRecord proc;
+ final ActivityRecord activity;
+ final boolean aboveSystem;
+
+ Data(ProcessRecord proc, ActivityRecord activity, boolean aboveSystem) {
+ this.proc = proc;
+ this.activity = activity;
+ this.aboveSystem = aboveSystem;
+ }
+ }
}