diff --git a/packages/core/android/src/main/kotlin/com/datadog/reactnative/DdSdkImplementation.kt b/packages/core/android/src/main/kotlin/com/datadog/reactnative/DdSdkImplementation.kt index 58c9b521f..f83dffdd5 100644 --- a/packages/core/android/src/main/kotlin/com/datadog/reactnative/DdSdkImplementation.kt +++ b/packages/core/android/src/main/kotlin/com/datadog/reactnative/DdSdkImplementation.kt @@ -37,6 +37,9 @@ class DdSdkImplementation( internal val initialized = AtomicBoolean(false) private var frameRateProvider: FrameRateProvider? = null + @Volatile + private var maxDisplayRefreshRate: Double? = null + // region DdSdk /** @@ -383,7 +386,7 @@ class DdSdkImplementation( val frameTimeMs = frameTimeSeconds * 1000.0 val frameBudgetHz = fpsBudget ?: DEFAULT_REFRESH_HZ val maxDeviceDisplayHz = deviceDisplayFps ?: getMaxDisplayRefreshRate(context) - ?: 60.0 + ?: DEFAULT_REFRESH_HZ val maxDeviceFrameTimeMs = 1000.0 / maxDeviceDisplayHz val budgetFrameTimeMs = 1000.0 / frameBudgetHz @@ -402,10 +405,14 @@ class DdSdkImplementation( @Suppress("CyclomaticComplexMethod") private fun getMaxDisplayRefreshRate(context: Context?): Double { - val dm = context?.getSystemService(Context.DISPLAY_SERVICE) as? DisplayManager ?: return 60.0 + maxDisplayRefreshRate?.let { return it } + + val dm = context?.getSystemService(Context.DISPLAY_SERVICE) as? DisplayManager ?: return DEFAULT_REFRESH_HZ val display: Display = dm.getDisplay(Display.DEFAULT_DISPLAY) ?: return DEFAULT_REFRESH_HZ + val hz = display.supportedModes.maxOfOrNull { it.refreshRate.toDouble() } ?: DEFAULT_REFRESH_HZ + maxDisplayRefreshRate = hz - return display.supportedModes.maxOfOrNull { it.refreshRate.toDouble() } ?: DEFAULT_REFRESH_HZ + return hz } // endregion diff --git a/packages/core/android/src/test/kotlin/com/datadog/reactnative/DdSdkTest.kt b/packages/core/android/src/test/kotlin/com/datadog/reactnative/DdSdkTest.kt index 1bd17f3f4..b49882242 100644 --- a/packages/core/android/src/test/kotlin/com/datadog/reactnative/DdSdkTest.kt +++ b/packages/core/android/src/test/kotlin/com/datadog/reactnative/DdSdkTest.kt @@ -76,6 +76,7 @@ import org.junit.jupiter.params.provider.MethodSource import org.mockito.Answers import org.mockito.Mock import org.mockito.Mockito.mock +import org.mockito.Mockito.times import org.mockito.Mockito.`when` import org.mockito.junit.jupiter.MockitoExtension import org.mockito.junit.jupiter.MockitoSettings @@ -3595,6 +3596,35 @@ internal class DdSdkTest { assertThat(result).isEqualTo(0.016, Offset.offset(0.001)) } + @Test + fun `M read supportedModes only once W normalizeFrameTime called multiple times`() { + // Given + val mockContext = mock(Context::class.java) + val mockDisplayManager = mock(DisplayManager::class.java) + val mockDisplay = mock(Display::class.java) + + `when`(mockContext.getSystemService(Context.DISPLAY_SERVICE)).thenReturn(mockDisplayManager) + `when`(mockDisplayManager.getDisplay(Display.DEFAULT_DISPLAY)).thenReturn(mockDisplay) + `when`(mockDisplay.supportedModes).thenReturn(arrayOf()) + + // When + testedBridgeSdk.normalizeFrameTime( + frameTimeSeconds = 0.016, + context = mockContext, + fpsBudget = null, + deviceDisplayFps = null + ) + testedBridgeSdk.normalizeFrameTime( + frameTimeSeconds = 0.016, + context = mockContext, + fpsBudget = null, + deviceDisplayFps = null + ) + + // Then + verify(mockDisplay, times(1)).supportedModes + } + // endregion // region Internal