Skip to content

Commit

Permalink
recording: session replay respect feature flag variants
Browse files Browse the repository at this point in the history
  • Loading branch information
marandaneto committed Oct 14, 2024
1 parent d770f8b commit 8afd45c
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 13 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
## Next

- recording: session replay respect feature flag variants ([#196](https://github.com/PostHog/posthog-android/pull/196))

## 3.8.1 - 2024-10-09

- recording: `OnTouchEventListener` try catch guard to swallow unexpected errors take 2 ([#196](https://github.com/PostHog/posthog-android/pull/196))
Expand Down
66 changes: 53 additions & 13 deletions posthog/src/main/java/com/posthog/internal/PostHogFeatureFlags.kt
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,37 @@ internal class PostHogFeatureFlags(
preloadSessionReplayFlag()
}

private fun isRecordingActive(
featureFlags: Map<String, Any>,
sessionRecording: Map<String, Any>,
): Boolean {
var recordingActive = true

// Check for boolean flags
val linkedFlag = sessionRecording["linkedFlag"]
if (linkedFlag is String) {
val value = featureFlags[linkedFlag]
if (value is Boolean) {
recordingActive = value
}
} else if (linkedFlag is Map<*, *>) {
// Check for specific flag variant
val flag = linkedFlag["flag"] as? String
val variant = linkedFlag["variant"] as? String
if (flag != null && variant != null) {
val value = featureFlags[flag] as? String
recordingActive = value == variant
}
}
// check for multi flag variant (any)
// val linkedFlag = sessionRecording["linkedFlag"] as? String,
// featureFlags[linkedFlag] != nil
// is also a valid check but since we cannot check the value of the flag,
// we consider session recording is active

return recordingActive
}

fun loadFeatureFlags(
distinctId: String,
anonymousId: String?,
Expand Down Expand Up @@ -74,26 +105,30 @@ internal class PostHogFeatureFlags(
this.featureFlagPayloads = normalizedPayloads
}

when (response.sessionRecording) {
when (val sessionRecording = response.sessionRecording) {
is Boolean -> {
// if sessionRecording is a Boolean, its always disabled
// so we don't enable sessionReplayFlagActive here
sessionReplayFlagActive = false
sessionReplayFlagActive = sessionRecording

config.cachePreferences?.remove(SESSION_REPLAY)
if (!sessionRecording) {
config.cachePreferences?.remove(SESSION_REPLAY)
} else {
// do nothing
}
}

is Map<*, *> -> {
@Suppress("UNCHECKED_CAST")
(response.sessionRecording as? Map<String, Any?>)?.let { sessionRecording ->
(sessionRecording as? Map<String, Any>)?.let {
// keeps the value from config.sessionReplay since having sessionRecording
// means its enabled on the project settings, but its only enabled
// when local config.sessionReplay is also enabled
config.snapshotEndpoint = sessionRecording["endpoint"] as? String
config.snapshotEndpoint = it["endpoint"] as? String
?: config.snapshotEndpoint

sessionReplayFlagActive = true
config.cachePreferences?.setValue(SESSION_REPLAY, sessionRecording)
sessionReplayFlagActive = isRecordingActive(this.featureFlags ?: mapOf(), it)
config.cachePreferences?.setValue(SESSION_REPLAY, it)

// TODO:
// consoleLogRecordingEnabled -> Boolean or null
Expand Down Expand Up @@ -131,14 +166,19 @@ internal class PostHogFeatureFlags(

private fun preloadSessionReplayFlag() {
synchronized(featureFlagsLock) {
@Suppress("UNCHECKED_CAST")
val sessionRecording = config.cachePreferences?.getValue(SESSION_REPLAY) as? Map<String, Any>
config.cachePreferences?.let { preferences ->
@Suppress("UNCHECKED_CAST")
val sessionRecording = preferences.getValue(SESSION_REPLAY) as? Map<String, Any>

@Suppress("UNCHECKED_CAST")
val flags = preferences.getValue(FEATURE_FLAGS) as? Map<String, Any>

if (sessionRecording != null) {
sessionReplayFlagActive = true
if (sessionRecording != null) {
sessionReplayFlagActive = isRecordingActive(flags ?: mapOf(), sessionRecording)

config.snapshotEndpoint = sessionRecording["endpoint"] as? String
?: config.snapshotEndpoint
config.snapshotEndpoint = sessionRecording["endpoint"] as? String
?: config.snapshotEndpoint
}
}
}
}
Expand Down

0 comments on commit 8afd45c

Please sign in to comment.