7
7
package com.datadog.android.rum.internal.vitals
8
8
9
9
import android.app.Activity
10
+ import android.content.Context
11
+ import android.hardware.display.DisplayManager
10
12
import android.os.Build
11
13
import android.os.Bundle
12
14
import android.view.Display
@@ -25,6 +27,7 @@ import com.datadog.tools.unit.annotations.TestConfigurationsProvider
25
27
import com.datadog.tools.unit.extensions.TestConfigurationExtension
26
28
import com.datadog.tools.unit.extensions.config.TestConfiguration
27
29
import fr.xgouchet.elmyr.Forge
30
+ import fr.xgouchet.elmyr.annotation.IntForgery
28
31
import fr.xgouchet.elmyr.junit5.ForgeConfiguration
29
32
import fr.xgouchet.elmyr.junit5.ForgeExtension
30
33
import org.assertj.core.api.Assertions.assertThat
@@ -43,6 +46,7 @@ import org.mockito.kotlin.doThrow
43
46
import org.mockito.kotlin.inOrder
44
47
import org.mockito.kotlin.mock
45
48
import org.mockito.kotlin.reset
49
+ import org.mockito.kotlin.times
46
50
import org.mockito.kotlin.verify
47
51
import org.mockito.kotlin.verifyNoInteractions
48
52
import org.mockito.kotlin.whenever
@@ -77,6 +81,9 @@ internal class JankStatsActivityLifecycleListenerTest {
77
81
@Mock
78
82
lateinit var mockDecorView: View
79
83
84
+ @Mock
85
+ lateinit var mockDisplayManager: DisplayManager
86
+
80
87
@Mock
81
88
lateinit var mockJankStatsProvider: JankStatsProvider
82
89
@@ -93,6 +100,8 @@ internal class JankStatsActivityLifecycleListenerTest {
93
100
whenever(mockWindow.peekDecorView()) doReturn mockDecorView
94
101
whenever(mockActivity.window) doReturn mockWindow
95
102
whenever(mockActivity.display) doReturn mockDisplay
103
+ whenever(mockDisplayManager.getDisplay(Display .DEFAULT_DISPLAY )) doReturn mockDisplay
104
+ whenever(mockActivity.getSystemService(Context .DISPLAY_SERVICE )) doReturn mockDisplayManager
96
105
whenever(mockJankStatsProvider.createJankStatsAndTrack(any(), any(), any())) doReturn mockJankStats
97
106
whenever(mockJankStats.isTrackingEnabled) doReturn true
98
107
@@ -383,6 +392,91 @@ internal class JankStatsActivityLifecycleListenerTest {
383
392
}
384
393
}
385
394
395
+ @Test
396
+ fun `M not call addOnFrameMetricsAvailableListener() W onActivityStarted { ANDROID_SDK less than S } ` (
397
+ @IntForgery(min = Build .VERSION_CODES .LOLLIPOP , max = Build .VERSION_CODES .S ) apiVersion : Int
398
+ ) {
399
+ // There is a bug in AndroidFramework that could throw NPE, so we subscribing to the FrameMetrics only since S
400
+ // https://github.com/DataDog/dd-sdk-android/issues/2556
401
+
402
+ // Given
403
+ whenever(mockDecorView.isHardwareAccelerated) doReturn true
404
+ whenever(mockBuildSdkVersionProvider.version) doReturn apiVersion
405
+
406
+ // When
407
+ testedJankListener.onActivityStarted(mockActivity)
408
+
409
+ // Then
410
+ verify(mockDecorView, times(0 )).post(any())
411
+ verify(mockWindow, times(0 )).addOnFrameMetricsAvailableListener(any(), any())
412
+ }
413
+
414
+ @Test
415
+ fun `M not call addOnFrameMetricsAvailableListener() W onActivityStarted { ANDROID_SDK grater or equal S } ` (
416
+ @IntForgery(min = Build .VERSION_CODES .S ) apiVersion : Int
417
+ ) {
418
+ // There is a bug in AndroidFramework that could throw NPE, so we subscribing to the FrameMetrics only since S
419
+ // https://github.com/DataDog/dd-sdk-android/issues/2556
420
+
421
+ // Given
422
+ whenever(mockDecorView.isHardwareAccelerated) doReturn true
423
+ whenever(mockBuildSdkVersionProvider.version) doReturn apiVersion
424
+ // When
425
+ testedJankListener.onActivityStarted(mockActivity)
426
+ argumentCaptor<Runnable > {
427
+ verify(mockDecorView).post(capture())
428
+ firstValue.run ()
429
+ }
430
+
431
+ // Then
432
+ verify(mockWindow).addOnFrameMetricsAvailableListener(any(), any())
433
+ }
434
+
435
+ @Test
436
+ fun `M not call addOnFrameMetricsAvailableListener() W onActivityDestroyed { ANDROID_SDK less than S } ` (
437
+ @IntForgery(min = Build .VERSION_CODES .LOLLIPOP , max = Build .VERSION_CODES .S ) apiVersion : Int
438
+ ) {
439
+ // There is a bug in AndroidFramework that could throw NPE, so we subscribing to the FrameMetrics only since S
440
+ // https://github.com/DataDog/dd-sdk-android/issues/2556
441
+
442
+ // Given
443
+ whenever(mockDecorView.isHardwareAccelerated) doReturn true
444
+ whenever(mockBuildSdkVersionProvider.version) doReturn apiVersion
445
+ testedJankListener.onActivityStarted(mockActivity)
446
+ testedJankListener.activeActivities.clear()
447
+
448
+ // When
449
+ testedJankListener.onActivityDestroyed(mockActivity)
450
+
451
+ // Then
452
+ verify(mockDecorView, times(0 )).post(any())
453
+ verify(mockWindow, times(0 )).removeOnFrameMetricsAvailableListener(any())
454
+ }
455
+
456
+ @Test
457
+ fun `M not call addOnFrameMetricsAvailableListener() W onActivityDestroyed { ANDROID_SDK grater or equal S } ` (
458
+ @IntForgery(min = Build .VERSION_CODES .S ) apiVersion : Int
459
+ ) {
460
+ // There is a bug in AndroidFramework that could throw NPE, so we subscribing to the FrameMetrics only since S
461
+ // https://github.com/DataDog/dd-sdk-android/issues/2556
462
+
463
+ // Given
464
+ whenever(mockDecorView.isHardwareAccelerated) doReturn true
465
+ whenever(mockBuildSdkVersionProvider.version) doReturn apiVersion
466
+ testedJankListener.onActivityStarted(mockActivity)
467
+ argumentCaptor<Runnable > {
468
+ verify(mockDecorView).post(capture())
469
+ firstValue.run ()
470
+ }
471
+ testedJankListener.activeActivities.clear()
472
+
473
+ // When
474
+ testedJankListener.onActivityDestroyed(mockActivity)
475
+
476
+ // Then
477
+ verify(mockWindow).removeOnFrameMetricsAvailableListener(any())
478
+ }
479
+
386
480
@Test
387
481
fun `M forward FrameData W onFrame` (forge : Forge ) {
388
482
val frameData = forge.getForgery<FrameData >()
0 commit comments