diff options
author | 2025-02-13 11:50:35 -0800 | |
---|---|---|
committer | 2025-02-13 11:50:35 -0800 | |
commit | 10d770d4df6daf44cc3cee9ec2a97ad51cec3dd0 (patch) | |
tree | 2b25fcadc4b3c888682bc31f89f5eda37e36114a | |
parent | 36323852044f25a66937499539c52df16c6d5220 (diff) | |
parent | 683cac14a37494431b94ce9df72b7c41a83b14f7 (diff) |
Merge "Added private event flag for committed states" into main
10 files changed, 140 insertions, 18 deletions
diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java index d8919160320a..7850e377ec4d 100644 --- a/core/java/android/hardware/display/DisplayManager.java +++ b/core/java/android/hardware/display/DisplayManager.java @@ -612,6 +612,7 @@ public final class DisplayManager { PRIVATE_EVENT_TYPE_DISPLAY_BRIGHTNESS, PRIVATE_EVENT_TYPE_HDR_SDR_RATIO_CHANGED, PRIVATE_EVENT_TYPE_DISPLAY_CONNECTION_CHANGED, + PRIVATE_EVENT_TYPE_DISPLAY_COMMITTED_STATE_CHANGED }) @Retention(RetentionPolicy.SOURCE) public @interface PrivateEventType {} @@ -677,7 +678,7 @@ public final class DisplayManager { * through the {@link DisplayListener#onDisplayChanged} callback method. New brightness * values can be retrieved via {@link android.view.Display#getBrightnessInfo()}. * - * @see #registerDisplayListener(DisplayListener, Handler, long) + * @see #registerDisplayListener(DisplayListener, Handler, long, long) * * @hide */ @@ -690,7 +691,7 @@ public final class DisplayManager { * * Requires that {@link Display#isHdrSdrRatioAvailable()} is true. * - * @see #registerDisplayListener(DisplayListener, Handler, long) + * @see #registerDisplayListener(DisplayListener, Handler, long, long) * * @hide */ @@ -699,11 +700,19 @@ public final class DisplayManager { /** * Event type to register for a display's connection changed. * - * @see #registerDisplayListener(DisplayListener, Handler, long) + * @see #registerDisplayListener(DisplayListener, Handler, long, long) * @hide */ public static final long PRIVATE_EVENT_TYPE_DISPLAY_CONNECTION_CHANGED = 1L << 2; + /** + * Event type to register for a display's committed state changes. + * + * @see #registerDisplayListener(DisplayListener, Handler, long, long) + * @hide + */ + public static final long PRIVATE_EVENT_TYPE_DISPLAY_COMMITTED_STATE_CHANGED = 1L << 3; + /** @hide */ public DisplayManager(Context context) { diff --git a/core/java/android/hardware/display/DisplayManagerGlobal.java b/core/java/android/hardware/display/DisplayManagerGlobal.java index 339dbf2c2029..a7d610e54e2c 100644 --- a/core/java/android/hardware/display/DisplayManagerGlobal.java +++ b/core/java/android/hardware/display/DisplayManagerGlobal.java @@ -113,7 +113,8 @@ public final class DisplayManagerGlobal { EVENT_DISPLAY_CONNECTED, EVENT_DISPLAY_DISCONNECTED, EVENT_DISPLAY_REFRESH_RATE_CHANGED, - EVENT_DISPLAY_STATE_CHANGED + EVENT_DISPLAY_STATE_CHANGED, + EVENT_DISPLAY_COMMITTED_STATE_CHANGED }) @Retention(RetentionPolicy.SOURCE) public @interface DisplayEvent {} @@ -128,6 +129,8 @@ public final class DisplayManagerGlobal { public static final int EVENT_DISPLAY_DISCONNECTED = 7; public static final int EVENT_DISPLAY_REFRESH_RATE_CHANGED = 8; public static final int EVENT_DISPLAY_STATE_CHANGED = 9; + public static final int EVENT_DISPLAY_COMMITTED_STATE_CHANGED = 10; + @LongDef(prefix = {"INTERNAL_EVENT_FLAG_"}, flag = true, value = { INTERNAL_EVENT_FLAG_DISPLAY_ADDED, @@ -139,6 +142,7 @@ public final class DisplayManagerGlobal { INTERNAL_EVENT_FLAG_DISPLAY_REFRESH_RATE, INTERNAL_EVENT_FLAG_DISPLAY_STATE, INTERNAL_EVENT_FLAG_TOPOLOGY_UPDATED, + INTERNAL_EVENT_FLAG_DISPLAY_COMMITTED_STATE_CHANGED }) @Retention(RetentionPolicy.SOURCE) public @interface InternalEventFlag {} @@ -152,6 +156,8 @@ public final class DisplayManagerGlobal { public static final long INTERNAL_EVENT_FLAG_DISPLAY_REFRESH_RATE = 1L << 6; public static final long INTERNAL_EVENT_FLAG_DISPLAY_STATE = 1L << 7; public static final long INTERNAL_EVENT_FLAG_TOPOLOGY_UPDATED = 1L << 8; + public static final long INTERNAL_EVENT_FLAG_DISPLAY_COMMITTED_STATE_CHANGED = 1L << 9; + @UnsupportedAppUsage private static DisplayManagerGlobal sInstance; @@ -1550,6 +1556,12 @@ public final class DisplayManagerGlobal { mListener.onDisplayChanged(displayId); } break; + case EVENT_DISPLAY_COMMITTED_STATE_CHANGED: + if ((mInternalEventFlagsMask + & INTERNAL_EVENT_FLAG_DISPLAY_COMMITTED_STATE_CHANGED) != 0) { + mListener.onDisplayChanged(displayId); + } + break; } if (DEBUG) { Trace.endSection(); @@ -1710,6 +1722,8 @@ public final class DisplayManagerGlobal { return "EVENT_DISPLAY_REFRESH_RATE_CHANGED"; case EVENT_DISPLAY_STATE_CHANGED: return "EVENT_DISPLAY_STATE_CHANGED"; + case EVENT_DISPLAY_COMMITTED_STATE_CHANGED: + return "EVENT_DISPLAY_COMMITTED_STATE_CHANGED"; } return "UNKNOWN"; } @@ -1756,6 +1770,13 @@ public final class DisplayManagerGlobal { & DisplayManager.PRIVATE_EVENT_TYPE_DISPLAY_CONNECTION_CHANGED) != 0) { baseEventMask |= INTERNAL_EVENT_FLAG_DISPLAY_CONNECTION_CHANGED; } + + if (Flags.committedStateSeparateEvent()) { + if ((privateEventFlags + & DisplayManager.PRIVATE_EVENT_TYPE_DISPLAY_COMMITTED_STATE_CHANGED) != 0) { + baseEventMask |= INTERNAL_EVENT_FLAG_DISPLAY_COMMITTED_STATE_CHANGED; + } + } return baseEventMask; } diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java index 464756842caf..41a64e22e058 100644 --- a/core/java/android/service/wallpaper/WallpaperService.java +++ b/core/java/android/service/wallpaper/WallpaperService.java @@ -1595,8 +1595,17 @@ public abstract class WallpaperService extends Service { mWindow.setSession(mSession); mLayout.packageName = getPackageName(); - mIWallpaperEngine.mDisplayManager.registerDisplayListener(mDisplayListener, - mCaller.getHandler()); + if (com.android.server.display.feature.flags.Flags + .displayListenerPerformanceImprovements() + && com.android.server.display.feature.flags.Flags + .committedStateSeparateEvent()) { + mIWallpaperEngine.mDisplayManager.registerDisplayListener(mDisplayListener, + mCaller.getHandler(), DisplayManager.EVENT_TYPE_DISPLAY_CHANGED, + DisplayManager.PRIVATE_EVENT_TYPE_DISPLAY_COMMITTED_STATE_CHANGED); + } else { + mIWallpaperEngine.mDisplayManager.registerDisplayListener(mDisplayListener, + mCaller.getHandler()); + } mDisplay = mIWallpaperEngine.mDisplay; // Use window context of TYPE_WALLPAPER so client can access UI resources correctly. mDisplayContext = createDisplayContext(mDisplay) diff --git a/core/java/android/view/DisplayInfo.java b/core/java/android/view/DisplayInfo.java index ecdbaa3cd2f4..d880072aa404 100644 --- a/core/java/android/view/DisplayInfo.java +++ b/core/java/android/view/DisplayInfo.java @@ -44,6 +44,7 @@ import android.util.SparseArray; import android.util.proto.ProtoOutputStream; import com.android.internal.display.BrightnessSynchronizer; +import com.android.server.display.feature.flags.Flags; import java.util.Arrays; import java.util.Objects; @@ -447,18 +448,20 @@ public final class DisplayInfo implements Parcelable { } public boolean equals(DisplayInfo other) { - return equals(other, /* compareRefreshRate */ true); + return equals(other, /* compareOnlyBasicChanges */ false); } /** * Compares if the two DisplayInfo objects are equal or not * @param other The other DisplayInfo against which the comparison is to be done - * @param compareRefreshRate Indicates if the refresh rate is also to be considered in - * comparison + * @param compareOnlyBasicChanges Indicates if the changes to be compared are the ones which + * could lead to an emission of + * {@link android.hardware.display.DisplayManager.EVENT_TYPE_DISPLAY_CHANGED} + * event * @return */ - public boolean equals(DisplayInfo other, boolean compareRefreshRate) { - boolean isEqualWithoutRefreshRate = other != null + public boolean equals(DisplayInfo other, boolean compareOnlyBasicChanges) { + boolean isEqualWithOnlyBasicChanges = other != null && layerStack == other.layerStack && flags == other.flags && type == other.type @@ -494,7 +497,6 @@ public final class DisplayInfo implements Parcelable { && physicalXDpi == other.physicalXDpi && physicalYDpi == other.physicalYDpi && state == other.state - && committedState == other.committedState && ownerUid == other.ownerUid && Objects.equals(ownerPackageName, other.ownerPackageName) && removeMode == other.removeMode @@ -512,14 +514,19 @@ public final class DisplayInfo implements Parcelable { thermalBrightnessThrottlingDataId, other.thermalBrightnessThrottlingDataId) && canHostTasks == other.canHostTasks; - if (compareRefreshRate) { - return isEqualWithoutRefreshRate + if (!Flags.committedStateSeparateEvent()) { + isEqualWithOnlyBasicChanges = isEqualWithOnlyBasicChanges + && (committedState == other.committedState); + } + if (!compareOnlyBasicChanges) { + return isEqualWithOnlyBasicChanges && (getRefreshRate() == other.getRefreshRate()) && appVsyncOffsetNanos == other.appVsyncOffsetNanos && presentationDeadlineNanos == other.presentationDeadlineNanos - && (modeId == other.modeId); + && (modeId == other.modeId) + && (committedState == other.committedState); } - return isEqualWithoutRefreshRate; + return isEqualWithOnlyBasicChanges; } @Override diff --git a/core/tests/coretests/src/android/hardware/display/DisplayManagerGlobalTest.java b/core/tests/coretests/src/android/hardware/display/DisplayManagerGlobalTest.java index dc2f0a69375d..9383807ec761 100644 --- a/core/tests/coretests/src/android/hardware/display/DisplayManagerGlobalTest.java +++ b/core/tests/coretests/src/android/hardware/display/DisplayManagerGlobalTest.java @@ -33,6 +33,7 @@ import android.content.Context; import android.os.Handler; import android.os.RemoteException; import android.platform.test.annotations.Presubmit; +import android.platform.test.annotations.RequiresFlagsDisabled; import android.platform.test.annotations.RequiresFlagsEnabled; import android.platform.test.flag.junit.CheckFlagsRule; import android.platform.test.flag.junit.DeviceFlagsValueProvider; @@ -348,6 +349,26 @@ public class DisplayManagerGlobalTest { DisplayManager.PRIVATE_EVENT_TYPE_DISPLAY_BRIGHTNESS)); } + @Test + @RequiresFlagsEnabled(Flags.FLAG_COMMITTED_STATE_SEPARATE_EVENT) + public void test_mapPrivateEventCommittedStateChanged_flagEnabled() { + // Test public flags mapping + assertEquals(DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_COMMITTED_STATE_CHANGED, + mDisplayManagerGlobal + .mapFiltersToInternalEventFlag(0, + DisplayManager.PRIVATE_EVENT_TYPE_DISPLAY_COMMITTED_STATE_CHANGED)); + } + + @Test + @RequiresFlagsDisabled(Flags.FLAG_COMMITTED_STATE_SEPARATE_EVENT) + public void test_mapPrivateEventCommittedStateChanged_flagDisabled() { + // Test public flags mapping + assertEquals(0, + mDisplayManagerGlobal + .mapFiltersToInternalEventFlag(0, + DisplayManager.PRIVATE_EVENT_TYPE_DISPLAY_COMMITTED_STATE_CHANGED)); + } + private void waitForHandler() { mHandler.runWithScissors(() -> { }, 0); diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java index b6a3f4041b13..0aa7227ac7e6 100644 --- a/services/core/java/com/android/server/display/DisplayManagerService.java +++ b/services/core/java/com/android/server/display/DisplayManagerService.java @@ -2587,6 +2587,11 @@ public final class DisplayManagerService extends SystemService { sendDisplayEventIfEnabledLocked(display, DisplayManagerGlobal.EVENT_DISPLAY_STATE_CHANGED); } + private void handleLogicalDisplayCommittedStateChangedLocked(@NonNull LogicalDisplay display) { + sendDisplayEventIfEnabledLocked(display, + DisplayManagerGlobal.EVENT_DISPLAY_COMMITTED_STATE_CHANGED); + } + private void notifyDefaultDisplayDeviceUpdated(LogicalDisplay display) { mDisplayModeDirector.defaultDisplayDeviceUpdated(display.getPrimaryDisplayDeviceLocked() .mDisplayDeviceConfig); @@ -4165,6 +4170,9 @@ public final class DisplayManagerService extends SystemService { case LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_STATE_CHANGED: handleLogicalDisplayStateChangedLocked(display); break; + case LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_COMMITTED_STATE_CHANGED: + handleLogicalDisplayCommittedStateChangedLocked(display); + break; } } @@ -4419,6 +4427,9 @@ public final class DisplayManagerService extends SystemService { case DisplayManagerGlobal.EVENT_DISPLAY_STATE_CHANGED: return (mask & DisplayManagerGlobal .INTERNAL_EVENT_FLAG_DISPLAY_STATE) != 0; + case DisplayManagerGlobal.EVENT_DISPLAY_COMMITTED_STATE_CHANGED: + return (mask & DisplayManagerGlobal + .INTERNAL_EVENT_FLAG_DISPLAY_COMMITTED_STATE_CHANGED) != 0; default: // This should never happen. Slog.e(TAG, "Unknown display event " + event); diff --git a/services/core/java/com/android/server/display/LogicalDisplayMapper.java b/services/core/java/com/android/server/display/LogicalDisplayMapper.java index 02db051dff57..872f33484951 100644 --- a/services/core/java/com/android/server/display/LogicalDisplayMapper.java +++ b/services/core/java/com/android/server/display/LogicalDisplayMapper.java @@ -91,6 +91,8 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { public static final int LOGICAL_DISPLAY_EVENT_DISCONNECTED = 1 << 8; public static final int LOGICAL_DISPLAY_EVENT_REFRESH_RATE_CHANGED = 1 << 9; public static final int LOGICAL_DISPLAY_EVENT_STATE_CHANGED = 1 << 10; + public static final int LOGICAL_DISPLAY_EVENT_COMMITTED_STATE_CHANGED = 1 << 11; + public static final int DISPLAY_GROUP_EVENT_ADDED = 1; public static final int DISPLAY_GROUP_EVENT_CHANGED = 2; @@ -810,7 +812,7 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { int logicalDisplayEventMask = mLogicalDisplaysToUpdate .get(displayId, LOGICAL_DISPLAY_EVENT_BASE); boolean hasBasicInfoChanged = - !mTempDisplayInfo.equals(newDisplayInfo, /* compareRefreshRate */ false); + !mTempDisplayInfo.equals(newDisplayInfo, /* compareOnlyBasicChanges */ true); // The display is no longer valid and needs to be removed. if (!display.isValidLocked()) { // Remove from group @@ -930,6 +932,7 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { sendUpdatesForDisplaysLocked(LOGICAL_DISPLAY_EVENT_BASIC_CHANGED); sendUpdatesForDisplaysLocked(LOGICAL_DISPLAY_EVENT_REFRESH_RATE_CHANGED); sendUpdatesForDisplaysLocked(LOGICAL_DISPLAY_EVENT_STATE_CHANGED); + sendUpdatesForDisplaysLocked(LOGICAL_DISPLAY_EVENT_COMMITTED_STATE_CHANGED); sendUpdatesForDisplaysLocked(LOGICAL_DISPLAY_EVENT_FRAME_RATE_OVERRIDES_CHANGED); sendUpdatesForDisplaysLocked(LOGICAL_DISPLAY_EVENT_SWAPPED); sendUpdatesForDisplaysLocked(LOGICAL_DISPLAY_EVENT_CONNECTED); @@ -961,6 +964,11 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { && mTempDisplayInfo.state != newDisplayInfo.state) { mask |= LOGICAL_DISPLAY_EVENT_STATE_CHANGED; } + + if (mFlags.isCommittedStateSeparateEventEnabled() + && mTempDisplayInfo.committedState != newDisplayInfo.committedState) { + mask |= LOGICAL_DISPLAY_EVENT_COMMITTED_STATE_CHANGED; + } return mask; } /** @@ -1360,6 +1368,8 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { return "disconnected"; case LOGICAL_DISPLAY_EVENT_STATE_CHANGED: return "state_changed"; + case LOGICAL_DISPLAY_EVENT_COMMITTED_STATE_CHANGED: + return "committed_state_changed"; case LOGICAL_DISPLAY_EVENT_REFRESH_RATE_CHANGED: return "refresh_rate_changed"; case LOGICAL_DISPLAY_EVENT_BASIC_CHANGED: diff --git a/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java b/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java index bc5d90599b41..e4b595ab7c55 100644 --- a/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java +++ b/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java @@ -280,6 +280,11 @@ public class DisplayManagerFlags { Flags::refreshRateEventForForegroundApps ); + private final FlagState mCommittedStateSeparateEvent = new FlagState( + Flags.FLAG_COMMITTED_STATE_SEPARATE_EVENT, + Flags::committedStateSeparateEvent + ); + /** * @return {@code true} if 'port' is allowed in display layout configuration file. */ @@ -603,6 +608,14 @@ public class DisplayManagerFlags { } /** + * @return {@code true} if the flag for having a separate event for display's committed state + * is enabled + */ + public boolean isCommittedStateSeparateEventEnabled() { + return mCommittedStateSeparateEvent.isEnabled(); + } + + /** * dumps all flagstates * @param pw printWriter */ @@ -659,6 +672,7 @@ public class DisplayManagerFlags { pw.println(" " + mBaseDensityForExternalDisplays); pw.println(" " + mFramerateOverrideTriggersRrCallbacks); pw.println(" " + mRefreshRateEventForForegroundApps); + pw.println(" " + mCommittedStateSeparateEvent); } private static class FlagState { diff --git a/services/core/java/com/android/server/display/feature/display_flags.aconfig b/services/core/java/com/android/server/display/feature/display_flags.aconfig index 8211febade60..70143f1c1a98 100644 --- a/services/core/java/com/android/server/display/feature/display_flags.aconfig +++ b/services/core/java/com/android/server/display/feature/display_flags.aconfig @@ -509,3 +509,14 @@ flag { bug: "293651324" is_fixed_read_only: false } + +flag { + name: "committed_state_separate_event" + namespace: "display_manager" + description: "Move Display committed state into a separate event" + bug: "342192387" + is_fixed_read_only: true + metadata { + purpose: PURPOSE_BUGFIX + } +} diff --git a/services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayMapperTest.java b/services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayMapperTest.java index 7d3cd8a8a9ae..38de7ce013c2 100644 --- a/services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayMapperTest.java +++ b/services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayMapperTest.java @@ -34,6 +34,7 @@ import static com.android.server.display.DisplayAdapter.DISPLAY_DEVICE_EVENT_REM import static com.android.server.display.DisplayDeviceInfo.DIFF_EVERYTHING; import static com.android.server.display.DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY; import static com.android.server.display.LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_ADDED; +import static com.android.server.display.LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_COMMITTED_STATE_CHANGED; import static com.android.server.display.LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_CONNECTED; import static com.android.server.display.LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_DISCONNECTED; import static com.android.server.display.LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_REMOVED; @@ -1180,13 +1181,21 @@ public class LogicalDisplayMapperTest { assertEquals(LOGICAL_DISPLAY_EVENT_STATE_CHANGED, mLogicalDisplayMapper.updateAndGetMaskForDisplayPropertyChanges(newDisplayInfo)); + // Change the display committed state + when(mFlagsMock.isCommittedStateSeparateEventEnabled()).thenReturn(true); + newDisplayInfo = new DisplayInfo(); + newDisplayInfo.committedState = STATE_OFF; + assertEquals(LOGICAL_DISPLAY_EVENT_COMMITTED_STATE_CHANGED, + mLogicalDisplayMapper.updateAndGetMaskForDisplayPropertyChanges(newDisplayInfo)); // Change multiple properties newDisplayInfo = new DisplayInfo(); newDisplayInfo.refreshRateOverride = 30; newDisplayInfo.state = STATE_OFF; + newDisplayInfo.committedState = STATE_OFF; assertEquals(LOGICAL_DISPLAY_EVENT_REFRESH_RATE_CHANGED - | LOGICAL_DISPLAY_EVENT_STATE_CHANGED, + | LOGICAL_DISPLAY_EVENT_STATE_CHANGED + | LOGICAL_DISPLAY_EVENT_COMMITTED_STATE_CHANGED, mLogicalDisplayMapper.updateAndGetMaskForDisplayPropertyChanges(newDisplayInfo)); } |