diff options
author | Ady Abraham <adyabr@google.com> | 2021-08-26 21:52:44 -0700 |
---|---|---|
committer | Ramakant Singh <ramakant@codeaurora.org> | 2021-09-23 18:18:35 +0000 |
commit | 0ae293a3b4853d07a3bce4178b9e40510e45be68 (patch) | |
tree | d5493810d0594aa42a6030a3e2079745243d3f76 | |
parent | 644004ac05e173a1701efc34d091e2d844edfa87 (diff) |
DisplayManagerGlobal: fix native refresh rate callback registration
When AChoreographer is the only callback registered with
DisplayManagerGlobal and there are no other display listeners,
DisplayManagerGlobal incorrectly skips callback registration with DMS.
Bug: 193945763
Test: atest DisplayManagerGlobalTest
Change-Id: I4b737fa0a91541fe331edcf3454724200e2db971
(cherry picked from commit 0ee31107edadae1842adc9ec1c15492bfe9ea52f)
CRs-Fixed: 2987744
-rw-r--r-- | core/java/android/hardware/display/DisplayManagerGlobal.java | 29 | ||||
-rw-r--r-- | core/tests/coretests/src/android/hardware/display/DisplayManagerGlobalTest.java | 41 |
2 files changed, 63 insertions, 7 deletions
diff --git a/core/java/android/hardware/display/DisplayManagerGlobal.java b/core/java/android/hardware/display/DisplayManagerGlobal.java index a9b95fce8777..6c3936569c28 100644 --- a/core/java/android/hardware/display/DisplayManagerGlobal.java +++ b/core/java/android/hardware/display/DisplayManagerGlobal.java @@ -361,6 +361,11 @@ public final class DisplayManagerGlobal { for (int i = 0; i < numListeners; i++) { mask |= mDisplayListeners.get(i).mEventsMask; } + if (mDispatchNativeCallbacks) { + mask |= DisplayManager.EVENT_FLAG_DISPLAY_ADDED + | DisplayManager.EVENT_FLAG_DISPLAY_CHANGED + | DisplayManager.EVENT_FLAG_DISPLAY_REMOVED; + } return mask; } @@ -1047,12 +1052,17 @@ public final class DisplayManagerGlobal { private static native void nSignalNativeCallbacks(float refreshRate); - // Called from AChoreographer via JNI. - // Registers AChoreographer so that refresh rate callbacks can be dispatched from DMS. - private void registerNativeChoreographerForRefreshRateCallbacks() { + /** + * Called from AChoreographer via JNI. + * Registers AChoreographer so that refresh rate callbacks can be dispatched from DMS. + * Public for unit testing to be able to call this method. + */ + @VisibleForTesting + public void registerNativeChoreographerForRefreshRateCallbacks() { synchronized (mLock) { - registerCallbackIfNeededLocked(); mDispatchNativeCallbacks = true; + registerCallbackIfNeededLocked(); + updateCallbackIfNeededLocked(); DisplayInfo display = getDisplayInfoLocked(Display.DEFAULT_DISPLAY); if (display != null) { // We need to tell AChoreographer instances the current refresh rate so that apps @@ -1063,11 +1073,16 @@ public final class DisplayManagerGlobal { } } - // Called from AChoreographer via JNI. - // Unregisters AChoreographer from receiving refresh rate callbacks. - private void unregisterNativeChoreographerForRefreshRateCallbacks() { + /** + * Called from AChoreographer via JNI. + * Unregisters AChoreographer from receiving refresh rate callbacks. + * Public for unit testing to be able to call this method. + */ + @VisibleForTesting + public void unregisterNativeChoreographerForRefreshRateCallbacks() { synchronized (mLock) { mDispatchNativeCallbacks = false; + updateCallbackIfNeededLocked(); } } } diff --git a/core/tests/coretests/src/android/hardware/display/DisplayManagerGlobalTest.java b/core/tests/coretests/src/android/hardware/display/DisplayManagerGlobalTest.java index dfc9013e3c05..149f58f0a69b 100644 --- a/core/tests/coretests/src/android/hardware/display/DisplayManagerGlobalTest.java +++ b/core/tests/coretests/src/android/hardware/display/DisplayManagerGlobalTest.java @@ -32,6 +32,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Captor; +import org.mockito.InOrder; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; @@ -121,6 +122,46 @@ public class DisplayManagerGlobalTest { Mockito.verifyZeroInteractions(mListener); } + @Test + public void testDisplayManagerGlobalRegistersWithDisplayManager_WhenThereAreNoOtherListeners() + throws RemoteException { + mDisplayManagerGlobal.registerNativeChoreographerForRefreshRateCallbacks(); + Mockito.verify(mDisplayManager) + .registerCallbackWithEventMask(mCallbackCaptor.capture(), eq(ALL_DISPLAY_EVENTS)); + + mDisplayManagerGlobal.unregisterNativeChoreographerForRefreshRateCallbacks(); + Mockito.verify(mDisplayManager) + .registerCallbackWithEventMask(mCallbackCaptor.capture(), eq(0L)); + + } + + @Test + public void testDisplayManagerGlobalRegistersWithDisplayManager_WhenThereAreListeners() + throws RemoteException { + mDisplayManagerGlobal.registerDisplayListener(mListener, mHandler, + DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS); + InOrder inOrder = Mockito.inOrder(mDisplayManager); + + inOrder.verify(mDisplayManager) + .registerCallbackWithEventMask(mCallbackCaptor.capture(), + eq(DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS)); + + mDisplayManagerGlobal.registerNativeChoreographerForRefreshRateCallbacks(); + inOrder.verify(mDisplayManager) + .registerCallbackWithEventMask(mCallbackCaptor.capture(), + eq(ALL_DISPLAY_EVENTS | DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS)); + + mDisplayManagerGlobal.unregisterNativeChoreographerForRefreshRateCallbacks(); + inOrder.verify(mDisplayManager) + .registerCallbackWithEventMask(mCallbackCaptor.capture(), + eq(DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS)); + + mDisplayManagerGlobal.unregisterDisplayListener(mListener); + inOrder.verify(mDisplayManager) + .registerCallbackWithEventMask(mCallbackCaptor.capture(), eq(0L)); + + } + private void waitForHandler() { mHandler.runWithScissors(() -> { }, 0); } |