Skip to content

Commit b5ac016

Browse files
Fix RumWindowCallbacksRegistry for multiple SDK instances
1 parent bc35e34 commit b5ac016

File tree

2 files changed

+62
-14
lines changed

2 files changed

+62
-14
lines changed

features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/utils/window/RumWindowCallbacksRegistry.kt

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -44,26 +44,28 @@ internal class RumWindowCallbacksRegistryImpl : RumWindowCallbacksRegistry {
4444
}
4545
}
4646
}
47-
}
4847

49-
private fun Window.wrapCallback(): RumWindowCallback {
50-
val currentCallback = callback
51-
val newCallback = RumWindowCallback(
52-
wrapped = currentCallback
53-
)
54-
callback = newCallback
55-
return newCallback
56-
}
48+
private fun Window.wrapCallback(): RumWindowCallback {
49+
val currentCallback = callback
50+
val newCallback = RumWindowCallback(
51+
wrapped = currentCallback,
52+
registry = this@RumWindowCallbacksRegistryImpl
53+
)
54+
callback = newCallback
55+
return newCallback
56+
}
5757

58-
private fun Window.tryToRemoveCallback() {
59-
val currentCallback = callback
60-
if (currentCallback is RumWindowCallback) {
61-
callback = currentCallback.wrapped
58+
private fun Window.tryToRemoveCallback() {
59+
val currentCallback = callback
60+
if (currentCallback is RumWindowCallback && currentCallback.registry === this@RumWindowCallbacksRegistryImpl) {
61+
callback = currentCallback.wrapped
62+
}
6263
}
6364
}
6465

6566
private class RumWindowCallback(
66-
val wrapped: Window.Callback
67+
val wrapped: Window.Callback,
68+
val registry: RumWindowCallbacksRegistry
6769
) : FixedWindowCallback(wrapped) {
6870

6971
val subscription = DDCoreSubscription.create<RumWindowCallbackListener>()

features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/utils/RumWindowCallbacksRegistryTest.kt

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,52 @@ class RumWindowCallbacksRegistryTest {
130130
// Then
131131
assertThat(callback).isEqualTo(anotherWrapper)
132132
}
133+
134+
@Test
135+
fun `M not restore the callback W removeListener { if there is another RumWindowCallbacksRegistry }`() {
136+
// Given
137+
val anotherRegistry = RumWindowCallbacksRegistryImpl()
138+
val anotherListener = mock<RumWindowCallbackListener>()
139+
140+
registry.addListener(activity, listener)
141+
val callback1 = window.callback
142+
143+
anotherRegistry.addListener(activity, anotherListener)
144+
val callback2 = window.callback
145+
146+
// When
147+
registry.removeListener(activity, listener)
148+
149+
// Then
150+
assertThat(callback1).isNotEqualTo(callback2)
151+
assertThat(window.callback).isEqualTo(callback2)
152+
}
153+
154+
@Test
155+
fun `M call listeners from both RumWindowCallbacksRegistries W addListener { onContentChanged called }`() {
156+
// Given
157+
val anotherRegistry = RumWindowCallbacksRegistryImpl()
158+
val anotherListener = mock<RumWindowCallbackListener>()
159+
160+
registry.addListener(activity, listener)
161+
val callback1 = window.callback
162+
163+
anotherRegistry.addListener(activity, anotherListener)
164+
val callback2 = window.callback
165+
166+
// When
167+
callback.onContentChanged()
168+
169+
// Then
170+
inOrder(listener, existingCallback, anotherListener) {
171+
verify(existingCallback).onContentChanged()
172+
verify(listener).onContentChanged()
173+
verify(anotherListener).onContentChanged()
174+
verifyNoMoreInteractions()
175+
}
176+
assertThat(callback1).isNotEqualTo(callback2)
177+
assertThat(window.callback).isEqualTo(callback2)
178+
}
133179
}
134180

135181
private class TestWindowCallbackWrapper(wrapped: Window.Callback) : FixedWindowCallback(wrapped)

0 commit comments

Comments
 (0)