Skip to content

Commit dad5b4c

Browse files
authored
Merge pull request #2823 from DataDog/jmoskovich/additional-accessibilty-coverage
Some additional accessibility test coverage
2 parents a76bac2 + aa79b82 commit dad5b4c

File tree

18 files changed

+342
-167
lines changed

18 files changed

+342
-167
lines changed

detekt_custom.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1203,6 +1203,7 @@ datadog:
12031203
- "kotlin.Any.toString()"
12041204
- "kotlin.Boolean.hashCode()"
12051205
- "kotlin.Boolean.not()"
1206+
- "kotlin.Boolean.takeIf(kotlin.Function1)"
12061207
- "kotlin.Byte.toInt()"
12071208
- "kotlin.ByteArray.constructor(kotlin.Int)"
12081209
- "kotlin.ByteArray.copyTo(kotlin.Int, kotlin.ByteArray, kotlin.Int, kotlin.Int, com.datadog.android.api.InternalLogger)"

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,7 @@ data class RumConfiguration internal constructor(
6060
}
6161

6262
/**
63-
* Whether to collect accessibility attributes inside the RUM view update event.
64-
* This is disabled by default.
63+
* Whether to collect accessibility attributes - this is disabled by default.
6564
*
6665
* @param enabled whether collecting accessibility attributes is enabled or not.
6766
*/

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

Lines changed: 1 addition & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,7 @@ internal class RumDataWriter(
3333
) ?: return false
3434

