RUMM-2777 SR add dialogs recording support#1206
Conversation
823cabb to
fb96550
Compare
fb96550 to
6c6dc8c
Compare
Codecov Report
@@ Coverage Diff @@
## feature/sdkv2 #1206 +/- ##
=================================================
+ Coverage 82.59% 82.61% +0.02%
=================================================
Files 351 353 +2
Lines 12480 12537 +57
Branches 2058 2075 +17
=================================================
+ Hits 10307 10357 +50
- Misses 1533 1539 +6
- Partials 640 641 +1
|
0xnm
left a comment
There was a problem hiding this comment.
lgtm! I've added some comments, but they are non-blocking.
| recorder.startRecording(windows, ownerActivity) | ||
| recordCallback.onStartRecording() |
There was a problem hiding this comment.
minor: It seems in the code recorder.startRecording is always followed by the recordCallback.onStartRecording (same for the stop sequence). Does it make sense to put recordCallback inside recorder?
There was a problem hiding this comment.
good point, let me check
|
|
||
| @Test | ||
| fun `M start recording activity W onActivityResumed()`() { | ||
| fun `M start register fragment lifecycle W onActivityCreated(){FragmentActivity}`() { |
There was a problem hiding this comment.
| fun `M start register fragment lifecycle W onActivityCreated(){FragmentActivity}`() { | |
| fun `M register fragment lifecycle W onActivityCreated(){FragmentActivity}`() { |
| // Then | ||
| verify(mockRecoder).startRecording(mockActivity) | ||
| assertThat(testedCallback.resumedActivities).containsKey(mockActivity) | ||
| verify(mockRecoder).startRecording(eq(listOf(mockWindow)), eq(mockActivity)) |
There was a problem hiding this comment.
minor: eq calls are not needed here and in some tests below as well, they are only needed when one of the arguments is capture() call.
There was a problem hiding this comment.
You are right, reason why I added those like that was cause I thought it will do the assertion by reference in cause of the lists. Apparently is doing it by value anyway without the eq
| @@ -1,4 +1,4 @@ | |||
| /* | |||
| /* | |||
| it.decorView.viewTreeObserver.inOrder { | ||
| verify().addOnDrawListener(captor.capture()) | ||
| verify().removeOnDrawListener(captor.firstValue) | ||
| verify().addOnDrawListener(captor.capture()) |
There was a problem hiding this comment.
we don't assert the result of the 2nd capture call, is it expected?
There was a problem hiding this comment.
yes because as the test is saying I just want to test that the previously registered windows (first call) were un - registered.
There was a problem hiding this comment.
yes, just semantically on this line we capture something what we don't use later, so maybe the cleaner thing will be something like verify().addOnDrawListener(any())
| val mockViewTreeObserver: ViewTreeObserver = mock() | ||
| val mockActivity = mockActivity(forge, mockViewTreeObserver) | ||
| testedRecorder.startRecording(mockActivity) | ||
| val fakeWindowsActivityPairs: List<Pair<List<Window>, Activity>> = forge.aList { |
There was a problem hiding this comment.
kotlin cannot infer the type here? given that types of aMockedWindowsList() and aMockedActivity() are known.
4203c9f to
dfe5da8
Compare
| import android.os.Build | ||
| import android.view.MotionEvent | ||
|
|
||
| internal class MotionEventUtils { |
There was a problem hiding this comment.
It seems like this could be an object, or just an ensemble of extension fun on MotionEvent
There was a problem hiding this comment.
I will make it an object, I don't like extensions as they are making your life harder when you have to mock them.
| } | ||
| } | ||
|
|
||
| private fun Fragment.asValidDialogFragment(): DialogFragment? { |
There was a problem hiding this comment.
It seems all usage of this method are followed by ?.let { … }, you could make this method look like this:
fun Fragment.asValidDialogFragment(block:(DialogFragment) ->) {
if (this is DialogFragment && context != null) {
block(this)
}
}| it.decorView.viewTreeObserver.inOrder { | ||
| verify().addOnDrawListener(captor.capture()) | ||
| verify().removeOnDrawListener(captor.firstValue) | ||
| verify().addOnDrawListener(captor.capture()) |
There was a problem hiding this comment.
yes, just semantically on this line we capture something what we don't use later, so maybe the cleaner thing will be something like verify().addOnDrawListener(any())
| verify(mockViewTreeObserver).addOnDrawListener(captor.capture()) | ||
| verify(mockViewTreeObserver).removeOnDrawListener(captor.firstValue) | ||
| fakeWindowsActivityPairs.map { it.first }.flatten().forEach { | ||
| val captor = argumentCaptor<ViewTreeObserver.OnDrawListener>() |
There was a problem hiding this comment.
We don't need captor here, because we don't run any assertions on the values captured. We can use simply verify().addOnDrawListener(any())
There was a problem hiding this comment.
well actually I am doing it here:
verify(it.decorView.viewTreeObserver).removeOnDrawListener(captor.firstValue). I know it could work with any too but I would rather use an explicit verification.
There was a problem hiding this comment.
Nevermind, you are right, I was looking at the wrong line actually.
dfe5da8 to
cb91a83
Compare
What does this PR do?
We were currently not recording the
DialogFragment(pop - ups) for session replay. In this PR we are adding this new feature which implies the following architectural changes:ScreenRecorderwill now be able to record multiple windows in the same time with the sameownerActivity. This actually covers the case of aDialogFragment.SnapshotProcessorwill be able to handle a list ofsnapshotsnow instead of onesingle snapshotat a time.I also addressed a bug in this PR : we were not using the
MotionEventabsolute X,Y positions when recording the user gestures for Session Replay.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)