Fix the async image loading logic inside the SR view mappers#1619
Conversation
d110cee to
908d8af
Compare
ecc4e35 to
adc96b0
Compare
Codecov Report
@@ Coverage Diff @@
## develop #1619 +/- ##
===========================================
+ Coverage 83.78% 83.86% +0.09%
===========================================
Files 452 455 +3
Lines 15668 15680 +12
Branches 2326 2326
===========================================
+ Hits 13126 13150 +24
+ Misses 1918 1915 -3
+ Partials 624 615 -9
|
adc96b0 to
edeaa29
Compare
| private val viewWireframeMapper: ViewWireframeMapper, | ||
| private val uniqueIdentifierGenerator: UniqueIdentifierGenerator = UniqueIdentifierGenerator | ||
| ) : BaseWireframeMapper<View, MobileSegment.Wireframe.ShapeWireframe>() { | ||
| ) : WireframeMapper<View, MobileSegment.Wireframe> { |
There was a problem hiding this comment.
we do not need the BaseWireframeMapper anymore here
| ) : AsyncJobStatusCallback { | ||
| fun map(view: View, mappingContext: MappingContext): | ||
| List<MobileSegment.Wireframe> { | ||
| (mapper as? BaseWireframeMapper<View, *>)?.registerAsyncImageProcessingCallback(this) |
There was a problem hiding this comment.
this was the main issue here as we were still registering a callback
| abstract class com.datadog.android.sessionreplay.internal.recorder.mapper.BaseAsyncBackgroundWireframeMapper<T: android.view.View> : BaseWireframeMapper<T, com.datadog.android.sessionreplay.model.MobileSegment.Wireframe> | ||
| constructor(com.datadog.android.sessionreplay.utils.StringUtils = StringUtils, com.datadog.android.sessionreplay.utils.ViewUtils = ViewUtils) | ||
| override fun map(T, com.datadog.android.sessionreplay.internal.recorder.MappingContext, com.datadog.android.sessionreplay.internal.AsyncJobStatusCallback): List<com.datadog.android.sessionreplay.model.MobileSegment.Wireframe> | ||
| companion object |
There was a problem hiding this comment.
if it doesn't expose public members, then we can make it internal
There was a problem hiding this comment.
actually not as we have the TextViewMapper class which extends it and it is public to be used in the other module
| ): | ||
| List<MobileSegment.Wireframe> { |
There was a problem hiding this comment.
| ): | |
| List<MobileSegment.Wireframe> { | |
| ): List<MobileSegment.Wireframe> { |
| override fun map( | ||
| view: T, | ||
| mappingContext: MappingContext, | ||
| asyncJobStatusCallback: AsyncJobStatusCallback | ||
| ): |
There was a problem hiding this comment.
we need to add a good documentation for this method in the future, because it is not clear why do we have such API - we return some result instantly and at the same time have an async callback with some notification mechanism. Usually APIs have either of the two - return result in a blocking way, or give it in the callback.
There was a problem hiding this comment.
I do agree, maybe once we will have a stable version, meaning the new resources endpoint in please (which will remove the base64 logic) and the fine grained masking we could simplify a bit this part. My plan is to assess after if we still need this queue or not. We already copy the drawable now so I am thinking to actually create this ViewPlacehdolder model that will be processed into wireframe at the Processor level. For now we are not ready for this switch as we do not know if copying the drawable will always be possible and also need to see how the logic will look like with the new resources endpoint in place.
| * @param mappingContext in which we provide useful information regarding the current | ||
| * system state. | ||
| * @param asyncJobStatusCallback a callback that can be called when the mapper starts or | ||
| * finishes processing an async job. This is useful to keep track of the current async jobs |
There was a problem hiding this comment.
since both jobStarted and jobFinished doesn't have any arguments like job ID and result, maybe we can elaborate why it is useful? Without any arguments passed it can probably be served as a counter only.
edeaa29 to
2339318
Compare
|
|
||
| @Test | ||
| fun `M resolve a TextWireframe with background ShapeWireframe W map { TextView with ColorDrawable }`( | ||
| fun `M resolve a TextWireframe with background ShapeWireframe W map {with ColorDrawable back}`( |
There was a problem hiding this comment.
| fun `M resolve a TextWireframe with background ShapeWireframe W map {with ColorDrawable back}`( | |
| fun `M resolve a TextWireframe with background ShapeWireframe W map() { ColorDrawable background }`( |
| } | ||
|
|
||
| @Test | ||
| fun `M resolve a TextWireframe with background ShapeWireframe W map {no ColorDrawable back}`( |
There was a problem hiding this comment.
| fun `M resolve a TextWireframe with background ShapeWireframe W map {no ColorDrawable back}`( | |
| fun `M resolve a TextWireframe with background ShapeWireframe W map() { not a ColorDrawable background }`( |
7c10d5a to
519310a
Compare
0xnm
left a comment
There was a problem hiding this comment.
lgtm. I've added few minor suggestions.
| import com.datadog.android.sessionreplay.utils.ViewUtils | ||
|
|
||
| @Suppress("UndocumentedPublicClass") | ||
| abstract class BaseAsyncBackgroundWireframeMapper<T : View>( |
There was a problem hiding this comment.
minor: does it make sense to use word async here in the class naming? WireframeMapper interface already hints that it supports async jobs by having async callback argument in map method.
There was a problem hiding this comment.
yeah it tells that the background will be handled in async way, hmm maybe I can find a better name for this if not will leave it like this.
| * not be consumed until all the wireframes are updated by the async jobs. The main reason we | ||
| * needed this functionality was to be able to unblock the main thread whenever we needed | ||
| * heavy operations like image capture or serialisation. |
There was a problem hiding this comment.
I would re-word this sentence about why it is needed. Not to say "we needed this functionality", but something like "it can be used to offload heavy work from the calling thread (like main) ... ", in such fashion.
519310a to
a9b96c3
Compare
What does this PR do?
A brief description of the change being made with this pull request.
Motivation
What inspired you to submit this pull request?
Additional Notes
Anything else we should know when reviewing?
Review checklist (to be filled by reviewers)