19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage com.android.server.am;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
199046222cb2b1bd57278ddbf71d9f628f8dd254aeAdrian Roosimport com.android.internal.logging.MetricsLogger;
20383db5ebcc3a4a615faf249bf4f126f42e80b82eTamas Berghammerimport com.android.internal.logging.nano.MetricsProto;
219046222cb2b1bd57278ddbf71d9f628f8dd254aeAdrian Roos
22f5b9c72022f574417862e064cc0fdd8ea2d846dcJacek Surazskiimport android.content.ActivityNotFoundException;
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context;
24f5b9c72022f574417862e064cc0fdd8ea2d846dcJacek Surazskiimport android.content.DialogInterface;
25f5b9c72022f574417862e064cc0fdd8ea2d846dcJacek Surazskiimport android.content.Intent;
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.Resources;
27a85a2c63f191ae8c567ba6845c063cbe3dd750fcAdrian Roosimport android.os.Bundle;
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Handler;
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Message;
30890f1f372e9bdaeefc1707acbbd97de95709db39Adrian Roosimport android.text.BidiFormatter;
318a9b22056b13477f59df934928c00c58b5871c95Joe Onoratoimport android.util.Slog;
32a85a2c63f191ae8c567ba6845c063cbe3dd750fcAdrian Roosimport android.view.LayoutInflater;
33a85a2c63f191ae8c567ba6845c063cbe3dd750fcAdrian Roosimport android.view.View;
345fe7e2a3043d6a8ca933c77ccf95c791b57b221aDianne Hackbornimport android.view.WindowManager;
35a85a2c63f191ae8c567ba6845c063cbe3dd750fcAdrian Roosimport android.widget.FrameLayout;
36a85a2c63f191ae8c567ba6845c063cbe3dd750fcAdrian Roosimport android.widget.TextView;
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
38a85a2c63f191ae8c567ba6845c063cbe3dd750fcAdrian Roosimport static com.android.server.am.ActivityManagerService.IS_USER_BUILD;
39a85a2c63f191ae8c567ba6845c063cbe3dd750fcAdrian Roos
40a85a2c63f191ae8c567ba6845c063cbe3dd750fcAdrian Roosfinal class AppNotRespondingDialog extends BaseErrorDialog implements View.OnClickListener {
41f5b9c72022f574417862e064cc0fdd8ea2d846dcJacek Surazski    private static final String TAG = "AppNotRespondingDialog";
42f5b9c72022f574417862e064cc0fdd8ea2d846dcJacek Surazski
43f5b9c72022f574417862e064cc0fdd8ea2d846dcJacek Surazski    // Event 'what' codes
44f5b9c72022f574417862e064cc0fdd8ea2d846dcJacek Surazski    static final int FORCE_CLOSE = 1;
45f5b9c72022f574417862e064cc0fdd8ea2d846dcJacek Surazski    static final int WAIT = 2;
46f5b9c72022f574417862e064cc0fdd8ea2d846dcJacek Surazski    static final int WAIT_AND_REPORT = 3;
47f5b9c72022f574417862e064cc0fdd8ea2d846dcJacek Surazski
489046222cb2b1bd57278ddbf71d9f628f8dd254aeAdrian Roos    public static final int CANT_SHOW = -1;
499046222cb2b1bd57278ddbf71d9f628f8dd254aeAdrian Roos    public static final int ALREADY_SHOWING = -2;
509046222cb2b1bd57278ddbf71d9f628f8dd254aeAdrian Roos
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final ActivityManagerService mService;
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final ProcessRecord mProc;
53a85a2c63f191ae8c567ba6845c063cbe3dd750fcAdrian Roos
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public AppNotRespondingDialog(ActivityManagerService service, Context context,
555fe7e2a3043d6a8ca933c77ccf95c791b57b221aDianne Hackborn            ProcessRecord app, ActivityRecord activity, boolean aboveSystem) {
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super(context);
57a85a2c63f191ae8c567ba6845c063cbe3dd750fcAdrian Roos
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mService = service;
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mProc = app;
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Resources res = context.getResources();
61a85a2c63f191ae8c567ba6845c063cbe3dd750fcAdrian Roos
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setCancelable(false);
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int resid;
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        CharSequence name1 = activity != null
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ? activity.info.loadLabel(context.getPackageManager())
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                : null;
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        CharSequence name2 = null;
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ((app.pkgList.size() == 1) &&
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                (name2=context.getPackageManager().getApplicationLabel(app.info)) != null) {
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (name1 != null) {
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                resid = com.android.internal.R.string.anr_activity_application;
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                name1 = name2;
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                name2 = app.processName;
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                resid = com.android.internal.R.string.anr_application_process;
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (name1 != null) {
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                name2 = app.processName;
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                resid = com.android.internal.R.string.anr_activity_process;
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                name1 = app.processName;
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                resid = com.android.internal.R.string.anr_process;
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
88890f1f372e9bdaeefc1707acbbd97de95709db39Adrian Roos        BidiFormatter bidi = BidiFormatter.getInstance();
89890f1f372e9bdaeefc1707acbbd97de95709db39Adrian Roos
90a85a2c63f191ae8c567ba6845c063cbe3dd750fcAdrian Roos        setTitle(name2 != null
91890f1f372e9bdaeefc1707acbbd97de95709db39Adrian Roos                ? res.getString(resid, bidi.unicodeWrap(name1.toString()), bidi.unicodeWrap(name2.toString()))
92890f1f372e9bdaeefc1707acbbd97de95709db39Adrian Roos                : res.getString(resid, bidi.unicodeWrap(name1.toString())));
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
945fe7e2a3043d6a8ca933c77ccf95c791b57b221aDianne Hackborn        if (aboveSystem) {
955fe7e2a3043d6a8ca933c77ccf95c791b57b221aDianne Hackborn            getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
965fe7e2a3043d6a8ca933c77ccf95c791b57b221aDianne Hackborn        }
975fe7e2a3043d6a8ca933c77ccf95c791b57b221aDianne Hackborn        WindowManager.LayoutParams attrs = getWindow().getAttributes();
985fe7e2a3043d6a8ca933c77ccf95c791b57b221aDianne Hackborn        attrs.setTitle("Application Not Responding: " + app.info.processName);
9995c42974f719d1fac90fc0438eac778e9795681fAdam Lesinski        attrs.privateFlags = WindowManager.LayoutParams.PRIVATE_FLAG_SYSTEM_ERROR |
10095c42974f719d1fac90fc0438eac778e9795681fAdam Lesinski                WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
1015fe7e2a3043d6a8ca933c77ccf95c791b57b221aDianne Hackborn        getWindow().setAttributes(attrs);
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
104a85a2c63f191ae8c567ba6845c063cbe3dd750fcAdrian Roos    @Override
105a85a2c63f191ae8c567ba6845c063cbe3dd750fcAdrian Roos    protected void onCreate(Bundle savedInstanceState) {
106a85a2c63f191ae8c567ba6845c063cbe3dd750fcAdrian Roos        super.onCreate(savedInstanceState);
10751efddbd3bb304de2dd47fa8cd1114ac555958bbAlan Viverette        final FrameLayout frame = findViewById(android.R.id.custom);
108a85a2c63f191ae8c567ba6845c063cbe3dd750fcAdrian Roos        final Context context = getContext();
109a85a2c63f191ae8c567ba6845c063cbe3dd750fcAdrian Roos        LayoutInflater.from(context).inflate(
110a85a2c63f191ae8c567ba6845c063cbe3dd750fcAdrian Roos                com.android.internal.R.layout.app_anr_dialog, frame, true);
111a85a2c63f191ae8c567ba6845c063cbe3dd750fcAdrian Roos
11251efddbd3bb304de2dd47fa8cd1114ac555958bbAlan Viverette        final TextView report = findViewById(com.android.internal.R.id.aerr_report);
113a85a2c63f191ae8c567ba6845c063cbe3dd750fcAdrian Roos        report.setOnClickListener(this);
114a85a2c63f191ae8c567ba6845c063cbe3dd750fcAdrian Roos        final boolean hasReceiver = mProc.errorReportReceiver != null;
115a85a2c63f191ae8c567ba6845c063cbe3dd750fcAdrian Roos        report.setVisibility(hasReceiver ? View.VISIBLE : View.GONE);
11651efddbd3bb304de2dd47fa8cd1114ac555958bbAlan Viverette        final TextView close = findViewById(com.android.internal.R.id.aerr_close);
117a85a2c63f191ae8c567ba6845c063cbe3dd750fcAdrian Roos        close.setOnClickListener(this);
11851efddbd3bb304de2dd47fa8cd1114ac555958bbAlan Viverette        final TextView wait = findViewById(com.android.internal.R.id.aerr_wait);
119a85a2c63f191ae8c567ba6845c063cbe3dd750fcAdrian Roos        wait.setOnClickListener(this);
120a85a2c63f191ae8c567ba6845c063cbe3dd750fcAdrian Roos
121a85a2c63f191ae8c567ba6845c063cbe3dd750fcAdrian Roos        findViewById(com.android.internal.R.id.customPanel).setVisibility(View.VISIBLE);
122a85a2c63f191ae8c567ba6845c063cbe3dd750fcAdrian Roos    }
123a85a2c63f191ae8c567ba6845c063cbe3dd750fcAdrian Roos
124a85a2c63f191ae8c567ba6845c063cbe3dd750fcAdrian Roos    @Override
125a85a2c63f191ae8c567ba6845c063cbe3dd750fcAdrian Roos    public void onClick(View v) {
126a85a2c63f191ae8c567ba6845c063cbe3dd750fcAdrian Roos        switch (v.getId()) {
127a85a2c63f191ae8c567ba6845c063cbe3dd750fcAdrian Roos            case com.android.internal.R.id.aerr_report:
128a85a2c63f191ae8c567ba6845c063cbe3dd750fcAdrian Roos                mHandler.obtainMessage(WAIT_AND_REPORT).sendToTarget();
129a85a2c63f191ae8c567ba6845c063cbe3dd750fcAdrian Roos                break;
130a85a2c63f191ae8c567ba6845c063cbe3dd750fcAdrian Roos            case com.android.internal.R.id.aerr_close:
131a85a2c63f191ae8c567ba6845c063cbe3dd750fcAdrian Roos                mHandler.obtainMessage(FORCE_CLOSE).sendToTarget();
132a85a2c63f191ae8c567ba6845c063cbe3dd750fcAdrian Roos                break;
133a85a2c63f191ae8c567ba6845c063cbe3dd750fcAdrian Roos            case com.android.internal.R.id.aerr_wait:
134a85a2c63f191ae8c567ba6845c063cbe3dd750fcAdrian Roos                mHandler.obtainMessage(WAIT).sendToTarget();
135a85a2c63f191ae8c567ba6845c063cbe3dd750fcAdrian Roos                break;
136a85a2c63f191ae8c567ba6845c063cbe3dd750fcAdrian Roos            default:
137a85a2c63f191ae8c567ba6845c063cbe3dd750fcAdrian Roos                break;
138a85a2c63f191ae8c567ba6845c063cbe3dd750fcAdrian Roos        }
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final Handler mHandler = new Handler() {
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void handleMessage(Message msg) {
143f5b9c72022f574417862e064cc0fdd8ea2d846dcJacek Surazski            Intent appErrorIntent = null;
1449046222cb2b1bd57278ddbf71d9f628f8dd254aeAdrian Roos
1459046222cb2b1bd57278ddbf71d9f628f8dd254aeAdrian Roos            MetricsLogger.action(getContext(), MetricsProto.MetricsEvent.ACTION_APP_ANR,
1469046222cb2b1bd57278ddbf71d9f628f8dd254aeAdrian Roos                    msg.what);
1479046222cb2b1bd57278ddbf71d9f628f8dd254aeAdrian Roos
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            switch (msg.what) {
149f5b9c72022f574417862e064cc0fdd8ea2d846dcJacek Surazski                case FORCE_CLOSE:
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // Kill the application.
15142471dd5552a346dd82a58a663159875ccc4fb79Dan Egnor                    mService.killAppAtUsersRequest(mProc, AppNotRespondingDialog.this);
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
153f5b9c72022f574417862e064cc0fdd8ea2d846dcJacek Surazski                case WAIT_AND_REPORT:
154f5b9c72022f574417862e064cc0fdd8ea2d846dcJacek Surazski                case WAIT:
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // Continue waiting for the application.
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    synchronized (mService) {
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        ProcessRecord app = mProc;
158f5b9c72022f574417862e064cc0fdd8ea2d846dcJacek Surazski
159f5b9c72022f574417862e064cc0fdd8ea2d846dcJacek Surazski                        if (msg.what == WAIT_AND_REPORT) {
16020d7df3c3ff0000678a208b25fcf7ddf90c5abe4Adrian Roos                            appErrorIntent = mService.mAppErrors.createAppErrorIntentLocked(app,
16141a9fd55ac0f50afb3d70b1ba0786dbb316eebceJacek Surazski                                    System.currentTimeMillis(), null);
162f5b9c72022f574417862e064cc0fdd8ea2d846dcJacek Surazski                        }
163f5b9c72022f574417862e064cc0fdd8ea2d846dcJacek Surazski
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        app.notResponding = false;
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        app.notRespondingReport = null;
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (app.anrDialog == AppNotRespondingDialog.this) {
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            app.anrDialog = null;
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
1692be00933163bb2bfa6b43cf2e1ddde7c284c7c4cDianne Hackborn                        mService.mServices.scheduleServiceTimeoutLocked(app);
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
173f5b9c72022f574417862e064cc0fdd8ea2d846dcJacek Surazski
174f5b9c72022f574417862e064cc0fdd8ea2d846dcJacek Surazski            if (appErrorIntent != null) {
175f5b9c72022f574417862e064cc0fdd8ea2d846dcJacek Surazski                try {
176f5b9c72022f574417862e064cc0fdd8ea2d846dcJacek Surazski                    getContext().startActivity(appErrorIntent);
177f5b9c72022f574417862e064cc0fdd8ea2d846dcJacek Surazski                } catch (ActivityNotFoundException e) {
1788a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                    Slog.w(TAG, "bug report receiver dissappeared", e);
179f5b9c72022f574417862e064cc0fdd8ea2d846dcJacek Surazski                }
180f5b9c72022f574417862e064cc0fdd8ea2d846dcJacek Surazski            }
181a85a2c63f191ae8c567ba6845c063cbe3dd750fcAdrian Roos
182a85a2c63f191ae8c567ba6845c063cbe3dd750fcAdrian Roos            dismiss();
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    };
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
186