Skip to content

Commit 1b90579

Browse files
authored
Merge pull request #2729 from DataDog/nogorodnikov/rum-10348/remove-feature-name-argument-from-add-remove-featurecontextupdate-receiver
RUM-10348: Remove feature name argument from APIs to set/remove feature context update listener
2 parents 97821b7 + c382035 commit 1b90579

File tree

19 files changed

+155
-312
lines changed

19 files changed

+155
-312
lines changed

dd-sdk-android-core/api/apiSurface

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,9 +130,9 @@ interface com.datadog.android.api.feature.FeatureSdkCore : com.datadog.android.a
130130
fun updateFeatureContext(String, Boolean = true, (MutableMap<String, Any?>) -> Unit)
131131
fun getFeatureContext(String, Boolean = true): Map<String, Any?>
132132
fun setEventReceiver(String, FeatureEventReceiver)
133-
fun setContextUpdateReceiver(String, FeatureContextUpdateReceiver)
134-
fun removeContextUpdateReceiver(String, FeatureContextUpdateReceiver)
135133
fun removeEventReceiver(String)
134+
fun setContextUpdateReceiver(FeatureContextUpdateReceiver)
135+
fun removeContextUpdateReceiver(FeatureContextUpdateReceiver)
136136
fun createSingleThreadExecutorService(String): java.util.concurrent.ExecutorService
137137
fun createScheduledExecutorService(String): java.util.concurrent.ScheduledExecutorService
138138
fun setAnonymousId(java.util.UUID?)

dd-sdk-android-core/api/dd-sdk-android-core.api

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -402,10 +402,10 @@ public abstract interface class com/datadog/android/api/feature/FeatureSdkCore :
402402
public abstract fun getFeatureContext (Ljava/lang/String;Z)Ljava/util/Map;
403403
public abstract fun getInternalLogger ()Lcom/datadog/android/api/InternalLogger;
404404
public abstract fun registerFeature (Lcom/datadog/android/api/feature/Feature;)V
405-
public abstract fun removeContextUpdateReceiver (Ljava/lang/String;Lcom/datadog/android/api/feature/FeatureContextUpdateReceiver;)V
405+
public abstract fun removeContextUpdateReceiver (Lcom/datadog/android/api/feature/FeatureContextUpdateReceiver;)V
406406
public abstract fun removeEventReceiver (Ljava/lang/String;)V
407407
public abstract fun setAnonymousId (Ljava/util/UUID;)V
408-
public abstract fun setContextUpdateReceiver (Ljava/lang/String;Lcom/datadog/android/api/feature/FeatureContextUpdateReceiver;)V
408+
public abstract fun setContextUpdateReceiver (Lcom/datadog/android/api/feature/FeatureContextUpdateReceiver;)V
409409
public abstract fun setEventReceiver (Ljava/lang/String;Lcom/datadog/android/api/feature/FeatureEventReceiver;)V
410410
public abstract fun updateFeatureContext (Ljava/lang/String;ZLkotlin/jvm/functions/Function1;)V
411411
}

dd-sdk-android-core/src/main/kotlin/com/datadog/android/api/feature/FeatureContextUpdateReceiver.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ fun interface FeatureContextUpdateReceiver {
1616
/**
1717
* Called when the context for a feature is updated.
1818
* @param featureName the name of the feature
19-
* @param event the updated context
19+
* @param context the updated context
2020
*/
2121
@AnyThread
22-
fun onContextUpdate(featureName: String, event: Map<String, Any?>)
22+
fun onContextUpdate(featureName: String, context: Map<String, Any?>)
2323
}

