AppErrorDialog.java revision a925f1897f9e8fa0db7cf8b72b53d7c56dc3921c
1/* 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 19import android.content.Context; 20import android.content.DialogInterface; 21import android.content.res.Resources; 22import android.os.Bundle; 23import android.os.Handler; 24import android.os.Message; 25import android.view.LayoutInflater; 26import android.view.View; 27import android.view.ViewGroup; 28import android.view.WindowManager; 29import android.widget.CheckBox; 30import android.widget.FrameLayout; 31import android.widget.TextView; 32 33final class AppErrorDialog extends BaseErrorDialog { 34 private final ActivityManagerService mService; 35 private final AppErrorResult mResult; 36 private final ProcessRecord mProc; 37 private CharSequence mName; 38 39 // Event 'what' codes 40 static final int FORCE_QUIT = 0; 41 static final int FORCE_QUIT_AND_REPORT = 1; 42 43 // 5-minute timeout, then we automatically dismiss the crash dialog 44 static final long DISMISS_TIMEOUT = 1000 * 60 * 5; 45 46 public AppErrorDialog(Context context, ActivityManagerService service, 47 AppErrorResult result, ProcessRecord app) { 48 super(context); 49 50 Resources res = context.getResources(); 51 52 mService = service; 53 mProc = app; 54 mResult = result; 55 if ((app.pkgList.size() == 1) && 56 (mName = context.getPackageManager().getApplicationLabel(app.info)) != null) { 57 setMessage(res.getString( 58 com.android.internal.R.string.aerr_application, 59 mName.toString(), app.info.processName)); 60 } else { 61 mName = app.processName; 62 setMessage(res.getString( 63 com.android.internal.R.string.aerr_process, 64 mName.toString())); 65 } 66 67 setCancelable(false); 68 69 setButton(DialogInterface.BUTTON_POSITIVE, 70 res.getText(com.android.internal.R.string.force_close), 71 mHandler.obtainMessage(FORCE_QUIT)); 72 73 if (app.errorReportReceiver != null) { 74 setButton(DialogInterface.BUTTON_NEGATIVE, 75 res.getText(com.android.internal.R.string.report), 76 mHandler.obtainMessage(FORCE_QUIT_AND_REPORT)); 77 } 78 79 setTitle(res.getText(com.android.internal.R.string.aerr_title)); 80 WindowManager.LayoutParams attrs = getWindow().getAttributes(); 81 attrs.setTitle("Application Error: " + app.info.processName); 82 attrs.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SYSTEM_ERROR 83 | WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 84 getWindow().setAttributes(attrs); 85 if (app.persistent) { 86 getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 87 } 88 89 // After the timeout, pretend the user clicked the quit button 90 mHandler.sendMessageDelayed( 91 mHandler.obtainMessage(FORCE_QUIT), 92 DISMISS_TIMEOUT); 93 } 94 95 @Override 96 protected void onCreate(Bundle savedInstanceState) { 97 super.onCreate(savedInstanceState); 98 if (!ActivityManagerService.IS_USER_BUILD) { 99 FrameLayout frame = (FrameLayout) findViewById(android.R.id.custom); 100 Context context = getContext(); 101 LayoutInflater.from(context).inflate( 102 com.android.internal.R.layout.app_error_dialog_dont_show_again, frame, true); 103 ((TextView) frame.findViewById(com.android.internal.R.id.text)).setText( 104 context.getResources().getString( 105 com.android.internal.R.string.aerr_process_silence, 106 mName.toString())); 107 findViewById(com.android.internal.R.id.customPanel).setVisibility(View.VISIBLE); 108 } 109 } 110 111 private final Handler mHandler = new Handler() { 112 public void handleMessage(Message msg) { 113 View view = findViewById(com.android.internal.R.id.checkbox); 114 final boolean stopReporting = view != null && ((CheckBox) view).isChecked(); 115 synchronized (mService) { 116 if (mProc != null && mProc.crashDialog == AppErrorDialog.this) { 117 mProc.crashDialog = null; 118 } 119 if (stopReporting) { 120 mService.stopReportingCrashesLocked(mProc); 121 } 122 } 123 mResult.set(msg.what); 124 125 // Make sure we don't have time timeout still hanging around. 126 removeMessages(FORCE_QUIT); 127 128 // If this is a timeout we won't be automatically closed, so go 129 // ahead and explicitly dismiss ourselves just in case. 130 dismiss(); 131 } 132 }; 133 134 @Override 135 public void dismiss() { 136 if (!mResult.mHasResult) { 137 // We are dismissing and the result has not been set...go ahead and set. 138 mResult.set(FORCE_QUIT); 139 } 140 super.dismiss(); 141 } 142} 143