diff options
| author | 2025-03-09 22:52:19 -0700 | |
|---|---|---|
| committer | 2025-03-09 22:52:19 -0700 | |
| commit | 759f9ccce1b30fbe82c7bbc3723b1fc97008a43d (patch) | |
| tree | b2d2b6416f42e545e9d029088bb6f45b1893fba6 | |
| parent | 2a9fba504b49169a7e9bcb9ce22fffb2741220c3 (diff) | |
| parent | 74127c07efd71aed94f2a79cfe07fa2b55a0a6a5 (diff) | |
Merge "Update rejected modes votes only if the display is registered" into main
| -rw-r--r-- | services/core/java/com/android/server/display/mode/ModeChangeObserver.java | 128 |
1 files changed, 93 insertions, 35 deletions
diff --git a/services/core/java/com/android/server/display/mode/ModeChangeObserver.java b/services/core/java/com/android/server/display/mode/ModeChangeObserver.java index 2751835f9958..50782a2f22c8 100644 --- a/services/core/java/com/android/server/display/mode/ModeChangeObserver.java +++ b/services/core/java/com/android/server/display/mode/ModeChangeObserver.java @@ -16,9 +16,11 @@ package com.android.server.display.mode; +import android.hardware.display.DisplayManager; +import android.os.Handler; import android.os.Looper; +import android.util.LongSparseArray; import android.util.Slog; -import android.util.SparseArray; import android.view.Display; import android.view.DisplayAddress; import android.view.DisplayEventReceiver; @@ -34,72 +36,128 @@ final class ModeChangeObserver { @SuppressWarnings("unused") private DisplayEventReceiver mModeChangeListener; - private final SparseArray<Set<Integer>> mRejectedModesByDisplay = new SparseArray<>(); - private Looper mLooper; + private DisplayManager.DisplayListener mDisplayListener; + private final LongSparseArray<Set<Integer>> mRejectedModesMap = + new LongSparseArray<>(); + private final LongSparseArray<Integer> mPhysicalIdToLogicalIdMap = new LongSparseArray<>(); + private final Looper mLooper; + private final Handler mHandler; + /** + * Observer for display mode changes. + * This class observes display mode rejections and updates the vote storage + * for rejected modes vote accordingly. + */ ModeChangeObserver(VotesStorage votesStorage, DisplayModeDirector.Injector injector, Looper looper) { mVotesStorage = votesStorage; mInjector = injector; mLooper = looper; + mHandler = new Handler(mLooper); } + /** + * Start observing display mode changes. + */ void observe() { - mModeChangeListener = new DisplayEventReceiver(mLooper) { + updatePhysicalIdToLogicalIdMap(); + mDisplayListener = new DisplayManager.DisplayListener() { @Override - public void onModeRejected(long physicalDisplayId, int modeId) { - Slog.d(TAG, "Mode Rejected event received"); - int displayId = getLogicalDisplayId(physicalDisplayId); - if (displayId < 0) { - Slog.e(TAG, "Logical Display Id not found"); + public void onDisplayAdded(int displayId) { + updateVoteForDisplay(displayId); + } + + @Override + public void onDisplayRemoved(int displayId) { + int oldPhysicalDisplayIdIndex = mPhysicalIdToLogicalIdMap.indexOfValue(displayId); + if (oldPhysicalDisplayIdIndex < 0) { + Slog.e(TAG, "Removed display not found"); return; } - populateRejectedModesListByDisplay(displayId, modeId); + long oldPhysicalDisplayId = + mPhysicalIdToLogicalIdMap.keyAt(oldPhysicalDisplayIdIndex); + mPhysicalIdToLogicalIdMap.delete(oldPhysicalDisplayId); + mRejectedModesMap.delete(oldPhysicalDisplayId); + mVotesStorage.updateVote(displayId, Vote.PRIORITY_REJECTED_MODES, null); } @Override - public void onHotplug(long timestampNanos, long physicalDisplayId, boolean connected) { - Slog.d(TAG, "Hotplug event received"); - if (!connected) { - int displayId = getLogicalDisplayId(physicalDisplayId); - if (displayId < 0) { - Slog.e(TAG, "Logical Display Id not found"); - return; - } - clearRejectedModesListByDisplay(displayId); + public void onDisplayChanged(int displayId) { + int oldPhysicalDisplayIdIndex = mPhysicalIdToLogicalIdMap.indexOfValue(displayId); + if (oldPhysicalDisplayIdIndex < 0) { + Slog.e(TAG, "Changed display not found"); + return; + } + long oldPhysicalDisplayId = + mPhysicalIdToLogicalIdMap.keyAt(oldPhysicalDisplayIdIndex); + mPhysicalIdToLogicalIdMap.delete(oldPhysicalDisplayId); + + updateVoteForDisplay(displayId); + } + }; + mInjector.registerDisplayListener(mDisplayListener, mHandler, + DisplayManager.EVENT_TYPE_DISPLAY_ADDED + | DisplayManager.EVENT_TYPE_DISPLAY_CHANGED + | DisplayManager.EVENT_TYPE_DISPLAY_REMOVED); + mModeChangeListener = new DisplayEventReceiver(mLooper) { + @Override + public void onModeRejected(long physicalDisplayId, int modeId) { + Slog.d(TAG, "Mode Rejected event received"); + updateRejectedModesListByDisplay(physicalDisplayId, modeId); + if (mPhysicalIdToLogicalIdMap.indexOfKey(physicalDisplayId) < 0) { + Slog.d(TAG, "Rejected Modes Vote will be updated after display is added"); + return; } + mVotesStorage.updateVote(mPhysicalIdToLogicalIdMap.get(physicalDisplayId), + Vote.PRIORITY_REJECTED_MODES, + Vote.forRejectedModes(mRejectedModesMap.get(physicalDisplayId))); } }; } - private int getLogicalDisplayId(long rejectedModePhysicalDisplayId) { + private void updateVoteForDisplay(int displayId) { + Display display = mInjector.getDisplay(displayId); + if (display == null) { + // We can occasionally get a display added or changed event for a display that was + // subsequently removed, which means this returns null. Check this case and bail + // out early; if it gets re-attached we will eventually get another call back for it. + Slog.e(TAG, "Added or Changed display has disappeared"); + return; + } + DisplayAddress address = display.getAddress(); + if (address instanceof DisplayAddress.Physical physical) { + long physicalDisplayId = physical.getPhysicalDisplayId(); + mPhysicalIdToLogicalIdMap.put(physicalDisplayId, displayId); + Set<Integer> modes = mRejectedModesMap.get(physicalDisplayId); + mVotesStorage.updateVote(displayId, Vote.PRIORITY_REJECTED_MODES, + modes != null ? Vote.forRejectedModes(modes) : null); + } + } + + private void updatePhysicalIdToLogicalIdMap() { Display[] displays = mInjector.getDisplays(); for (Display display : displays) { + if (display == null) { + continue; + } DisplayAddress address = display.getAddress(); if (address instanceof DisplayAddress.Physical physical) { - long physicalDisplayId = physical.getPhysicalDisplayId(); - if (physicalDisplayId == rejectedModePhysicalDisplayId) { - return display.getDisplayId(); - } + mPhysicalIdToLogicalIdMap.put(physical.getPhysicalDisplayId(), + display.getDisplayId()); } } - return -1; } - private void populateRejectedModesListByDisplay(int displayId, int rejectedModeId) { - Set<Integer> alreadyRejectedModes = mRejectedModesByDisplay.get(displayId); + private void updateRejectedModesListByDisplay(long rejectedModePhysicalDisplayId, + int rejectedModeId) { + Set<Integer> alreadyRejectedModes = + mRejectedModesMap.get(rejectedModePhysicalDisplayId); if (alreadyRejectedModes == null) { alreadyRejectedModes = new HashSet<>(); - mRejectedModesByDisplay.put(displayId, alreadyRejectedModes); + mRejectedModesMap.put(rejectedModePhysicalDisplayId, + alreadyRejectedModes); } alreadyRejectedModes.add(rejectedModeId); - mVotesStorage.updateVote(displayId, Vote.PRIORITY_REJECTED_MODES, - Vote.forRejectedModes(alreadyRejectedModes)); - } - - private void clearRejectedModesListByDisplay(int displayId) { - mRejectedModesByDisplay.remove(displayId); - mVotesStorage.updateVote(displayId, Vote.PRIORITY_REJECTED_MODES, null); } } |