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

Commit c4baa0a3 authored by Chih-Yu Huang's avatar Chih-Yu Huang
Browse files

am: Centralize process unfreeze logic in AMS

The `unfreezeTemporarily` method is now exposed directly by
`ActivityManagerService`. This refactors internal callers in
`BroadcastQueue` and `ContentProviderHelper` to use the new
API, providing a more consistent and centralized entry point
for managing temporary unfreezing of processes.

Bug: 441178013
Test: m services.core
Test: atest MockingOomAdjusterTests OomAdjusterTests
Test: atest FrameworksServicesTestsRavenwood_ProcessStateController
Test: atest BroadcastQueueTest
Flag: EXEMPT PURE_REFACTOR

Change-Id: I3da095b13e0848f99beb5de040c52592dd330a4b
parent b0bfc6aa
Loading
Loading
Loading
Loading
+36 −0
Original line number Diff line number Diff line
@@ -165,6 +165,7 @@ import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.am.CachedAppOptimizer.getUnfreezeReasonCodeFromOomAdjReason;
import static com.android.server.am.LogcatFetcher.LOGCAT_TIMEOUT_SEC;
import static com.android.server.am.LogcatFetcher.RESERVED_BYTES_PER_LOGCAT_LINE;
import static com.android.server.am.MemoryStatUtil.hasMemcg;
@@ -642,6 +643,11 @@ public class ActivityManagerService extends IActivityManager.Stub
    OomAdjuster mOomAdjuster;
    @GuardedBy("this")
    ProcessStateController mProcessStateController;
    /**
     * Temporary list that are currently being processed for temporary unfreezing.
     * @see #unfreezeTemporarily(ProcessRecord, int)
     */
    private final ArrayList<ProcessRecordInternal> mTmpProcessesToUnfreeze = new ArrayList<>();
    static final String EXTRA_TITLE = "android.intent.extra.TITLE";
    static final String EXTRA_DESCRIPTION = "android.intent.extra.DESCRIPTION";
