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

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

am: Refactor ActiveUids state observation

ActiveUids now uses a generic `Observer` interface to notify about
UID active/inactive state changes. ActivityManagerService sets its
ActivityTaskManagerInternal instance as this observer.

This change decouples ActiveUids from a direct dependency on
ActivityManagerService and its internal components, improving
modularity and clarity of the notification flow.

Bug: 425766486
Test: m services.core
Test: atest MockingOomAdjusterTests OomAdjusterTests
Test: FrameworksServicesTestsRavenwood_ProcessStateController
Flag: EXEMPT pure refactor

Change-Id: I0ae990a9d459dd79306cd5273ba54460561b9a95
parent 6efe8db1
Loading
Loading
Loading
Loading
+34 −33
Original line number Diff line number Diff line
@@ -21,77 +21,78 @@ import android.os.UserHandle;
import android.util.SparseArray;
import android.util.proto.ProtoOutputStream;

import com.android.internal.annotations.CompositeRWLock;
import com.android.internal.annotations.GuardedBy;

import java.io.PrintWriter;

/** Class for tracking active uids for running processes. */
final class ActiveUids {

    private final ActivityManagerService mService;
    private final ActivityManagerGlobalLock mProcLock;
/**
 * Class for tracking active uids for running processes.
 * Note: This class is not thread-safe, caller should handle the synchronization.
 *
 * TODO(b/425766486): Maybe rename it to "UidRecordMap", so we can reuse it for other purposes than
 *   "active" UIDs.
 */
public final class ActiveUids {
    /**
     * Interface for observing changes in UID active/inactive states based on state changes of
     * processes running for that UID.
     */
    public interface Observer {
        /**
         * Called when a UID becomes active.
         * @param uid The UID that became active.
         * @param procState The current process state of the UID.
         */
        void onUidActive(int uid, int procState);

    private final boolean mPostChangesToAtm;
        /**
         * Called when a UID becomes inactive.
         * @param uid The UID that became inactive.
         */
        void onUidInactive(int uid);
    }

    @CompositeRWLock({"mService", "mProcLock"})
    private final Observer mObserver;
    private final SparseArray<UidRecord> mActiveUids = new SparseArray<>();

