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

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

Decouple ProcessStateRecord with Observer pattern

This CL introduces the `ProcessStateRecord.Observer` and
`ProcessStateRecord.StartedServiceObserver` interfaces to decouple
`ProcessStateRecord` from directly interacting with `ProcessRecord`'s
`WindowProcessController` and `ProcessProfileRecord`.

Previously, `ProcessStateRecord` directly updated `ProcessRecord`'s
components (like `WindowProcessController` and `ProcessProfileRecord`)
upon internal state changes (e.g., OOM adj, process state). This created
a tight coupling.

This change introduces:
- New `ProcessStateRecord.Observer` and
  `ProcessStateRecord.StartedServiceObserver`interfaces with callbacks
  for various state changes.
- `WindowProcessController` and `ProcessProfileRecord` now implement the
  observer interfaces and register with the corresponding
  `ProcessStateRecord` instance.
- `ProcessStateRecord` now notifies its observers of state changes.

Bug: 425766486
Test: atest MockingOomAdjusterTests
Flag: EXEMPT pure refactor
Change-Id: Iaa5f824ff923eaae6744688879a33fcfe435d6ab
parent ea8e96ba
Loading
Loading
Loading
Loading
+11 −1
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.server.am;

import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
import static android.app.ProcessMemoryState.HOSTING_COMPONENT_TYPE_EMPTY;
import static android.app.ProcessMemoryState.HOSTING_COMPONENT_TYPE_STARTED_SERVICE;

import android.app.IApplicationThread;
import android.app.ProcessMemoryState.HostingComponentType;
@@ -44,7 +45,7 @@ import java.util.concurrent.atomic.AtomicLong;
 *
 * TODO(b/297542292): Update PSS names with RSS once AppProfiler's PSS profiling has been replaced.
 */
final class ProcessProfileRecord {
final class ProcessProfileRecord implements ProcessStateRecord.StartedServiceObserver {
    final ProcessRecord mApp;

    private final ActivityManagerService mService;
@@ -731,4 +732,13 @@ final class ProcessProfileRecord {
        }
        pw.println();
    }

    @Override
    public void onHasStartedServicesChanged(boolean hasStartedServices) {
        if (hasStartedServices) {
            addHostingComponentType(HOSTING_COMPONENT_TYPE_STARTED_SERVICE);
        } else {
            clearHostingComponentType(HOSTING_COMPONENT_TYPE_STARTED_SERVICE);
        }
    }
}
+3 −3
Original line number Diff line number Diff line
@@ -627,14 +627,14 @@ class ProcessRecord implements WindowProcessListener {
        mProviders = new ProcessProviderRecord(this);
        mReceivers = new ProcessReceiverRecord(this);
        mErrorState = new ProcessErrorStateRecord(this);
        mState = new ProcessStateRecord(processName, uid, this);
        mWindowProcessController = new WindowProcessController(
                mService.mActivityTaskManager, info, processName, uid, userId, this, this);
        mState = new ProcessStateRecord(processName, uid, mWindowProcessController, mProfile, this);
        mOptRecord = new ProcessCachedOptimizerRecord(this);
        final long now = SystemClock.uptimeMillis();
        mProfile.init(now);
        mOptRecord.init(now);
        mState.init(now);
        mWindowProcessController = new WindowProcessController(
                mService.mActivityTaskManager, info, processName, uid, userId, this, this);
        mPkgList.put(_info.packageName, new ProcessStats.ProcessStateHolder(_info.longVersionCode));
        updateProcessRecordNodes(this);
    }
+108 −19
Original line number Diff line number Diff line
@@ -21,7 +21,6 @@ import static android.app.ActivityManager.PROCESS_STATE_CACHED_EMPTY;
import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
import static android.app.ProcessMemoryState.HOSTING_COMPONENT_TYPE_ACTIVITY;
import static android.app.ProcessMemoryState.HOSTING_COMPONENT_TYPE_BROADCAST_RECEIVER;
import static android.app.ProcessMemoryState.HOSTING_COMPONENT_TYPE_STARTED_SERVICE;

import static com.android.server.am.ProcessList.CACHED_APP_MIN_ADJ;
import static com.android.server.wm.WindowProcessController.ACTIVITY_STATE_FLAG_IS_PAUSING_OR_PAUSED;
@@ -46,7 +45,97 @@ import java.io.PrintWriter;
/**
 * The state info of the process, including proc state, oom adj score, et al.
 */