@@ -19373,6 +19379,36 @@ public class ActivityManagerService extends IActivityManager.Stub
        return mCachedAppOptimizer.useFreezer();
    }
    /**
     * Temporarily unfreezes the given application process and any other processes it is associated
     * with (i.e., reachable processes). This operation is only performed if the freezer is enabled
     * and the application is currently in a frozen or pending-freeze state.
     *
     * @param app The application process to unfreeze.
     * @param reason The {@link OomAdjReason} explaining why the process is being unfrozen.
     */
    @GuardedBy("this")
    void unfreezeTemporarily(ProcessRecord app, @OomAdjReason int reason) {
        if (!mCachedAppOptimizer.useFreezer()) {
            return;
        }
        synchronized (mProcLock) {
            if (!app.isFrozen() && !app.isPendingFreeze()) {
                return;
            }
        }
        final int unfrozenReason = getUnfreezeReasonCodeFromOomAdjReason(reason);
        final ArrayList<ProcessRecordInternal> processesToUnfreeze = mTmpProcessesToUnfreeze;
        processesToUnfreeze.clear();
        mOomAdjuster.populateAllReachableProcessesLocked(app, processesToUnfreeze);
        for (int i = 0; i < processesToUnfreeze.size(); i++) {
            final ProcessRecord process = (ProcessRecord) processesToUnfreeze.get(i);
            mCachedAppOptimizer.unfreezeTemporarily(process, unfrozenReason);
        }
        processesToUnfreeze.clear();
    }
    /**
     * Resets the state of the {@link com.android.server.am.AppErrors} instance.
     * This is intended for testing within the CTS only and is protected by
+3 −3
Original line number Diff line number Diff line
@@ -507,7 +507,7 @@ class BroadcastQueueImpl extends BroadcastQueue {

            final boolean processWarm = queue.isProcessWarm();
            if (processWarm) {
                mService.mOomAdjuster.unfreezeTemporarily(queue.app,
                mService.unfreezeTemporarily(queue.app,
                        CachedAppOptimizer.UNFREEZE_REASON_START_RECEIVER);
                // The process could be killed as part of unfreezing. So, check again if it
                // is still warm.
@@ -1253,7 +1253,7 @@ class BroadcastQueueImpl extends BroadcastQueue {
        final ProcessRecord app = r.resultToApp;
        final IApplicationThread thread = (app != null) ? app.getOnewayThread() : null;
        if (thread != null) {
            mService.mOomAdjuster.unfreezeTemporarily(
            mService.unfreezeTemporarily(
                    app, CachedAppOptimizer.UNFREEZE_REASON_FINISH_RECEIVER);
            if (r.shareIdentity && app.uid != r.callingUid) {
                mService.mPackageManagerInt.grantImplicitAccess(r.userId, r.intent,
@@ -2096,7 +2096,7 @@ class BroadcastQueueImpl extends BroadcastQueue {
                mService.updateLruProcessLocked(queue.app, false, null);
            }

            mService.mOomAdjuster.unfreezeTemporarily(queue.app,
            mService.unfreezeTemporarily(queue.app,
                    CachedAppOptimizer.UNFREEZE_REASON_START_RECEIVER);

            mService.mProcessStateController.noteBroadcastDeliveryStarted(queue.app,
+1 −1
Original line number Diff line number Diff line
@@ -535,7 +535,7 @@ public class ContentProviderHelper {
                            if (mService.mProcessStateController.addPublishedProvider(proc,
                                    cpi.name, cpr)) {
                                checkTime(startTime, "getContentProviderImpl: scheduling install");
                                mService.mOomAdjuster.unfreezeTemporarily(proc,
                                mService.unfreezeTemporarily(proc,
                                        CachedAppOptimizer.UNFREEZE_REASON_GET_PROVIDER);
                                try {
                                    thread.scheduleInstallProvider(cpi);
+12 −23
Original line number Diff line number Diff line
@@ -2696,37 +2696,26 @@ public abstract class OomAdjuster {
        }
    }

    /**
     * Collects the given application process and all other processes reachable from it
     * (e.g., via service or content provider connections) into the provided list.
     *
     * @param app The initial application process from which to start collecting.
     * @param processesOut The list to populate with the collected ProcessRecordInternal objects.
     */
    @GuardedBy("mService")
    void unfreezeTemporarily(ProcessRecordInternal app, @OomAdjReason int reason) {
        if (!mService.getCachedAppOptimizer().useFreezer()) {
            return;
        }

        if (!app.isFrozen() && !app.isPendingFreeze()) {
            return;
        }

        final ArrayList<ProcessRecordInternal> processes = mTmpProcessList;

    public void populateAllReachableProcessesLocked(ProcessRecordInternal app,
            ArrayList<ProcessRecordInternal> processesOut) {
        if (Flags.consolidateCollectReachable()) {
            processes.add(app);
            processesOut.add(app);
            synchronized (mProcLock) {
                collectReachableProcessesLSP(processes);
                collectReachableProcessesLSP(processesOut);
            }
        } else {
            mTmpProcessSet.add(app);
            collectReachableProcessesLocked(mTmpProcessSet, processes);
            collectReachableProcessesLocked(mTmpProcessSet, processesOut);
            mTmpProcessSet.clear();
        }
        // Now processes contains app's downstream and app
        final int size = processes.size();
        for (int i = 0; i < size; i++) {
            // TODO: b/425766486 - Consider how to pass ProcessRecordInternal to CachedAppOptimizer.
            ProcessRecord proc = (ProcessRecord) processes.get(i);
            mService.getCachedAppOptimizer().unfreezeTemporarily(proc,
                    CachedAppOptimizer.getUnfreezeReasonCodeFromOomAdjReason(reason));
        }
        processes.clear();
    }

    @GuardedBy("mService")
+3 −4
Original line number Diff line number Diff line
@@ -778,7 +778,7 @@ public class BroadcastQueueTest extends BaseBroadcastQueueTest {
            verify(mAms, times(2)).enqueueOomAdjTargetLocked(eq(receiverApp));

            // Confirm that app was thawed
            verify(mAms.mOomAdjuster, atLeastOnce()).unfreezeTemporarily(
            verify(mAms, atLeastOnce()).unfreezeTemporarily(
                    eq(receiverApp), eq(OOM_ADJ_REASON_START_RECEIVER));

            // Confirm that we added package to process
@@ -1221,7 +1221,7 @@ public class BroadcastQueueTest extends BaseBroadcastQueueTest {
                mActiveProcesses.remove(app);
            }
            return null;
        }).when(mAms.mOomAdjuster).unfreezeTemporarily(eq(receiverBlueApp), anyInt());
        }).when(mAms).unfreezeTemporarily(eq(receiverBlueApp), anyInt());
        doAnswer(invocation -> {
            final ProcessRecord app = invocation.getArgument(0);
            if (app == receiverBlueApp) {
@@ -1378,8 +1378,7 @@ public class BroadcastQueueTest extends BaseBroadcastQueueTest {
                anyInt(), any());

        // Finally, verify that we thawed the final receiver
        verify(mAms.mOomAdjuster).unfreezeTemporarily(eq(callerApp),
                eq(OOM_ADJ_REASON_FINISH_RECEIVER));
        verify(mAms).unfreezeTemporarily(eq(callerApp), eq(OOM_ADJ_REASON_FINISH_RECEIVER));
    }

    /**