[RUM-8652] Allow definition of custom implementations of specific SR methods#2516
Conversation
| data class SessionReplayCustomCallbacks( | ||
| val getCurrentWindows: (() -> List<Window>)? = null | ||
| ) No newline at end of file |
There was a problem hiding this comment.
Note
Why did you chose to make it a data class instead of an interface?
There was a problem hiding this comment.
The general idea was to make a simple configuration object we could add to the configuration builder that holds optional callbacks, allowing clients to set only the ones they needed. But here both would work.
8d1bb14 to
fdb1b74
Compare
|
I think we shouldn't go this way (by exposing it in the public API along with other methods), it should be an internal API accessible from the proxy. |
| */ | ||
| @InternalApi | ||
| @Suppress( | ||
| "UndocumentedPublicClass", |
There was a problem hiding this comment.
This class has been documented above, why do we still need this Suppression here?
| import android.view.Window | ||
|
|
||
| data class SessionReplayCustomCallbacks( | ||
| val getCurrentWindows: (() -> List<Window>)? = null |
There was a problem hiding this comment.
I think instead of having a data class with only one callback inside, you can just make it as an interface
@NoOpImplementation
interface SessionReplayCustomCallback{
fun getCurrentWindows() : List<Window>
}
There was a problem hiding this comment.
I'm still not sure how many callbacks there will be for sure, for now it's just one, if it turns out to be just this one, we will likely not even need this and I'll change this then.
There was a problem hiding this comment.
Instead of having several callbacks feature, is that possible to have only one callback but with more functions in it?
There was a problem hiding this comment.
Not sure what that means, can you explain it a bit more or give an example ? Just for context, all these functions we need to override from RN or other project can all be unrelated to each other and can affect different parts of the sdk.
There was a problem hiding this comment.
If I understand correctly, what you intent to do should be like:
data class SessionReplayCustomCallbacks(
val getCurrentWindows: (() -> List<Window>)? = null
val doSomethingElseA: ((SomeInputA) -> SomeOutputA)? = null
val doSomethingElseB: ((SomeInputB) -> List<SomeOutputB>)? = null
)
Instead of doing that, you can do :
@NoOpImplementation
interface SessionReplayCustomCallback{
fun getCurrentWindows() : List<Window>
fun doSomethingElseA(input: SomeInputA) : SomeOutputA
fun doSomethingElseA(input: SomeInputB) : SomeOutputB
}
In that case you will have only one callback but can be called in different placesto serve for your need.
| private var extensionSupportSet: MutableSet<ExtensionSupport> = mutableSetOf() | ||
| private var dynamicOptimizationEnabled = true | ||
| private var systemRequirementsConfiguration = SystemRequirementsConfiguration.NONE | ||
| private var customCallbacks: SessionReplayCustomCallbacks = SessionReplayCustomCallbacks() |
There was a problem hiding this comment.
is it expected that the class name and field name are all pluriel?
There was a problem hiding this comment.
I would say in this case yes, but what would you suggest ?
There was a problem hiding this comment.
usually we keep class name singular to represent a single instance of an object, unless the class itself presents a pluriel collection such as data class Users(val users: List<User>), and for the field name it should be like:
private var customCallback : SessionReplayCustomCallback = SessionReplayCustomCallback()
// or
private var customCallbacks : List<SessionReplayCustomCallback> = SessionReplayCustomCallback()
There was a problem hiding this comment.
I don't mind changing the name, but having something called SessionReplayCustomCallback, will be incorrect as soon as another callback is added no ?
|
Please ignore my comment above, I had an old version of this PR opened. I will review a new one. |
0xnm
left a comment
There was a problem hiding this comment.
I left few suggestions, but nothing blocking. LGTM.
| import android.view.Window | ||
|
|
||
| data class SessionReplayCustomCallbacks( | ||
| val getCurrentWindows: (() -> List<Window>)? = null |
There was a problem hiding this comment.
minor: there is no need to use get prefix for val property, it can be just val currentWindows
| logger = internalLogger, | ||
| resourceResolver = resourceResolver, | ||
| logger = internalLogger, resourceResolver = resourceResolver, |
| data class SessionReplayCustomCallbacks( | ||
| val getCurrentWindows: (() -> List<Window>)? = null |
There was a problem hiding this comment.
maybe some explanation/docs here will be useful
| "ClassNaming", | ||
| "VariableNaming" | ||
| ) | ||
| class _SessionReplayInternalProxy { |
There was a problem hiding this comment.
_SessionReplayInternalProxy.setCustomCallbacks(builder, customCallbacks)
_SessionReplayInternalProxy(builder).setCustomCallbacks(customCallbacks)
cf978c3 to
8e98c06
Compare
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #2516 +/- ##
===========================================
- Coverage 70.07% 70.07% -0.01%
===========================================
Files 796 797 +1
Lines 29970 29990 +20
Branches 5016 5018 +2
===========================================
+ Hits 21001 21013 +12
- Misses 7574 7576 +2
- Partials 1395 1401 +6
🚀 New features to boost your workflow:
|
8e98c06 to
5cfbd1c
Compare
… builder - have the option to set `getCurrentActivity` in order to allow fragments lifecycle callbacks to be registered after Application.onCreate phase - make `setInternalCallback`to be available only through internal proxy tmp
5cfbd1c to
f0da63c
Compare
|
|
||
| private val currentActiveWindows = WeakHashMap<Window, Any?>() | ||
|
|
||
| fun setCurrentWindow(activity: Activity) { |
There was a problem hiding this comment.
Here the function name is setCurrentWindow but you are taking activity as the argument, which makes a bit confusing,
you can just change to setCurrentWindow(window: Window) and let the call site worry about how to retrieve the window.
What does this PR do?
Exposes a new SessionReplayConfigutation option to allow clients to pass their own implementations of specific methods used in the Session Replay SDK.
Updates the SDK code to use the overriden function if provided and falling back to the original implementation otherwise.
( Currently only
getCurrentActivityis allowed to be redefined, but there's a high likelihood that more will be needed )Motivation
What inspired you to submit this pull request?
Certain parts of the session replay SDK don't work as intended when ran in a react-native environment, leading to broken replays. In order to keep platform specific code out of the android SDK, the goal is to allow each client to add their own implementations of the parts that don't work.
Additional Notes
We keep the
setInternalCallbackonly accessible through a internal proxy in order to not expose internal config options. In practice it would look something like this:Review checklist (to be filled by reviewers)