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

Commit dfd41627 authored by Songchun Fan's avatar Songchun Fan
Browse files

[am/incremental] make package unstartable if it crashes/ANRs while loading

BUG: 171252552
Test: atest CtsWindowManagerDeviceTestCases:AnrTests
Test: atest FrameworksServicesTests:AnrHelperTest
Test: atest FrameworksServicesTests:ActivityManagerServiceTest
Test: atest IncrementalStatesTest
Change-Id: I30c9aafc52ef1b6939bb724c11794b5a60661740
parent 56838fba
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -1119,4 +1119,8 @@ public abstract class PackageManagerInternal {
    public abstract IncrementalStatesInfo getIncrementalStatesInfo(String packageName,
            int filterCallingUid, int userId);

    /**
     * Notifies that a package has crashed or ANR'd.
     */
    public abstract void notifyPackageCrashOrAnr(String packageName);
}
+4 −0
Original line number Diff line number Diff line
@@ -7595,6 +7595,10 @@ public class ActivityManagerService extends IActivityManager.Stub
                eventType, r, processName, null, null, null, null, null, null, crashInfo);
        mAppErrors.crashApplication(r, crashInfo);
        // Notify package manager service to possibly update package state
        if (r != null && r.info != null && r.info.packageName != null) {
            mPackageManagerInt.notifyPackageCrashOrAnr(r.info.packageName);
        }
    }
    public void handleApplicationStrictModeViolation(
+6 −0
Original line number Diff line number Diff line
@@ -1764,6 +1764,12 @@ class ProcessRecord implements WindowProcessListener {
            makeAppNotRespondingLocked(activityShortComponentName,
                    annotation != null ? "ANR " + annotation : "ANR", info.toString());

            // Notify package manager service to possibly update package state
            if (aInfo != null && aInfo.packageName != null) {
                mService.getPackageManagerInternalLocked().notifyPackageCrashOrAnr(
                        aInfo.packageName);
            }

            // mUiHandler can be null if the AMS is constructed with injector only. This will only
            // happen in tests.
            if (mService.mUiHandler != null) {
+27 −0
Original line number Diff line number Diff line
@@ -119,6 +119,33 @@ public final class IncrementalStates {
        }
    }

    /**
     * Change the startable state if the app has crashed or ANR'd during loading.
     * If the app is not loading (i.e., fully loaded), this event doesn't change startable state.
     */
    public void onCrashOrAnr() {
        if (DEBUG) {
            Slog.i(TAG, "received package crash or ANR event");
        }
        final boolean startableStateChanged;
        synchronized (mLock) {
            if (mStartableState.isStartable() && mLoadingState.isLoading()) {
                // Changing from startable -> unstartable only if app is still loading.
                mStartableState.adoptNewStartableStateLocked(false);
                startableStateChanged = true;
            } else {
                // If the app is fully loaded, the crash or ANR is caused by the app itself, so
                // we do not change the startable state.
                startableStateChanged = false;
            }
        }
        if (startableStateChanged) {
            mHandler.post(PooledLambda.obtainRunnable(
                    IncrementalStates::reportStartableState,
                    IncrementalStates.this).recycleOnUse());
        }
    }

    private void reportStartableState() {
        final Callback callback;
        final boolean startable;
+14 −0
Original line number Diff line number Diff line
@@ -25761,6 +25761,20 @@ public class PackageManagerService extends IPackageManager.Stub
            }
            return ps.getIncrementalStates();
        }
        @Override
        public void notifyPackageCrashOrAnr(@NonNull String packageName) {
            final PackageSetting ps;
            synchronized (mLock) {
                ps = mSettings.mPackages.get(packageName);
                if (ps == null) {
                    Slog.w(TAG, "Failed notifyPackageCrash. Package " + packageName
                            + " is not installed");
                    return;
                }
            }
            ps.setStatesOnCrashOrAnr();
        }
    }
Loading