    ActiveUids(ActivityManagerService service, boolean postChangesToAtm) {
        mService = service;
        mProcLock = service != null ? service.mProcLock : null;
        mPostChangesToAtm = postChangesToAtm;
    ActiveUids(Observer observer) {
        mObserver = observer;
    }

    @GuardedBy({"mService", "mProcLock"})
    void put(int uid, UidRecord value) {
        mActiveUids.put(uid, value);
        if (mPostChangesToAtm) {
            mService.mAtmInternal.onUidActive(uid, value.getCurProcState());
        if (mObserver != null) {
            mObserver.onUidActive(uid, value.getCurProcState());
        }
    }

    @GuardedBy({"mService", "mProcLock"})
    void remove(int uid) {
        mActiveUids.remove(uid);
        if (mPostChangesToAtm) {
            mService.mAtmInternal.onUidInactive(uid);
        if (mObserver != null) {
            mObserver.onUidInactive(uid);
        }
    }

    @GuardedBy({"mService", "mProcLock"})
    void clear() {
        mActiveUids.clear();
        // It is only called for a temporal container with mPostChangesToAtm == false or test case.
        // It is only called for a temporal container with mObserver == null or test case.
        // So there is no need to notify activity task manager.
    }

    @GuardedBy(anyOf = {"mService", "mProcLock"})
    UidRecord get(int uid) {
        return mActiveUids.get(uid);
    }

    @GuardedBy(anyOf = {"mService", "mProcLock"})
    int size() {
        return mActiveUids.size();
    }

    @GuardedBy(anyOf = {"mService", "mProcLock"})
    UidRecord valueAt(int index) {
        return mActiveUids.valueAt(index);
    }

    @GuardedBy(anyOf = {"mService", "mProcLock"})
    int keyAt(int index) {
        return mActiveUids.keyAt(index);
    }

    @GuardedBy(anyOf = {"mService", "mProcLock"})
    int indexOfKey(int uid) {
        return mActiveUids.indexOfKey(uid);
    }

    @GuardedBy(anyOf = {"mService", "mProcLock"})
    boolean dump(final PrintWriter pw, String dumpPackage, int dumpAppId,
            String header, boolean needSep) {
        boolean printed = false;
+3 −4
Original line number Diff line number Diff line
@@ -2415,7 +2415,7 @@ public class ActivityManagerService extends IActivityManager.Stub
        mHandler = new MainHandler(handlerThread.getLooper());
        mHandlerThread = handlerThread;
        mConstants = new ActivityManagerConstants(mContext, this, mHandler);
        final ActiveUids activeUids = new ActiveUids(this, false /* postChangesToAtm */);
        final ActiveUids activeUids = new ActiveUids(null);
        mPlatformCompat = null;
        mProcessList = injector.getProcessList(this);
        mProcessList.init(this, activeUids, mPlatformCompat);
@@ -2479,7 +2479,8 @@ public class ActivityManagerService extends IActivityManager.Stub
        mProcStartHandler = new ProcStartHandler(this, mProcStartHandlerThread.getLooper());
        mConstants = new ActivityManagerConstants(mContext, this, mHandler);
        final ActiveUids activeUids = new ActiveUids(this, true /* postChangesToAtm */);
        mAtmInternal = LocalServices.getService(ActivityTaskManagerInternal.class);
        final ActiveUids activeUids = new ActiveUids(mAtmInternal);
        mPlatformCompat = (PlatformCompat) ServiceManager.getService(
                Context.PLATFORM_COMPAT_SERVICE);
        mProcessList = mInjector.getProcessList(this);
@@ -2534,8 +2535,6 @@ public class ActivityManagerService extends IActivityManager.Stub
        mActivityTaskManager = atm;
        mActivityTaskManager.initialize(mIntentFirewall, mPendingIntentController,
                mProcessStateController, activityTaskLooper);
        mAtmInternal = LocalServices.getService(ActivityTaskManagerInternal.class);
        mHiddenApiBlacklist = new HiddenApiSettings(mHandler, mContext);
        Watchdog.getInstance().addMonitor(this);
+1 −1
Original line number Diff line number Diff line
@@ -507,7 +507,7 @@ public abstract class OomAdjuster {
            mService.mPhantomProcessList.setProcessGroupForPhantomProcessOfApp(app, group);
            return true;
        });
        mTmpUidRecords = new ActiveUids(service, false);
        mTmpUidRecords = new ActiveUids(null);
        mTmpQueue = new ArrayDeque<ProcessRecord>(mConstants.CUR_MAX_CACHED_PROCESSES << 1);
        mNumSlots = ((CACHED_APP_MAX_ADJ - CACHED_APP_MIN_ADJ + 1) >> 1)
                / CACHED_APP_IMPORTANCE_LEVELS;
+1 −1
Original line number Diff line number Diff line
@@ -83,7 +83,7 @@ public class UidObserverController {

    UidObserverController(@NonNull Handler handler) {
        mHandler = handler;
        mValidateUids = new ActiveUids(null /* service */, false /* postChangesToAtm */);
        mValidateUids = new ActiveUids(null);
    }

    IBinder register(@NonNull IUidObserver observer, int which, int cutpoint,
+2 −3
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@ import android.window.TaskSnapshot;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.IVoiceInteractor;
import com.android.server.am.ActiveUids;
import com.android.server.am.PendingIntentRecord;
import com.android.server.am.UserState;

@@ -57,7 +58,7 @@ import java.util.Set;
 * Activity Task manager local system service interface.
 * @hide Only for use within system server
 */
public abstract class ActivityTaskManagerInternal {
public abstract class ActivityTaskManagerInternal implements ActiveUids.Observer {

    /**
     * Type for {@link #notifyAppTransitionStarting}: The transition was started because we drew
@@ -557,8 +558,6 @@ public abstract class ActivityTaskManagerInternal {
    public abstract int finishTopCrashedActivities(
            WindowProcessController crashedApp, String reason);

    public abstract void onUidActive(int uid, int procState);
    public abstract void onUidInactive(int uid);
    public abstract void onUidProcStateChanged(int uid, int procState);

    /** Handle app crash event in {@link android.app.IActivityController} if there is one. */
Loading