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