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

Commit 5d4c24ad authored by Li Li's avatar Li Li Committed by Android (Google) Code Review
Browse files

Merge "Fix race between WM launching app and AMS freezer" into tm-dev

parents 441e705d 950919b2
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -16999,6 +16999,15 @@ public class ActivityManagerService extends IActivityManager.Stub
        @Override
        public void addPendingTopUid(int uid, int pid) {
            mPendingStartActivityUids.add(uid, pid);
            // If the next top activity is in cached and frozen mode, WM should raise its priority
            // to unfreeze it. This is done by calling AMS.updateOomAdj that will lower its oom adj.
            // However, WM cannot hold the AMS clock here so the updateOomAdj operation is performed
            // in a separate thread asynchronously. Therefore WM can't guarantee AMS will unfreeze
            // next top activity on time. This race will fail the following binder transactions WM
            // sends to the activity. After this race issue between WM/ATMS and AMS is solved, this
            // workaround can be removed. (b/213288355)
            mOomAdjuster.mCachedAppOptimizer.unfreezeProcess(pid);
        }
        @Override
+40 −4
Original line number Diff line number Diff line
@@ -183,6 +183,8 @@ public final class CachedAppOptimizer {

    private final ActivityManagerGlobalLock mProcLock;

    private final Object mFreezerLock = new Object();

    private final OnPropertiesChangedListener mOnFlagsChangedListener =
            new OnPropertiesChangedListener() {
                @Override
@@ -949,8 +951,8 @@ public final class CachedAppOptimizer {
        }
    }

    @GuardedBy({"mAm", "mProcLock"})
    void unfreezeAppLSP(ProcessRecord app) {
    @GuardedBy({"mAm", "mProcLock", "mFreezerLock"})
    void unfreezeAppInternalLSP(ProcessRecord app) {
        final int pid = app.getPid();
        final ProcessCachedOptimizerRecord opt = app.mOptRecord;
        if (opt.isPendingFreeze()) {
@@ -1035,6 +1037,42 @@ public final class CachedAppOptimizer {
        }
    }

    @GuardedBy({"mAm", "mProcLock"})
    void unfreezeAppLSP(ProcessRecord app) {
        synchronized (mFreezerLock) {
            unfreezeAppInternalLSP(app);
        }
    }

    /**
     * This quick function works around the race condition between WM/ATMS and AMS, allowing
     * the former to directly unfreeze a frozen process before the latter runs updateOomAdj.
     * After the race issue is solved, this workaround can be removed. (b/213288355)
     * @param pid pid of the process to be unfrozen
     */
    @GuardedBy({"mFreezerLock"})
    void unfreezeProcess(int pid) {
        synchronized (mFreezerLock) {
            ProcessRecord app = mFrozenProcesses.get(pid);
            if (app == null) {
                return;
            }
            Slog.i(TAG_AM, "quick sync unfreeze " + pid);
            try {
                freezeBinder(pid, false);
            } catch (RuntimeException e) {
                Slog.e(TAG_AM, "Unable to quick unfreeze binder for " + pid);
                return;
            }

            try {
                Process.setProcessFrozen(pid, app.uid, false);
            } catch (Exception e) {
                Slog.e(TAG_AM, "Unable to quick unfreeze " + pid);
            }
        }
    }

    /**
     * To be called when the given app is killed.
     */
@@ -1464,8 +1502,6 @@ public final class CachedAppOptimizer {
                return;
            }

            Slog.d(TAG_AM, "froze " + pid + " " + name);

            EventLog.writeEvent(EventLogTags.AM_FREEZE, pid, name);

            // See above for why we're not taking mPhenotypeFlagLock here