From e02c223cfd5e7a39f89a1a8d7fa7ccf4238b6135 Mon Sep 17 00:00:00 2001 From: Thomson Thomas Date: Mon, 2 Feb 2026 11:24:20 -0500 Subject: [PATCH 1/4] feat: Introduce PlacementOptions and jointSdkSelectPlacements - Propagate PlacementOptions and timestamps to Rokt SDK - Capture timestamp in compose scenario --- .../kotlin/com/mparticle/kits/RoktConfigExtensions.kt | 7 +++++++ src/main/kotlin/com/mparticle/kits/RoktKit.kt | 3 +++ src/main/kotlin/com/mparticle/kits/RoktLayout.kt | 11 ++++++++++- 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/main/kotlin/com/mparticle/kits/RoktConfigExtensions.kt b/src/main/kotlin/com/mparticle/kits/RoktConfigExtensions.kt index a5492a4..2136310 100644 --- a/src/main/kotlin/com/mparticle/kits/RoktConfigExtensions.kt +++ b/src/main/kotlin/com/mparticle/kits/RoktConfigExtensions.kt @@ -1,5 +1,6 @@ package com.mparticle.kits +import com.mparticle.rokt.PlacementOptions import com.mparticle.rokt.RoktConfig import com.rokt.roktsdk.CacheConfig import com.mparticle.rokt.CacheConfig as MpCacheConfig @@ -30,3 +31,9 @@ fun RoktConfig.toRoktSdkConfig(): RoktSdkConfig { return builder.build() } + +// TODO: Update the mapping +/*fun PlacementOptions.toRoktSdkPlacementOptions(): com.rokt.roktsdk.PlacementOptions = com.rokt.roktsdk.PlacementOptions( + jointSdkSelectPlacements = this.jointSdkSelectPlacements, + dynamicPerformanceMarkers = this.dynamicPerformanceMarkers, +)*/ diff --git a/src/main/kotlin/com/mparticle/kits/RoktKit.kt b/src/main/kotlin/com/mparticle/kits/RoktKit.kt index 4cfc804..371e56e 100644 --- a/src/main/kotlin/com/mparticle/kits/RoktKit.kt +++ b/src/main/kotlin/com/mparticle/kits/RoktKit.kt @@ -20,6 +20,7 @@ import com.mparticle.internal.Logger import com.mparticle.kits.KitIntegration.CommerceListener import com.mparticle.kits.KitIntegration.IdentityListener import com.mparticle.kits.KitIntegration.RoktListener +import com.mparticle.rokt.PlacementOptions import com.mparticle.rokt.RoktConfig import com.mparticle.rokt.RoktEmbeddedView import com.rokt.roktsdk.Rokt @@ -174,6 +175,7 @@ class RoktKit : fontTypefaces: MutableMap>?, filterUser: FilteredMParticleUser?, mpRoktConfig: RoktConfig?, + placementOptions: PlacementOptions?, ) { val placeholders: Map>? = placeHolders?.mapNotNull { entry -> val widget = Widget(entry.value.get()?.context as Context) @@ -198,6 +200,7 @@ class RoktKit : this.mpRoktEventCallback = mpRoktEventCallback val finalAttributes = prepareFinalAttributes(filterUser, attributes) val roktConfig = mpRoktConfig?.toRoktSdkConfig() + // TODO: propagate the `placementOptions` to Rokt SDK after the API changes are available Rokt.execute( viewName, finalAttributes, diff --git a/src/main/kotlin/com/mparticle/kits/RoktLayout.kt b/src/main/kotlin/com/mparticle/kits/RoktLayout.kt index a088573..88ccbf7 100644 --- a/src/main/kotlin/com/mparticle/kits/RoktLayout.kt +++ b/src/main/kotlin/com/mparticle/kits/RoktLayout.kt @@ -6,8 +6,10 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import com.mparticle.MpRoktEventCallback +import com.mparticle.rokt.PlacementOptions import com.mparticle.rokt.RoktConfig import com.rokt.roktsdk.Rokt +import com.rokt.roktsdk.RoktLayout @Composable @Suppress("FunctionName") @@ -20,9 +22,15 @@ fun RoktLayout( mpRoktEventCallback: MpRoktEventCallback? = null, config: RoktConfig? = null, ) { + var placementOptions: PlacementOptions? = null val instance = RoktKit.instance val resultMapState = remember { mutableStateOf(null) } if (sdkTriggered) { + // Capture the timestamp when the SDK is triggered + placementOptions = PlacementOptions( + jointSdkSelectPlacements = System.currentTimeMillis(), + dynamicPerformanceMarkers = mutableMapOf(), + ) LaunchedEffect(Unit) { instance?.runComposableWithCallback( HashMap(attributes), @@ -35,7 +43,8 @@ fun RoktLayout( } resultMapState.value?.let { resultMap -> - com.rokt.roktsdk.RoktLayout( + // TODO: Propagate the `placementOptions` to Rokt SDK after the API changes are available + RoktLayout( sdkTriggered, identifier, modifier, resultMap.attributes, location, onLoad = { resultMap.callback.onLoad() }, onShouldShowLoadingIndicator = { resultMap.callback.onShouldShowLoadingIndicator() }, From ba9350f0c1bbe1f38dc10da9f7305bc9c0d5c9dd Mon Sep 17 00:00:00 2001 From: Thomson Thomas Date: Mon, 9 Feb 2026 20:10:03 -0500 Subject: [PATCH 2/4] Update Rokt SDK and add PlacementOptions with timestamps --- build.gradle | 2 +- src/main/kotlin/com/mparticle/kits/RoktConfigExtensions.kt | 5 ++--- src/main/kotlin/com/mparticle/kits/RoktKit.kt | 4 ++-- src/main/kotlin/com/mparticle/kits/RoktLayout.kt | 2 +- src/test/kotlin/com/mparticle/kits/RoktKitTests.kt | 7 +++++++ 5 files changed, 13 insertions(+), 7 deletions(-) diff --git a/build.gradle b/build.gradle index 221e279..08edcdc 100644 --- a/build.gradle +++ b/build.gradle @@ -75,7 +75,7 @@ dependencies { implementation 'androidx.annotation:annotation:1.5.0' implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4' implementation 'androidx.compose.runtime:runtime' - api 'com.rokt:roktsdk:4.13.0' + api 'com.rokt:roktsdk:4.13.1' testImplementation files('libs/java-json.jar') testImplementation 'com.squareup.assertj:assertj-android:1.2.0' diff --git a/src/main/kotlin/com/mparticle/kits/RoktConfigExtensions.kt b/src/main/kotlin/com/mparticle/kits/RoktConfigExtensions.kt index 2136310..45a6ee4 100644 --- a/src/main/kotlin/com/mparticle/kits/RoktConfigExtensions.kt +++ b/src/main/kotlin/com/mparticle/kits/RoktConfigExtensions.kt @@ -32,8 +32,7 @@ fun RoktConfig.toRoktSdkConfig(): RoktSdkConfig { return builder.build() } -// TODO: Update the mapping -/*fun PlacementOptions.toRoktSdkPlacementOptions(): com.rokt.roktsdk.PlacementOptions = com.rokt.roktsdk.PlacementOptions( +fun PlacementOptions.toRoktSdkPlacementOptions(): com.rokt.roktsdk.PlacementOptions = com.rokt.roktsdk.PlacementOptions( jointSdkSelectPlacements = this.jointSdkSelectPlacements, dynamicPerformanceMarkers = this.dynamicPerformanceMarkers, -)*/ +) diff --git a/src/main/kotlin/com/mparticle/kits/RoktKit.kt b/src/main/kotlin/com/mparticle/kits/RoktKit.kt index 371e56e..2d80bad 100644 --- a/src/main/kotlin/com/mparticle/kits/RoktKit.kt +++ b/src/main/kotlin/com/mparticle/kits/RoktKit.kt @@ -200,7 +200,6 @@ class RoktKit : this.mpRoktEventCallback = mpRoktEventCallback val finalAttributes = prepareFinalAttributes(filterUser, attributes) val roktConfig = mpRoktConfig?.toRoktSdkConfig() - // TODO: propagate the `placementOptions` to Rokt SDK after the API changes are available Rokt.execute( viewName, finalAttributes, @@ -209,6 +208,7 @@ class RoktKit : placeholders.takeIf { it?.isNotEmpty() == true }, fontTypefaces.takeIf { it?.isNotEmpty() == true }, roktConfig, + placementOptions?.toRoktSdkPlacementOptions(), ) } @@ -351,7 +351,7 @@ class RoktKit : ) { val instance = MParticle.getInstance() deferredAttributes = CompletableDeferred() - instance?.Internal()?.kitManager?.prepareAttributesAsync(attributes) + instance?.Internal()?.kitManager?.roktKitApi?.prepareAttributesAsync(attributes) this.mpRoktEventCallback = mpRoktEventCallback CoroutineScope(Dispatchers.Default).launch { val resultAttributes = deferredAttributes!!.await() diff --git a/src/main/kotlin/com/mparticle/kits/RoktLayout.kt b/src/main/kotlin/com/mparticle/kits/RoktLayout.kt index 88ccbf7..ead65e4 100644 --- a/src/main/kotlin/com/mparticle/kits/RoktLayout.kt +++ b/src/main/kotlin/com/mparticle/kits/RoktLayout.kt @@ -43,7 +43,6 @@ fun RoktLayout( } resultMapState.value?.let { resultMap -> - // TODO: Propagate the `placementOptions` to Rokt SDK after the API changes are available RoktLayout( sdkTriggered, identifier, modifier, resultMap.attributes, location, onLoad = { resultMap.callback.onLoad() }, @@ -51,6 +50,7 @@ fun RoktLayout( onShouldHideLoadingIndicator = { resultMap.callback.onShouldHideLoadingIndicator() }, onUnload = { reason -> resultMap.callback.onUnload(reason) }, config = config?.toRoktSdkConfig(), + placementOptions = placementOptions?.toRoktSdkPlacementOptions(), ) } } diff --git a/src/test/kotlin/com/mparticle/kits/RoktKitTests.kt b/src/test/kotlin/com/mparticle/kits/RoktKitTests.kt index 1a18b5a..ac637f2 100644 --- a/src/test/kotlin/com/mparticle/kits/RoktKitTests.kt +++ b/src/test/kotlin/com/mparticle/kits/RoktKitTests.kt @@ -164,6 +164,7 @@ class RoktKitTests { fontTypefaces = null, filterUser = mockFilterUser, mpRoktConfig = null, + placementOptions = null, ) // Assert @@ -220,6 +221,7 @@ class RoktKitTests { fontTypefaces = null, filterUser = mockFilterUser, mpRoktConfig = null, + placementOptions = null, ) // Assert @@ -268,6 +270,7 @@ class RoktKitTests { fontTypefaces = null, filterUser = mockFilterUser, mpRoktConfig = null, + placementOptions = null, ) // Assert @@ -316,6 +319,7 @@ class RoktKitTests { fontTypefaces = null, filterUser = mockFilterUser, mpRoktConfig = null, + placementOptions = null, ) // Assert @@ -382,6 +386,7 @@ class RoktKitTests { fontTypefaces = null, filterUser = mockFilterUser, mpRoktConfig = null, + placementOptions = null, ) // Assert @@ -456,6 +461,7 @@ class RoktKitTests { fontTypefaces = null, filterUser = mockFilterUser, mpRoktConfig = null, + placementOptions = null, ) // Assert @@ -1356,6 +1362,7 @@ class RoktKitTests { fontTypefaces = null, filterUser = mockFilterUser, mpRoktConfig = null, + placementOptions = null, ) verify(exactly = 1) { From ebe90e3f63d4211c5542d369e95e570d0ba52595 Mon Sep 17 00:00:00 2001 From: Thomson Thomas Date: Wed, 11 Feb 2026 13:18:25 -0500 Subject: [PATCH 3/4] Make the dynamicPerformanceMarkers immutable --- src/main/kotlin/com/mparticle/kits/RoktLayout.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/com/mparticle/kits/RoktLayout.kt b/src/main/kotlin/com/mparticle/kits/RoktLayout.kt index ead65e4..8459636 100644 --- a/src/main/kotlin/com/mparticle/kits/RoktLayout.kt +++ b/src/main/kotlin/com/mparticle/kits/RoktLayout.kt @@ -29,7 +29,7 @@ fun RoktLayout( // Capture the timestamp when the SDK is triggered placementOptions = PlacementOptions( jointSdkSelectPlacements = System.currentTimeMillis(), - dynamicPerformanceMarkers = mutableMapOf(), + dynamicPerformanceMarkers = mapOf(), ) LaunchedEffect(Unit) { instance?.runComposableWithCallback( From b5db14b94f8a82361629b64cfaeacaca41e27e33 Mon Sep 17 00:00:00 2001 From: Thomson Thomas Date: Wed, 11 Feb 2026 13:48:36 -0500 Subject: [PATCH 4/4] Refactor and rename the execute method used in core->kit communication to selectPlacements --- src/main/kotlin/com/mparticle/kits/RoktKit.kt | 2 +- src/main/kotlin/com/mparticle/kits/RoktLayout.kt | 3 +-- src/test/kotlin/com/mparticle/kits/RoktKitTests.kt | 14 +++++++------- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/main/kotlin/com/mparticle/kits/RoktKit.kt b/src/main/kotlin/com/mparticle/kits/RoktKit.kt index 2d80bad..bac0ab9 100644 --- a/src/main/kotlin/com/mparticle/kits/RoktKit.kt +++ b/src/main/kotlin/com/mparticle/kits/RoktKit.kt @@ -167,7 +167,7 @@ class RoktKit : For more details, visit the official documentation: https://docs.rokt.com/developers/integration-guides/android/how-to/adding-a-placement/ */ - override fun execute( + override fun selectPlacements( viewName: String, attributes: Map, mpRoktEventCallback: MpRoktEventCallback?, diff --git a/src/main/kotlin/com/mparticle/kits/RoktLayout.kt b/src/main/kotlin/com/mparticle/kits/RoktLayout.kt index 8459636..0987ea4 100644 --- a/src/main/kotlin/com/mparticle/kits/RoktLayout.kt +++ b/src/main/kotlin/com/mparticle/kits/RoktLayout.kt @@ -9,7 +9,6 @@ import com.mparticle.MpRoktEventCallback import com.mparticle.rokt.PlacementOptions import com.mparticle.rokt.RoktConfig import com.rokt.roktsdk.Rokt -import com.rokt.roktsdk.RoktLayout @Composable @Suppress("FunctionName") @@ -43,7 +42,7 @@ fun RoktLayout( } resultMapState.value?.let { resultMap -> - RoktLayout( + com.rokt.roktsdk.RoktLayout( sdkTriggered, identifier, modifier, resultMap.attributes, location, onLoad = { resultMap.callback.onLoad() }, onShouldShowLoadingIndicator = { resultMap.callback.onShouldShowLoadingIndicator() }, diff --git a/src/test/kotlin/com/mparticle/kits/RoktKitTests.kt b/src/test/kotlin/com/mparticle/kits/RoktKitTests.kt index ac637f2..d1a9f7d 100644 --- a/src/test/kotlin/com/mparticle/kits/RoktKitTests.kt +++ b/src/test/kotlin/com/mparticle/kits/RoktKitTests.kt @@ -156,7 +156,7 @@ class RoktKitTests { // Act val inputAttributes: Map = mapOf("initial_attr" to "initial_value") - roktKit.execute( + roktKit.selectPlacements( viewName = "test_view", attributes = inputAttributes, mpRoktEventCallback = null, @@ -213,7 +213,7 @@ class RoktKitTests { roktKit.configuration = MockKitConfiguration.createKitConfiguration(JSONObject().put("hs", JSONObject())) // Act - roktKit.execute( + roktKit.selectPlacements( viewName = "test_view", attributes = emptyMap(), mpRoktEventCallback = null, @@ -262,7 +262,7 @@ class RoktKitTests { roktKit.configuration = MockKitConfiguration.createKitConfiguration(JSONObject().put("hs", JSONObject())) // Act - roktKit.execute( + roktKit.selectPlacements( viewName = "test_view", attributes = emptyMap(), mpRoktEventCallback = null, @@ -311,7 +311,7 @@ class RoktKitTests { roktKit.configuration = MockKitConfiguration.createKitConfiguration(JSONObject().put("hs", JSONObject())) // Act - roktKit.execute( + roktKit.selectPlacements( viewName = "test_view", attributes = emptyMap(), mpRoktEventCallback = null, @@ -378,7 +378,7 @@ class RoktKitTests { "ShouldFilter" to "testData", ) // Act - roktKit.execute( + roktKit.selectPlacements( viewName = "test", attributes = inputAttributes, mpRoktEventCallback = null, @@ -453,7 +453,7 @@ class RoktKitTests { "ShouldFilter" to "testData", ) // Act - roktKit.execute( + roktKit.selectPlacements( viewName = "test", attributes = inputAttributes, mpRoktEventCallback = null, @@ -1354,7 +1354,7 @@ class RoktKitTests { // Set MParticle instance to null MParticle.setInstance(null) - roktKit.execute( + roktKit.selectPlacements( viewName = "test_view", attributes = testAttributes, mpRoktEventCallback = null,