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.os.Process; 29 import android.util.Slog; 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 AppNotRespondingDialog(ActivityManagerService service, Context context, ProcessRecord app, ActivityRecord activity)42 public AppNotRespondingDialog(ActivityManagerService service, Context context, 43 ProcessRecord app, ActivityRecord activity) { 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 getWindow().addFlags(FLAG_SYSTEM_ERROR); 95 getWindow().setTitle("Application Not Responding: " + app.info.processName); 96 } 97 onStop()98 public void onStop() { 99 } 100 101 private final Handler mHandler = new Handler() { 102 public void handleMessage(Message msg) { 103 Intent appErrorIntent = null; 104 switch (msg.what) { 105 case FORCE_CLOSE: 106 // Kill the application. 107 mService.killAppAtUsersRequest(mProc, AppNotRespondingDialog.this); 108 break; 109 case WAIT_AND_REPORT: 110 case WAIT: 111 // Continue waiting for the application. 112 synchronized (mService) { 113 ProcessRecord app = mProc; 114 115 if (msg.what == WAIT_AND_REPORT) { 116 appErrorIntent = mService.createAppErrorIntentLocked(app, 117 System.currentTimeMillis(), null); 118 } 119 120 app.notResponding = false; 121 app.notRespondingReport = null; 122 if (app.anrDialog == AppNotRespondingDialog.this) { 123 app.anrDialog = null; 124 } 125 } 126 break; 127 } 128 129 if (appErrorIntent != null) { 130 try { 131 getContext().startActivity(appErrorIntent); 132 } catch (ActivityNotFoundException e) { 133 Slog.w(TAG, "bug report receiver dissappeared", e); 134 } 135 } 136 } 137 }; 138 } 139