Skip to content

Commit 7153c75

Browse files
committed
RUM-11120: Use generics in InfoProvider
1 parent a390640 commit 7153c75

32 files changed

+361
-812
lines changed

features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/RumFeature.kt

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,19 @@ import com.datadog.android.rum.configuration.VitalsUpdateFrequency
4343
import com.datadog.android.rum.internal.anr.ANRDetectorRunnable
4444
import com.datadog.android.rum.internal.debug.UiRumDebugListener
4545
import com.datadog.android.rum.internal.domain.InfoProvider
46-
import com.datadog.android.rum.internal.domain.NoOpInfoProvider
4746
import com.datadog.android.rum.internal.domain.RumDataWriter
47+
import com.datadog.android.rum.internal.domain.accessibility.AccessibilityInfo
4848
import com.datadog.android.rum.internal.domain.accessibility.AccessibilitySnapshotManager
49-
import com.datadog.android.rum.internal.domain.accessibility.DatadogAccessibilityReader
49+
import com.datadog.android.rum.internal.domain.accessibility.DefaultAccessibilityReader
5050
import com.datadog.android.rum.internal.domain.accessibility.DefaultAccessibilitySnapshotManager
51+
import com.datadog.android.rum.internal.domain.accessibility.NoOpAccessibilityReader
5152
import com.datadog.android.rum.internal.domain.accessibility.NoOpAccessibilitySnapshotManager
53+
import com.datadog.android.rum.internal.domain.battery.BatteryInfo
5254
import com.datadog.android.rum.internal.domain.battery.DefaultBatteryInfoProvider
55+
import com.datadog.android.rum.internal.domain.battery.NoOpBatteryInfoProvider
5356
import com.datadog.android.rum.internal.domain.display.DefaultDisplayInfoProvider
57+
import com.datadog.android.rum.internal.domain.display.DisplayInfo
58+
import com.datadog.android.rum.internal.domain.display.NoOpDisplayInfoProvider
5459
import com.datadog.android.rum.internal.domain.event.RumEventMapper
5560
import com.datadog.android.rum.internal.domain.event.RumEventMetaDeserializer
5661
import com.datadog.android.rum.internal.domain.event.RumEventMetaSerializer
@@ -153,11 +158,11 @@ internal class RumFeature(
153158
internal var initialResourceIdentifier: InitialResourceIdentifier = NoOpInitialResourceIdentifier()
154159
internal var lastInteractionIdentifier: LastInteractionIdentifier? = NoOpLastInteractionIdentifier()
155160
internal var slowFramesListener: SlowFramesListener? = null
156-
internal var accessibilityReader: InfoProvider = NoOpInfoProvider()
161+
internal var accessibilityReader: InfoProvider<AccessibilityInfo> = NoOpAccessibilityReader()
157162
internal var accessibilitySnapshotManager: AccessibilitySnapshotManager =
158163
NoOpAccessibilitySnapshotManager()
159-
internal var batteryInfoProvider: InfoProvider = NoOpInfoProvider()
160-
internal var displayInfoProvider: InfoProvider = NoOpInfoProvider()
164+
internal var batteryInfoProvider: InfoProvider<BatteryInfo> = NoOpBatteryInfoProvider()
165+
internal var displayInfoProvider: InfoProvider<DisplayInfo> = NoOpDisplayInfoProvider()
161166

162167
private val lateCrashEventHandler by lazy { lateCrashReporterFactory(sdkCore as InternalSdkCore) }
163168

@@ -170,7 +175,7 @@ internal class RumFeature(
170175
this.appContext = appContext
171176

172177
if (configuration.collectAccessibility) {
173-
accessibilityReader = DatadogAccessibilityReader(
178+
accessibilityReader = DefaultAccessibilityReader(
174179
internalLogger = sdkCore.internalLogger,
175180
applicationContext = appContext
176181
)
@@ -329,14 +334,14 @@ internal class RumFeature(
329334
private fun cleanupInfoProviders() {
330335
if (configuration.collectAccessibility) {
331336
accessibilityReader.cleanup()
332-
accessibilityReader = NoOpInfoProvider()
337+
accessibilityReader = NoOpAccessibilityReader()
333338
accessibilitySnapshotManager = NoOpAccessibilitySnapshotManager()
334339
}
335340

336341
batteryInfoProvider.cleanup()
337-
batteryInfoProvider = NoOpInfoProvider()
342+
batteryInfoProvider = NoOpBatteryInfoProvider()
338343
displayInfoProvider.cleanup()
339-
displayInfoProvider = NoOpInfoProvider()
344+
displayInfoProvider = NoOpDisplayInfoProvider()
340345
}
341346

342347
private fun createDataWriter(

features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/InfoProvider.kt

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,9 @@
66

77
package com.datadog.android.rum.internal.domain
88

9-
import com.datadog.tools.annotation.NoOpImplementation
9+
internal interface InfoData
1010

11-
@NoOpImplementation
12-
internal interface InfoProvider {
13-
fun getState(): Map<String, Any>
11+
internal interface InfoProvider<T : InfoData> {
12+
fun getState(): T
1413
fun cleanup()
1514
}

features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/accessibility/Accessibility.kt

Lines changed: 0 additions & 60 deletions
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
* Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0.
3+
* This product includes software developed at Datadog (https://www.datadoghq.com/).
4+
* Copyright 2016-Present Datadog, Inc.
5+
*/
6+
7+
package com.datadog.android.rum.internal.domain.accessibility
8+
9+
import com.datadog.android.rum.internal.domain.InfoData
10+
11+
/**
12+
* Represents the accessibility settings state of the device.
13+
*
14+
* @property textSize The font scale factor (1.0 = normal, >1.0 = larger, <1.0 = smaller)
15+
* @property isScreenReaderEnabled Whether touch exploration is enabled (TalkBack, etc.)
16+
* @property isColorInversionEnabled Whether color inversion is enabled
17+
* @property isClosedCaptioningEnabled Whether closed captions are enabled
18+
* @property isReducedAnimationsEnabled Whether animations are disabled/reduced
19+
* @property isScreenPinningEnabled Whether the device is in single-app mode
20+
* @property isRtlEnabled Whether right to left layout is enabled
21+
*/
22+
internal data class AccessibilityInfo(
23+
val textSize: String? = null,
24+
val isScreenReaderEnabled: Boolean? = null,
25+
val isColorInversionEnabled: Boolean? = null,
26+
val isClosedCaptioningEnabled: Boolean? = null,
27+
val isReducedAnimationsEnabled: Boolean? = null,
28+
val isScreenPinningEnabled: Boolean? = null,
29+
val isRtlEnabled: Boolean? = null
30+
) : InfoData

features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/accessibility/AccessibilitySnapshotManager.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,5 @@ import com.datadog.tools.annotation.NoOpImplementation
1010

1111
@NoOpImplementation
1212
internal interface AccessibilitySnapshotManager {
13-
fun latestSnapshot(): Accessibility
13+
fun latestSnapshot(): AccessibilityInfo
1414
}
Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import com.datadog.android.rum.internal.domain.InfoProvider
2626
import java.util.concurrent.atomic.AtomicLong
2727

2828
@Suppress("TooManyFunctions")
29-
internal class DatadogAccessibilityReader(
29+
internal class DefaultAccessibilityReader(
3030
private val internalLogger: InternalLogger,
3131
private val applicationContext: Context,
3232
private val resources: Resources = applicationContext.resources,
@@ -37,7 +37,7 @@ internal class DatadogAccessibilityReader(
3737
private val secureWrapper: SecureWrapper = SecureWrapper(),
3838
private val globalWrapper: GlobalWrapper = GlobalWrapper(),
3939
private val handler: Handler = Handler(Looper.getMainLooper())
40-
) : InfoProvider, ComponentCallbacks {
40+
) : InfoProvider<AccessibilityInfo>, ComponentCallbacks {
4141

4242
private val displayInversionListener = object : ContentObserver(handler) {
4343
override fun onChange(selfChange: Boolean, uri: Uri?) {
@@ -66,7 +66,7 @@ internal class DatadogAccessibilityReader(
6666
}
6767

6868
@Volatile
69-
private var currentState = Accessibility()
69+
private var currentState = AccessibilityInfo()
7070

7171
private var lastPollTime: AtomicLong = AtomicLong(0)
7272

@@ -96,24 +96,24 @@ internal class DatadogAccessibilityReader(
9696
}
9797

9898
@Synchronized
99-
override fun getState(): Map<String, Any> {
99+
override fun getState(): AccessibilityInfo {
100100
val currentTime = System.currentTimeMillis()
101101
val shouldPoll = currentTime - lastPollTime.get() >= POLL_THRESHOLD
102102
if (shouldPoll) {
103103
lastPollTime.set(currentTime)
104104
pollForAttributesWithoutListeners()
105105
}
106106

107-
return currentState.toMap()
107+
return currentState
108108
}
109109

110110
@Synchronized
111-
private fun updateState(updater: (Accessibility) -> Accessibility) {
111+
private fun updateState(updater: (AccessibilityInfo) -> AccessibilityInfo) {
112112
currentState = updater(currentState)
113113
}
114114

115115
private fun buildInitialState() {
116-
currentState = Accessibility(
116+
currentState = AccessibilityInfo(
117117
textSize = getTextSize(),
118118
isScreenReaderEnabled = isScreenReaderEnabled(accessibilityManager),
119119
isColorInversionEnabled = isDisplayInversionEnabled(),

features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/accessibility/DefaultAccessibilitySnapshotManager.kt

Lines changed: 58 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,28 +9,71 @@ package com.datadog.android.rum.internal.domain.accessibility
99
import com.datadog.android.rum.internal.domain.InfoProvider
1010

1111
internal class DefaultAccessibilitySnapshotManager(
12-
private val accessibilityReader: InfoProvider
12+
private val accessibilityReader: InfoProvider<AccessibilityInfo>
1313
) : AccessibilitySnapshotManager {
14-
private val lastSnapshot = mutableMapOf<String, Any>()
14+
@Volatile
15+
private var lastSnapshot = AccessibilityInfo()
1516

1617
@Synchronized
17-
override fun latestSnapshot(): Accessibility {
18-
val newAccessibilityState = accessibilityReader.getState()
19-
val newSnapshot = mutableMapOf<String, Any>()
18+
override fun latestSnapshot(): AccessibilityInfo {
19+
val newAccessibilitySnapshot = accessibilityReader.getState()
2020

21-
// remove the ones we saw already
22-
for (key in newAccessibilityState.keys) {
23-
val newValue = newAccessibilityState[key]
24-
?: continue
21+
// Create delta by comparing new snapshot to last snapshot
22+
// Only include properties that have changed (null for unchanged properties)
23+
val deltaSnapshot = AccessibilityInfo(
24+
textSize =
25+
if (newAccessibilitySnapshot.textSize != lastSnapshot.textSize) {
26+
newAccessibilitySnapshot.textSize
27+
} else {
28+
null
29+
},
2530

26-
val oldValue = lastSnapshot[key]
31+
isScreenReaderEnabled =
32+
if (newAccessibilitySnapshot.isScreenReaderEnabled != lastSnapshot.isScreenReaderEnabled) {
33+
newAccessibilitySnapshot.isScreenReaderEnabled
34+
} else {
35+
null
36+
},
2737

28-
if (newValue != oldValue) {
29-
newSnapshot[key] = newValue
30-
lastSnapshot[key] = newValue
38+
isColorInversionEnabled =
39+
if (newAccessibilitySnapshot.isColorInversionEnabled != lastSnapshot.isColorInversionEnabled) {
40+
newAccessibilitySnapshot.isColorInversionEnabled
41+
} else {
42+
null
43+
},
44+
45+
isClosedCaptioningEnabled =
46+
if (newAccessibilitySnapshot.isClosedCaptioningEnabled != lastSnapshot.isClosedCaptioningEnabled) {
47+
newAccessibilitySnapshot.isClosedCaptioningEnabled
48+
} else {
49+
null
50+
},
51+
52+
isReducedAnimationsEnabled =
53+
if (newAccessibilitySnapshot.isReducedAnimationsEnabled != lastSnapshot.isReducedAnimationsEnabled) {
54+
newAccessibilitySnapshot.isReducedAnimationsEnabled
55+
} else {
56+
null
57+
},
58+
59+
isScreenPinningEnabled =
60+
if (newAccessibilitySnapshot.isScreenPinningEnabled != lastSnapshot.isScreenPinningEnabled) {
61+
newAccessibilitySnapshot.isScreenPinningEnabled
62+
} else {
63+
null
64+
},
65+
66+
isRtlEnabled =
67+
if (newAccessibilitySnapshot.isRtlEnabled != lastSnapshot.isRtlEnabled) {
68+
newAccessibilitySnapshot.isRtlEnabled
69+
} else {
70+
null
3171
}
32-
}
72+
)
73+
74+
// Update last snapshot for future comparisons
75+
lastSnapshot = newAccessibilitySnapshot
3376

34-
return Accessibility.fromMap(newSnapshot)
77+
return deltaSnapshot
3578
}
3679
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/*
2+
* Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0.
3+
* This product includes software developed at Datadog (https://www.datadoghq.com/).
4+
* Copyright 2016-Present Datadog, Inc.
5+
*/
6+
7+
package com.datadog.android.rum.internal.domain.accessibility
8+
9+
import com.datadog.android.rum.internal.domain.InfoProvider
10+
11+
internal class NoOpAccessibilityReader : InfoProvider<AccessibilityInfo> {
12+
override fun getState(): AccessibilityInfo {
13+
return AccessibilityInfo()
14+
}
15+
16+
override fun cleanup() {}
17+
}

features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/battery/BatteryInfo.kt

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,31 +7,16 @@
77
package com.datadog.android.rum.internal.domain.battery
88

99
import androidx.annotation.FloatRange
10+
import com.datadog.android.rum.internal.domain.InfoData
1011

1112
/**
1213
* Provides information about the battery state.
1314
*
14-
* @property batteryLevel the current battery charge level, expressed as a float from 0.0f (empty) to 1.0f (full).
15+
* @property batteryLevel the current battery charge level, expressed as a float from 0.0f (empty) to 1.0f (full)
16+
* to two decimal places.
1517
* @property lowPowerMode a boolean indicating whether the device is currently in Low Power Mode.
1618
*/
1719
internal data class BatteryInfo(
1820
@FloatRange(0.0, 1.0) val batteryLevel: Float? = null,
1921
val lowPowerMode: Boolean? = null
20-
) {
21-
fun toMap(): Map<String, Any> = buildMap {
22-
batteryLevel?.let { put(BATTERY_LEVEL_KEY, it) }
23-
lowPowerMode?.let { put(LOW_POWER_MODE_KEY, it) }
24-
}
25-
26-
internal companion object {
27-
const val BATTERY_LEVEL_KEY = "battery_level"
28-
const val LOW_POWER_MODE_KEY = "low_power_mode"
29-
30-
fun fromMap(map: Map<String, Any>): BatteryInfo {
31-
return BatteryInfo(
32-
batteryLevel = map[BATTERY_LEVEL_KEY] as? Float,
33-
lowPowerMode = map[LOW_POWER_MODE_KEY] as? Boolean
34-
)
35-
}
36-
}
37-
}
22+
) : InfoData

0 commit comments

Comments
 (0)