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

Commit ed64b9cd authored by Lee Shombert's avatar Lee Shombert
Browse files

Refactor DisplayManagerService

This is a do-no-harm refactor of DisplayManagerService in preparation
for a change that defers sending display events to frozen processes.

This change also ports the CTS DisplayEventTest to a similarly-named
unit test.

Flag: EXEMPT refactor
Test: atest
 * CtsDisplayTestCases
 * DisplayEventTest
Bug: 326315985
Change-Id: I60ac877235939342300a851465220027f07a04b9
parent a776451e
Loading
Loading
Loading
Loading
+55 −28
Original line number Diff line number Diff line
@@ -269,6 +269,7 @@ public final class DisplayManagerService extends SystemService {

    private final Context mContext;
    private final DisplayManagerHandler mHandler;
    private final HandlerExecutor mHandlerExecutor;
    private final Handler mUiHandler;
    private final DisplayModeDirector mDisplayModeDirector;
    private final ExternalDisplayPolicy mExternalDisplayPolicy;
@@ -315,6 +316,7 @@ public final class DisplayManagerService extends SystemService {
    public boolean mSafeMode;

    // All callback records indexed by calling process id.
    @GuardedBy("mSyncRoot")
    private final SparseArray<CallbackRecord> mCallbacks = new SparseArray<>();

    /**
@@ -602,6 +604,7 @@ public final class DisplayManagerService extends SystemService {
        mContext = context;
        mFlags = injector.getFlags();
        mHandler = new DisplayManagerHandler(displayThreadLooper);
        mHandlerExecutor = new HandlerExecutor(mHandler);
        mUiHandler = UiThread.getHandler();
        mDisplayDeviceRepo = new DisplayDeviceRepository(mSyncRoot, mPersistentDataStore);
        mLogicalDisplayMapper = new LogicalDisplayMapper(mContext,
@@ -760,12 +763,13 @@ public final class DisplayManagerService extends SystemService {
            mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
            mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
            mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);

            ActivityManager activityManager = mContext.getSystemService(ActivityManager.class);
            activityManager.addOnUidImportanceListener(mUidImportanceListener, IMPORTANCE_CACHED);

            mDeviceStateManager = LocalServices.getService(DeviceStateManagerInternal.class);
            mContext.getSystemService(DeviceStateManager.class).registerCallback(
                    new HandlerExecutor(mHandler), new DeviceStateListener());
                    mHandlerExecutor, new DeviceStateListener());

            mLogicalDisplayMapper.onWindowManagerReady();
            scheduleTraversalLocked(false);
@@ -1019,6 +1023,10 @@ public final class DisplayManagerService extends SystemService {
    private class UidImportanceListener implements ActivityManager.OnUidImportanceListener {
        @Override
        public void onUidImportance(int uid, int importance) {
          onUidImportanceInternal(uid, importance);
        }

        private void onUidImportanceInternal(int uid, int importance) {
            synchronized (mPendingCallbackSelfLocked) {
                if (importance >= IMPORTANCE_GONE) {
                    // Clean up as the app is already gone
@@ -3232,6 +3240,12 @@ public final class DisplayManagerService extends SystemService {
        // After releasing the lock, send the notifications out.
        for (int i = 0; i < mTempCallbacks.size(); i++) {
            CallbackRecord callbackRecord = mTempCallbacks.get(i);
            deliverEventInternal(callbackRecord, displayId, event);
        }
        mTempCallbacks.clear();
    }

    private void deliverEventInternal(CallbackRecord callbackRecord, int displayId, int event) {
        final int uid = callbackRecord.mUid;
        final int pid = callbackRecord.mPid;
        if (isUidCached(uid)) {
@@ -3259,8 +3273,6 @@ public final class DisplayManagerService extends SystemService {
            callbackRecord.notifyDisplayEventAsync(displayId, event);
        }
    }
        mTempCallbacks.clear();
    }

    private boolean extraLogging(String packageName) {
        return mExtraDisplayEventLogging && mExtraDisplayLoggingPackageName.equals(packageName);
@@ -3764,7 +3776,7 @@ public final class DisplayManagerService extends SystemService {

        public boolean mWifiDisplayScanRequested;

        CallbackRecord(int pid, int uid, IDisplayManagerCallback callback,
        CallbackRecord(int pid, int uid, @NonNull IDisplayManagerCallback callback,
                @EventsMask long eventsMask) {
            mPid = pid;
            mUid = uid;
@@ -3792,7 +3804,9 @@ public final class DisplayManagerService extends SystemService {
        }

        /**
         * @return {@code false} if RemoteException happens; otherwise {@code true} for success.
         * @return {@code false} if RemoteException happens; otherwise {@code true} for
         * success.  This returns true even if the event was deferred because the remote client is
         * cached.
         */
        public boolean notifyDisplayEventAsync(int displayId, @DisplayEvent int event) {
            if (!shouldSendEvent(event)) {
@@ -3805,9 +3819,19 @@ public final class DisplayManagerService extends SystemService {
                            "notifyDisplayEventAsync#notSendingEvent=" + event + ",mEventsMask="
                                    + mEventsMask);
                }
                // The client is not interested in this event, so do nothing.
                return true;
            }

            return transmitDisplayEvent(displayId, event);
        }

        /**
         * Transmit a single display event.  The client is presumed ready.  Return true on success
         * and false if the client died.
         */
        private boolean transmitDisplayEvent(int displayId, @DisplayEvent int event) {
            // The client is ready to receive the event.
            try {
                mCallback.onDisplayEvent(displayId, event);
                return true;
@@ -3819,6 +3843,9 @@ public final class DisplayManagerService extends SystemService {
            }
        }

        /**
         * Return true if the client is interested in this event.
         */
        private boolean shouldSendEvent(@DisplayEvent int event) {
            final long mask = mEventsMask.get();
            switch (event) {
+4 −0
Original line number Diff line number Diff line
@@ -64,6 +64,7 @@ import static org.mockito.Mockito.when;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManagerInternal;
import android.app.ActivityOptions.LaunchCookie;
import android.app.PropertyInvalidatedCache;
import android.companion.virtual.IVirtualDevice;
@@ -358,6 +359,7 @@ public class DisplayManagerServiceTest {
    @Mock DisplayDeviceConfig mMockDisplayDeviceConfig;
    @Mock PackageManagerInternal mMockPackageManagerInternal;
    @Mock DisplayManagerInternal mMockDisplayManagerInternal;
    @Mock ActivityManagerInternal mMockActivityManagerInternal;
    @Mock DisplayAdapter mMockDisplayAdapter;

    @Captor ArgumentCaptor<ContentRecordingSession> mContentRecordingSessionCaptor;
@@ -388,6 +390,8 @@ public class DisplayManagerServiceTest {
                PackageManagerInternal.class, mMockPackageManagerInternal);
        mLocalServiceKeeperRule.overrideLocalService(
                DisplayManagerInternal.class, mMockDisplayManagerInternal);
        mLocalServiceKeeperRule.overrideLocalService(
                ActivityManagerInternal.class, mMockActivityManagerInternal);
        Display display = mock(Display.class);
        when(display.getDisplayAdjustments()).thenReturn(new DisplayAdjustments());
        when(display.getBrightnessInfo()).thenReturn(mock(BrightnessInfo.class));