@@ -11,6 +11,7 @@ import androidx.compose.ui.semantics.SemanticsProperties
11
11
import androidx.compose.ui.semantics.getOrNull
12
12
import androidx.compose.ui.state.ToggleableState
13
13
import com.datadog.android.sessionreplay.ImagePrivacy
14
+ import com.datadog.android.sessionreplay.TextAndInputPrivacy
14
15
import com.datadog.android.sessionreplay.compose.internal.data.SemanticsWireframe
15
16
import com.datadog.android.sessionreplay.compose.internal.data.UiContext
16
17
import com.datadog.android.sessionreplay.compose.internal.utils.PathUtils
@@ -33,27 +34,70 @@ internal class CheckboxSemanticsNodeMapper(
33
34
): SemanticsWireframe {
34
35
val globalBounds = resolveBounds(semanticsNode)
35
36
36
- val wireframes = if (isCheckboxChecked(semanticsNode)) {
37
- createCheckedWireframes(
38
- parentContext = parentContext,
39
- asyncJobStatusCallback = asyncJobStatusCallback,
37
+ val checkableWireframes = if (parentContext.textAndInputPrivacy != TextAndInputPrivacy .MASK_SENSITIVE_INPUTS ) {
38
+ resolveMaskedCheckable(
40
39
semanticsNode = semanticsNode,
41
40
globalBounds = globalBounds
42
41
)
43
42
} else {
44
- createUncheckedWireframes(
43
+ // Resolves checkable view regardless the state
44
+ resolveCheckable(
45
45
semanticsNode = semanticsNode,
46
- globalBounds = globalBounds,
47
- backgroundColor = DEFAULT_COLOR_WHITE
46
+ parentContext = parentContext,
47
+ asyncJobStatusCallback = asyncJobStatusCallback,
48
+ globalBounds = globalBounds
48
49
)
49
50
}
50
51
51
52
return SemanticsWireframe (
52
53
uiContext = null ,
53
- wireframes = wireframes
54
+ wireframes = checkableWireframes
54
55
)
55
56
}
56
57
58
+ private fun resolveMaskedCheckable (
59
+ semanticsNode : SemanticsNode ,
60
+ globalBounds : GlobalBounds
61
+ ): List <MobileSegment .Wireframe > {
62
+ // TODO RUM-5118: Decide how to display masked checkbox, Currently use old unchecked shape wireframe,
63
+ return createUncheckedWireframes(
64
+ semanticsNode = semanticsNode,
65
+ globalBounds = globalBounds,
66
+ backgroundColor = DEFAULT_COLOR_WHITE ,
67
+ borderColor = DEFAULT_COLOR_BLACK ,
68
+ currentIndex = 0
69
+ )
70
+ }
71
+
72
+ private fun resolveCheckable (
73
+ semanticsNode : SemanticsNode ,
74
+ parentContext : UiContext ,
75
+ asyncJobStatusCallback : AsyncJobStatusCallback ,
76
+ globalBounds : GlobalBounds
77
+ ): List <MobileSegment .Wireframe > =
78
+ if (isCheckboxChecked(semanticsNode)) {
79
+ createCheckedWireframes(
80
+ parentContext = parentContext,
81
+ asyncJobStatusCallback = asyncJobStatusCallback,
82
+ semanticsNode = semanticsNode,
83
+ globalBounds = globalBounds
84
+ )
85
+ } else {
86
+ val borderColor =
87
+ semanticsUtils.resolveBorderColor(semanticsNode)
88
+ ?.let { rawColor ->
89
+ convertColor(rawColor)
90
+ } ? : DEFAULT_COLOR_BLACK
91
+
92
+ createUncheckedWireframes(
93
+ semanticsNode = semanticsNode,
94
+ globalBounds = globalBounds,
95
+ backgroundColor = DEFAULT_COLOR_WHITE ,
96
+ borderColor = borderColor,
97
+ currentIndex = 0
98
+ )
99
+ }
100
+
57
101
private fun createCheckedWireframes (
58
102
parentContext : UiContext ,
59
103
asyncJobStatusCallback : AsyncJobStatusCallback ,
@@ -119,18 +163,32 @@ internal class CheckboxSemanticsNodeMapper(
119
163
): List <MobileSegment .Wireframe > {
120
164
val strokeColor = getFallbackCheckmarkColor(backgroundColor)
121
165
122
- val background: MobileSegment .Wireframe = createUncheckedWireframes(
166
+ val wireframesList = mutableListOf<MobileSegment .Wireframe >()
167
+ var index = 0
168
+
169
+ val borderColor =
170
+ semanticsUtils.resolveBorderColor(semanticsNode)
171
+ ?.let { rawColor ->
172
+ convertColor(rawColor)
173
+ } ? : DEFAULT_COLOR_BLACK
174
+
175
+ createUncheckedWireframes(
123
176
semanticsNode = semanticsNode,
124
177
globalBounds = globalBounds,
125
- backgroundColor = backgroundColor
126
- )[0 ]
178
+ backgroundColor = backgroundColor,
179
+ borderColor = borderColor,
180
+ currentIndex = 0
181
+ ).firstOrNull()?.let {
182
+ wireframesList.add(it)
183
+ index++
184
+ }
127
185
128
186
val checkmarkWidth = globalBounds.width * CHECKMARK_SIZE_FACTOR
129
187
val checkmarkHeight = globalBounds.height * CHECKMARK_SIZE_FACTOR
130
188
val xPos = globalBounds.x + ((globalBounds.width / 2 ) - (checkmarkWidth / 2 ))
131
189
val yPos = globalBounds.y + ((globalBounds.height / 2 ) - (checkmarkHeight / 2 ))
132
- val foreground: MobileSegment . Wireframe = MobileSegment .Wireframe .ShapeWireframe (
133
- id = resolveId(semanticsNode, 1 ),
190
+ val foreground = MobileSegment .Wireframe .ShapeWireframe (
191
+ id = resolveId(semanticsNode, index ),
134
192
x = xPos.toLong(),
135
193
y = yPos.toLong(),
136
194
width = checkmarkWidth.toLong(),
@@ -145,23 +203,21 @@ internal class CheckboxSemanticsNodeMapper(
145
203
width = BOX_BORDER_WIDTH_DP
146
204
)
147
205
)
148
- return listOf (background, foreground)
206
+
207
+ wireframesList.add(foreground)
208
+ return wireframesList
149
209
}
150
210
151
211
private fun createUncheckedWireframes (
152
212
semanticsNode : SemanticsNode ,
153
213
globalBounds : GlobalBounds ,
154
- backgroundColor : String
214
+ backgroundColor : String ,
215
+ borderColor : String ,
216
+ currentIndex : Int
155
217
): List <MobileSegment .Wireframe > {
156
- val borderColor =
157
- semanticsUtils.resolveBorderColor(semanticsNode)
158
- ?.let { rawColor ->
159
- convertColor(rawColor)
160
- } ? : DEFAULT_COLOR_BLACK
161
-
162
218
return listOf (
163
219
MobileSegment .Wireframe .ShapeWireframe (
164
- id = resolveId(semanticsNode, 0 ),
220
+ id = resolveId(semanticsNode, currentIndex ),
165
221
x = globalBounds.x,
166
222
y = globalBounds.y,
167
223
width = globalBounds.width,
0 commit comments