dd-sdk-android-core/src/main/kotlin/com/datadog/android/api/feature/FeatureSdkCore.kt

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -79,28 +79,26 @@ interface FeatureSdkCore : SdkCore {
7979
fun setEventReceiver(featureName: String, receiver: FeatureEventReceiver)
8080

8181
/**
82-
* Sets context update receiver for the given feature. Once subscribed, current context will be emitted
83-
* immdediately if it exists.
82+
* Removes events receive for the given feature.
8483
*
8584
* @param featureName Feature name.
86-
* @param listener Listener to remove.
8785
*/
88-
fun setContextUpdateReceiver(featureName: String, listener: FeatureContextUpdateReceiver)
86+
fun removeEventReceiver(featureName: String)
8987

9088
/**
91-
* Removes context update listener for the given feature.
89+
* Sets feature context update listener. Once subscribed, current context will be emitted
90+
* immdediately if it exists.
9291
*
93-
* @param featureName Feature name.
9492
* @param listener Listener to remove.
9593
*/
96-
fun removeContextUpdateReceiver(featureName: String, listener: FeatureContextUpdateReceiver)
94+
fun setContextUpdateReceiver(listener: FeatureContextUpdateReceiver)
9795

9896
/**
99-
* Removes events receive for the given feature.
97+
* Removes feature context update listener.
10098
*
101-
* @param featureName Feature name.
99+
* @param listener Listener to remove.
102100
*/
103-
fun removeEventReceiver(featureName: String)
101+
fun removeContextUpdateReceiver(listener: FeatureContextUpdateReceiver)
104102

105103
/**
106104
* Returns a new single thread [ExecutorService], set up with backpressure and internal monitoring.

dd-sdk-android-core/src/main/kotlin/com/datadog/android/core/internal/DatadogCore.kt

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ import com.datadog.android.ndk.internal.NdkCrashHandler
4545
import com.datadog.android.privacy.TrackingConsent
4646
import com.google.gson.JsonObject
4747
import java.io.File
48+
import java.util.Collections
4849
import java.util.Locale
4950
import java.util.UUID
5051
import java.util.concurrent.Callable
@@ -89,6 +90,10 @@ internal class DatadogCore(
8990

9091
private var processLifecycleMonitor: ProcessLifecycleMonitor? = null
9192

93+
@Suppress("UnsafeThirdPartyFunctionCall") // the argument is always empty
94+
internal val featureContextUpdateReceivers: MutableSet<FeatureContextUpdateReceiver> =
95+
Collections.newSetFromMap(ConcurrentHashMap<FeatureContextUpdateReceiver, Boolean>())
96+
9297
// region SdkCore
9398

9499
/** @inheritDoc */
@@ -233,8 +238,8 @@ internal class DatadogCore(
233238
feature.featureContextLock.writeLock().safeTryWithLock(1, TimeUnit.SECONDS) {
234239
val currentContext = feature.featureContext
235240
updateCallback(currentContext)
236-
features.values.forEach {
237-
it.notifyContextUpdated(featureName, currentContext)
241+
featureContextUpdateReceivers.forEach {
242+
it.onContextUpdate(featureName, currentContext)
238243
}
239244
}
240245
}
@@ -298,28 +303,27 @@ internal class DatadogCore(
298303
}
299304
}
300305

301-
@Suppress("NestedBlockDepth")
302-
override fun setContextUpdateReceiver(featureName: String, listener: FeatureContextUpdateReceiver) {
303-
val feature = features[featureName]
304-
if (feature == null) {
306+
override fun setContextUpdateReceiver(listener: FeatureContextUpdateReceiver) {
307+
// the argument is always non - null, so we can suppress the warning
308+
@Suppress("UnsafeThirdPartyFunctionCall")
309+
if (featureContextUpdateReceivers.contains(listener)) {
305310
internalLogger.log(
306311
InternalLogger.Level.WARN,
307312
InternalLogger.Target.USER,
308-
{ MISSING_FEATURE_FOR_CONTEXT_UPDATE_LISTENER.format(Locale.US, featureName) }
313+
{ CONTEXT_UPDATE_LISTENER_ALREADY_REGISTERED.format(Locale.US, listener) }
309314
)
310-
} else {
311-
feature.setContextUpdateListener(listener)
312-
features.forEach {
313-
val currentContext = getFeatureContext(it.key, false)
314-
if (currentContext.isNotEmpty()) {
315-
listener.onContextUpdate(it.key, currentContext)
316-
}
315+
}
316+
features.forEach {
317+
val currentContext = getFeatureContext(it.key, false)
318+
if (currentContext.isNotEmpty()) {
319+
listener.onContextUpdate(it.key, currentContext)
317320
}
318321
}
322+
featureContextUpdateReceivers.add(listener)
319323
}
320324

321-
override fun removeContextUpdateReceiver(featureName: String, listener: FeatureContextUpdateReceiver) {
322-
features[featureName]?.removeContextUpdateListener(listener)
325+
override fun removeContextUpdateReceiver(listener: FeatureContextUpdateReceiver) {
326+
featureContextUpdateReceivers.remove(listener)
323327
}
324328

325329
/** @inheritDoc */
@@ -736,6 +740,9 @@ internal class DatadogCore(
736740
"No need to write last RUM view event: NDK" +
737741
" crash reports feature is not enabled and API is below 30."
738742

743+
internal const val CONTEXT_UPDATE_LISTENER_ALREADY_REGISTERED =
744+
"SDK core already has \"%s\" listener registered."
745+
739746
internal val CONFIGURATION_TELEMETRY_DELAY_MS = TimeUnit.SECONDS.toMillis(5)
740747

741748
// fallback for APIs below Android N, see [DefaultAppStartTimeProvider].

dd-sdk-android-core/src/main/kotlin/com/datadog/android/core/internal/NoOpInternalSdkCore.kt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,12 +123,10 @@ internal object NoOpInternalSdkCore : InternalSdkCore {
123123
override fun removeEventReceiver(featureName: String) = Unit
124124

125125
override fun setContextUpdateReceiver(
126-
featureName: String,
127126
listener: FeatureContextUpdateReceiver
128127
) = Unit
129128

130129
override fun removeContextUpdateReceiver(
131-
featureName: String,
132130
listener: FeatureContextUpdateReceiver
133131
) = Unit
134132

dd-sdk-android-core/src/main/kotlin/com/datadog/android/core/internal/SdkFeature.kt

Lines changed: 0 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import com.datadog.android.api.InternalLogger
1414
import com.datadog.android.api.context.DatadogContext
1515
import com.datadog.android.api.feature.EventWriteScope
1616
import com.datadog.android.api.feature.Feature
17-
import com.datadog.android.api.feature.FeatureContextUpdateReceiver
1817
import com.datadog.android.api.feature.FeatureEventReceiver
1918
import com.datadog.android.api.feature.FeatureScope
2019
import com.datadog.android.api.feature.StorageBackedFeature
@@ -60,10 +59,8 @@ import com.datadog.android.internal.profiler.BenchmarkSdkUploads
6059
import com.datadog.android.internal.profiler.GlobalBenchmark
6160
import com.datadog.android.privacy.TrackingConsentProviderCallback
6261
import com.datadog.android.security.Encryption
63-
import java.util.Collections
6462
import java.util.Locale
6563
import java.util.concurrent.Callable
66-
import java.util.concurrent.ConcurrentHashMap
6764
import java.util.concurrent.atomic.AtomicBoolean
6865
import java.util.concurrent.atomic.AtomicReference
6966
import java.util.concurrent.locks.ReadWriteLock
@@ -81,10 +78,6 @@ internal class SdkFeature(
8178
override var dataStore: DataStoreHandler = NoOpDataStoreHandler()
8279

8380
internal val initialized = AtomicBoolean(false)
84-
85-
@Suppress("UnsafeThirdPartyFunctionCall") // the argument is always empty
86-
internal val contextUpdateListeners =
87-
Collections.newSetFromMap(ConcurrentHashMap<FeatureContextUpdateReceiver, Boolean>())
8881
internal val eventReceiver = AtomicReference<FeatureEventReceiver>(null)
8982
internal var storage: Storage = NoOpStorage()
9083
internal var uploader: DataUploader = NoOpDataUploader()
@@ -238,39 +231,6 @@ internal class SdkFeature(
238231

239232
// endregion
240233

241-
// region Context Update Listener
242-
243-
internal fun notifyContextUpdated(featureName: String, context: Map<String, Any?>) {
244-
contextUpdateListeners.forEach {
245-
it.onContextUpdate(featureName, context)
246-
}
247-
}
248-
249-
internal fun setContextUpdateListener(listener: FeatureContextUpdateReceiver) {
250-
synchronized(contextUpdateListeners) {
251-
// the argument is always non - null, so we can suppress the warning
252-
@Suppress("UnsafeThirdPartyFunctionCall")
253-
if (contextUpdateListeners.contains(listener)) {
254-
internalLogger.log(
255-
InternalLogger.Level.WARN,
256-
InternalLogger.Target.USER,
257-
{ CONTEXT_UPDATE_LISTENER_ALREADY_EXISTS.format(Locale.US, wrappedFeature.name) }
258-
)
259-
}
260-
contextUpdateListeners.add(listener)
261-
}
262-
}
263-
264-
internal fun removeContextUpdateListener(listener: FeatureContextUpdateReceiver) {
265-
synchronized(contextUpdateListeners) {
266-
@Suppress("UnsafeThirdPartyFunctionCall")
267-
// the argument is always non - null, so we can suppress the warning
268-
contextUpdateListeners.remove(listener)
269-
}
270-
}
271-
272-
// endregion
273-
274234
// region Internal
275235

276236
private fun createBatchCountBenchmark() {
@@ -485,8 +445,6 @@ internal class SdkFeature(
485445
// endregion
486446

487447
companion object {
488-
internal const val CONTEXT_UPDATE_LISTENER_ALREADY_EXISTS =
489-
"Feature \"%s\" already has this listener registered."
490448
const val NO_EVENT_RECEIVER =
491449
"Feature \"%s\" has no event receiver registered, ignoring event."
492450
internal const val TRACK_NAME = "track"

0 commit comments

Comments
 (0)