AppErrorDialog.java revision a925f1897f9e8fa0db7cf8b72b53d7c56dc3921c
123c2c5d1c6aaeaeb1804b7aa9b667e7e58c941bbJamie Gennis/* 223c2c5d1c6aaeaeb1804b7aa9b667e7e58c941bbJamie Gennis * Copyright (C) 2006 The Android Open Source Project 323c2c5d1c6aaeaeb1804b7aa9b667e7e58c941bbJamie Gennis * 423c2c5d1c6aaeaeb1804b7aa9b667e7e58c941bbJamie Gennis * Licensed under the Apache License, Version 2.0 (the "License"); 523c2c5d1c6aaeaeb1804b7aa9b667e7e58c941bbJamie Gennis * you may not use this file except in compliance with the License. 623c2c5d1c6aaeaeb1804b7aa9b667e7e58c941bbJamie Gennis * You may obtain a copy of the License at 723c2c5d1c6aaeaeb1804b7aa9b667e7e58c941bbJamie Gennis * 823c2c5d1c6aaeaeb1804b7aa9b667e7e58c941bbJamie Gennis * http://www.apache.org/licenses/LICENSE-2.0 923c2c5d1c6aaeaeb1804b7aa9b667e7e58c941bbJamie Gennis * 1023c2c5d1c6aaeaeb1804b7aa9b667e7e58c941bbJamie Gennis * Unless required by applicable law or agreed to in writing, software 1123c2c5d1c6aaeaeb1804b7aa9b667e7e58c941bbJamie Gennis * distributed under the License is distributed on an "AS IS" BASIS, 1223c2c5d1c6aaeaeb1804b7aa9b667e7e58c941bbJamie Gennis * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1323c2c5d1c6aaeaeb1804b7aa9b667e7e58c941bbJamie Gennis * See the License for the specific language governing permissions and 1423c2c5d1c6aaeaeb1804b7aa9b667e7e58c941bbJamie Gennis * limitations under the License. 1523c2c5d1c6aaeaeb1804b7aa9b667e7e58c941bbJamie Gennis */ 1623c2c5d1c6aaeaeb1804b7aa9b667e7e58c941bbJamie Gennis 17718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wupackage com.android.server.am; 18718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu 19718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wuimport android.content.Context; 20718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wuimport android.content.DialogInterface; 21718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wuimport android.content.res.Resources; 2223c2c5d1c6aaeaeb1804b7aa9b667e7e58c941bbJamie Gennisimport android.os.Bundle; 2323c2c5d1c6aaeaeb1804b7aa9b667e7e58c941bbJamie Gennisimport android.os.Handler; 245a16a62950de06d48769e29f0c68a154ed7a7a89Michael Lentineimport android.os.Message; 255a16a62950de06d48769e29f0c68a154ed7a7a89Michael Lentineimport android.view.LayoutInflater; 2690ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopianimport android.view.View; 274cdc58f6840d15b4952149d2b345ec1f97d505bcRobert Carrimport android.view.ViewGroup; 284cdc58f6840d15b4952149d2b345ec1f97d505bcRobert Carrimport android.view.WindowManager; 2990ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopianimport android.widget.CheckBox; 3090ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopianimport android.widget.FrameLayout; 3190ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopianimport android.widget.TextView; 3290ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian 33c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopianfinal class AppErrorDialog extends BaseErrorDialog { 34718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu private final ActivityManagerService mService; 351078bbba175b7a4b62a2c24ec64928345feb42e6Chia-I Wu private final AppErrorResult mResult; 3623c2c5d1c6aaeaeb1804b7aa9b667e7e58c941bbJamie Gennis private final ProcessRecord mProc; 375e4fcbe411f0a941d604d8a9974a02faa3fda170Pablo Ceballos private CharSequence mName; 3813fdc49516d17f41e64e62e73c313b0928bf13ccchaviw 395e4fcbe411f0a941d604d8a9974a02faa3fda170Pablo Ceballos // Event 'what' codes 4023c2c5d1c6aaeaeb1804b7aa9b667e7e58c941bbJamie Gennis static final int FORCE_QUIT = 0; 4123c2c5d1c6aaeaeb1804b7aa9b667e7e58c941bbJamie Gennis static final int FORCE_QUIT_AND_REPORT = 1; 42718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu 43718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu // 5-minute timeout, then we automatically dismiss the crash dialog 44718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu static final long DISMISS_TIMEOUT = 1000 * 60 * 5; 45718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu 46718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu public AppErrorDialog(Context context, ActivityManagerService service, 47718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu AppErrorResult result, ProcessRecord app) { 48718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu super(context); 49718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu 50718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu Resources res = context.getResources(); 510ea0f82a7d89190ceff5701ea012ea7611291928Chia-I Wu 52493133032d4d7e680b76553c1b5a4d7a76cda6b1Chia-I Wu mService = service; 5393853fe18c4b7201774337b104db1974a74d1982Chia-I Wu mProc = app; 54718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu mResult = result; 552113bdd3561e17238a1787c749329b995016aec4Chia-I Wu if ((app.pkgList.size() == 1) && 56718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu (mName = context.getPackageManager().getApplicationLabel(app.info)) != null) { 57718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu setMessage(res.getString( 58718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu com.android.internal.R.string.aerr_application, 590ea0f82a7d89190ceff5701ea012ea7611291928Chia-I Wu mName.toString(), app.info.processName)); 60493133032d4d7e680b76553c1b5a4d7a76cda6b1Chia-I Wu } else { 6193853fe18c4b7201774337b104db1974a74d1982Chia-I Wu mName = app.processName; 62718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu setMessage(res.getString( 632113bdd3561e17238a1787c749329b995016aec4Chia-I Wu com.android.internal.R.string.aerr_process, 64718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu mName.toString())); 65718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu } 66718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu 67718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu setCancelable(false); 68718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu 69718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu setButton(DialogInterface.BUTTON_POSITIVE, 70718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu res.getText(com.android.internal.R.string.force_close), 71718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu mHandler.obtainMessage(FORCE_QUIT)); 72718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu 73718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu if (app.errorReportReceiver != null) { 74718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu setButton(DialogInterface.BUTTON_NEGATIVE, 75718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu res.getText(com.android.internal.R.string.report), 76718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu mHandler.obtainMessage(FORCE_QUIT_AND_REPORT)); 77718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu } 78718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu 79718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu setTitle(res.getText(com.android.internal.R.string.aerr_title)); 80718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu WindowManager.LayoutParams attrs = getWindow().getAttributes(); 81718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu attrs.setTitle("Application Error: " + app.info.processName); 82718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu attrs.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SYSTEM_ERROR 83718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu | WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 84718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu getWindow().setAttributes(attrs); 85718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu if (app.persistent) { 86718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 87718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu } 88718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu 89718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu // After the timeout, pretend the user clicked the quit button 90718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu mHandler.sendMessageDelayed( 91718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu mHandler.obtainMessage(FORCE_QUIT), 92718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu DISMISS_TIMEOUT); 93718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu } 94718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu 95718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu @Override 96718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu protected void onCreate(Bundle savedInstanceState) { 97718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu super.onCreate(savedInstanceState); 98718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu if (!ActivityManagerService.IS_USER_BUILD) { 99718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu FrameLayout frame = (FrameLayout) findViewById(android.R.id.custom); 100718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu Context context = getContext(); 101718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu LayoutInflater.from(context).inflate( 102718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu com.android.internal.R.layout.app_error_dialog_dont_show_again, frame, true); 103718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu ((TextView) frame.findViewById(com.android.internal.R.id.text)).setText( 104718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu context.getResources().getString( 105718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu com.android.internal.R.string.aerr_process_silence, 106718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu mName.toString())); 10740482ff650751819d4104c10a30974838168438cChavi Weingarten findViewById(com.android.internal.R.id.customPanel).setVisibility(View.VISIBLE); 108718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu } 109718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu } 110718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu 111718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu private final Handler mHandler = new Handler() { 112718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu public void handleMessage(Message msg) { 113718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu View view = findViewById(com.android.internal.R.id.checkbox); 11440482ff650751819d4104c10a30974838168438cChavi Weingarten final boolean stopReporting = view != null && ((CheckBox) view).isChecked(); 11540482ff650751819d4104c10a30974838168438cChavi Weingarten synchronized (mService) { 11640482ff650751819d4104c10a30974838168438cChavi Weingarten if (mProc != null && mProc.crashDialog == AppErrorDialog.this) { 11740482ff650751819d4104c10a30974838168438cChavi Weingarten mProc.crashDialog = null; 11840482ff650751819d4104c10a30974838168438cChavi Weingarten } 119718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu if (stopReporting) { 12040482ff650751819d4104c10a30974838168438cChavi Weingarten mService.stopReportingCrashesLocked(mProc); 12140482ff650751819d4104c10a30974838168438cChavi Weingarten } 12240482ff650751819d4104c10a30974838168438cChavi Weingarten } 123718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu mResult.set(msg.what); 124718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu 125718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu // Make sure we don't have time timeout still hanging around. 126718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu removeMessages(FORCE_QUIT); 127718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu 128718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu // If this is a timeout we won't be automatically closed, so go 129718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu // ahead and explicitly dismiss ourselves just in case. 13040482ff650751819d4104c10a30974838168438cChavi Weingarten dismiss(); 131718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu } 132718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu }; 133718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu 134718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu @Override 135718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu public void dismiss() { 136718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu if (!mResult.mHasResult) { 137718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu // We are dismissing and the result has not been set...go ahead and set. 138718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu mResult.set(FORCE_QUIT); 139718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu } 140718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu super.dismiss(); 141718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu } 142718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu} 143718daf8b58cdaa4fb87ee4093df44d423218aa9fChia-I Wu