blob: a80a5b5211eab76faf0f3026155b1bb5c52acf82 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
Wale Ogunwale64258362018-10-16 15:13:37 -070019import static android.app.ActivityTaskManager.INVALID_TASK_ID;
20
Adrian Roosad028c12016-05-17 14:30:42 -070021import android.content.BroadcastReceiver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080022import android.content.Context;
Adrian Roosad028c12016-05-17 14:30:42 -070023import android.content.Intent;
24import android.content.IntentFilter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080025import android.content.res.Resources;
Jeff Sharkey5ab02432017-06-27 11:01:36 -060026import android.os.Build;
Filip Gruszczynskia925f182015-07-28 09:36:51 -070027import android.os.Bundle;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080028import android.os.Handler;
29import android.os.Message;
Adrian Roosad028c12016-05-17 14:30:42 -070030import android.provider.Settings;
Adrian Roos890f1f32016-03-03 16:23:30 -080031import android.text.BidiFormatter;
Filip Gruszczynskia925f182015-07-28 09:36:51 -070032import android.view.LayoutInflater;
33import android.view.View;
Dianne Hackborn38cc8962011-10-13 11:33:55 -070034import android.view.WindowManager;
Filip Gruszczynskia925f182015-07-28 09:36:51 -070035import android.widget.FrameLayout;
36import android.widget.TextView;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080037
Adrian Roos20d7df32016-01-12 18:59:43 +010038final class AppErrorDialog extends BaseErrorDialog implements View.OnClickListener {
Adrian Roos90462222016-02-17 15:45:09 -080039
Dianne Hackbornd4ac8d72012-09-27 23:20:10 -070040 private final ActivityManagerService mService;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041 private final AppErrorResult mResult;
42 private final ProcessRecord mProc;
Adrian Roos805ea302016-07-27 12:25:54 -070043 private final boolean mIsRestartable;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080044
Adrian Roos90462222016-02-17 15:45:09 -080045 static int CANT_SHOW = -1;
46 static int BACKGROUND_USER = -2;
47 static int ALREADY_SHOWING = -3;
48
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080049 // Event 'what' codes
Adrian Roos20d7df32016-01-12 18:59:43 +010050 static final int FORCE_QUIT = 1;
51 static final int FORCE_QUIT_AND_REPORT = 2;
52 static final int RESTART = 3;
Adrian Roos20d7df32016-01-12 18:59:43 +010053 static final int MUTE = 5;
Adrian Roos90462222016-02-17 15:45:09 -080054 static final int TIMEOUT = 6;
Adrian Roosad028c12016-05-17 14:30:42 -070055 static final int CANCEL = 7;
Andrew Sapperstein5b679c42018-01-16 11:13:40 -080056 static final int APP_INFO = 8;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080057
58 // 5-minute timeout, then we automatically dismiss the crash dialog
59 static final long DISMISS_TIMEOUT = 1000 * 60 * 5;
Filip Gruszczynskia925f182015-07-28 09:36:51 -070060
Adrian Roos20d7df32016-01-12 18:59:43 +010061 public AppErrorDialog(Context context, ActivityManagerService service, Data data) {
62 super(context);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080063 Resources res = context.getResources();
Filip Gruszczynskia925f182015-07-28 09:36:51 -070064
Dianne Hackbornd4ac8d72012-09-27 23:20:10 -070065 mService = service;
Adrian Roos20d7df32016-01-12 18:59:43 +010066 mProc = data.proc;
67 mResult = data.result;
Wale Ogunwale64258362018-10-16 15:13:37 -070068 mIsRestartable = (data.taskId != INVALID_TASK_ID || data.isRestartableForService)
Andrew Sapperstein5b679c42018-01-16 11:13:40 -080069 && Settings.Global.getInt(context.getContentResolver(),
70 Settings.Global.SHOW_RESTART_IN_CRASH_DIALOG, 0) != 0;
Adrian Roos890f1f32016-03-03 16:23:30 -080071 BidiFormatter bidi = BidiFormatter.getInstance();
72
Andrew Sapperstein5b679c42018-01-16 11:13:40 -080073 CharSequence name;
Adrian Roos20d7df32016-01-12 18:59:43 +010074 if ((mProc.pkgList.size() == 1) &&
Andrew Sapperstein5b679c42018-01-16 11:13:40 -080075 (name = context.getPackageManager().getApplicationLabel(mProc.info)) != null) {
Adrian Roos20d7df32016-01-12 18:59:43 +010076 setTitle(res.getString(
Andrew Sapperstein5b679c42018-01-16 11:13:40 -080077 data.repeating ? com.android.internal.R.string.aerr_application_repeated
Adrian Roos20d7df32016-01-12 18:59:43 +010078 : com.android.internal.R.string.aerr_application,
Andrew Sapperstein5b679c42018-01-16 11:13:40 -080079 bidi.unicodeWrap(name.toString()),
Adrian Roos890f1f32016-03-03 16:23:30 -080080 bidi.unicodeWrap(mProc.info.processName)));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080081 } else {
Andrew Sapperstein5b679c42018-01-16 11:13:40 -080082 name = mProc.processName;
Adrian Roos20d7df32016-01-12 18:59:43 +010083 setTitle(res.getString(
Andrew Sapperstein5b679c42018-01-16 11:13:40 -080084 data.repeating ? com.android.internal.R.string.aerr_process_repeated
Adrian Roos20d7df32016-01-12 18:59:43 +010085 : com.android.internal.R.string.aerr_process,
Andrew Sapperstein5b679c42018-01-16 11:13:40 -080086 bidi.unicodeWrap(name.toString())));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080087 }
88
Adrian Roosad028c12016-05-17 14:30:42 -070089 setCancelable(true);
90 setCancelMessage(mHandler.obtainMessage(CANCEL));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080091
Dianne Hackborn5fe7e2a2012-10-04 11:58:16 -070092 WindowManager.LayoutParams attrs = getWindow().getAttributes();
Adrian Roos20d7df32016-01-12 18:59:43 +010093 attrs.setTitle("Application Error: " + mProc.info.processName);
Adam Lesinski95c42972013-10-02 10:13:27 -070094 attrs.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SYSTEM_ERROR
95 | WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
Dianne Hackborn5fe7e2a2012-10-04 11:58:16 -070096 getWindow().setAttributes(attrs);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -070097 if (mProc.isPersistent()) {
Dianne Hackborn38cc8962011-10-13 11:33:55 -070098 getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
99 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800100
101 // After the timeout, pretend the user clicked the quit button
102 mHandler.sendMessageDelayed(
Adrian Roos90462222016-02-17 15:45:09 -0800103 mHandler.obtainMessage(TIMEOUT),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800104 DISMISS_TIMEOUT);
105 }
Dan Egnorb7f03672009-12-09 16:22:32 -0800106
Filip Gruszczynskia925f182015-07-28 09:36:51 -0700107 @Override
108 protected void onCreate(Bundle savedInstanceState) {
109 super.onCreate(savedInstanceState);
Alan Viverette51efddb2017-04-05 10:00:01 -0400110 final FrameLayout frame = findViewById(android.R.id.custom);
Adrian Roos20d7df32016-01-12 18:59:43 +0100111 final Context context = getContext();
112 LayoutInflater.from(context).inflate(
113 com.android.internal.R.layout.app_error_dialog, frame, true);
114
Adrian Roosad028c12016-05-17 14:30:42 -0700115 final boolean hasReceiver = mProc.errorReportReceiver != null;
116
Alan Viverette51efddb2017-04-05 10:00:01 -0400117 final TextView restart = findViewById(com.android.internal.R.id.aerr_restart);
Adrian Roos20d7df32016-01-12 18:59:43 +0100118 restart.setOnClickListener(this);
Amith Yamasanib0c8a882017-08-28 09:36:42 -0700119 restart.setVisibility(mIsRestartable ? View.VISIBLE : View.GONE);
Alan Viverette51efddb2017-04-05 10:00:01 -0400120 final TextView report = findViewById(com.android.internal.R.id.aerr_report);
Adrian Roos20d7df32016-01-12 18:59:43 +0100121 report.setOnClickListener(this);
Adrian Roos20d7df32016-01-12 18:59:43 +0100122 report.setVisibility(hasReceiver ? View.VISIBLE : View.GONE);
Alan Viverette51efddb2017-04-05 10:00:01 -0400123 final TextView close = findViewById(com.android.internal.R.id.aerr_close);
Adrian Roos20d7df32016-01-12 18:59:43 +0100124 close.setOnClickListener(this);
Andrew Sapperstein5b679c42018-01-16 11:13:40 -0800125 final TextView appInfo = findViewById(com.android.internal.R.id.aerr_app_info);
126 appInfo.setOnClickListener(this);
Adrian Roosad028c12016-05-17 14:30:42 -0700127
Jeff Sharkey5ab02432017-06-27 11:01:36 -0600128 boolean showMute = !Build.IS_USER && Settings.Global.getInt(context.getContentResolver(),
Andrew Sapperstein5b679c42018-01-16 11:13:40 -0800129 Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) != 0
130 && Settings.Global.getInt(context.getContentResolver(),
131 Settings.Global.SHOW_MUTE_IN_CRASH_DIALOG, 0) != 0;
Alan Viverette51efddb2017-04-05 10:00:01 -0400132 final TextView mute = findViewById(com.android.internal.R.id.aerr_mute);
Adrian Roos20d7df32016-01-12 18:59:43 +0100133 mute.setOnClickListener(this);
Adrian Roosad028c12016-05-17 14:30:42 -0700134 mute.setVisibility(showMute ? View.VISIBLE : View.GONE);
Adrian Roos20d7df32016-01-12 18:59:43 +0100135
136 findViewById(com.android.internal.R.id.customPanel).setVisibility(View.VISIBLE);
Filip Gruszczynskia925f182015-07-28 09:36:51 -0700137 }
138
Adrian Roosad028c12016-05-17 14:30:42 -0700139 @Override
140 public void onStart() {
141 super.onStart();
142 getContext().registerReceiver(mReceiver,
143 new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
144 }
145
146 @Override
147 protected void onStop() {
148 super.onStop();
149 getContext().unregisterReceiver(mReceiver);
150 }
151
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800152 private final Handler mHandler = new Handler() {
153 public void handleMessage(Message msg) {
Adrian Roos0da67d662017-04-17 14:50:22 -0700154 setResult(msg.what);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800155 dismiss();
156 }
157 };
Wale Ogunwale31dd3a72015-07-07 17:13:13 -0700158
159 @Override
160 public void dismiss() {
161 if (!mResult.mHasResult) {
162 // We are dismissing and the result has not been set...go ahead and set.
Adrian Roos0da67d662017-04-17 14:50:22 -0700163 setResult(FORCE_QUIT);
Wale Ogunwale31dd3a72015-07-07 17:13:13 -0700164 }
165 super.dismiss();
166 }
Adrian Roos20d7df32016-01-12 18:59:43 +0100167
Adrian Roos0da67d662017-04-17 14:50:22 -0700168 private void setResult(int result) {
169 synchronized (mService) {
170 if (mProc != null && mProc.crashDialog == AppErrorDialog.this) {
171 mProc.crashDialog = null;
172 }
173 }
174 mResult.set(result);
175
176 // Make sure we don't have time timeout still hanging around.
177 mHandler.removeMessages(TIMEOUT);
178 }
179
Adrian Roos20d7df32016-01-12 18:59:43 +0100180 @Override
181 public void onClick(View v) {
182 switch (v.getId()) {
183 case com.android.internal.R.id.aerr_restart:
184 mHandler.obtainMessage(RESTART).sendToTarget();
185 break;
Adrian Roos20d7df32016-01-12 18:59:43 +0100186 case com.android.internal.R.id.aerr_report:
187 mHandler.obtainMessage(FORCE_QUIT_AND_REPORT).sendToTarget();
188 break;
189 case com.android.internal.R.id.aerr_close:
190 mHandler.obtainMessage(FORCE_QUIT).sendToTarget();
191 break;
Andrew Sapperstein5b679c42018-01-16 11:13:40 -0800192 case com.android.internal.R.id.aerr_app_info:
193 mHandler.obtainMessage(APP_INFO).sendToTarget();
194 break;
Adrian Roos20d7df32016-01-12 18:59:43 +0100195 case com.android.internal.R.id.aerr_mute:
196 mHandler.obtainMessage(MUTE).sendToTarget();
197 break;
198 default:
199 break;
200 }
201 }
202
Adrian Roosad028c12016-05-17 14:30:42 -0700203 private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
204 @Override
205 public void onReceive(Context context, Intent intent) {
206 if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(intent.getAction())) {
207 cancel();
208 }
209 }
210 };
211
Adrian Roos20d7df32016-01-12 18:59:43 +0100212 static class Data {
213 AppErrorResult result;
Wale Ogunwale64258362018-10-16 15:13:37 -0700214 int taskId;
Adrian Roos20d7df32016-01-12 18:59:43 +0100215 boolean repeating;
216 ProcessRecord proc;
Adrian Roos805ea302016-07-27 12:25:54 -0700217 boolean isRestartableForService;
Adrian Roos20d7df32016-01-12 18:59:43 +0100218 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800219}