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

Commit ee890b38 authored by Rupesh Bansal's avatar Rupesh Bansal
Browse files

Added API to register DisplayListener with EventMask

This change does a bunch of things
1. Introduces a new IntDef PrivateEventFlag for clients to subscribe to
   hidden properties
2. Introduces InternalEventFlag, which unifies both public and private
   event flags to a single mapping
3. Adds a new hidden API registerDisplayListener which takes in both public and
   private event masks.

Bug: 372700957
Test: atest com.android.server.display
Flag: EXEMPT Refactoring
Change-Id: I79e85fb1c82aab8da53a2379e79e13a3fc034489
parent 49abbf0d
Loading
Loading
Loading
Loading
+49 −10
Original line number Diff line number Diff line
@@ -575,13 +575,21 @@ public final class DisplayManager {
            EVENT_FLAG_DISPLAY_ADDED,
            EVENT_FLAG_DISPLAY_CHANGED,
            EVENT_FLAG_DISPLAY_REMOVED,
            EVENT_FLAG_DISPLAY_BRIGHTNESS,
            EVENT_FLAG_HDR_SDR_RATIO_CHANGED,
            EVENT_FLAG_DISPLAY_CONNECTION_CHANGED,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface EventFlag {}

    /**
     * @hide
     */
    @LongDef(flag = true, prefix = {"PRIVATE_EVENT_FLAG_"}, value = {
            PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS,
            PRIVATE_EVENT_FLAG_HDR_SDR_RATIO_CHANGED,
            PRIVATE_EVENT_FLAG_DISPLAY_CONNECTION_CHANGED,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface PrivateEventFlag {}

    /**
     * Event type for when a new display is added.
     *
@@ -618,7 +626,7 @@ public final class DisplayManager {
     *
     * @hide
     */
    public static final long EVENT_FLAG_DISPLAY_BRIGHTNESS = 1L << 3;
    public static final long PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS = 1L << 0;

    /**
     * Event flag to register for a display's hdr/sdr ratio changes. This notification is sent
@@ -631,14 +639,16 @@ public final class DisplayManager {
     *
     * @hide
     */
    public static final long EVENT_FLAG_HDR_SDR_RATIO_CHANGED = 1L << 4;
    public static final long PRIVATE_EVENT_FLAG_HDR_SDR_RATIO_CHANGED = 1L << 1;

    /**
     * Event flag to register for a display's connection changed.
     *
     * @see #registerDisplayListener(DisplayListener, Handler, long)
     * @hide
     */
    public static final long EVENT_FLAG_DISPLAY_CONNECTION_CHANGED = 1L << 5;
    public static final long PRIVATE_EVENT_FLAG_DISPLAY_CONNECTION_CHANGED = 1L << 2;


    /** @hide */
    public DisplayManager(Context context) {
@@ -774,20 +784,49 @@ public final class DisplayManager {
     * @param listener The listener to register.
     * @param handler The handler on which the listener should be invoked, or null
     * if the listener should be invoked on the calling thread's looper.
     * @param eventFlagsMask A bitmask of the event types for which this listener is subscribed.
     * @param eventFlags A bitmask of the event types for which this listener is subscribed.
     *
     * @see #EVENT_FLAG_DISPLAY_ADDED
     * @see #EVENT_FLAG_DISPLAY_CHANGED
     * @see #EVENT_FLAG_DISPLAY_REMOVED
     * @see #registerDisplayListener(DisplayListener, Handler)
     * @see #unregisterDisplayListener
     *
     * @hide
     */
    public void registerDisplayListener(@NonNull DisplayListener listener,
            @Nullable Handler handler, @EventFlag long eventFlags) {
        mGlobal.registerDisplayListener(listener, handler,
                mGlobal.mapFlagsToInternalEventFlag(eventFlags, 0),
                ActivityThread.currentPackageName());
    }

    /**
     * Registers a display listener to receive notifications about given display event types.
     *
     * @param listener The listener to register.
     * @param handler The handler on which the listener should be invoked, or null
     * if the listener should be invoked on the calling thread's looper.
     * @param eventFlags A bitmask of the event types for which this listener is subscribed.
     * @param privateEventFlags A bitmask of the private event types for which this listener
     *                          is subscribed.
     *
     * @see #EVENT_FLAG_DISPLAY_ADDED
     * @see #EVENT_FLAG_DISPLAY_CHANGED
     * @see #EVENT_FLAG_DISPLAY_REMOVED
     * @see #EVENT_FLAG_DISPLAY_BRIGHTNESS
     * @see #PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS
     * @see #PRIVATE_EVENT_FLAG_DISPLAY_CONNECTION_CHANGED
     * @see #PRIVATE_EVENT_FLAG_HDR_SDR_RATIO_CHANGED
     * @see #registerDisplayListener(DisplayListener, Handler)
     * @see #unregisterDisplayListener
     *
     * @hide
     */
    public void registerDisplayListener(@NonNull DisplayListener listener,
            @Nullable Handler handler, @EventFlag long eventFlagsMask) {
        mGlobal.registerDisplayListener(listener, handler, eventFlagsMask,
            @Nullable Handler handler, @EventFlag long eventFlags,
            @PrivateEventFlag long privateEventFlags) {
        mGlobal.registerDisplayListener(listener, handler,
                mGlobal.mapFlagsToInternalEventFlag(eventFlags, privateEventFlags),
                ActivityThread.currentPackageName());
    }

+116 −42
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import android.Manifest;
import android.annotation.FlaggedApi;
import android.annotation.FloatRange;
import android.annotation.IntDef;
import android.annotation.LongDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
@@ -118,6 +119,24 @@ public final class DisplayManagerGlobal {
    public static final int EVENT_DISPLAY_CONNECTED = 6;
    public static final int EVENT_DISPLAY_DISCONNECTED = 7;

    @LongDef(prefix = {"INTERNAL_EVENT_DISPLAY"}, flag = true, value = {
            INTERNAL_EVENT_FLAG_DISPLAY_ADDED,
            INTERNAL_EVENT_FLAG_DISPLAY_CHANGED,
            INTERNAL_EVENT_FLAG_DISPLAY_REMOVED,
            INTERNAL_EVENT_FLAG_DISPLAY_BRIGHTNESS_CHANGED,
            INTERNAL_EVENT_FLAG_DISPLAY_HDR_SDR_RATIO_CHANGED,
            INTERNAL_EVENT_FLAG_DISPLAY_CONNECTION_CHANGED,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface InternalEventFlag {}

    public static final long INTERNAL_EVENT_FLAG_DISPLAY_ADDED = 1L << 0;
    public static final long INTERNAL_EVENT_FLAG_DISPLAY_CHANGED = 1L << 1;
    public static final long INTERNAL_EVENT_FLAG_DISPLAY_REMOVED = 1L << 2;
    public static final long INTERNAL_EVENT_FLAG_DISPLAY_BRIGHTNESS_CHANGED = 1L << 3;
    public static final long INTERNAL_EVENT_FLAG_DISPLAY_HDR_SDR_RATIO_CHANGED = 1L << 4;
    public static final long INTERNAL_EVENT_FLAG_DISPLAY_CONNECTION_CHANGED = 1L << 5;

    @UnsupportedAppUsage
    private static DisplayManagerGlobal sInstance;

@@ -130,7 +149,7 @@ public final class DisplayManagerGlobal {
    private final IDisplayManager mDm;

    private DisplayManagerCallback mCallback;
    private @EventFlag long mRegisteredEventFlagsMask = 0;
    private @InternalEventFlag long mRegisteredInternalEventFlag = 0;
    private final CopyOnWriteArrayList<DisplayListenerDelegate> mDisplayListeners =
            new CopyOnWriteArrayList<>();

@@ -346,11 +365,11 @@ public final class DisplayManagerGlobal {
     * @param packageName of the calling package.
     */
    public void registerDisplayListener(@NonNull DisplayListener listener,
            @Nullable Handler handler, @EventFlag long eventFlagsMask,
            @Nullable Handler handler, @InternalEventFlag long internalEventFlagsMask,
            String packageName) {
        Looper looper = getLooperForHandler(handler);
        Handler springBoard = new Handler(looper);
        registerDisplayListener(listener, new HandlerExecutor(springBoard), eventFlagsMask,
        registerDisplayListener(listener, new HandlerExecutor(springBoard), internalEventFlagsMask,
                packageName);
    }

@@ -359,32 +378,34 @@ public final class DisplayManagerGlobal {
     *
     * @param listener The listener that will be called when display changes occur.
     * @param executor Executor for the thread that will be receiving the callbacks. Cannot be null.
     * @param eventFlagsMask Flag of events to be listened to.
     * @param internalEventFlagsMask Mask of events to be listened to.
     * @param packageName of the calling package.
     */
    public void registerDisplayListener(@NonNull DisplayListener listener,
            @NonNull Executor executor, @EventFlag long eventFlagsMask, String packageName) {
            @NonNull Executor executor, @InternalEventFlag long internalEventFlagsMask,
            String packageName) {
        if (listener == null) {
            throw new IllegalArgumentException("listener must not be null");
        }

        if (eventFlagsMask == 0) {
        if (internalEventFlagsMask == 0) {
            throw new IllegalArgumentException("The set of events to listen to must not be empty.");
        }

        if (extraLogging()) {
            Slog.i(TAG, "Registering Display Listener: "
                    + Long.toBinaryString(eventFlagsMask) + ", packageName: " + packageName);
                    + Long.toBinaryString(internalEventFlagsMask)
                    + ", packageName: " + packageName);
        }

        synchronized (mLock) {
            int index = findDisplayListenerLocked(listener);
            if (index < 0) {
                mDisplayListeners.add(new DisplayListenerDelegate(listener, executor,
                        eventFlagsMask, packageName));
                        internalEventFlagsMask, packageName));
                registerCallbackIfNeededLocked();
            } else {
                mDisplayListeners.get(index).setEventFlagsMask(eventFlagsMask);
                mDisplayListeners.get(index).setEventsMask(internalEventFlagsMask);
            }
            updateCallbackIfNeededLocked();
            maybeLogAllDisplayListeners();
@@ -456,17 +477,17 @@ public final class DisplayManagerGlobal {
        return -1;
    }

    @EventFlag
    private int calculateEventFlagsMaskLocked() {
        int mask = 0;
    @InternalEventFlag
    private long calculateEventsMaskLocked() {
        long mask = 0;
        final int numListeners = mDisplayListeners.size();
        for (int i = 0; i < numListeners; i++) {
            mask |= mDisplayListeners.get(i).mEventFlagsMask;
            mask |= mDisplayListeners.get(i).mInternalEventFlagsMask;
        }
        if (mDispatchNativeCallbacks) {
            mask |= DisplayManager.EVENT_FLAG_DISPLAY_ADDED
                    | DisplayManager.EVENT_FLAG_DISPLAY_CHANGED
                    | DisplayManager.EVENT_FLAG_DISPLAY_REMOVED;
            mask |= INTERNAL_EVENT_FLAG_DISPLAY_ADDED
                    | INTERNAL_EVENT_FLAG_DISPLAY_CHANGED
                    | INTERNAL_EVENT_FLAG_DISPLAY_REMOVED;
        }
        return mask;
    }
@@ -479,14 +500,14 @@ public final class DisplayManagerGlobal {
    }

    private void updateCallbackIfNeededLocked() {
        int mask = calculateEventFlagsMaskLocked();
        long mask = calculateEventsMaskLocked();
        if (DEBUG) {
            Log.d(TAG, "Flag for listener: " + mask);
            Log.d(TAG, "Mask for listener: " + mask);
        }
        if (mask != mRegisteredEventFlagsMask) {
        if (mask != mRegisteredInternalEventFlag) {
            try {
                mDm.registerCallbackWithEventMask(mCallback, mask);
                mRegisteredEventFlagsMask = mask;
                mRegisteredInternalEventFlag = mask;
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
@@ -1268,8 +1289,8 @@ public final class DisplayManagerGlobal {
        @Override
        public void onDisplayEvent(int displayId, @DisplayEvent int event) {
            if (DEBUG) {
                Log.d(TAG, "onDisplayEvent: displayId=" + displayId + ", event=" + eventToString(
                        event));
                Log.d(TAG, "onDisplayEvent: displayId=" + displayId + ", event="
                        + eventToString(event));
            }
            handleDisplayEvent(displayId, event, false /* forceUpdate */);
        }
@@ -1277,7 +1298,7 @@ public final class DisplayManagerGlobal {

    private static final class DisplayListenerDelegate {
        public final DisplayListener mListener;
        public volatile long mEventFlagsMask;
        public volatile long mInternalEventFlagsMask;

        private final DisplayInfo mDisplayInfo = new DisplayInfo();
        private final Executor mExecutor;
@@ -1285,10 +1306,10 @@ public final class DisplayManagerGlobal {
        private final String mPackageName;

        DisplayListenerDelegate(DisplayListener listener, @NonNull Executor executor,
                @EventFlag long eventFlag, String packageName) {
                @InternalEventFlag long internalEventFlag, String packageName) {
            mExecutor = executor;
            mListener = listener;
            mEventFlagsMask = eventFlag;
            mInternalEventFlagsMask = internalEventFlag;
            mPackageName = packageName;
        }

@@ -1310,16 +1331,16 @@ public final class DisplayManagerGlobal {
            mGenerationId.incrementAndGet();
        }

        void setEventFlagsMask(@EventFlag long newEventsFlag) {
            mEventFlagsMask = newEventsFlag;
        void setEventsMask(@InternalEventFlag long newInternalEventFlagsMask) {
            mInternalEventFlagsMask = newInternalEventFlagsMask;
        }

        private void handleDisplayEventInner(int displayId, @DisplayEvent int eventFlagsMask,
        private void handleDisplayEventInner(int displayId, @DisplayEvent int event,
                @Nullable DisplayInfo info, boolean forceUpdate) {
            if (extraLogging()) {
                Slog.i(TAG, "DLD(" + eventToString(eventFlagsMask)
                Slog.i(TAG, "DLD(" + eventToString(event)
                        + ", display=" + displayId
                        + ", mEventsFlagMask=" + Long.toBinaryString(mEventFlagsMask)
                        + ", mEventsMask=" + Long.toBinaryString(mInternalEventFlagsMask)
                        + ", mPackageName=" + mPackageName
                        + ", displayInfo=" + info
                        + ", listener=" + mListener.getClass() + ")");
@@ -1327,18 +1348,19 @@ public final class DisplayManagerGlobal {
            if (DEBUG) {
                Trace.beginSection(
                        TextUtils.trimToSize(
                                "DLD(" + eventToString(eventFlagsMask)
                                "DLD(" + eventToString(event)
                                + ", display=" + displayId
                                + ", listener=" + mListener.getClass() + ")", 127));
            }
            switch (eventFlagsMask) {
            switch (event) {
                case EVENT_DISPLAY_ADDED:
                    if ((mEventFlagsMask & DisplayManager.EVENT_FLAG_DISPLAY_ADDED) != 0) {
                    if ((mInternalEventFlagsMask & INTERNAL_EVENT_FLAG_DISPLAY_ADDED) != 0) {
                        mListener.onDisplayAdded(displayId);
                    }
                    break;
                case EVENT_DISPLAY_CHANGED:
                    if ((mEventFlagsMask & DisplayManager.EVENT_FLAG_DISPLAY_CHANGED) != 0) {
                    if ((mInternalEventFlagsMask & INTERNAL_EVENT_FLAG_DISPLAY_CHANGED)
                            != 0) {
                        if (info != null && (forceUpdate || !info.equals(mDisplayInfo))) {
                            if (extraLogging()) {
                                Slog.i(TAG, "Sending onDisplayChanged: Display Changed. Info: "
@@ -1350,29 +1372,32 @@ public final class DisplayManagerGlobal {
                    }
                    break;
                case EVENT_DISPLAY_BRIGHTNESS_CHANGED:
                    if ((mEventFlagsMask & DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS) != 0) {
                    if ((mInternalEventFlagsMask
                            & INTERNAL_EVENT_FLAG_DISPLAY_BRIGHTNESS_CHANGED) != 0) {
                        mListener.onDisplayChanged(displayId);
                    }
                    break;
                case EVENT_DISPLAY_REMOVED:
                    if ((mEventFlagsMask & DisplayManager.EVENT_FLAG_DISPLAY_REMOVED) != 0) {
                    if ((mInternalEventFlagsMask & INTERNAL_EVENT_FLAG_DISPLAY_REMOVED)
                            != 0) {
                        mListener.onDisplayRemoved(displayId);
                    }
                    break;
                case EVENT_DISPLAY_HDR_SDR_RATIO_CHANGED:
                    if ((mEventFlagsMask & DisplayManager.EVENT_FLAG_HDR_SDR_RATIO_CHANGED) != 0) {
                    if ((mInternalEventFlagsMask
                            & INTERNAL_EVENT_FLAG_DISPLAY_HDR_SDR_RATIO_CHANGED) != 0) {
                        mListener.onDisplayChanged(displayId);
                    }
                    break;
                case EVENT_DISPLAY_CONNECTED:
                    if ((mEventFlagsMask & DisplayManager.EVENT_FLAG_DISPLAY_CONNECTION_CHANGED)
                            != 0) {
                    if ((mInternalEventFlagsMask
                            & INTERNAL_EVENT_FLAG_DISPLAY_CONNECTION_CHANGED) != 0) {
                        mListener.onDisplayConnected(displayId);
                    }
                    break;
                case EVENT_DISPLAY_DISCONNECTED:
                    if ((mEventFlagsMask & DisplayManager.EVENT_FLAG_DISPLAY_CONNECTION_CHANGED)
                            != 0) {
                    if ((mInternalEventFlagsMask
                            & INTERNAL_EVENT_FLAG_DISPLAY_CONNECTION_CHANGED) != 0) {
                        mListener.onDisplayDisconnected(displayId);
                    }
                    break;
@@ -1384,7 +1409,7 @@ public final class DisplayManagerGlobal {

        @Override
        public String toString() {
            return "mEventFlagsMask: {" + mEventFlagsMask + "}, for " + mListener.getClass();
            return "flag: {" + mInternalEventFlagsMask + "}, for " + mListener.getClass();
        }
    }

@@ -1525,4 +1550,53 @@ public final class DisplayManagerGlobal {
    private static boolean extraLogging() {
        return sExtraDisplayListenerLogging;
    }


    /**
     * Maps the supplied public and private event flags to a unified InternalEventFlag
     * @param eventFlags A bitmask of the event types for which this listener is subscribed.
     * @param privateEventFlags A bitmask of the private event types for which this listener
     *                          is subscribed.
     * @return returns the bitmask of both public and private event flags unified to
     * InternalEventFlag
     */
    public @InternalEventFlag long mapFlagsToInternalEventFlag(@EventFlag long eventFlags,
            @DisplayManager.PrivateEventFlag long privateEventFlags) {
        return mapPrivateEventFlags(privateEventFlags) | mapPublicEventFlags(eventFlags);
    }

    private long mapPrivateEventFlags(@DisplayManager.PrivateEventFlag long privateEventFlags) {
        long baseEventMask = 0;
        if ((privateEventFlags & DisplayManager.PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS) != 0) {
            baseEventMask |= INTERNAL_EVENT_FLAG_DISPLAY_BRIGHTNESS_CHANGED;
        }

        if ((privateEventFlags & DisplayManager.PRIVATE_EVENT_FLAG_HDR_SDR_RATIO_CHANGED) != 0) {
            baseEventMask |= INTERNAL_EVENT_FLAG_DISPLAY_HDR_SDR_RATIO_CHANGED;
        }

        if ((privateEventFlags
                & DisplayManager.PRIVATE_EVENT_FLAG_DISPLAY_CONNECTION_CHANGED) != 0) {
            baseEventMask |= INTERNAL_EVENT_FLAG_DISPLAY_CONNECTION_CHANGED;
        }
        return baseEventMask;
    }

    private long mapPublicEventFlags(@EventFlag long eventFlags) {
        long baseEventMask = 0;
        if ((eventFlags & DisplayManager.EVENT_FLAG_DISPLAY_ADDED) != 0) {
            baseEventMask |= INTERNAL_EVENT_FLAG_DISPLAY_ADDED;
        }

        if ((eventFlags & DisplayManager.EVENT_FLAG_DISPLAY_CHANGED) != 0) {
            baseEventMask |= INTERNAL_EVENT_FLAG_DISPLAY_CHANGED;
        }

        if ((eventFlags
                & DisplayManager.EVENT_FLAG_DISPLAY_REMOVED) != 0) {
            baseEventMask |= INTERNAL_EVENT_FLAG_DISPLAY_REMOVED;
        }

        return baseEventMask;
    }
}
+3 −2
Original line number Diff line number Diff line
@@ -1549,8 +1549,9 @@ public final class Display {
            // Although we only care about the HDR/SDR ratio changing, that can also come in the
            // form of the larger DISPLAY_CHANGED event
            mGlobal.registerDisplayListener(toRegister, executor,
                    DisplayManager.EVENT_FLAG_HDR_SDR_RATIO_CHANGED
                            | DisplayManagerGlobal.EVENT_DISPLAY_CHANGED,
                    DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_CHANGED
                            | DisplayManagerGlobal
                                    .INTERNAL_EVENT_FLAG_DISPLAY_HDR_SDR_RATIO_CHANGED,
                    ActivityThread.currentPackageName());
        }

+3 −4
Original line number Diff line number Diff line
@@ -185,7 +185,6 @@ import android.graphics.RenderNode;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.hardware.SyncFence;
import android.hardware.display.DisplayManager;
import android.hardware.display.DisplayManager.DisplayListener;
import android.hardware.display.DisplayManagerGlobal;
import android.hardware.input.InputManagerGlobal;
@@ -1816,9 +1815,9 @@ public final class ViewRootImpl implements ViewParent,
                .registerDisplayListener(
                        mDisplayListener,
                        mHandler,
                        DisplayManager.EVENT_FLAG_DISPLAY_ADDED
                        | DisplayManager.EVENT_FLAG_DISPLAY_CHANGED
                        | DisplayManager.EVENT_FLAG_DISPLAY_REMOVED,
                        DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_ADDED
                        | DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_CHANGED
                        | DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_REMOVED,
                        mBasePackageName);
        if (forceInvertColor()) {
+2 −2
Original line number Diff line number Diff line
@@ -600,8 +600,8 @@ public class BrightnessSynchronizer {
            final ContentResolver cr = mContext.getContentResolver();
            cr.registerContentObserver(BRIGHTNESS_URI, false,
                    createBrightnessContentObserver(handler), UserHandle.USER_ALL);
            mDisplayManager.registerDisplayListener(mListener, handler,
                    DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS);
            mDisplayManager.registerDisplayListener(mListener, handler, /* eventFlags */ 0,
                    DisplayManager.PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS);
            mIsObserving = true;
        }
    }
Loading