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 17 package com.android.server.am; 18 19 import static android.view.WindowManager.LayoutParams.FLAG_SYSTEM_ERROR; 20 21 import android.content.ActivityNotFoundException; 22 import android.content.Context; 23 import android.content.DialogInterface; 24 import android.content.Intent; 25 import android.content.res.Resources; 26 import android.os.Handler; 27 import android.os.Message; 28 import android.util.Slog; 29 import android.view.WindowManager; 30 31 class AppNotRespondingDialog extends BaseErrorDialog { 32 private static final String TAG = "AppNotRespondingDialog"; 33 34 // Event 'what' codes 35 static final int FORCE_CLOSE = 1; 36 static final int WAIT = 2; 37 static final int WAIT_AND_REPORT = 3; 38 39 private final ActivityManagerService mService; 40 private final ProcessRecord mProc; 41 42 public AppNotRespondingDialog(ActivityManagerService service, Context context, 43 ProcessRecord app, ActivityRecord activity, boolean aboveSystem) { 44 super(context); 45 46 mService = service; 47 mProc = app; 48 Resources res = context.getResources(); 49 50 setCancelable(false); 51 52 int resid; 53 CharSequence name1 = activity != null 54 ? activity.info.loadLabel(context.getPackageManager()) 55 : null; 56 CharSequence name2 = null; 57 if ((app.pkgList.size() == 1) && 58 (name2=context.getPackageManager().getApplicationLabel(app.info)) != null) { 59 if (name1 != null) { 60 resid = com.android.internal.R.string.anr_activity_application; 61 } else { 62 name1 = name2; 63 name2 = app.processName; 64 resid = com.android.internal.R.string.anr_application_process; 65 } 66 } else { 67 if (name1 != null) { 68 name2 = app.processName; 69 resid = com.android.internal.R.string.anr_activity_process; 70 } else { 71 name1 = app.processName; 72 resid = com.android.internal.R.string.anr_process; 73 } 74 } 75 76 setMessage(name2 != null 77 ? res.getString(resid, name1.toString(), name2.toString()) 78 : res.getString(resid, name1.toString())); 79 80 setButton(DialogInterface.BUTTON_POSITIVE, 81 res.getText(com.android.internal.R.string.force_close), 82 mHandler.obtainMessage(FORCE_CLOSE)); 83 setButton(DialogInterface.BUTTON_NEGATIVE, 84 res.getText(com.android.internal.R.string.wait), 85 mHandler.obtainMessage(WAIT)); 86 87 if (app.errorReportReceiver != null) { 88 setButton(DialogInterface.BUTTON_NEUTRAL, 89 res.getText(com.android.internal.R.string.report), 90 mHandler.obtainMessage(WAIT_AND_REPORT)); 91 } 92 93 setTitle(res.getText(com.android.internal.R.string.anr_title)); 94 if (aboveSystem) { 95 getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 96 } 97 getWindow().addFlags(FLAG_SYSTEM_ERROR); 98 WindowManager.LayoutParams attrs = getWindow().getAttributes(); 99 attrs.setTitle("Application Not Responding: " + app.info.processName); 100 attrs.privateFlags = WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 101 getWindow().setAttributes(attrs); 102 } 103 104 public void onStop() { 105 } 106 107 private final Handler mHandler = new Handler() { 108 public void handleMessage(Message msg) { 109 Intent appErrorIntent = null; 110 switch (msg.what) { 111 case FORCE_CLOSE: 112 // Kill the application. 113 mService.killAppAtUsersRequest(mProc, AppNotRespondingDialog.this); 114 break; 115 case WAIT_AND_REPORT: 116 case WAIT: 117 // Continue waiting for the application. 118 synchronized (mService) { 119 ProcessRecord app = mProc; 120 121 if (msg.what == WAIT_AND_REPORT) { 122 appErrorIntent = mService.createAppErrorIntentLocked(app, 123 System.currentTimeMillis(), null); 124 } 125 126 app.notResponding = false; 127 app.notRespondingReport = null; 128 if (app.anrDialog == AppNotRespondingDialog.this) { 129 app.anrDialog = null; 130 } 131 } 132 break; 133 } 134 135 if (appErrorIntent != null) { 136 try { 137 getContext().startActivity(appErrorIntent); 138 } catch (ActivityNotFoundException e) { 139 Slog.w(TAG, "bug report receiver dissappeared", e); 140 } 141 } 142 } 143 }; 144 } 145