You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: sdk/@launchdarkly/observability-android/README.md
+15-2Lines changed: 15 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -244,6 +244,19 @@ Call `LDReplay.stop()` to pause recording.
244
244
245
245
Use `ldMask()` to mark views that should be masked in session replay. There are helpers for both XML-based Views and Jetpack Compose.
246
246
247
+
##### How the SDK Determines What to Mask
248
+
249
+
When deciding whether a specific view should be masked in a Session Replay, the SDK evaluates rules in a strict order of precedence. It checks these conditions from top to bottom and stops at the first one that applies:
250
+
251
+
1.**Explicit Masking (Highest Priority)**: Is the view, or *any* of its parent views, explicitly masked (e.g., using `.ldMask()` or matching `maskXMLViewIds`)?
252
+
***Yes**: The view is **masked**. This overrides all other rules.
253
+
2.**Explicit Unmasking**: Is the view, or *any* of its parent views, explicitly unmasked (e.g., using `.ldUnmask()`)?
254
+
***Yes**: The view is **unmasked**.
255
+
3.**Global Configuration**: Does your global privacy configuration (like `maskTextInputs`, `maskImages`, etc.) apply to this view?
256
+
***Yes**: The view follows the global configuration.
257
+
258
+
*Note: If multiple rules conflict at the same level, masking wins over unmasking.*
259
+
247
260
##### Configure masking via `PrivacyProfile`
248
261
249
262
If you want to configure masking globally (instead of calling `ldMask()` on each element), pass a `PrivacyProfile` to `ReplayOptions`:
@@ -322,7 +335,7 @@ override fun onCreateView(
322
335
}
323
336
```
324
337
325
-
Optional: use `ldUnmask()` to explicitly clear maskingon a view you previously masked.
338
+
Use `ldUnmask()` to explicitly opt a view out of masking. This overrides global masking rules (e.g. `maskText`) for the view and its descendants — but an explicit `ldMask()`on the view itself or any ancestor still wins.
326
339
327
340
##### Jetpack Compose
328
341
@@ -348,7 +361,7 @@ fun CreditCardField() {
348
361
}
349
362
```
350
363
351
-
Optional: use `Modifier.ldUnmask()` to explicitly clear maskingon a composable you previously masked.
364
+
Use `Modifier.ldUnmask()` to explicitly opt a composable out of masking. This overrides global masking rules (e.g. `maskText`) for the composable and its descendants — but an explicit `ldMask()`on the composable itself or any ancestor still wins.
352
365
353
366
Notes:
354
367
- Masking marks elements so their contents are obscured in recorded sessions.
Copy file name to clipboardExpand all lines: sdk/@launchdarkly/observability-android/lib/src/main/kotlin/com/launchdarkly/observability/api/ComposeMaskingAPI.kt
+6-2Lines changed: 6 additions & 2 deletions
Original file line number
Diff line number
Diff line change
@@ -16,14 +16,18 @@ val LdMaskSemanticsKey = SemanticsPropertyKey<Boolean>("ld_mask")
16
16
varSemanticsPropertyReceiver.ldMask by LdMaskSemanticsKey
17
17
18
18
/**
19
-
* Marks this Compose element as sensitive; session replay should mask it.
19
+
* Marks this Compose element — and every descendant of it — as sensitive for masking in session
20
+
* replay.
20
21
*/
21
22
fun Modifier.ldMask(): Modifier=this.semantics {
22
23
ldMask =true
23
24
}
24
25
25
26
/**
26
-
* Marks this Compose element as not sensitive; session replay should not mask it.
27
+
* Marks this Compose element — and every descendant of it — as explicitly *not* sensitive for
28
+
* masking in session replay. This overrides global masking rules such as `maskText` and
29
+
* `maskTextInputs` for the affected elements. If this element or one of its ancestors is also
30
+
* explicitly masked via [ldMask], the explicit mask wins.
27
31
*/
28
32
fun Modifier.ldUnmask(): Modifier=this.semantics {
Copy file name to clipboardExpand all lines: sdk/@launchdarkly/observability-android/lib/src/main/kotlin/com/launchdarkly/observability/api/MaskingViewAPI.kt
+6-4Lines changed: 6 additions & 4 deletions
Original file line number
Diff line number
Diff line change
@@ -3,16 +3,18 @@ import android.view.View
3
3
importcom.launchdarkly.observability.R
4
4
5
5
/**
6
-
* Marks this native View as sensitive for masking in session replay.
7
-
* Sets a tag so the replay system can detect and apply masking.
6
+
* Marks this native View — and every descendant of it — as sensitive for masking in session
7
+
* replay.
8
8
*/
9
9
fun View.ldMask() {
10
10
setTag(R.id.ld_mask_tag, true)
11
11
}
12
12
13
13
/**
14
-
* Unmarks this native View as sensitive for masking in session replay.
15
-
* Sets a tag so the replay system will not mask this view.
14
+
* Marks this native View — and every descendant of it — as explicitly *not* sensitive for
15
+
* masking in session replay. This overrides global masking rules such as `maskText` and
16
+
* `maskTextInputs` for the affected views. If this view or one of its ancestors is also
17
+
* explicitly masked via [ldMask], the explicit mask wins.
Copy file name to clipboardExpand all lines: sdk/@launchdarkly/observability-android/lib/src/main/kotlin/com/launchdarkly/observability/replay/PrivacyProfile.kt
+34-16Lines changed: 34 additions & 16 deletions
Original file line number
Diff line number
Diff line change
@@ -49,22 +49,6 @@ data class PrivacyProfile(
49
49
}
50
50
}.toSet()
51
51
52
-
/**
53
-
* Converts this [PrivacyProfile] into its equivalent [MaskMatcher] list.
54
-
*
55
-
* Note: matchers are evaluated with `any { ... }`, so ordering only affects performance
56
-
* (earlier matchers can short-circuit later ones).
Copy file name to clipboardExpand all lines: sdk/@launchdarkly/observability-android/lib/src/main/kotlin/com/launchdarkly/observability/replay/capture/ImageCaptureService.kt
Copy file name to clipboardExpand all lines: sdk/@launchdarkly/observability-android/lib/src/main/kotlin/com/launchdarkly/observability/replay/masking/ComposeMaskTarget.kt
0 commit comments