Skip to content

Commit b1d6ebb

Browse files
authored
Merge pull request #2365 from DataDog/yl/sr-mnt/fix-checkable-image-cache
Fix CompoundButton mapper drawable clone issue
2 parents b83e7b6 + 6349277 commit b1d6ebb

File tree

6 files changed

+33
-40
lines changed

6 files changed

+33
-40
lines changed

features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/CheckableCompoundButtonMapper.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,10 +103,10 @@ internal abstract class CheckableCompoundButtonMapper<T : CompoundButton>(
103103
null
104104
}
105105
}
106-
return originCheckableDrawable?.let { cloneCheckableDrawable(view, it) }
106+
return originCheckableDrawable
107107
}
108108

109-
private fun cloneCheckableDrawable(view: T, drawable: Drawable): Drawable? {
109+
override fun cloneCheckableDrawable(view: T, drawable: Drawable): Drawable? {
110110
return drawable.constantState?.newDrawable(view.resources)?.apply {
111111
// Set state to make the drawable have correct tint.
112112
setState(view.drawableState)

features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/CheckableTextViewMapper.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import android.widget.Checkable
1111
import android.widget.TextView
1212
import androidx.annotation.UiThread
1313
import com.datadog.android.api.InternalLogger
14+
import com.datadog.android.sessionreplay.internal.recorder.resources.DrawableCopier
1415
import com.datadog.android.sessionreplay.model.MobileSegment
1516
import com.datadog.android.sessionreplay.recorder.MappingContext
1617
import com.datadog.android.sessionreplay.recorder.mapper.TextViewMapper
@@ -109,6 +110,7 @@ internal abstract class CheckableTextViewMapper<T>(
109110
view,
110111
mappingContext.systemInformation.screenDensity
111112
)
113+
val drawableCopier = DrawableCopier { _, _ -> cloneCheckableDrawable(view, it) }
112114
mappingContext.imageWireframeHelper.createImageWireframe(
113115
view = view,
114116
imagePrivacy = mapInputPrivacyToImagePrivacy(mappingContext.textAndInputPrivacy),
@@ -117,6 +119,7 @@ internal abstract class CheckableTextViewMapper<T>(
117119
y = checkBoxBounds.y,
118120
width = it.intrinsicWidth,
119121
height = it.intrinsicHeight,
122+
drawableCopier = drawableCopier,
120123
drawable = it,
121124
shapeStyle = null,
122125
border = null,
@@ -127,6 +130,8 @@ internal abstract class CheckableTextViewMapper<T>(
127130
}
128131
}
129132

133+
abstract fun cloneCheckableDrawable(view: T, drawable: Drawable): Drawable?
134+
130135
@UiThread
131136
abstract fun getCheckableDrawable(view: T): Drawable?
132137

features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/CheckedTextViewMapper.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,11 @@ internal open class CheckedTextViewMapper(
7575

7676
return (view.checkMarkDrawable?.constantState as? DrawableContainer.DrawableContainerState)?.getChild(
7777
checkableDrawableIndex
78-
)?.constantState?.newDrawable(view.resources)?.apply {
78+
)
79+
}
80+
81+
override fun cloneCheckableDrawable(view: CheckedTextView, drawable: Drawable): Drawable? {
82+
return drawable.constantState?.newDrawable(view.resources)?.apply {
7983
// Set state to make the drawable have correct tint according to the state.
8084
setState(view.drawableState)
8185
// Set tint list to drawable if the button has declared `checkMarkTint` attribute.

features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/SwitchCompatMapper.kt

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66

77
package com.datadog.android.sessionreplay.internal.recorder.mapper
88

9-
import android.content.res.Resources
10-
import android.graphics.drawable.Drawable
119
import androidx.annotation.UiThread
1210
import androidx.appcompat.widget.SwitchCompat
1311
import com.datadog.android.api.InternalLogger
@@ -75,14 +73,12 @@ internal open class SwitchCompatMapper(
7573
)
7674
return trackBounds?.let {
7775
val trackDrawable = view.trackDrawable
78-
val drawableCopier = object : DrawableCopier {
79-
override fun copy(originalDrawable: Drawable, resources: Resources): Drawable? {
80-
return originalDrawable.constantState?.newDrawable(view.resources)?.apply {
81-
setState(view.trackDrawable.state)
82-
bounds = view.trackDrawable.bounds
83-
view.trackTintList?.let {
84-
setTintList(it)
85-
}
76+
val drawableCopier = DrawableCopier { originalDrawable, resources ->
77+
originalDrawable.constantState?.newDrawable(resources)?.apply {
78+
setState(view.trackDrawable.state)
79+
bounds = view.trackDrawable.bounds
80+
view.trackTintList?.let { tintList ->
81+
setTintList(tintList)
8682
}
8783
}
8884
}
@@ -118,17 +114,16 @@ internal open class SwitchCompatMapper(
118114
)
119115

120116
val thumbDrawable = view.thumbDrawable
121-
val drawableCopier = object : DrawableCopier {
122-
override fun copy(originalDrawable: Drawable, resources: Resources): Drawable? {
123-
return originalDrawable.constantState?.newDrawable(view.resources)?.apply {
117+
val drawableCopier =
118+
DrawableCopier { originalDrawable, resources ->
119+
originalDrawable.constantState?.newDrawable(resources)?.apply {
124120
setState(view.thumbDrawable.state)
125121
bounds = view.thumbDrawable.bounds
126122
view.thumbTintList?.let {
127123
setTintList(it)
128124
}
129125
}
130126
}
131-
}
132127
return thumbBounds?.let {
133128
mappingContext.imageWireframeHelper.createImageWireframe(
134129
view = view,

features/dd-sdk-android-session-replay/src/main/kotlin/com/datadog/android/sessionreplay/internal/recorder/resources/DrawableCopier.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import com.datadog.android.lint.InternalApi
1414
* Interface of copying drawable to a new one.
1515
*/
1616
@InternalApi
17-
interface DrawableCopier {
17+
fun interface DrawableCopier {
1818

1919
/**
2020
* Called to copy the drawable.

features/dd-sdk-android-session-replay/src/test/kotlin/com/datadog/android/sessionreplay/internal/recorder/mapper/BaseCheckableTextViewMapperTest.kt

Lines changed: 11 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,6 @@ internal abstract class BaseCheckableTextViewMapperTest<T> :
8787
@Mock
8888
lateinit var mockConstantState: DrawableContainer.DrawableContainerState
8989

90-
@Mock
91-
lateinit var mockCheckedConstantState: DrawableContainer.DrawableContainerState
92-
9390
@IntForgery(min = 0, max = 0xffffff)
9491
var fakeCurrentTextColor: Int = 0
9592

@@ -108,35 +105,27 @@ internal abstract class BaseCheckableTextViewMapperTest<T> :
108105
@Mock
109106
lateinit var mockNotCheckedDrawable: Drawable
110107

111-
@Mock
112-
lateinit var mockClonedDrawable: Drawable
113-
114108
@Mock
115109
lateinit var mockDrawableCopier: DrawableCopier
116110

117111
@IntForgery
118-
var mockCloneDrawableIntrinsicHeight: Int = 0
112+
var fakeDrawableIntrinsicHeight: Int = 0
119113

120114
@IntForgery
121-
var mockCloneDrawableIntrinsicWidth: Int = 0
115+
var fakeDrawableIntrinsicWidth: Int = 0
122116

123117
@Forgery
124118
lateinit var fakeImagePrivacy: ImagePrivacy
125119

126120
@BeforeEach
127121
fun `set up`() {
128-
mockClonedDrawable = mock {
129-
whenever(it.intrinsicHeight) doReturn mockCloneDrawableIntrinsicHeight
130-
whenever(it.intrinsicWidth) doReturn mockCloneDrawableIntrinsicWidth
131-
}
132-
mockCheckedConstantState = mock {
133-
whenever(it.newDrawable(mockResources)) doReturn mockClonedDrawable
134-
}
135122
mockCheckedDrawable = mock {
136-
whenever(it.constantState) doReturn mockCheckedConstantState
123+
whenever(it.intrinsicHeight) doReturn fakeDrawableIntrinsicHeight
124+
whenever(it.intrinsicWidth) doReturn fakeDrawableIntrinsicWidth
137125
}
138126
mockNotCheckedDrawable = mock {
139-
whenever(it.constantState) doReturn mockCheckedConstantState
127+
whenever(it.intrinsicHeight) doReturn fakeDrawableIntrinsicHeight
128+
whenever(it.intrinsicWidth) doReturn fakeDrawableIntrinsicWidth
140129
}
141130
mockConstantState = mock {
142131
whenever(it.getChild(CHECK_BOX_CHECKED_DRAWABLE_INDEX)) doReturn mockCheckedDrawable
@@ -226,8 +215,8 @@ internal abstract class BaseCheckableTextViewMapperTest<T> :
226215
currentWireframeIndex = anyInt(),
227216
x = eq(expectedX),
228217
y = eq(expectedY),
229-
width = eq(mockCloneDrawableIntrinsicWidth),
230-
height = eq(mockCloneDrawableIntrinsicHeight),
218+
width = eq(fakeDrawableIntrinsicWidth),
219+
height = eq(fakeDrawableIntrinsicHeight),
231220
usePIIPlaceholder = anyBoolean(),
232221
drawable = any(),
233222
drawableCopier = any(),
@@ -270,10 +259,10 @@ internal abstract class BaseCheckableTextViewMapperTest<T> :
270259
currentWireframeIndex = anyInt(),
271260
x = eq(expectedX),
272261
y = eq(expectedY),
273-
width = eq(mockCloneDrawableIntrinsicWidth),
274-
height = eq(mockCloneDrawableIntrinsicHeight),
262+
width = eq(fakeDrawableIntrinsicWidth),
263+
height = eq(fakeDrawableIntrinsicHeight),
275264
usePIIPlaceholder = anyBoolean(),
276-
drawable = eq(mockClonedDrawable),
265+
drawable = eq(mockNotCheckedDrawable),
277266
drawableCopier = any(),
278267
asyncJobStatusCallback = eq(mockAsyncJobStatusCallback),
279268
clipping = eq(MobileSegment.WireframeClip()),

0 commit comments

Comments
 (0)