final class ProcessStateRecord {
public final class ProcessStateRecord {
    /**
     * An observer interface for {@link ProcessStateRecord} to notify about changes to its internal
     * state fields.
     * TODO(b/429069530): Investigate why WindowManager needs to know any of the mCurXXX value.
     */
    public interface Observer {
        /**
         * Called when mCurRawAdj changes.
         *
         * @param curRawAdj The new mCurRawAdj value.
         */
        void onCurRawAdjChanged(int curRawAdj);

        /**
         * Called when mCurAdj changes.
         *
         * @param curAdj The new mCurAdj value.
         */
        void onCurAdjChanged(int curAdj);

        /**
         * Called when mCurSchedGroup changes.
         *
         * @param curSchedGroup The new mCurSchedGroup value.
         */
        void onCurrentSchedulingGroupChanged(int curSchedGroup);

        /**
         * Called when mCurProcState changes.
         *
         * @param curProcState The new mCurProcState value.
         */
        void onCurProcStateChanged(int curProcState);

        /**
         * Called when mRepProcState changes.
         *
         * @param repProcState The new mRepProcState value.
         */
        void onReportedProcStateChanged(int repProcState);

        /**
         * Called when mHasTopUi changes.
         *
         * @param hasTopUi The new mHasTopUi value.
         */
        void onHasTopUiChanged(boolean hasTopUi);

        /**
         * Called when mHasOverlayUi changes.
         *
         * @param hasOverlayUi The new mHasOverlayUi value.
         */
        void onHasOverlayUiChanged(boolean hasOverlayUi);

        /**
         * Called when mInteractionEventTime changes.
         *
         * @param interactionEventTime The new mInteractionEventTime value.
         */
        void onInteractionEventTimeChanged(long interactionEventTime);

        /**
         * Called when mFgInteractionTime changes.
         *
         * @param fgInteractionTime The new mFgInteractionTime value.
         */
        void onFgInteractionTimeChanged(long fgInteractionTime);

        /**
         * Called when mWhenUnimportant changes.
         *
         * @param whenUnimportant The new mWhenUnimportant value.
         */
        void onWhenUnimportantChanged(long whenUnimportant);
    }

    /**
     * An observer interface for {@link ProcessStateRecord} to notify about changes of
     * the mHasStartedServices fields.
     */
    public interface StartedServiceObserver {
        /**
         * Called when mHasStartedServices changes.
         *
         * @param hasStartedServices The new mHasStartedServices value.
         */
        void onHasStartedServicesChanged(boolean hasStartedServices);
    }

