Skip to content

Commit 65f2af5

Browse files
committed
fix(android): maskImageViews matches ImageView subclasses
1 parent a13641b commit 65f2af5

2 files changed

Lines changed: 15 additions & 13 deletions

File tree

sdk/@launchdarkly/observability-android/lib/src/main/kotlin/com/launchdarkly/observability/replay/PrivacyProfile.kt

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ private fun List<String>.normalizeXmlIds(): Set<String> = map {
2828
*
2929
* @param maskTextInputs Set to false to disable masking text input targets.
3030
* @param maskText Set to false to disable masking text targets.
31-
* @param maskImageViews Set to true to mask [ImageView] targets by exact class match.
31+
* @param maskImageViews Set to true to mask [ImageView] targets.
3232
* @param maskViews Additional Views to mask by exact class match (see [viewsMatcher]).
3333
* @param maskXMLViewIds Additional Views to mask by resource entry name (see [xmlViewIdsMatcher]).
3434
* accepts `"@+id/foo"`, `"@id/foo"`, or `"foo"`. When the React Native library is on the runtime
@@ -56,7 +56,6 @@ data class PrivacyProfile(
5656
) {
5757
private val viewClassSet = buildSet {
5858
addAll(maskViews.map { it.clazz })
59-
if (maskImageViews) add(ImageView::class.java)
6059
}
6160

6261
private val webViewClassNameSet = if (maskWebViews) webViewClassNames.toSet() else emptySet()
@@ -75,6 +74,15 @@ data class PrivacyProfile(
7574
}
7675
}
7776

77+
/**
78+
* Matches targets whose underlying Android View is an [ImageView].
79+
*/
80+
internal val imageViewMatcher: MaskMatcher = object : MaskMatcher {
81+
override fun isMatch(target: MaskTarget): Boolean {
82+
return target.view is ImageView
83+
}
84+
}
85+
7886
/**
7987
* Matches targets whose underlying Android View is a subclass (or implements an interface)
8088
* with a class name included in [webViewClassNames] when [maskWebViews] is enabled.
@@ -203,6 +211,7 @@ data class PrivacyProfile(
203211
// Prefer cheaper checks first; heavier checks should be later.
204212
if (maskTextInputs) add(textInputMatcher)
205213
if (maskText) add(textMatcher)
214+
if (maskImageViews) add(imageViewMatcher)
206215
if (viewClassSet.isNotEmpty()) add(viewsMatcher)
207216
if (maskBySemanticsKeywords) add(sensitiveMatcher)
208217
if (webViewClassNameSet.isNotEmpty()) add(webViewClassHierarchyMatcher)

sdk/@launchdarkly/observability-android/lib/src/test/kotlin/com/launchdarkly/observability/replay/PrivacyProfileTest.kt

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package com.launchdarkly.observability.replay
22

3-
import android.widget.ImageView
43
import org.junit.jupiter.api.Assertions.assertFalse
54
import org.junit.jupiter.api.Assertions.assertThrows
65
import org.junit.jupiter.api.Assertions.assertTrue
@@ -84,23 +83,17 @@ class PrivacyProfileTest {
8483
}
8584

8685
@Test
87-
fun `maskImageViews adds ImageView to viewClassSet and includes viewsMatcher even when maskViews is empty`() {
86+
fun `maskImageViews true adds imageViewMatcher to global matchers`() {
8887
val profile = PrivacyProfile(maskImageViews = true, maskViews = emptyList())
8988

90-
assertTrue(profile.globalMaskMatchers.contains(profile.viewsMatcher))
91-
92-
val viewClassSet = profile.getPrivateSet("viewClassSet")
93-
assertTrue(viewClassSet.contains(ImageView::class.java))
89+
assertTrue(profile.globalMaskMatchers.contains(profile.imageViewMatcher))
9490
}
9591

9692
@Test
97-
fun `maskImageViews false does not add ImageView to viewClassSet and does not include viewsMatcher when maskViews is empty`() {
93+
fun `maskImageViews false does not include imageViewMatcher in global matchers`() {
9894
val profile = PrivacyProfile(maskImageViews = false, maskViews = emptyList())
9995

100-
assertFalse(profile.globalMaskMatchers.contains(profile.viewsMatcher))
101-
102-
val viewClassSet = profile.getPrivateSet("viewClassSet")
103-
assertFalse(viewClassSet.contains(ImageView::class.java))
96+
assertFalse(profile.globalMaskMatchers.contains(profile.imageViewMatcher))
10497
}
10598

10699
@Test

0 commit comments

Comments
 (0)