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

Commit 6290916b authored by Chris Tate's avatar Chris Tate Committed by Android (Google) Code Review
Browse files

Merge "Kill apps outright for API contract violations"

parents 5b46495d 9fbc5e75
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -287,7 +287,8 @@ interface IActivityManager {
    void handleApplicationStrictModeViolation(in IBinder app, int penaltyMask,
            in StrictMode.ViolationInfo crashInfo);
    boolean isTopActivityImmersive();
    void crashApplication(int uid, int initialPid, in String packageName, int userId, in String message);
    void crashApplication(int uid, int initialPid, in String packageName, int userId,
            in String message, boolean force);
    @UnsupportedAppUsage
    String getProviderMimeType(in Uri uri, int userId);
    // Cause the specified process to dump the specified heap.
+10 −1
Original line number Diff line number Diff line
@@ -829,6 +829,15 @@ public final class ActiveServices {
        }
    }

    void killMisbehavingService(ServiceRecord r,
            int appUid, int appPid, String localPackageName) {
        synchronized (mAm) {
            stopServiceLocked(r);
            mAm.crashApplication(appUid, appPid, localPackageName, -1,
                    "Bad notification for startForeground", true /*force*/);
        }
    }

    IBinder peekServiceLocked(Intent service, String resolvedType, String callingPackage) {
        ServiceLookupResult r = retrieveServiceLocked(service, null, resolvedType, callingPackage,
                Binder.getCallingPid(), Binder.getCallingUid(),
@@ -3930,7 +3939,7 @@ public final class ActiveServices {
    void serviceForegroundCrash(ProcessRecord app, CharSequence serviceRecord) {
        mAm.crashApplication(app.uid, app.pid, app.info.packageName, app.userId,
                "Context.startForegroundService() did not then call Service.startForeground(): "
                    + serviceRecord);
                    + serviceRecord, false /*force*/);
    }

    void scheduleServiceTimeoutLocked(ProcessRecord proc) {
+3 −2
Original line number Diff line number Diff line
@@ -3568,7 +3568,7 @@ public class ActivityManagerService extends IActivityManager.Stub
    @Override
    public void crashApplication(int uid, int initialPid, String packageName, int userId,
            String message) {
            String message, boolean force) {
        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
                != PackageManager.PERMISSION_GRANTED) {
            String msg = "Permission Denial: crashApplication() from pid="
@@ -3580,7 +3580,8 @@ public class ActivityManagerService extends IActivityManager.Stub
        }
        synchronized(this) {
            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, message);
            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId,
                    message, force);
        }
    }
+1 −1
Original line number Diff line number Diff line
@@ -1070,7 +1070,7 @@ final class ActivityManagerShellCommand extends ShellCommand {
        } catch (NumberFormatException e) {
            packageName = arg;
        }
        mInterface.crashApplication(-1, pid, packageName, userId, "shell-induced crash");
        mInterface.crashApplication(-1, pid, packageName, userId, "shell-induced crash", false);
        return 0;
    }

+19 −7
Original line number Diff line number Diff line
@@ -314,20 +314,24 @@ class AppErrors {
    }

    void killAppAtUserRequestLocked(ProcessRecord app, Dialog fromDialog) {
        app.setCrashing(false);
        app.crashingReport = null;
        app.setNotResponding(false);
        app.notRespondingReport = null;
        if (app.anrDialog == fromDialog) {
            app.anrDialog = null;
        }
        if (app.waitDialog == fromDialog) {
            app.waitDialog = null;
        }
        killAppImmediateLocked(app, "user-terminated", "user request after error");
    }

    private void killAppImmediateLocked(ProcessRecord app, String reason, String killReason) {
        app.setCrashing(false);
        app.crashingReport = null;
        app.setNotResponding(false);
        app.notRespondingReport = null;
        if (app.pid > 0 && app.pid != MY_PID) {
            handleAppCrashLocked(app, "user-terminated" /*reason*/,
            handleAppCrashLocked(app, reason,
                    null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/, null /*data*/);
            app.kill("user request after error", true);
            app.kill(killReason, true);
        }
    }

@@ -341,7 +345,7 @@ class AppErrors {
     * @param message
     */
    void scheduleAppCrashLocked(int uid, int initialPid, String packageName, int userId,
            String message) {
            String message, boolean force) {
        ProcessRecord proc = null;

        // Figure out which process to kill.  We don't trust that initialPid
@@ -374,6 +378,14 @@ class AppErrors {
        }

        proc.scheduleCrash(message);
        if (force) {
            // If the app is responsive, the scheduled crash will happen as expected
            // and then the delayed summary kill will be a no-op.
            final ProcessRecord p = proc;
            mService.mHandler.postDelayed(
                    () -> killAppImmediateLocked(p, "forced", "killed for invalid state"),
                    5000L);
        }
    }

    /**
Loading