    // Enable this to trace all OomAdjuster state transitions
    private static final boolean TRACE_OOM_ADJ = false;

@@ -54,6 +143,8 @@ final class ProcessStateRecord {
    private final int mUid;
    private String mTrackName;

    private final Observer mObserver;
    private final StartedServiceObserver mStartedServiceObserver;
    private final ProcessRecord mApp;
    private final ActivityManagerService mService;
    private final ActivityManagerGlobalLock mProcLock;
@@ -442,9 +533,12 @@ final class ProcessStateRecord {
    @GuardedBy("mService")
    private long mFollowupUpdateUptimeMs = Long.MAX_VALUE;

    ProcessStateRecord(String processName, int uid, ProcessRecord app) {
    ProcessStateRecord(String processName, int uid, Observer observer,
            StartedServiceObserver startedServiceObserver, ProcessRecord app) {
        mProcessName = processName;
        mUid = uid;
        mObserver = observer;
        mStartedServiceObserver = startedServiceObserver;
        mApp = app;
        mService = app.mService;
        mProcLock = mService.mProcLock;
@@ -479,8 +573,7 @@ final class ProcessStateRecord {
            return mCurRawAdj > curRawAdj;
        }
        mCurRawAdj = curRawAdj;
        mApp.getWindowProcessController().setPerceptible(
                curRawAdj <= ProcessList.PERCEPTIBLE_APP_ADJ);
        mObserver.onCurRawAdjChanged(mCurRawAdj);
        return false;
    }

@@ -502,7 +595,7 @@ final class ProcessStateRecord {
    @GuardedBy({"mService", "mProcLock"})
    void setCurAdj(int curAdj) {
        mCurAdj = curAdj;
        mApp.getWindowProcessController().setCurrentAdj(curAdj);
        mObserver.onCurAdjChanged(mCurAdj);
    }

    @GuardedBy(anyOf = {"mService", "mProcLock"})
@@ -563,7 +656,7 @@ final class ProcessStateRecord {
    @GuardedBy({"mService", "mProcLock"})
    void setCurrentSchedulingGroup(int curSchedGroup) {
        mCurSchedGroup = curSchedGroup;
        mApp.getWindowProcessController().setCurrentSchedulingGroup(curSchedGroup);
        mObserver.onCurrentSchedulingGroupChanged(mCurSchedGroup);
    }

    @GuardedBy(anyOf = {"mService", "mProcLock"})
@@ -584,7 +677,7 @@ final class ProcessStateRecord {
    @GuardedBy({"mService", "mProcLock"})
    void setCurProcState(int curProcState) {
        mCurProcState = curProcState;
        mApp.getWindowProcessController().setCurrentProcState(mCurProcState);
        mObserver.onCurProcStateChanged(mCurProcState);
    }

    @GuardedBy(anyOf = {"mService", "mProcLock"})
@@ -618,7 +711,7 @@ final class ProcessStateRecord {
    @GuardedBy({"mService", "mProcLock"})
    void setReportedProcState(int repProcState) {
        mRepProcState = repProcState;
        mApp.getWindowProcessController().setReportedProcState(repProcState);
        mObserver.onReportedProcStateChanged(mRepProcState);
    }

    @GuardedBy(anyOf = {"mService", "mProcLock"})
@@ -683,11 +776,7 @@ final class ProcessStateRecord {
    @GuardedBy("mProcLock")
    void setHasStartedServices(boolean hasStartedServices) {
        mHasStartedServices = hasStartedServices;
        if (hasStartedServices) {
            mApp.mProfile.addHostingComponentType(HOSTING_COMPONENT_TYPE_STARTED_SERVICE);
        } else {
            mApp.mProfile.clearHostingComponentType(HOSTING_COMPONENT_TYPE_STARTED_SERVICE);
        }
        mStartedServiceObserver.onHasStartedServicesChanged(mHasStartedServices);
    }

    @GuardedBy("mProcLock")
@@ -728,7 +817,7 @@ final class ProcessStateRecord {
    @GuardedBy("mService")
    void setHasTopUi(boolean hasTopUi) {
        mHasTopUi = hasTopUi;
        mApp.getWindowProcessController().setHasTopUi(hasTopUi);
        mObserver.onHasTopUiChanged(mHasTopUi);
    }

    @GuardedBy("mService")
@@ -739,7 +828,7 @@ final class ProcessStateRecord {
    @GuardedBy("mService")
    void setHasOverlayUi(boolean hasOverlayUi) {
        mHasOverlayUi = hasOverlayUi;
        mApp.getWindowProcessController().setHasOverlayUi(hasOverlayUi);
        mObserver.onHasOverlayUiChanged(mHasOverlayUi);
    }

    @GuardedBy("mService")
@@ -780,7 +869,7 @@ final class ProcessStateRecord {
    @GuardedBy({"mService", "mProcLock"})
    void setInteractionEventTime(long interactionEventTime) {
        mInteractionEventTime = interactionEventTime;
        mApp.getWindowProcessController().setInteractionEventTime(interactionEventTime);
        mObserver.onInteractionEventTimeChanged(mInteractionEventTime);
    }

    @GuardedBy(anyOf = {"mService", "mProcLock"})
@@ -791,7 +880,7 @@ final class ProcessStateRecord {
    @GuardedBy({"mService", "mProcLock"})
    void setFgInteractionTime(long fgInteractionTime) {
        mFgInteractionTime = fgInteractionTime;
        mApp.getWindowProcessController().setFgInteractionTime(fgInteractionTime);
        mObserver.onFgInteractionTimeChanged(mFgInteractionTime);
    }

    @GuardedBy(anyOf = {"mService", "mProcLock"})
@@ -842,7 +931,7 @@ final class ProcessStateRecord {
    @GuardedBy({"mService", "mProcLock"})
    void setWhenUnimportant(long whenUnimportant) {
        mWhenUnimportant = whenUnimportant;
        mApp.getWindowProcessController().setWhenUnimportant(whenUnimportant);
        mObserver.onWhenUnimportantChanged(mWhenUnimportant);
    }

    @GuardedBy(anyOf = {"mService", "mProcLock"})
+54 −34
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import static android.view.WindowManager.TRANSIT_FLAG_APP_CRASHED;
import static com.android.internal.protolog.WmProtoLogGroups.WM_DEBUG_CONFIGURATION;
import static com.android.internal.util.Preconditions.checkArgument;
import static com.android.server.am.ProcessList.INVALID_ADJ;
import static com.android.server.am.ProcessList.PERCEPTIBLE_APP_ADJ;
import static com.android.server.wm.ActivityRecord.State.DESTROYED;
import static com.android.server.wm.ActivityRecord.State.DESTROYING;
import static com.android.server.wm.ActivityRecord.State.PAUSED;
@@ -88,6 +89,7 @@ import com.android.internal.app.HeavyWeightSwitcherActivity;
import com.android.internal.protolog.ProtoLog;
import com.android.internal.util.function.pooled.PooledLambda;
import com.android.server.Watchdog;
import com.android.server.am.ProcessStateRecord;
import com.android.server.art.ReasonMapping;
import com.android.server.grammaticalinflection.GrammaticalInflectionManagerInternal;
import com.android.server.wm.ActivityTaskManagerService.HotPath;
@@ -112,7 +114,7 @@ import java.util.List;
 * calls are allowed to proceed.
 */
public class WindowProcessController extends ConfigurationContainer<ConfigurationContainer>
        implements ConfigurationContainerListener {
        implements ConfigurationContainerListener, ProcessStateRecord.Observer {
    private static final String TAG = TAG_WITH_CLASS_NAME ? "WindowProcessController" : TAG_ATM;
    private static final String TAG_RELEASE = TAG + POSTFIX_RELEASE;
    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
@@ -412,15 +414,11 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
        return mThread != null;
    }

    public void setCurrentSchedulingGroup(int curSchedGroup) {
        mCurSchedGroup = curSchedGroup;
    }

    int getCurrentSchedulingGroup() {
        return mCurSchedGroup;
    }

    public void setCurrentProcState(int curProcState) {
    void setCurrentProcState(int curProcState) {
        mCurProcState = curProcState;
    }

@@ -428,10 +426,6 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
        return mCurProcState;
    }

    public void setCurrentAdj(int curAdj) {
        mCurAdj = curAdj;
    }

    int getCurrentAdj() {
        return mCurAdj;
    }
@@ -535,18 +529,10 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
        return mHasClientActivities;
    }

    public void setHasTopUi(boolean hasTopUi) {
        mHasTopUi = hasTopUi;
    }

    boolean hasTopUi() {
        return mHasTopUi;
    }

    public void setHasOverlayUi(boolean hasOverlayUi) {
        mHasOverlayUi = hasOverlayUi;
    }

    boolean hasOverlayUi() {
        return mHasOverlayUi;
    }
@@ -577,26 +563,14 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
        mAtm.mH.sendMessage(m);
    }

    public void setInteractionEventTime(long interactionEventTime) {
        mInteractionEventTime = interactionEventTime;
    }

    long getInteractionEventTime() {
        return mInteractionEventTime;
    }

    public void setFgInteractionTime(long fgInteractionTime) {
        mFgInteractionTime = fgInteractionTime;
    }

    long getFgInteractionTime() {
        return mFgInteractionTime;
    }

    public void setWhenUnimportant(long whenUnimportant) {
        mWhenUnimportant = whenUnimportant;
    }

    long getWhenUnimportant() {
        return mWhenUnimportant;
    }
@@ -774,10 +748,6 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
        return mInstrumentationSourceUid;
    }

    public void setPerceptible(boolean perceptible) {
        mPerceptible = perceptible;
    }

    boolean isPerceptible() {
        return mPerceptible;
    }
@@ -2004,6 +1974,56 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
        }
    }

    @Override
    public void onCurRawAdjChanged(int curRawAdj) {
        mPerceptible = (curRawAdj <= PERCEPTIBLE_APP_ADJ);
    }

    @Override
    public void onCurAdjChanged(int curAdj) {
        mCurAdj = curAdj;
    }

    @Override
    public void onCurrentSchedulingGroupChanged(int curSchedGroup) {
        mCurSchedGroup = curSchedGroup;
    }

    @Override
    public void onCurProcStateChanged(int curProcState) {
        mCurProcState = curProcState;
    }

    @Override
    public void onReportedProcStateChanged(int repProcState) {
        setReportedProcState(repProcState);
    }

    @Override
    public void onHasTopUiChanged(boolean hasTopUi) {
        mHasTopUi = hasTopUi;
    }

    @Override
    public void onHasOverlayUiChanged(boolean hasOverlayUi) {
        mHasOverlayUi = hasOverlayUi;
    }

    @Override
    public void onInteractionEventTimeChanged(long interactionEventTime) {
        mInteractionEventTime = interactionEventTime;
    }

    @Override
    public void onFgInteractionTimeChanged(long fgInteractionTime) {
        mFgInteractionTime = fgInteractionTime;
    }

    @Override
    public void onWhenUnimportantChanged(long whenUnimportant) {
        mWhenUnimportant = whenUnimportant;
    }

    /** Returns {@code true} if the process prefers to use fifo scheduling. */
    public boolean useFifoUiScheduling() {
        return mUseFifoUiScheduling;