Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9046222c authored by Adrian Roos's avatar Adrian Roos
Browse files

Add logging to crash and anr dialog

Bug: 26760334
Change-Id: If81c7a6834e86f7390febef6767a07fa4caded4d
parent d7dbe7c4
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -441,5 +441,11 @@ message MetricsEvent {

    // Tuner: Change do not disturb volume buttons shortcut.
    ACTION_TUNER_DO_NOT_DISTURB_VOLUME_SHORTCUT = 315;

    // Logs the action the user takes when an app crashed.
    ACTION_APP_CRASH = 316;

    // Logs the action the user takes when an app ANR'd.
    ACTION_APP_ANR = 317;
  }
}
+8 −2
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@ import java.util.List;
import static com.android.server.am.ActivityManagerService.IS_USER_BUILD;

final class AppErrorDialog extends BaseErrorDialog implements View.OnClickListener {

    private final ActivityManagerService mService;
    private final AppErrorResult mResult;
    private final ProcessRecord mProc;
@@ -44,12 +45,17 @@ final class AppErrorDialog extends BaseErrorDialog implements View.OnClickListen

    private CharSequence mName;

    static int CANT_SHOW = -1;
    static int BACKGROUND_USER = -2;
    static int ALREADY_SHOWING = -3;

    // Event 'what' codes
    static final int FORCE_QUIT = 1;
    static final int FORCE_QUIT_AND_REPORT = 2;
    static final int RESTART = 3;
    static final int RESET = 4;
    static final int MUTE = 5;
    static final int TIMEOUT = 6;

    // 5-minute timeout, then we automatically dismiss the crash dialog
    static final long DISMISS_TIMEOUT = 1000 * 60 * 5;
@@ -89,7 +95,7 @@ final class AppErrorDialog extends BaseErrorDialog implements View.OnClickListen

        // After the timeout, pretend the user clicked the quit button
        mHandler.sendMessageDelayed(
                mHandler.obtainMessage(FORCE_QUIT),
                mHandler.obtainMessage(TIMEOUT),
                DISMISS_TIMEOUT);
    }

@@ -132,7 +138,7 @@ final class AppErrorDialog extends BaseErrorDialog implements View.OnClickListen
            mResult.set(result);

            // Make sure we don't have time timeout still hanging around.
            removeMessages(FORCE_QUIT);
            removeMessages(TIMEOUT);

            dismiss();
        }
+13 −3
Original line number Diff line number Diff line
@@ -17,6 +17,8 @@
package com.android.server.am;

import com.android.internal.app.ProcessMap;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.MetricsProto;
import com.android.internal.os.ProcessCpuTracker;
import com.android.server.Watchdog;

@@ -403,6 +405,10 @@ class AppErrors {
        Intent appErrorIntent = null;
        final long ident = Binder.clearCallingIdentity();
        try {
            MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_APP_CRASH, res);
            if (res == AppErrorDialog.TIMEOUT) {
                res = AppErrorDialog.FORCE_QUIT;
            }
            if (res == AppErrorDialog.RESET) {
                String[] packageList = r.getPackageList();
                if (packageList != null) {
@@ -697,7 +703,7 @@ class AppErrors {
            if (proc != null && proc.crashDialog != null) {
                Slog.e(TAG, "App already has crash dialog: " + proc);
                if (res != null) {
                    res.set(0);
                    res.set(AppErrorDialog.ALREADY_SHOWING);
                }
                return;
            }
@@ -710,7 +716,7 @@ class AppErrors {
            if (isBackground && !showBackground) {
                Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
                if (res != null) {
                    res.set(0);
                    res.set(AppErrorDialog.BACKGROUND_USER);
                }
                return;
            }
@@ -724,7 +730,7 @@ class AppErrors {
                // The device is asleep, so just pretend that the user
                // saw a crash dialog and hit "force quit".
                if (res != null) {
                    res.set(0);
                    res.set(AppErrorDialog.CANT_SHOW);
                }
            }
        }
@@ -920,6 +926,8 @@ class AppErrors {
            ProcessRecord proc = (ProcessRecord)data.get("app");
            if (proc != null && proc.anrDialog != null) {
                Slog.e(TAG, "App already has anr dialog: " + proc);
                MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_APP_ANR,
                        AppNotRespondingDialog.ALREADY_SHOWING);
                return;
            }

@@ -939,6 +947,8 @@ class AppErrors {
                d.show();
                proc.anrDialog = d;
            } else {
                MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_APP_ANR,
                        AppNotRespondingDialog.CANT_SHOW);
                // Just kill the app if there is no dialog to be shown.
                mService.killAppAtUsersRequest(proc, null);
            }
+10 −0
Original line number Diff line number Diff line
@@ -16,6 +16,9 @@

package com.android.server.am;

import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.MetricsProto;

import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.DialogInterface;
@@ -41,6 +44,9 @@ final class AppNotRespondingDialog extends BaseErrorDialog implements View.OnCli
    static final int WAIT = 2;
    static final int WAIT_AND_REPORT = 3;

    public static final int CANT_SHOW = -1;
    public static final int ALREADY_SHOWING = -2;

    private final ActivityManagerService mService;
    private final ProcessRecord mProc;

@@ -132,6 +138,10 @@ final class AppNotRespondingDialog extends BaseErrorDialog implements View.OnCli
    private final Handler mHandler = new Handler() {
        public void handleMessage(Message msg) {
            Intent appErrorIntent = null;

            MetricsLogger.action(getContext(), MetricsProto.MetricsEvent.ACTION_APP_ANR,
                    msg.what);

            switch (msg.what) {
                case FORCE_CLOSE:
                    // Kill the application.