3535
val batchEvent = if (element is ViewEvent) {
36-
val hasAccessibility = if (element.view.accessibility != null) {
37-
isAccessibilityPopulated(element.view.accessibility)
38-
} else {
39-
false
40-
}
36+
val hasAccessibility = element.view.accessibility != null
4137

4238
val eventMeta = RumEventMeta.View(
4339
viewId = element.view.id,
@@ -75,33 +71,6 @@ internal class RumDataWriter(
7571
}
7672
}
7773

78-
private fun isAccessibilityPopulated(accessibility: ViewEvent.Accessibility): Boolean {
79-
return setOf<Any?>(
80-
accessibility.textSize,
81-
accessibility.assistiveSwitchEnabled,
82-
accessibility.assistiveTouchEnabled,
83-
accessibility.boldTextEnabled,
84-
accessibility.buttonShapesEnabled,
85-
accessibility.closedCaptioningEnabled,
86-
accessibility.grayscaleEnabled,
87-
accessibility.increaseContrastEnabled,
88-
accessibility.invertColorsEnabled,
89-
accessibility.monoAudioEnabled,
90-
accessibility.onOffSwitchLabelsEnabled,
91-
accessibility.reduceMotionEnabled,
92-
accessibility.reduceTransparencyEnabled,
93-
accessibility.reducedAnimationsEnabled,
94-
accessibility.rtlEnabled,
95-
accessibility.screenReaderEnabled,
96-
accessibility.shakeToUndoEnabled,
97-
accessibility.shouldDifferentiateWithoutColor,
98-
accessibility.singleAppModeEnabled,
99-
accessibility.speakScreenEnabled,
100-
accessibility.speakSelectionEnabled,
101-
accessibility.videoAutoplayEnabled
102-
).any { it != null }
103-
}
104-
10574
// endregion
10675

10776
companion object {

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(): AccessibilityInfo
13+
fun getIfChanged(): AccessibilityInfo?
1414
}

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

Lines changed: 30 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -12,65 +12,47 @@ internal class DefaultAccessibilitySnapshotManager(
1212
private val accessibilityReader: InfoProvider<AccessibilityInfo>
1313
) : AccessibilitySnapshotManager {
1414
@Volatile
15-
private var lastSnapshot = AccessibilityInfo()
15+
private var lastSnapshot: AccessibilityInfo? = null
1616

1717
@Synchronized
18-
override fun latestSnapshot(): AccessibilityInfo {
19-
val newAccessibilitySnapshot = accessibilityReader.getState()
18+
override fun getIfChanged(): AccessibilityInfo? {
19+
val newSnapshot = accessibilityReader.getState()
20+
if (newSnapshot == lastSnapshot) return null
2021

21-
val deltaSnapshot = AccessibilityInfo(
22-
textSize =
23-
if (newAccessibilitySnapshot.textSize != lastSnapshot.textSize) {
24-
newAccessibilitySnapshot.textSize
25-
} else {
26-
null
27-
},
22+
val deltaSnapshot = createDelta(newSnapshot, lastSnapshot)
23+
lastSnapshot = newSnapshot
2824

29-
isScreenReaderEnabled =
30-
if (newAccessibilitySnapshot.isScreenReaderEnabled != lastSnapshot.isScreenReaderEnabled) {
31-
newAccessibilitySnapshot.isScreenReaderEnabled
32-
} else {
33-
null
34-
},
25+
return if (deltaSnapshot.hasAnyNonNullValues()) deltaSnapshot else null
26+
}
3527

28+
private fun createDelta(new: AccessibilityInfo, old: AccessibilityInfo?): AccessibilityInfo {
29+
return AccessibilityInfo(
30+
textSize =
31+
new.textSize.takeIf { it != old?.textSize },
32+
isScreenReaderEnabled =
33+
new.isScreenReaderEnabled.takeIf { it != old?.isScreenReaderEnabled },
3634
isColorInversionEnabled =
37-
if (newAccessibilitySnapshot.isColorInversionEnabled != lastSnapshot.isColorInversionEnabled) {
38-
newAccessibilitySnapshot.isColorInversionEnabled
39-
} else {
40-
null
41-
},
42-
35+
new.isColorInversionEnabled.takeIf { it != old?.isColorInversionEnabled },
4336
isClosedCaptioningEnabled =
44-
if (newAccessibilitySnapshot.isClosedCaptioningEnabled != lastSnapshot.isClosedCaptioningEnabled) {
45-
newAccessibilitySnapshot.isClosedCaptioningEnabled
46-
} else {
47-
null
48-
},
49-
37+
new.isClosedCaptioningEnabled.takeIf { it != old?.isClosedCaptioningEnabled },
5038
isReducedAnimationsEnabled =
51-
if (newAccessibilitySnapshot.isReducedAnimationsEnabled != lastSnapshot.isReducedAnimationsEnabled) {
52-
newAccessibilitySnapshot.isReducedAnimationsEnabled
53-
} else {
54-
null
55-
},
56-
39+
new.isReducedAnimationsEnabled.takeIf { it != old?.isReducedAnimationsEnabled },
5740
isScreenPinningEnabled =
58-
if (newAccessibilitySnapshot.isScreenPinningEnabled != lastSnapshot.isScreenPinningEnabled) {
59-
newAccessibilitySnapshot.isScreenPinningEnabled
60-
} else {
61-
null
62-
},
63-
41+
new.isScreenPinningEnabled.takeIf { it != old?.isScreenPinningEnabled },
6442
isRtlEnabled =
65-
if (newAccessibilitySnapshot.isRtlEnabled != lastSnapshot.isRtlEnabled) {
66-
newAccessibilitySnapshot.isRtlEnabled
67-
} else {
68-
null
69-
}
43+
new.isRtlEnabled.takeIf { it != old?.isRtlEnabled }
7044
)
45+
}
7146

72-
lastSnapshot = newAccessibilitySnapshot
73-
74-
return deltaSnapshot
47+
private fun AccessibilityInfo.hasAnyNonNullValues(): Boolean {
48+
return setOf<Any?>(
49+
this.textSize,
50+
this.isScreenReaderEnabled,
51+
this.isRtlEnabled,
52+
this.isScreenPinningEnabled,
53+
this.isColorInversionEnabled,
54+
this.isClosedCaptioningEnabled,
55+
this.isReducedAnimationsEnabled
56+
).any { it != null }
7557
}
7658
}

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

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -997,16 +997,17 @@ internal open class RumViewScope(
997997
)
998998
}
999999

1000-
val accessibilityState = accessibilitySnapshotManager.latestSnapshot()
1001-
val accessibility = ViewEvent.Accessibility(
1002-
textSize = accessibilityState.textSize,
1003-
invertColorsEnabled = accessibilityState.isColorInversionEnabled,
1004-
singleAppModeEnabled = accessibilityState.isScreenPinningEnabled,
1005-
screenReaderEnabled = accessibilityState.isScreenReaderEnabled,
1006-
closedCaptioningEnabled = accessibilityState.isClosedCaptioningEnabled,
1007-
reducedAnimationsEnabled = accessibilityState.isReducedAnimationsEnabled,
1008-
rtlEnabled = accessibilityState.isRtlEnabled
1009-
)
1000+
val accessibility = accessibilitySnapshotManager.getIfChanged()?.let {
1001+
ViewEvent.Accessibility(
1002+
textSize = it.textSize,
1003+
invertColorsEnabled = it.isColorInversionEnabled,
1004+
singleAppModeEnabled = it.isScreenPinningEnabled,
1005+
screenReaderEnabled = it.isScreenReaderEnabled,
1006+
closedCaptioningEnabled = it.isClosedCaptioningEnabled,
1007+
reducedAnimationsEnabled = it.isReducedAnimationsEnabled,
1008+
rtlEnabled = it.isRtlEnabled
1009+
)
1010+
}
10101011

10111012
val batteryInfo = batteryInfoProvider.getState()
10121013
val displayInfo = displayInfoProvider.getState()

features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/RumDataWriterTest.kt

Lines changed: 55 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import org.junit.jupiter.api.extension.Extensions
3636
import org.mockito.Mock
3737
import org.mockito.junit.jupiter.MockitoExtension
3838
import org.mockito.junit.jupiter.MockitoSettings
39+
import org.mockito.kotlin.argumentCaptor
3940
import org.mockito.kotlin.doReturn
4041
import org.mockito.kotlin.doThrow
4142
import org.mockito.kotlin.verify
@@ -129,7 +130,7 @@ internal class RumDataWriterTest {
129130
) {
130131
// Given
131132
whenever(mockSerializer.serialize(fakeViewEvent)) doReturn fakeSerializedEvent
132-
val hasAccessibility = isAccessibilityPopulated(fakeViewEvent.view.accessibility)
133+
val hasAccessibility = fakeViewEvent.view.accessibility != null
133134
val eventMeta = RumEventMeta.View(
134135
viewId = fakeViewEvent.view.id,
135136
documentVersion = fakeViewEvent.dd.documentVersion,
@@ -159,7 +160,7 @@ internal class RumDataWriterTest {
159160
) {
160161
// Given
161162
whenever(mockSerializer.serialize(fakeViewEvent)) doReturn fakeSerializedEvent
162-
val hasAccessibility = isAccessibilityPopulated(fakeViewEvent.view.accessibility)
163+
val hasAccessibility = fakeViewEvent.view.accessibility != null
163164
val eventMeta = RumEventMeta.View(
164165
viewId = fakeViewEvent.view.id,
165166
documentVersion = fakeViewEvent.dd.documentVersion,
@@ -252,34 +253,60 @@ internal class RumDataWriterTest {
252253

253254
// endregion
254255

255-
private fun isAccessibilityPopulated(accessibility: ViewEvent.Accessibility?): Boolean {
256-
if (accessibility == null) return false
257-
return setOf<Any?>(
258-
accessibility.textSize,
259-
accessibility.assistiveSwitchEnabled,
260-
accessibility.assistiveTouchEnabled,
261-
accessibility.boldTextEnabled,
262-
accessibility.buttonShapesEnabled,
263-
accessibility.closedCaptioningEnabled,
264-
accessibility.grayscaleEnabled,
265-
accessibility.increaseContrastEnabled,
266-
accessibility.invertColorsEnabled,
267-
accessibility.monoAudioEnabled,
268-
accessibility.onOffSwitchLabelsEnabled,
269-
accessibility.reduceMotionEnabled,
270-
accessibility.reduceTransparencyEnabled,
271-
accessibility.reducedAnimationsEnabled,
272-
accessibility.rtlEnabled,
273-
accessibility.screenReaderEnabled,
274-
accessibility.shakeToUndoEnabled,
275-
accessibility.shouldDifferentiateWithoutColor,
276-
accessibility.singleAppModeEnabled,
277-
accessibility.speakScreenEnabled,
278-
accessibility.speakSelectionEnabled,
279-
accessibility.videoAutoplayEnabled
280-
).any { it != null }
256+
// region accessibility
257+
258+
@Test
259+
fun `M hasAccessibility false W write() { null accessibility }`(
260+
forge: Forge
261+
) {
262+
// Given
263+
val viewEvent = forge.getForgery<ViewEvent>()
264+
val newView = viewEvent.view.copy(
265+
accessibility = null
266+
)
267+
val newViewEvent = viewEvent.copy(
268+
view = newView
269+
)
270+
271+
whenever(mockSerializer.serialize(newViewEvent)) doReturn fakeSerializedEvent
272+
273+
// When
274+
testedWriter.write(mockEventBatchWriter, newViewEvent, fakeEventType)
275+
276+
// Then
277+
val captor = argumentCaptor<RumEventMeta.View>()
278+
verify(mockEventMetaSerializer).serialize(captor.capture())
279+
val metaData = captor.firstValue
280+
assertThat(metaData.hasAccessibility).isFalse
281281
}
282282

283+
@Test
284+
fun `M hasAccessibility true W write() { non-null accessibility }`(
285+
forge: Forge
286+
) {
287+
// Given
288+
val viewEvent = forge.getForgery<ViewEvent>()
289+
val newView = viewEvent.view.copy(
290+
accessibility = forge.getForgery()
291+
)
292+
val newViewEvent = viewEvent.copy(
293+
view = newView
294+
)
295+
296+
whenever(mockSerializer.serialize(newViewEvent)) doReturn fakeSerializedEvent
297+
298+
// When
299+
testedWriter.write(mockEventBatchWriter, newViewEvent, fakeEventType)
300+
301+
// Then
302+
val captor = argumentCaptor<RumEventMeta.View>()
303+
verify(mockEventMetaSerializer).serialize(captor.capture())
304+
val metaData = captor.firstValue
305+
assertThat(metaData.hasAccessibility).isTrue
306+
}
307+
308+
// endregion
309+
283310
companion object {
284311
val rumMonitor = GlobalRumMonitorTestConfiguration()
285312

0 commit comments

Comments
 (0)