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

Commit a9ddac9d authored by Andrii Kulian's avatar Andrii Kulian Committed by android-build-merger
Browse files

Merge "Fix crash loop when activity controller was set" into nyc-dev am: 09934793 am: 6454a6e7

am: a6d40472

* commit 'a6d40472':
  Fix crash loop when activity controller was set

Change-Id: I47003c8671c045d9553d5cf0f4cbe29f6ba70fb7
parents 1b958bbb a6d40472
Loading
Loading
Loading
Loading
+130 −117
Original line number Original line Diff line number Diff line
@@ -304,6 +304,15 @@ class AppErrors {
     * @param crashInfo describing the failure
     * @param crashInfo describing the failure
     */
     */
    void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
    void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
        final long origId = Binder.clearCallingIdentity();
        try {
            crashApplicationInner(r, crashInfo);
        } finally {
            Binder.restoreCallingIdentity(origId);
        }
    }

    void crashApplicationInner(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
        long timeMillis = System.currentTimeMillis();
        long timeMillis = System.currentTimeMillis();
        String shortMsg = crashInfo.exceptionClassName;
        String shortMsg = crashInfo.exceptionClassName;
        String longMsg = crashInfo.exceptionMessage;
        String longMsg = crashInfo.exceptionMessage;
@@ -317,49 +326,20 @@ class AppErrors {
        AppErrorResult result = new AppErrorResult();
        AppErrorResult result = new AppErrorResult();
        TaskRecord task;
        TaskRecord task;
        synchronized (mService) {
        synchronized (mService) {
            if (mService.mController != null) {
            /**
                try {
             * If crash is handled by instance of {@link android.app.IActivityController},
                    String name = r != null ? r.processName : null;
             * finish now and don't show the app error dialog.
                    int pid = r != null ? r.pid : Binder.getCallingPid();
             */
                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
            if (handleAppCrashInActivityController(r, crashInfo, shortMsg, longMsg, stackTrace,
                    if (!mService.mController.appCrashed(name, pid,
                    timeMillis)) {
                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
                                && "Native crash".equals(crashInfo.exceptionClassName)) {
                            Slog.w(TAG, "Skip killing native crashed app " + name
                                    + "(" + pid + ") during testing");
                        } else {
                            Slog.w(TAG, "Force-killing crashed app " + name
                                    + " at watcher's request");
                            if (r != null) {
                                r.kill("crash", true);
                            } else {
                                // Huh.
                                Process.killProcess(pid);
                                ActivityManagerService.killProcessGroup(uid, pid);
                            }
                        }
                return;
                return;
            }
            }
                } catch (RemoteException e) {
                    mService.mController = null;
                    Watchdog.getInstance().setActivityController(null);
                }
            }


            final long origId = Binder.clearCallingIdentity();
            /**

             * If this process was running instrumentation, finish now - it will be handled in
            // If this process is running instrumentation, finish it.
             * {@link ActivityManagerService#handleAppDiedLocked}.
             */
            if (r != null && r.instrumentationClass != null) {
            if (r != null && r.instrumentationClass != null) {
                Slog.w(TAG, "Error in app " + r.processName
                        + " running instrumentation " + r.instrumentationClass + ":");
                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
                Bundle info = new Bundle();
                info.putString("shortMsg", shortMsg);
                info.putString("longMsg", longMsg);
                mService.finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
                Binder.restoreCallingIdentity(origId);
                return;
                return;
            }
            }


@@ -375,7 +355,6 @@ class AppErrors {
            // If we can't identify the process or it's already exceeded its crash quota,
            // If we can't identify the process or it's already exceeded its crash quota,
            // quit right away without showing a crash dialog.
            // quit right away without showing a crash dialog.
            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace, data)) {
            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace, data)) {
                Binder.restoreCallingIdentity(origId);
                return;
                return;
            }
            }


@@ -385,15 +364,11 @@ class AppErrors {
            task = data.task;
            task = data.task;
            msg.obj = data;
            msg.obj = data;
            mService.mUiHandler.sendMessage(msg);
            mService.mUiHandler.sendMessage(msg);

            Binder.restoreCallingIdentity(origId);
        }
        }


        int res = result.get();
        int res = result.get();


        Intent appErrorIntent = null;
        Intent appErrorIntent = null;
        final long ident = Binder.clearCallingIdentity();
        try {
        MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_APP_CRASH, res);
        MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_APP_CRASH, res);
        if (res == AppErrorDialog.TIMEOUT) {
        if (res == AppErrorDialog.TIMEOUT) {
            res = AppErrorDialog.FORCE_QUIT;
            res = AppErrorDialog.FORCE_QUIT;
@@ -474,9 +449,6 @@ class AppErrors {
                        SystemClock.uptimeMillis());
                        SystemClock.uptimeMillis());
            }
            }
        }
        }
        } finally {
            Binder.restoreCallingIdentity(ident);
        }


        if (appErrorIntent != null) {
        if (appErrorIntent != null) {
            try {
            try {
@@ -487,6 +459,47 @@ class AppErrors {
        }
        }
    }
    }


    private boolean handleAppCrashInActivityController(ProcessRecord r,
                                                       ApplicationErrorReport.CrashInfo crashInfo,
                                                       String shortMsg, String longMsg,
                                                       String stackTrace, long timeMillis) {
        if (mService.mController == null) {
            return false;
        }

        try {
            String name = r != null ? r.processName : null;
            int pid = r != null ? r.pid : Binder.getCallingPid();
            int uid = r != null ? r.info.uid : Binder.getCallingUid();
            if (!mService.mController.appCrashed(name, pid,
                    shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
                if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
                        && "Native crash".equals(crashInfo.exceptionClassName)) {
                    Slog.w(TAG, "Skip killing native crashed app " + name
                            + "(" + pid + ") during testing");
                } else {
                    Slog.w(TAG, "Force-killing crashed app " + name
                            + " at watcher's request");
                    if (r != null) {
                        if (!makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace, null))
                        {
                            r.kill("crash", true);
                        }
                    } else {
                        // Huh.
                        Process.killProcess(pid);
                        ActivityManagerService.killProcessGroup(uid, pid);
                    }
                }
                return true;
            }
        } catch (RemoteException e) {
            mService.mController = null;
            Watchdog.getInstance().setActivityController(null);
        }
        return false;
    }

    private boolean makeAppCrashingLocked(ProcessRecord app,
    private boolean makeAppCrashingLocked(ProcessRecord app,
            String shortMsg, String longMsg, String stackTrace, AppErrorDialog.Data data) {
            String shortMsg, String longMsg, String stackTrace, AppErrorDialog.Data data) {
        app.crashing = true;
        app.crashing = true;