diff --git a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/RumFeature.kt b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/RumFeature.kt index f00cae4072..aa957e1dd8 100644 --- a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/RumFeature.kt +++ b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/RumFeature.kt @@ -431,10 +431,7 @@ internal class RumFeature( TELEMETRY_SESSION_REPLAY_SKIP_FRAME -> addSessionReplaySkippedFrame() FLUSH_AND_STOP_MONITOR_MESSAGE_TYPE -> { - (GlobalRumMonitor.get(sdkCore) as? DatadogRumMonitor)?.let { - it.stopKeepAliveCallback() - it.drainExecutorService() - } + (GlobalRumMonitor.get(sdkCore) as? DatadogRumMonitor)?.drainExecutorService() } else -> { diff --git a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/scope/RumRawEvent.kt b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/scope/RumRawEvent.kt index c12b827716..9605ad1bfd 100644 --- a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/scope/RumRawEvent.kt +++ b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/scope/RumRawEvent.kt @@ -170,10 +170,6 @@ internal sealed class RumRawEvent { override val eventTime: Time = Time() ) : RumRawEvent() - internal data class KeepAlive( - override val eventTime: Time = Time() - ) : RumRawEvent() - internal data class ApplicationStarted( override val eventTime: Time, val applicationStartupNanos: Long diff --git a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/scope/RumViewManagerScope.kt b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/scope/RumViewManagerScope.kt index 066404efcc..44f1bffde4 100644 --- a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/scope/RumViewManagerScope.kt +++ b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/scope/RumViewManagerScope.kt @@ -108,7 +108,8 @@ internal class RumViewManagerScope( delegateToChildren(event, datadogContext, writeScope, writer) if (event is RumRawEvent.StartView && !stopped) { - startForegroundView(event, datadogContext, writeScope, writer) + startForegroundView(event) + sendViewUpdateToChildren(event, datadogContext, writeScope, writer) lastStoppedViewTime?.let { val gap = event.eventTime.nanoTime - it.nanoTime if (gap in 1 until THREE_SECONDS_GAP_NS) { @@ -176,6 +177,15 @@ internal class RumViewManagerScope( childrenScopes.add(viewScope) } + private fun sendViewUpdateToChildren( + event: RumRawEvent, + datadogContext: DatadogContext, + writeScope: EventWriteScope, + writer: DataWriter + ) { + childrenScopes.forEach { it.sendViewUpdate(event, datadogContext, writeScope, writer) } + } + @WorkerThread private fun delegateToChildren( event: RumRawEvent, @@ -262,10 +272,7 @@ internal class RumViewManagerScope( @WorkerThread private fun startForegroundView( - event: RumRawEvent.StartView, - datadogContext: DatadogContext, - writeScope: EventWriteScope, - writer: DataWriter + event: RumRawEvent.StartView ) { val viewScope = RumViewScope.fromEvent( parentScope = this, @@ -289,7 +296,6 @@ internal class RumViewManagerScope( ) applicationDisplayed = true childrenScopes.add(viewScope) - viewScope.handleEvent(RumRawEvent.KeepAlive(), datadogContext, writeScope, writer) viewChangedListener?.onViewChanged( RumViewInfo( key = event.key, @@ -428,7 +434,6 @@ internal class RumViewManagerScope( internal val silentOrphanEventTypes = arrayOf>( RumRawEvent.ApplicationStarted::class.java, - RumRawEvent.KeepAlive::class.java, RumRawEvent.ResetSession::class.java, RumRawEvent.StopView::class.java, RumRawEvent.ActionDropped::class.java, diff --git a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/scope/RumViewScope.kt b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/scope/RumViewScope.kt index e214bd199d..fd3a2c2ac7 100644 --- a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/scope/RumViewScope.kt +++ b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/scope/RumViewScope.kt @@ -226,7 +226,6 @@ internal open class RumViewScope( ) is RumRawEvent.AddCustomTiming -> onAddCustomTiming(event, datadogContext, writeScope, writer) - is RumRawEvent.KeepAlive -> onKeepAlive(event, datadogContext, writeScope, writer) is RumRawEvent.StopSession -> onStopSession(event, datadogContext, writeScope, writer) @@ -898,19 +897,6 @@ internal open class RumViewScope( stopScope(event, datadogContext, writeScope, writer) } - @WorkerThread - private fun onKeepAlive( - event: RumRawEvent.KeepAlive, - datadogContext: DatadogContext, - writeScope: EventWriteScope, - writer: DataWriter - ) { - delegateEventToChildren(event, datadogContext, writeScope, writer) - if (stopped) return - - sendViewUpdate(event, datadogContext, writeScope, writer) - } - @WorkerThread private fun delegateEventToChildren( event: RumRawEvent, @@ -1111,7 +1097,7 @@ internal open class RumViewScope( } @Suppress("LongMethod", "ComplexMethod") - private fun sendViewUpdate( + internal fun sendViewUpdate( event: RumRawEvent, datadogContext: DatadogContext, writeScope: EventWriteScope, diff --git a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/monitor/DatadogRumMonitor.kt b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/monitor/DatadogRumMonitor.kt index 222cd8d917..4a32f73e38 100644 --- a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/monitor/DatadogRumMonitor.kt +++ b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/monitor/DatadogRumMonitor.kt @@ -122,18 +122,10 @@ internal class DatadogRumMonitor( rumSessionScopeStartupManagerFactory = rumSessionScopeStartupManagerFactory ) - internal val keepAliveRunnable = Runnable { - handleEvent(RumRawEvent.KeepAlive()) - } - internal var debugListener: RumDebugListener? = null private val internalProxy = _RumInternalProxy(this) - init { - handler.postDelayed(keepAliveRunnable, KEEP_ALIVE_MS) - } - private val globalAttributes: MutableMap = ConcurrentHashMap() private val isDebugEnabled = AtomicBoolean(false) @@ -804,7 +796,6 @@ internal class DatadogRumMonitor( } else if (event is RumRawEvent.TelemetryEventWrapper) { telemetryEventHandler.handleEvent(event, writer) } else { - handler.removeCallbacks(keepAliveRunnable) sdkCore.getFeature(Feature.RUM_FEATURE_NAME) ?.withWriteContext( withFeatureContexts = setOf(Feature.SESSION_REPLAY_FEATURE_NAME) @@ -822,7 +813,6 @@ internal class DatadogRumMonitor( handleEventWithMethodCallPerf(event, datadogContext, writeScope) notifyDebugListenerWithState() } - handler.postDelayed(keepAliveRunnable, KEEP_ALIVE_MS) currentRumContext() } ) @@ -885,10 +875,6 @@ internal class DatadogRumMonitor( return context } - internal fun stopKeepAliveCallback() { - handler.removeCallbacks(keepAliveRunnable) - } - internal fun notifyDebugListenerWithState() { debugListener?.let { val sessionScope = rootScope.activeSession @@ -928,7 +914,6 @@ internal class DatadogRumMonitor( // endregion companion object { - internal val KEEP_ALIVE_MS = TimeUnit.MINUTES.toMillis(5) // should be aligned with CoreFeature#DRAIN_WAIT_SECONDS, but not a requirement internal const val DRAIN_WAIT_SECONDS = 10L diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumRawEventExt.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumRawEventExt.kt index d2b430bae5..82851074a6 100644 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumRawEventExt.kt +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumRawEventExt.kt @@ -263,7 +263,6 @@ internal fun Forge.silentOrphanEvent(): RumRawEvent { listOf( RumRawEvent.ApplicationStarted(Time(), aLong()), RumRawEvent.ResetSession(), - RumRawEvent.KeepAlive(), RumRawEvent.StopView(getForgery(), emptyMap()), RumRawEvent.ActionSent( fakeId, diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumViewScopeAttributePropagationTest.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumViewScopeAttributePropagationTest.kt index d8e9afd654..fb45dfacb3 100644 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumViewScopeAttributePropagationTest.kt +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumViewScopeAttributePropagationTest.kt @@ -21,7 +21,6 @@ import com.datadog.android.core.internal.net.FirstPartyHostHeaderTypeResolver import com.datadog.android.rum.RumAttributes import com.datadog.android.rum.RumErrorSource import com.datadog.android.rum.RumSessionType -import com.datadog.android.rum.assertj.ActionEventAssert.Companion.assertThat import com.datadog.android.rum.assertj.ErrorEventAssert.Companion.assertThat import com.datadog.android.rum.assertj.LongTaskEventAssert.Companion.assertThat import com.datadog.android.rum.assertj.ViewEventAssert.Companion.assertThat @@ -263,68 +262,6 @@ internal class RumViewScopeAttributePropagationTest { // region Propagate parent attributes in View Event - @Test - fun `M send event with parent attributes W handleEvent(KeepAlive) on active view`() { - // Given - val expectedAttributes = mutableMapOf() - expectedAttributes.putAll(fakeParentAttributes) - testedScope = newRumViewScope(initialAttributes = emptyMap()) - - // When - val result = - testedScope.handleEvent(RumRawEvent.KeepAlive(), fakeDatadogContext, mockEventWriteScope, mockWriter) - - // Then - argumentCaptor { - verify(mockWriter).write(eq(mockEventBatchWriter), capture(), eq(EventType.DEFAULT)) - assertThat(lastValue) - .containsExactlyContextAttributes(expectedAttributes) - } - assertThat(result).isNotNull() - } - - @Test - fun `M send event with both parent and view attributes W handleEvent(KeepAlive) on active view`() { - // Given - val expectedAttributes = mutableMapOf() - expectedAttributes.putAll(fakeParentAttributes) - expectedAttributes.putAll(fakeViewAttributes) - testedScope = newRumViewScope(initialAttributes = fakeViewAttributes) - - // When - val result = - testedScope.handleEvent(RumRawEvent.KeepAlive(), fakeDatadogContext, mockEventWriteScope, mockWriter) - - // Then - argumentCaptor { - verify(mockWriter).write(eq(mockEventBatchWriter), capture(), eq(EventType.DEFAULT)) - assertThat(lastValue) - .containsExactlyContextAttributes(expectedAttributes) - } - assertThat(result).isNotNull() - } - - @Test - fun `M send event with overridden parent attributes W handleEvent(KeepAlive) on active view`( - forge: Forge - ) { - // Given - val overriddenAttributes = fakeParentAttributes.map { it.key to forge.aString() }.toMap() - testedScope = newRumViewScope(initialAttributes = overriddenAttributes) - - // When - val result = - testedScope.handleEvent(RumRawEvent.KeepAlive(), fakeDatadogContext, mockEventWriteScope, mockWriter) - - // Then - argumentCaptor { - verify(mockWriter).write(eq(mockEventBatchWriter), capture(), eq(EventType.DEFAULT)) - assertThat(lastValue) - .containsExactlyContextAttributes(overriddenAttributes) - } - assertThat(result).isNotNull() - } - @Test fun `M send event with original parent attributes W handleEvent(StopView+ErrorSent) on active view`( @StringForgery fakeAttrKey: String, @@ -360,7 +297,7 @@ internal class RumViewScopeAttributePropagationTest { } @Test - fun `M send event with added view attributes W handleEvent(AddViewAttributes+KeepAlive) on active view`() { + fun `M send event with added view attributes W handleEvent(AddViewAttributes+StopView) on active view`() { // Given val expectedAttributes = mutableMapOf() expectedAttributes.putAll(fakeParentAttributes) @@ -368,14 +305,19 @@ internal class RumViewScopeAttributePropagationTest { testedScope = newRumViewScope(initialAttributes = emptyMap()) // When - testedScope.handleEvent( + val result = testedScope.handleEvent( RumRawEvent.AddViewAttributes(fakeViewAttributes), fakeDatadogContext, mockEventWriteScope, mockWriter ) - val result = - testedScope.handleEvent(RumRawEvent.KeepAlive(), fakeDatadogContext, mockEventWriteScope, mockWriter) + + testedScope.handleEvent( + RumRawEvent.StopView(testedScope.key, emptyMap()), + fakeDatadogContext, + mockEventWriteScope, + mockWriter + ) // Then argumentCaptor { @@ -387,7 +329,7 @@ internal class RumViewScopeAttributePropagationTest { } @Test - fun `M send event without removed view attributes W handleEvent(AddViewAttributes+KeepAlive) on active view`( + fun `M send event without removed view attributes W handleEvent(AddViewAttributes+StopView) on active view`( @MapForgery( key = AdvancedForgery(string = [StringForgery(StringForgeryType.ALPHABETICAL)]), value = AdvancedForgery(string = [StringForgery()]) @@ -399,14 +341,19 @@ internal class RumViewScopeAttributePropagationTest { testedScope = newRumViewScope(initialAttributes = fakeViewAttributes) // When - testedScope.handleEvent( + val result = testedScope.handleEvent( RumRawEvent.RemoveViewAttributes(fakeViewAttributes.keys), fakeDatadogContext, mockEventWriteScope, mockWriter ) - val result = - testedScope.handleEvent(RumRawEvent.KeepAlive(), fakeDatadogContext, mockEventWriteScope, mockWriter) + + testedScope.handleEvent( + RumRawEvent.StopView(testedScope.key, emptyMap()), + fakeDatadogContext, + mockEventWriteScope, + mockWriter + ) // Then argumentCaptor { diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumViewScopeTest.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumViewScopeTest.kt index 6914d57816..16f843c93b 100644 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumViewScopeTest.kt +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumViewScopeTest.kt @@ -2414,95 +2414,6 @@ internal class RumViewScopeTest { assertThat(testedScope.pendingLongTaskCount).isEqualTo(pending) } - @Test - fun `M do nothing W handleEvent(KeepAlive) on stopped view`() { - // Given - testedScope.stopped = true - - // When - val result = testedScope.handleEvent( - RumRawEvent.KeepAlive(), - fakeDatadogContext, - mockEventWriteScope, - mockWriter - ) - - // Then - verifyNoInteractions(mockWriter) - assertThat(result).isNull() - } - - @Test - fun `M send event W handleEvent(KeepAlive) on active view`() { - // When - val result = testedScope.handleEvent( - RumRawEvent.KeepAlive(), - fakeDatadogContext, - mockEventWriteScope, - mockWriter - ) - - // Then - argumentCaptor { - verify(mockWriter).write(eq(mockEventBatchWriter), capture(), eq(EventType.DEFAULT)) - assertThat(lastValue) - .apply { - hasTimestamp(resolveExpectedTimestamp(fakeEventTime.timestamp)) - hasName(fakeKey.name) - hasUrl(fakeUrl) - hasDurationGreaterThan(1) - hasVersion(2) - hasErrorCount(0) - hasCrashCount(0) - hasResourceCount(0) - hasActionCount(0) - hasFrustrationCount(0) - hasLongTaskCount(0) - hasFrozenFrameCount(0) - hasCpuMetric(null) - hasMemoryMetric(null, null) - hasRefreshRateMetric(null, null) - isActive(true) - isSlowRendered(false) - hasNoCustomTimings() - hasUserInfo(fakeDatadogContext.userInfo) - hasAccountInfo(fakeDatadogContext.accountInfo) - hasViewId(testedScope.viewId) - hasApplicationId(fakeParentContext.applicationId) - hasSessionId(fakeParentContext.sessionId) - hasSessionType(fakeRumSessionType?.toView() ?: ViewEvent.ViewEventSessionType.USER) - hasNoSyntheticsTest() - hasStartReason(fakeParentContext.sessionStartReason) - hasReplay(fakeHasReplay) - hasReplayStats(fakeReplayStats) - containsExactlyContextAttributes(fakeAttributes) - hasSource(fakeSourceViewEvent) - hasDeviceInfo( - fakeDatadogContext.deviceInfo.deviceName, - fakeDatadogContext.deviceInfo.deviceModel, - fakeDatadogContext.deviceInfo.deviceBrand, - fakeDatadogContext.deviceInfo.deviceType.toViewSchemaType(), - fakeDatadogContext.deviceInfo.architecture - ) - hasOsInfo( - fakeDatadogContext.deviceInfo.osName, - fakeDatadogContext.deviceInfo.osVersion, - fakeDatadogContext.deviceInfo.osMajorVersion - ) - hasSlownessInfo(fakeSlowRecords) - hasConnectivityInfo(fakeDatadogContext.networkInfo) - hasServiceName(fakeDatadogContext.service) - hasVersion(fakeDatadogContext.version) - hasBuildVersion(fakeDatadogContext.versionCode) - hasBuildId(fakeDatadogContext.appBuildId) - hasSessionActive(fakeParentContext.isSessionActive) - hasSampleRate(fakeSampleRate) - } - } - verifyNoMoreInteractions(mockWriter) - assertThat(result).isSameAs(testedScope) - } - @Test fun `M returns null W handleEvent(any) on stopped view {no pending event}`() { // Given @@ -6177,7 +6088,7 @@ internal class RumViewScopeTest { // region Vitals @Test - fun `M send View update W onVitalUpdate()+handleEvent(KeepAlive) {CPU}`( + fun `M send View update W onVitalUpdate()+handleEvent(StopView) {CPU}`( forge: Forge ) { // Given @@ -6193,7 +6104,7 @@ internal class RumViewScopeTest { listener.onVitalUpdate(VitalInfo(index + 1, 0.0, value, value / 2.0)) } val result = testedScope.handleEvent( - RumRawEvent.KeepAlive(), + RumRawEvent.StopView(testedScope.key, emptyMap()), fakeDatadogContext, mockEventWriteScope, mockWriter @@ -6225,7 +6136,7 @@ internal class RumViewScopeTest { hasCpuMetric(expectedTotal) hasMemoryMetric(null, null) hasRefreshRateMetric(null, null) - isActive(true) + isActive(false) isSlowRendered(false) hasNoCustomTimings() hasUserInfo(fakeDatadogContext.userInfo) @@ -6252,7 +6163,7 @@ internal class RumViewScopeTest { fakeDatadogContext.deviceInfo.osVersion, fakeDatadogContext.deviceInfo.osMajorVersion ) - hasSlownessInfo(fakeSlowRecords) + hasSlownessInfo(fakeSlowRecords, fakeSlownessRate, fakeFreezeRate) hasConnectivityInfo(fakeDatadogContext.networkInfo) hasServiceName(fakeDatadogContext.service) hasVersion(fakeDatadogContext.version) @@ -6263,11 +6174,11 @@ internal class RumViewScopeTest { } } verifyNoMoreInteractions(mockWriter) - assertThat(result).isSameAs(testedScope) + assertThat(result).isSameAs(null) } @Test - fun `M send View update W onVitalUpdate()+handleEvent(KeepAlive) {CPU short timespan}`( + fun `M send View update W onVitalUpdate()+handleEvent(StopView) {CPU short timespan}`( @DoubleForgery(1024.0, 65536.0) cpuTicks: Double ) { // Given @@ -6281,7 +6192,7 @@ internal class RumViewScopeTest { listener.onVitalUpdate(VitalInfo(1, 0.0, 0.0, 0.0)) listener.onVitalUpdate(VitalInfo(1, 0.0, cpuTicks, cpuTicks / 2.0)) val result = testedScope.handleEvent( - RumRawEvent.KeepAlive(fakeEventTime), + RumRawEvent.StopView(testedScope.key, emptyMap()), fakeDatadogContext, mockEventWriteScope, mockWriter @@ -6307,7 +6218,7 @@ internal class RumViewScopeTest { hasCpuMetric(cpuTicks) hasMemoryMetric(null, null) hasRefreshRateMetric(null, null) - isActive(true) + isActive(false) isSlowRendered(false) hasNoCustomTimings() hasUserInfo(fakeDatadogContext.userInfo) @@ -6334,7 +6245,7 @@ internal class RumViewScopeTest { fakeDatadogContext.deviceInfo.osVersion, fakeDatadogContext.deviceInfo.osMajorVersion ) - hasSlownessInfo(fakeSlowRecords) + hasSlownessInfo(fakeSlowRecords, fakeSlownessRate, fakeFreezeRate) hasConnectivityInfo(fakeDatadogContext.networkInfo) hasServiceName(fakeDatadogContext.service) hasVersion(fakeDatadogContext.version) @@ -6345,11 +6256,11 @@ internal class RumViewScopeTest { } } verifyNoMoreInteractions(mockWriter) - assertThat(result).isSameAs(testedScope) + assertThat(result).isSameAs(null) } @Test - fun `M send View update W onVitalUpdate()+handleEvent(KeepAlive) {Memory}`( + fun `M send View update W onVitalUpdate()+handleEvent(StopView) {Memory}`( forge: Forge ) { // Given @@ -6362,7 +6273,7 @@ internal class RumViewScopeTest { // When vitals.forEach { listener.onVitalUpdate(it) } val result = testedScope.handleEvent( - RumRawEvent.KeepAlive(), + RumRawEvent.StopView(testedScope.key, emptyMap()), fakeDatadogContext, mockEventWriteScope, mockWriter @@ -6388,7 +6299,7 @@ internal class RumViewScopeTest { hasCpuMetric(null) hasMemoryMetric(vitals.last().meanValue, vitals.last().maxValue) hasRefreshRateMetric(null, null) - isActive(true) + isActive(false) isSlowRendered(false) hasNoCustomTimings() hasUserInfo(fakeDatadogContext.userInfo) @@ -6415,7 +6326,7 @@ internal class RumViewScopeTest { fakeDatadogContext.deviceInfo.osVersion, fakeDatadogContext.deviceInfo.osMajorVersion ) - hasSlownessInfo(fakeSlowRecords) + hasSlownessInfo(fakeSlowRecords, fakeSlownessRate, fakeFreezeRate) hasConnectivityInfo(fakeDatadogContext.networkInfo) hasServiceName(fakeDatadogContext.service) hasVersion(fakeDatadogContext.version) @@ -6426,11 +6337,11 @@ internal class RumViewScopeTest { } } verifyNoMoreInteractions(mockWriter) - assertThat(result).isSameAs(testedScope) + assertThat(result).isSameAs(null) } @Test - fun `M send View update W onVitalUpdate()+handleEvent(KeepAlive) {high frameRate}`( + fun `M send View update W onVitalUpdate()+handleEvent(StopView) {high frameRate}`( forge: Forge ) { // Given @@ -6453,7 +6364,7 @@ internal class RumViewScopeTest { listener.onVitalUpdate(VitalInfo(count, min, max, sum / count)) } val result = testedScope.handleEvent( - RumRawEvent.KeepAlive(), + RumRawEvent.StopView(testedScope.key, emptyMap()), fakeDatadogContext, mockEventWriteScope, mockWriter @@ -6479,7 +6390,7 @@ internal class RumViewScopeTest { hasCpuMetric(null) hasMemoryMetric(null, null) hasRefreshRateMetric(sum / frameRates.size, min) - isActive(true) + isActive(false) isSlowRendered(false) hasNoCustomTimings() hasUserInfo(fakeDatadogContext.userInfo) @@ -6506,7 +6417,7 @@ internal class RumViewScopeTest { fakeDatadogContext.deviceInfo.osVersion, fakeDatadogContext.deviceInfo.osMajorVersion ) - hasSlownessInfo(fakeSlowRecords) + hasSlownessInfo(fakeSlowRecords, fakeSlownessRate, fakeFreezeRate) hasConnectivityInfo(fakeDatadogContext.networkInfo) hasServiceName(fakeDatadogContext.service) hasVersion(fakeDatadogContext.version) @@ -6517,11 +6428,11 @@ internal class RumViewScopeTest { } } verifyNoMoreInteractions(mockWriter) - assertThat(result).isSameAs(testedScope) + assertThat(result).isSameAs(null) } @Test - fun `M send View update W onVitalUpdate()+handleEvent(KeepAlive) {low frameRate}`( + fun `M send View update W onVitalUpdate()+handleEvent(StopView) {low frameRate}`( forge: Forge ) { // Given @@ -6544,7 +6455,7 @@ internal class RumViewScopeTest { listener.onVitalUpdate(VitalInfo(count, min, max, sum / count)) } val result = testedScope.handleEvent( - RumRawEvent.KeepAlive(), + RumRawEvent.StopView(testedScope.key, emptyMap()), fakeDatadogContext, mockEventWriteScope, mockWriter @@ -6570,7 +6481,7 @@ internal class RumViewScopeTest { hasCpuMetric(null) hasMemoryMetric(null, null) hasRefreshRateMetric(sum / frameRates.size, min) - isActive(true) + isActive(false) isSlowRendered(true) hasNoCustomTimings() hasUserInfo(fakeDatadogContext.userInfo) @@ -6597,7 +6508,11 @@ internal class RumViewScopeTest { fakeDatadogContext.deviceInfo.osVersion, fakeDatadogContext.deviceInfo.osMajorVersion ) - hasSlownessInfo(fakeSlowRecords) + hasSlownessInfo( + fakeSlowRecords, + fakeSlownessRate, + fakeFreezeRate + ) hasConnectivityInfo(fakeDatadogContext.networkInfo) hasServiceName(fakeDatadogContext.service) hasVersion(fakeDatadogContext.version) @@ -6608,7 +6523,7 @@ internal class RumViewScopeTest { } } verifyNoMoreInteractions(mockWriter) - assertThat(result).isSameAs(testedScope) + assertThat(result).isSameAs(null) } @Test @@ -6898,14 +6813,14 @@ internal class RumViewScopeTest { // region Cross-platform performance metrics @Test - fun `M send update W handleEvent(UpdatePerformanceMetric+KeepAlive) { FlutterBuildTime }`( + fun `M send update W handleEvent(UpdatePerformanceMetric+StopView) { FlutterBuildTime }`( forge: Forge ) { // GIVEN val value = forge.aDouble() // WHEN - testedScope.handleEvent( + val result = testedScope.handleEvent( RumRawEvent.UpdatePerformanceMetric( metric = RumPerformanceMetric.FLUTTER_BUILD_TIME, value = value @@ -6914,8 +6829,8 @@ internal class RumViewScopeTest { mockEventWriteScope, mockWriter ) - val result = testedScope.handleEvent( - RumRawEvent.KeepAlive(), + testedScope.handleEvent( + RumRawEvent.StopView(testedScope.key, emptyMap()), fakeDatadogContext, mockEventWriteScope, mockWriter @@ -6936,14 +6851,14 @@ internal class RumViewScopeTest { } @Test - fun `M send update W handleEvent(UpdatePerformanceMetric+KeepAlive) { FlutterRasterTime }`( + fun `M send update W handleEvent(UpdatePerformanceMetric+StopView) { FlutterRasterTime }`( forge: Forge ) { // GIVEN val value = forge.aDouble() // WHEN - testedScope.handleEvent( + val result = testedScope.handleEvent( RumRawEvent.UpdatePerformanceMetric( metric = RumPerformanceMetric.FLUTTER_RASTER_TIME, value = value @@ -6952,8 +6867,8 @@ internal class RumViewScopeTest { mockEventWriteScope, mockWriter ) - val result = testedScope.handleEvent( - RumRawEvent.KeepAlive(), + testedScope.handleEvent( + RumRawEvent.StopView(testedScope.key, emptyMap()), fakeDatadogContext, mockEventWriteScope, mockWriter @@ -6974,7 +6889,7 @@ internal class RumViewScopeTest { } @Test - fun `M send View update W handleEvent(UpdatePerformanceMetric+KeepAlive) { JsRefreshRate }`( + fun `M send View update W handleEvent(UpdatePerformanceMetric+StopView) { JsRefreshRate }`( forge: Forge ) { // GIVEN @@ -6982,7 +6897,7 @@ internal class RumViewScopeTest { val frameRate = TimeUnit.SECONDS.toNanos(1) / value // WHEN - testedScope.handleEvent( + val result = testedScope.handleEvent( RumRawEvent.UpdatePerformanceMetric( metric = RumPerformanceMetric.JS_FRAME_TIME, value = value @@ -6991,8 +6906,8 @@ internal class RumViewScopeTest { mockEventWriteScope, mockWriter ) - val result = testedScope.handleEvent( - RumRawEvent.KeepAlive(), + testedScope.handleEvent( + RumRawEvent.StopView(testedScope.key, emptyMap()), fakeDatadogContext, mockEventWriteScope, mockWriter @@ -7020,7 +6935,7 @@ internal class RumViewScopeTest { } @Test - fun `M send View update with all values W handleEvent(UpdatePerformanceMetric+KeepAlive)`( + fun `M send View update with all values W handleEvent(UpdatePerformanceMetric+StopView)`( forge: Forge ) { // GIVEN @@ -7058,8 +6973,8 @@ internal class RumViewScopeTest { mockWriter ) } - val result = testedScope.handleEvent( - RumRawEvent.KeepAlive(), + testedScope.handleEvent( + RumRawEvent.StopView(testedScope.key, emptyMap()), fakeDatadogContext, mockEventWriteScope, mockWriter @@ -7097,7 +7012,6 @@ internal class RumViewScopeTest { } } verifyNoMoreInteractions(mockWriter) - assertThat(result).isSameAs(testedScope) } // endregion @@ -7105,7 +7019,7 @@ internal class RumViewScopeTest { // region External Refresh Rate @Test - fun `M send update W handleEvent(UpdateExternalRefreshRate+KeepAlive) { single value }`( + fun `M send update W handleEvent(UpdateExternalRefreshRate+StopView) { single value }`( forge: Forge ) { // GIVEN @@ -7114,14 +7028,14 @@ internal class RumViewScopeTest { val expectedRefreshRateMin = expectedRefreshRate // WHEN - testedScope.handleEvent( + val result = testedScope.handleEvent( RumRawEvent.UpdateExternalRefreshRate(frameTimeSeconds), fakeDatadogContext, mockEventWriteScope, mockWriter ) - val result = testedScope.handleEvent( - RumRawEvent.KeepAlive(), + testedScope.handleEvent( + RumRawEvent.StopView(testedScope.key, emptyMap()), fakeDatadogContext, mockEventWriteScope, mockWriter @@ -7138,7 +7052,7 @@ internal class RumViewScopeTest { } @Test - fun `M send update W handleEvent(UpdateExternalRefreshRate+KeepAlive) { multiple values }`( + fun `M send update W handleEvent(UpdateExternalRefreshRate+StopView) { multiple values }`( forge: Forge ) { // GIVEN @@ -7152,6 +7066,7 @@ internal class RumViewScopeTest { val refreshRates = mutableListOf() // WHEN + var result: RumScope? = null frameTimesSeconds.forEach { frameTime -> val refreshRate = 1.0 / frameTime refreshRates.add(refreshRate) @@ -7159,7 +7074,7 @@ internal class RumViewScopeTest { min = min(min, refreshRate) max = max(max, refreshRate) - testedScope.handleEvent( + result = testedScope.handleEvent( RumRawEvent.UpdateExternalRefreshRate(frameTime), fakeDatadogContext, mockEventWriteScope, @@ -7167,8 +7082,8 @@ internal class RumViewScopeTest { ) } - val result = testedScope.handleEvent( - RumRawEvent.KeepAlive(), + testedScope.handleEvent( + RumRawEvent.StopView(testedScope.key, emptyMap()), fakeDatadogContext, mockEventWriteScope, mockWriter @@ -7186,16 +7101,16 @@ internal class RumViewScopeTest { } @Test - fun `M ignore invalid frame time W handleEvent(UpdateExternalRefreshRate+KeepAlive) { zero frame time }`() { + fun `M ignore invalid frame time W handleEvent(UpdateExternalRefreshRate+StopView) { zero frame time }`() { // WHEN - testedScope.handleEvent( + val result = testedScope.handleEvent( RumRawEvent.UpdateExternalRefreshRate(0.0), fakeDatadogContext, mockEventWriteScope, mockWriter ) - val result = testedScope.handleEvent( - RumRawEvent.KeepAlive(), + testedScope.handleEvent( + RumRawEvent.StopView(testedScope.key, emptyMap()), fakeDatadogContext, mockEventWriteScope, mockWriter @@ -7212,7 +7127,7 @@ internal class RumViewScopeTest { } @Test - fun `M prioritize external data W handleEvent(UpdateExternalRefreshRate+VitalUpdate+KeepAlive)`( + fun `M prioritize external data W handleEvent(UpdateExternalRefreshRate+VitalUpdate+StopView)`( forge: Forge ) { // GIVEN @@ -7226,7 +7141,7 @@ internal class RumViewScopeTest { val vitalListener = listenerCaptor.firstValue // WHEN - testedScope.handleEvent( + val result = testedScope.handleEvent( RumRawEvent.UpdateExternalRefreshRate(externalFrameTime), fakeDatadogContext, mockEventWriteScope, @@ -7236,8 +7151,8 @@ internal class RumViewScopeTest { // AND vitalListener.onVitalUpdate(VitalInfo(1, internalRefreshRate, internalRefreshRate, internalRefreshRate)) - val result = testedScope.handleEvent( - RumRawEvent.KeepAlive(), + testedScope.handleEvent( + RumRawEvent.StopView(testedScope.key, emptyMap()), fakeDatadogContext, mockEventWriteScope, mockWriter @@ -7268,7 +7183,7 @@ internal class RumViewScopeTest { vitalListener.onVitalUpdate(VitalInfo(1, internalRefreshRate, internalRefreshRate, internalRefreshRate)) val result = testedScope.handleEvent( - RumRawEvent.KeepAlive(), + RumRawEvent.StopView(testedScope.key, emptyMap()), fakeDatadogContext, mockEventWriteScope, mockWriter @@ -7281,7 +7196,7 @@ internal class RumViewScopeTest { .hasRefreshRateMetric(internalRefreshRate, internalRefreshRate) } verifyNoMoreInteractions(mockWriter) - assertThat(result).isSameAs(testedScope) + assertThat(result).isSameAs(null) } @Test @@ -7337,15 +7252,15 @@ internal class RumViewScopeTest { mockEventWriteScope, mockWriter ) - testedScope.handleEvent( + val result = testedScope.handleEvent( RumRawEvent.UpdateExternalRefreshRate(frameTime3), fakeDatadogContext, mockEventWriteScope, mockWriter ) - val result = testedScope.handleEvent( - RumRawEvent.KeepAlive(), + testedScope.handleEvent( + RumRawEvent.StopView(testedScope.key, emptyMap()), fakeDatadogContext, mockEventWriteScope, mockWriter @@ -7366,14 +7281,14 @@ internal class RumViewScopeTest { // region Internal attributes @Test - fun `M send View update with fbc metric W handleEvent(SetInternalViewAttribute+KeepAlive)`( + fun `M send View update with fbc metric W handleEvent(SetInternalViewAttribute+StopView)`( forge: Forge ) { // GIVEN val fbc = forge.aPositiveLong() // WHEN - testedScope.handleEvent( + val result = testedScope.handleEvent( RumRawEvent.SetInternalViewAttribute( key = RumAttributes.FLUTTER_FIRST_BUILD_COMPLETE, value = fbc @@ -7382,8 +7297,8 @@ internal class RumViewScopeTest { mockEventWriteScope, mockWriter ) - val result = testedScope.handleEvent( - RumRawEvent.KeepAlive(), + testedScope.handleEvent( + RumRawEvent.StopView(testedScope.key, emptyMap()), fakeDatadogContext, mockEventWriteScope, mockWriter @@ -7400,7 +7315,7 @@ internal class RumViewScopeTest { } @Test - fun `M send View update with custom inv metric W handleEvent(inv disabled+SetInternalViewAttribute+KeepAlive)`( + fun `M send View update with custom inv metric W handleEvent(inv disabled+SetInternalViewAttribute+StopView)`( forge: Forge ) { // GIVEN @@ -7413,7 +7328,7 @@ internal class RumViewScopeTest { val customInv = forge.aPositiveLong() // WHEN - testedScope.handleEvent( + val result = testedScope.handleEvent( RumRawEvent.SetInternalViewAttribute( key = RumAttributes.CUSTOM_INV_VALUE, value = customInv @@ -7422,8 +7337,8 @@ internal class RumViewScopeTest { mockEventWriteScope, mockWriter ) - val result = testedScope.handleEvent( - RumRawEvent.KeepAlive(), + testedScope.handleEvent( + RumRawEvent.StopView(testedScope.key, emptyMap()), fakeDatadogContext, mockEventWriteScope, mockWriter @@ -8276,7 +8191,6 @@ internal class RumViewScopeTest { fun `M call resolveReport(viewId, false) of slowFramesListener W handleEvent()`(forge: Forge) { // Given val nonTerminalViewUpdateEvents = listOf( - forge.getForgery(), forge.getForgery(), forge.getForgery(), forge.getForgery(), @@ -9135,12 +9049,6 @@ internal class RumViewScopeTest { val fakeName = forge.anAlphabeticalString() val eventTime = Time(0, 0) return listOf( - RumRawEventData( - RumRawEvent.KeepAlive( - eventTime = eventTime - ), - fakeKey - ), RumRawEventData( RumRawEvent.AddCustomTiming( name = fakeName, diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/monitor/DatadogRumMonitorTest.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/monitor/DatadogRumMonitorTest.kt index 3670397b96..80eea0b596 100644 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/monitor/DatadogRumMonitorTest.kt +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/monitor/DatadogRumMonitorTest.kt @@ -1944,65 +1944,6 @@ internal class DatadogRumMonitorTest { verifyNoMoreInteractions(mockWriter) } - @Test - fun `sends keep alive event to rootScope regularly`() { - argumentCaptor { - inOrder(mockApplicationScope, mockWriter, mockHandler) { - verify(mockHandler).postDelayed(capture(), eq(DatadogRumMonitor.KEEP_ALIVE_MS)) - verifyNoInteractions(mockApplicationScope) - val runnable = firstValue - runnable.run() - verify(mockHandler).removeCallbacks(same(runnable)) - verify(mockApplicationScope).handleEvent( - argThat { this is RumRawEvent.KeepAlive }, - same(fakeDatadogContext), - same(mockEventWriteScope), - same(mockWriter) - ) - verify(mockHandler).postDelayed(same(runnable), eq(DatadogRumMonitor.KEEP_ALIVE_MS)) - verify(mockApplicationScope).activeSession - verify(mockApplicationScope).getRumContext() - verifyNoMoreInteractions() - } - } - } - - @Test - fun `delays keep alive runnable on other event`() { - val mockEvent: RumRawEvent = mock() - val runnable = testedMonitor.keepAliveRunnable - - testedMonitor.handleEvent(mockEvent) - - argumentCaptor { - inOrder(mockApplicationScope, mockWriter, mockHandler) { - verify(mockHandler).removeCallbacks(same(runnable)) - verify(mockApplicationScope).handleEvent( - same(mockEvent), - same(fakeDatadogContext), - same(mockEventWriteScope), - same(mockWriter) - ) - verify(mockHandler).postDelayed(same(runnable), eq(DatadogRumMonitor.KEEP_ALIVE_MS)) - verify(mockApplicationScope).activeSession - verify(mockApplicationScope).getRumContext() - verifyNoMoreInteractions() - } - } - } - - @Test - fun `removes callback from handler on stopKeepAliveCallback`() { - // When - testedMonitor.stopKeepAliveCallback() - - // Then - // initial post - verify(mockHandler).postDelayed(any(), any()) - verify(mockHandler).removeCallbacks(same(testedMonitor.keepAliveRunnable)) - verifyNoMoreInteractions(mockHandler, mockWriter, mockApplicationScope) - } - @Test fun `M drain the executor queue W drainExecutorService()`(forge: Forge) { // Given diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/utils/forge/Configurator.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/utils/forge/Configurator.kt index e5d0c32dd8..16fa387995 100644 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/utils/forge/Configurator.kt +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/utils/forge/Configurator.kt @@ -79,7 +79,6 @@ internal class Configurator : BaseConfigurator() { forge.addFactory(AddFeatureFlagEvaluationForgeryFactory()) forge.addFactory(AddFeatureFlagEvaluationsForgeryFactory()) forge.addFactory(ErrorSentForgeryFactory()) - forge.addFactory(KeepAliveForgeryFactory()) forge.addFactory(LongTaskSentForgeryFactory()) } } diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/utils/forge/KeepAliveForgeryFactory.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/utils/forge/KeepAliveForgeryFactory.kt deleted file mode 100644 index ee0b7d4e07..0000000000 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/utils/forge/KeepAliveForgeryFactory.kt +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0. - * This product includes software developed at Datadog (https://www.datadoghq.com/). - * Copyright 2016-Present Datadog, Inc. - */ -package com.datadog.android.rum.utils.forge - -import com.datadog.android.rum.internal.domain.scope.RumRawEvent -import fr.xgouchet.elmyr.Forge -import fr.xgouchet.elmyr.ForgeryFactory - -internal class KeepAliveForgeryFactory : ForgeryFactory { - override fun getForgery(forge: Forge) = RumRawEvent.KeepAlive() -}