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

Commit 16a89ea8 authored by Sean Stout's avatar Sean Stout Committed by Android (Google) Code Review
Browse files

Merge "Send events when DisplayGroups are added/modified/removed" into sc-dev

parents a1a18aa7 ee31f857
Loading
Loading
Loading
Loading
+25 −7
Original line number Diff line number Diff line
@@ -47,20 +47,22 @@ public abstract class DisplayManagerInternal {
     * begins adjusting the power state to match what was requested.
     * </p>
     *
     * @param groupId The identifier for the display group being requested to change power state
     * @param request The requested power state.
     * @param waitForNegativeProximity If true, issues a request to wait for
     * @param waitForNegativeProximity If {@code true}, issues a request to wait for
     * negative proximity before turning the screen back on, assuming the screen
     * was turned off by the proximity sensor.
     * @return True if display is ready, false if there are important changes that must
     * be made asynchronously (such as turning the screen on), in which case the caller
     * should grab a wake lock, watch for {@link DisplayPowerCallbacks#onStateChanged()}
     * then try the request again later until the state converges.
     * @return {@code true} if display group is ready, {@code false} if there are important
     * changes that must be made asynchronously (such as turning the screen on), in which case
     * the caller should grab a wake lock, watch for {@link DisplayPowerCallbacks#onStateChanged}
     * then try the request again later until the state converges. If the provided {@code groupId}
     * cannot be found then {@code true} will be returned.
     */
    public abstract boolean requestPowerState(DisplayPowerRequest request,
    public abstract boolean requestPowerState(int groupId, DisplayPowerRequest request,
            boolean waitForNegativeProximity);

    /**
     * Returns true if the proximity sensor screen-off function is available.
     * Returns {@code true} if the proximity sensor screen-off function is available.
     */
    public abstract boolean isProximitySensorAvailable();

@@ -70,6 +72,22 @@ public abstract class DisplayManagerInternal {
     */
    public abstract int getDisplayGroupId(int displayId);

    /**
     * Registers a display group listener which will be informed of the addition, removal, or change
     * of display groups.
     *
     * @param listener The listener to register.
     */
    public abstract void registerDisplayGroupListener(DisplayGroupListener listener);

    /**
     * Unregisters a display group listener which will be informed of the addition, removal, or
     * change of display groups.
     *
     * @param listener The listener to unregister.
     */
    public abstract void unregisterDisplayGroupListener(DisplayGroupListener listener);

    /**
     * Screenshot for internal system-only use such as rotation, etc.  This method includes
     * secure layers and the result should never be exposed to non-system applications.
+31 −3
Original line number Diff line number Diff line
@@ -21,7 +21,8 @@ import java.util.List;

/**
 * Represents a collection of {@link LogicalDisplay}s which act in unison for certain behaviors and
 * operations.
 * operations; particularly display-state.
 *
 * @hide
 */
public class DisplayGroup {
@@ -33,17 +34,44 @@ public class DisplayGroup {
        mGroupId = groupId;
    }

    /** Returns the identifier for the Group. */
    int getGroupId() {
        return mGroupId;
    }

    void addDisplay(LogicalDisplay display) {
    /**
     * Adds the provided {@code display} to the Group
     *
     * @param display the {@link LogicalDisplay} to add to the Group
     */
    void addDisplayLocked(LogicalDisplay display) {
        if (!mDisplays.contains(display)) {
            mDisplays.add(display);
        }
    }

    boolean removeDisplay(LogicalDisplay display) {
    /**
     * Removes the provided {@code display} from the Group.
     *
     * @param display The {@link LogicalDisplay} to remove from the Group.
     * @return {@code true} if the {@code display} was removed; otherwise {@code false}
     */
    boolean removeDisplayLocked(LogicalDisplay display) {
        return mDisplays.remove(display);
    }

    /** Returns {@code true} if there are no {@link LogicalDisplay LogicalDisplays} in the Group. */
    boolean isEmptyLocked() {
        return mDisplays.isEmpty();
    }

    /** Returns the number of {@link LogicalDisplay LogicalDisplays} in the Group. */
    int getSizeLocked() {
        return mDisplays.size();
    }

    /** Returns the ID of the {@link LogicalDisplay} at the provided {@code index}. */
    int getIdLocked(int index) {
        return mDisplays.get(index).getDisplayIdLocked();
    }
}
+77 −3
Original line number Diff line number Diff line
@@ -57,6 +57,7 @@ import android.hardware.display.Curve;
import android.hardware.display.DisplayManager;
import android.hardware.display.DisplayManagerGlobal;
import android.hardware.display.DisplayManagerInternal;
import android.hardware.display.DisplayManagerInternal.DisplayGroupListener;
import android.hardware.display.DisplayManagerInternal.DisplayTransactionListener;
import android.hardware.display.DisplayViewport;
import android.hardware.display.DisplayedContentSample;
@@ -190,6 +191,7 @@ public final class DisplayManagerService extends SystemService {
    private static final int MSG_UPDATE_VIEWPORT = 5;
    private static final int MSG_LOAD_BRIGHTNESS_CONFIGURATION = 6;
    private static final int MSG_DELIVER_DISPLAY_EVENT_FRAME_RATE_OVERRIDE = 7;
    private static final int MSG_DELIVER_DISPLAY_GROUP_EVENT = 8;

    private final Context mContext;
    private final DisplayManagerHandler mHandler;
@@ -237,6 +239,10 @@ public final class DisplayManagerService extends SystemService {
    private final CopyOnWriteArrayList<DisplayTransactionListener> mDisplayTransactionListeners =
            new CopyOnWriteArrayList<DisplayTransactionListener>();

    /** List of all display group listeners. */
    private final CopyOnWriteArrayList<DisplayGroupListener> mDisplayGroupListeners =
            new CopyOnWriteArrayList<>();

    /** All {@link DisplayPowerController}s indexed by {@link LogicalDisplay} ID. */
    private final SparseArray<DisplayPowerController> mDisplayPowerControllers =
            new SparseArray<>();
@@ -1677,6 +1683,11 @@ public final class DisplayManagerService extends SystemService {
        mHandler.sendMessage(msg);
    }

    private void sendDisplayGroupEvent(int groupId, int event) {
        Message msg = mHandler.obtainMessage(MSG_DELIVER_DISPLAY_GROUP_EVENT, groupId, event);
        mHandler.sendMessage(msg);
    }

    private void sendDisplayEventFrameRateOverrideLocked(int displayId) {
        Message msg = mHandler.obtainMessage(MSG_DELIVER_DISPLAY_EVENT_FRAME_RATE_OVERRIDE,
                displayId, DisplayManagerGlobal.EVENT_DISPLAY_CHANGED);
@@ -1721,6 +1732,35 @@ public final class DisplayManagerService extends SystemService {
        mTempCallbacks.clear();
    }

    // Runs on Handler thread.
    // Delivers display group event notifications to callbacks.
    private void deliverDisplayGroupEvent(int groupId, int event) {
        if (DEBUG) {
            Slog.d(TAG, "Delivering display group event: groupId=" + groupId + ", event="
                    + event);
        }

        switch (event) {
            case LogicalDisplayMapper.DISPLAY_GROUP_EVENT_ADDED:
                for (DisplayGroupListener listener : mDisplayGroupListeners) {
                    listener.onDisplayGroupAdded(groupId);
                }
                break;

            case LogicalDisplayMapper.DISPLAY_GROUP_EVENT_CHANGED:
                for (DisplayGroupListener listener : mDisplayGroupListeners) {
                    listener.onDisplayGroupChanged(groupId);
                }
                break;

            case LogicalDisplayMapper.DISPLAY_GROUP_EVENT_REMOVED:
                for (DisplayGroupListener listener : mDisplayGroupListeners) {
                    listener.onDisplayGroupRemoved(groupId);
                }
                break;
        }
    }

    private IMediaProjectionManager getProjectionService() {
        if (mProjectionService == null) {
            IBinder b = ServiceManager.getService(Context.MEDIA_PROJECTION_SERVICE);
@@ -1943,6 +1983,11 @@ public final class DisplayManagerService extends SystemService {
                    }
                    deliverDisplayEvent(msg.arg1, uids, msg.arg2);
                    break;

                case MSG_DELIVER_DISPLAY_GROUP_EVENT:
                    deliverDisplayGroupEvent(msg.arg1, msg.arg2);
                    break;

            }
        }
    }
@@ -1973,6 +2018,11 @@ public final class DisplayManagerService extends SystemService {
            }
        }

        @Override
        public void onDisplayGroupEventLocked(int groupId, int event) {
            sendDisplayGroupEvent(groupId, event);
        }

        @Override
        public void onTraversalRequested() {
            synchronized (mSyncRoot) {
@@ -2708,11 +2758,25 @@ public final class DisplayManagerService extends SystemService {
        }

        @Override
        public boolean requestPowerState(DisplayPowerRequest request,
        public boolean requestPowerState(int groupId, DisplayPowerRequest request,
                boolean waitForNegativeProximity) {
            synchronized (mSyncRoot) {
                return mDisplayPowerControllers.get(Display.DEFAULT_DISPLAY)
                        .requestPowerState(request, waitForNegativeProximity);
                final DisplayGroup displayGroup = mLogicalDisplayMapper.getDisplayGroupLocked(
                        groupId);
                if (displayGroup == null) {
                    return true;
                }

                final int size = displayGroup.getSizeLocked();
                boolean ready = true;
                for (int i = 0; i < size; i++) {
                    final DisplayPowerController displayPowerController =
                            mDisplayPowerControllers.get(displayGroup.getIdLocked(i));
                    ready &= displayPowerController.requestPowerState(request,
                            waitForNegativeProximity);
                }

                return ready;
            }
        }

@@ -2731,6 +2795,16 @@ public final class DisplayManagerService extends SystemService {
            }
        }

        @Override
        public void registerDisplayGroupListener(DisplayGroupListener listener) {
            mDisplayGroupListeners.add(listener);
        }

        @Override
        public void unregisterDisplayGroupListener(DisplayGroupListener listener) {
            mDisplayGroupListeners.remove(listener);
        }

        @Override
        public SurfaceControl.ScreenshotHardwareBuffer systemScreenshot(int displayId) {
            return systemScreenshotInternal(displayId);
+67 −14
Original line number Diff line number Diff line
@@ -55,6 +55,10 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
    public static final int LOGICAL_DISPLAY_EVENT_SWAPPED = 4;
    public static final int LOGICAL_DISPLAY_EVENT_FRAME_RATE_OVERRIDES_CHANGED = 5;

    public static final int DISPLAY_GROUP_EVENT_ADDED = 1;
    public static final int DISPLAY_GROUP_EVENT_CHANGED = 2;
    public static final int DISPLAY_GROUP_EVENT_REMOVED = 3;

    /**
     * Temporary display info, used for comparing display configurations.
     */
@@ -99,7 +103,7 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
    private int mNextNonDefaultGroupId = Display.DEFAULT_DISPLAY_GROUP + 1;

    /** A mapping from logical display id to display group. */
    private final SparseArray<DisplayGroup> mDisplayGroups = new SparseArray<>();
    private final SparseArray<DisplayGroup> mDisplayIdToGroupMap = new SparseArray<>();

    private final DisplayDeviceRepository mDisplayDeviceRepo;
    private final Listener mListener;
@@ -183,7 +187,7 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
    }

    public int getDisplayGroupIdLocked(int displayId) {
        final DisplayGroup displayGroup = mDisplayGroups.get(displayId);
        final DisplayGroup displayGroup = mDisplayIdToGroupMap.get(displayId);
        if (displayGroup != null) {
            return displayGroup.getGroupId();
        }
@@ -191,6 +195,18 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
        return -1;
    }

    public DisplayGroup getDisplayGroupLocked(int groupId) {
        final int size = mDisplayIdToGroupMap.size();
        for (int i = 0; i < size; i++) {
            final DisplayGroup displayGroup = mDisplayIdToGroupMap.valueAt(i);
            if (displayGroup.getGroupId() == groupId) {
                return displayGroup;
            }
        }

        return null;
    }

    public void dumpLocked(PrintWriter pw) {
        pw.println("LogicalDisplayMapper:");
        IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ");
@@ -320,7 +336,7 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
            final int groupId = assignDisplayGroupIdLocked(isDefault);
            displayGroup = new DisplayGroup(groupId);
        } else {
            displayGroup = mDisplayGroups.get(Display.DEFAULT_DISPLAY);
            displayGroup = mDisplayIdToGroupMap.get(Display.DEFAULT_DISPLAY);
        }

        LogicalDisplay display = new LogicalDisplay(displayId, layerStack, device);
@@ -335,11 +351,23 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {

        mLogicalDisplays.put(displayId, display);

        displayGroup.addDisplay(display);
        mDisplayGroups.append(displayId, displayGroup);
        displayGroup.addDisplayLocked(display);
        mDisplayIdToGroupMap.append(displayId, displayGroup);

        if (addNewDisplayGroup) {
            // Group added events happen before Logical Display added events.
            mListener.onDisplayGroupEventLocked(displayGroup.getGroupId(),
                    LogicalDisplayMapper.DISPLAY_GROUP_EVENT_ADDED);
        }

        mListener.onLogicalDisplayEventLocked(display,
                LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_ADDED);

        if (!addNewDisplayGroup) {
            // Group changed events happen after Logical Display added events.
            mListener.onDisplayGroupEventLocked(displayGroup.getGroupId(),
                    LogicalDisplayMapper.DISPLAY_GROUP_EVENT_CHANGED);
        }
    }

    /**
@@ -356,33 +384,47 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
            DisplayEventReceiver.FrameRateOverride[] frameRatesOverrides =
                    display.getFrameRateOverrides();
            display.updateLocked(mDisplayDeviceRepo);
            final DisplayGroup changedDisplayGroup;
            if (!display.isValidLocked()) {
                mLogicalDisplays.removeAt(i);
                mDisplayGroups.removeReturnOld(displayId).removeDisplay(display);
                final DisplayGroup displayGroup = mDisplayIdToGroupMap.removeReturnOld(displayId);
                displayGroup.removeDisplayLocked(display);

                mListener.onLogicalDisplayEventLocked(display,
                        LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_REMOVED);

                changedDisplayGroup = displayGroup;
            } else if (!mTempDisplayInfo.equals(display.getDisplayInfoLocked())) {
                final int flags = display.getDisplayInfoLocked().flags;
                final DisplayGroup defaultDisplayGroup = mDisplayGroups.get(
                final DisplayGroup defaultDisplayGroup = mDisplayIdToGroupMap.get(
                        Display.DEFAULT_DISPLAY);
                if ((flags & Display.FLAG_OWN_DISPLAY_GROUP) != 0) {
                    // The display should have its own DisplayGroup.
                    if (defaultDisplayGroup.removeDisplay(display)) {
                    if (defaultDisplayGroup.removeDisplayLocked(display)) {
                        final int groupId = assignDisplayGroupIdLocked(false);
                        final DisplayGroup displayGroup = new DisplayGroup(groupId);
                        displayGroup.addDisplay(display);
                        mDisplayGroups.append(display.getDisplayIdLocked(), displayGroup);
                        displayGroup.addDisplayLocked(display);
                        display.updateDisplayGroupIdLocked(groupId);
                        mDisplayIdToGroupMap.append(display.getDisplayIdLocked(), displayGroup);
                        mListener.onDisplayGroupEventLocked(displayGroup.getGroupId(),
                                LogicalDisplayMapper.DISPLAY_GROUP_EVENT_ADDED);
                        changedDisplayGroup = defaultDisplayGroup;
                    } else {
                        changedDisplayGroup = null;
                    }
                } else {
                    // The display should be a part of the default DisplayGroup.
                    final DisplayGroup displayGroup = mDisplayGroups.get(displayId);
                    final DisplayGroup displayGroup = mDisplayIdToGroupMap.get(displayId);
                    if (displayGroup != defaultDisplayGroup) {
                        displayGroup.removeDisplay(display);
                        defaultDisplayGroup.addDisplay(display);
                        mDisplayGroups.put(displayId, defaultDisplayGroup);
                        displayGroup.removeDisplayLocked(display);
                        defaultDisplayGroup.addDisplayLocked(display);
                        display.updateDisplayGroupIdLocked(defaultDisplayGroup.getGroupId());
                        mListener.onDisplayGroupEventLocked(defaultDisplayGroup.getGroupId(),
                                LogicalDisplayMapper.DISPLAY_GROUP_EVENT_CHANGED);
                        mDisplayIdToGroupMap.put(displayId, defaultDisplayGroup);
                        changedDisplayGroup = displayGroup;
                    } else {
                        changedDisplayGroup = null;
                    }
                }

@@ -394,6 +436,7 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
            } else if (!display.getPendingFrameRateOverrideUids().isEmpty()) {
                mListener.onLogicalDisplayEventLocked(display,
                        LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_FRAME_RATE_OVERRIDES_CHANGED);
                changedDisplayGroup = null;
            } else {
                // While applications shouldn't know nor care about the non-overridden info, we
                // still need to let WindowManager know so it can update its own internal state for
@@ -403,6 +446,15 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
                    mListener.onLogicalDisplayEventLocked(display,
                            LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_CHANGED);
                }
                changedDisplayGroup = null;
            }

            // CHANGED and REMOVED DisplayGroup events should always fire after Display events.
            if (changedDisplayGroup != null) {
                final int event = changedDisplayGroup.isEmptyLocked()
                        ? LogicalDisplayMapper.DISPLAY_GROUP_EVENT_REMOVED
                        : LogicalDisplayMapper.DISPLAY_GROUP_EVENT_CHANGED;
                mListener.onDisplayGroupEventLocked(changedDisplayGroup.getGroupId(), event);
            }
        }
    }
@@ -438,6 +490,7 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {

    public interface Listener {
        void onLogicalDisplayEventLocked(LogicalDisplay display, int event);
        void onDisplayGroupEventLocked(int groupId, int event);
        void onTraversalRequested();
    }
}
+2 −2
Original line number Diff line number Diff line
@@ -2892,8 +2892,8 @@ public final class PowerManagerService extends SystemService
                        PowerManager.BRIGHTNESS_INVALID_FLOAT;
            }

            mDisplayReady = mDisplayManagerInternal.requestPowerState(displayPowerRequest,
                    mRequestWaitForNegativeProximity);
            mDisplayReady = mDisplayManagerInternal.requestPowerState(Display.DEFAULT_DISPLAY_GROUP,
                    displayPowerRequest, mRequestWaitForNegativeProximity);
            mRequestWaitForNegativeProximity = false;

            if (DEBUG_SPEW) {
Loading