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

Commit 99723963 authored by Mark Fasheh's avatar Mark Fasheh
Browse files

Re-evaluate frozen state in CAO.onCleanupApplicationRecordLocked

CachedAppOptimzer.onCleanupApplicationRecordLocked() is unconditionally
setting the UID record as unfrozen and sending the corresponding
callback. This is wrong as the frozen/unfrozen state may have changed
when that process went away.  As an example, if the process being
cleaned up was the last unfrozen process in the UID, then we would need
to send a frozen state changed message.

The easiest way to do this (and avoid sending redundant FROZEN messages)
is to re-evaluate our UIDs frozen state, compare it to what is recorded
in the UidRec and update the record / send a callback only if the frozen
state changed from what it previously was.

From what I can tell, there's a possibility that the process going away
may still be in the UidRecord.  Since we don't want to count that
processes state, I added a new version of
UidRecord.areAllProcessesFrozen() which will skip over a given process
record when evaluating the UidRecord frozen state.

Test: tested on a pixel 6
Bug: 283537511
Change-Id: If809b04f42e737f3a0379bcd08d6cf4aba70e207
parent fd9d67ef
Loading
Loading
Loading
Loading
+8 −4
Original line number Diff line number Diff line
@@ -1525,10 +1525,14 @@ public final class CachedAppOptimizer {
                opt.setPendingFreeze(false);
            }

            UidRecord uidRec = app.getUidRecord();
            if (uidRec != null && uidRec.isFrozen()) {
                uidRec.setFrozen(false);
                postUidFrozenMessage(uidRec.getUid(), false);
            final UidRecord uidRec = app.getUidRecord();
            if (uidRec != null) {
                final boolean isFrozen = uidRec.getNumOfProcs() > 1
                        && uidRec.areAllProcessesFrozen(app);
                if (isFrozen != uidRec.isFrozen()) {
                    uidRec.setFrozen(isFrozen);
                    postUidFrozenMessage(uidRec.getUid(), isFrozen);
                }
            }

            mFrozenProcesses.delete(app.getPid());
+13 −2
Original line number Diff line number Diff line
@@ -345,21 +345,32 @@ public final class UidRecord {
    }

    /**
     * Check whether all processes in the Uid are frozen.
     *
     * @param excluding Skip this process record during the check.
     * @return true if all processes in the Uid are frozen, false otherwise.
     */
    @GuardedBy(anyOf = {"mService", "mProcLock"})
    public boolean areAllProcessesFrozen() {
    public boolean areAllProcessesFrozen(ProcessRecord excluding) {
        for (int i = mProcRecords.size() - 1; i >= 0; i--) {
            final ProcessRecord app = mProcRecords.valueAt(i);
            final ProcessCachedOptimizerRecord opt = app.mOptRecord;

            if (!opt.isFrozen()) {
            if (excluding != app && !opt.isFrozen()) {
                return false;
            }
        }
        return true;
    }

    /**
     * @return true if all processes in the Uid are frozen, false otherwise.
     */
    @GuardedBy(anyOf = {"mService", "mProcLock"})
    public boolean areAllProcessesFrozen() {
        return areAllProcessesFrozen(null);
    }

    @GuardedBy(anyOf = {"mService", "mProcLock"})
    public void setFrozen(boolean frozen) {
        mUidIsFrozen = frozen;