diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index e43ce910e..88b64e489 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -50,8 +50,13 @@ jobs: #script: ./gradlew :android-core:cAT :android-kit-base:cAT --stacktrace script: | # Disable benchmark tests as they do not work on emulators - adb uninstall com.mparticle.kits.test; ./gradlew connectedCheck --stacktrace - ./gradlew :android-core:cAT :android-kit-base:cAT -Pandroid.testInstrumentationRunnerArguments.androidx.benchmark.enabledRules=none + adb uninstall com.mparticle.kits.test || true + adb uninstall com.mparticle.testutils.test || true + ./gradlew connectedCheck --stacktrace + + adb uninstall com.mparticle.kits.test || true + adb uninstall com.mparticle.testutils.test || true + ./gradlew :android-core:cAT :android-kit-base:cAT -Pandroid.testInstrumentationRunnerArguments.androidx.benchmark.enabledRules=none - name: "Archive Instrumented Tests Results" uses: actions/upload-artifact@v4 if: always() diff --git a/android-core/proguard.pro b/android-core/proguard.pro index dca57ac7c..c3ade4b62 100644 --- a/android-core/proguard.pro +++ b/android-core/proguard.pro @@ -198,6 +198,20 @@ -keep public class com.mparticle.rokt.* { *; } + +# Additional Rokt-specific rules to preserve all classes and method signatures +-keep class com.mparticle.rokt.RoktConfig { *; } +-keep class com.mparticle.rokt.RoktConfig$Builder { *; } +-keep class com.mparticle.rokt.RoktConfig$ColorMode { *; } +-keep class com.mparticle.rokt.CacheConfig { *; } +-keep class com.mparticle.rokt.RoktEmbeddedView { *; } +-keep class com.mparticle.rokt.RoktLayoutDimensionCallBack { *; } + +# Preserve all method signatures in the Rokt class to prevent overload resolution issues +-keepclassmembers class com.mparticle.Rokt { + public void selectPlacements(...); + public void purchaseFinalized(...); +} -keep public class com.mparticle.audience.* { *; } @@ -223,4 +237,15 @@ -keepnames class * implements android.os.Parcelable { public static final ** CREATOR; -} \ No newline at end of file +} + +-keepclassmembers class com.mparticle.Rokt { + (...); + void *(...); + void *$default(...); + ; +} + +-keep interface com.mparticle.MpRoktEventCallback { *; } +-keep interface com.mparticle.UnloadReasons { *; } +-keep class com.mparticle.UnloadReasons { *; } diff --git a/android-core/src/main/java/com/mparticle/MParticle.java b/android-core/src/main/java/com/mparticle/MParticle.java index 8bcd377f1..26d07c2d4 100644 --- a/android-core/src/main/java/com/mparticle/MParticle.java +++ b/android-core/src/main/java/com/mparticle/MParticle.java @@ -6,7 +6,6 @@ import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; -import android.graphics.Typeface; import android.location.Location; import android.location.LocationManager; import android.net.Uri; @@ -52,14 +51,11 @@ import com.mparticle.media.MediaCallbacks; import com.mparticle.messaging.MPMessagingAPI; import com.mparticle.messaging.ProviderCloudMessage; -import com.mparticle.rokt.RoktConfig; -import com.mparticle.rokt.RoktEmbeddedView; import org.jetbrains.annotations.NotNull; import org.json.JSONObject; import java.io.File; -import java.lang.ref.WeakReference; import java.math.BigDecimal; import java.util.HashMap; import java.util.HashSet; @@ -114,7 +110,7 @@ public class MParticle { protected boolean locationTrackingEnabled = false; @NonNull protected Internal mInternal = new Internal(); - protected Rokt rokt = new Rokt(); + protected Rokt rokt; private IdentityStateListener mDeferredModifyPushRegistrationListener; @NonNull private WrapperSdkVersion wrapperSdkVersion = new WrapperSdkVersion(WrapperSdk.WrapperNone, null); @@ -194,6 +190,7 @@ private static MParticle getInstance(@NonNull Context context, @NonNull MParticl instance = new MParticle(options); instance.mKitManager = new KitFrameworkWrapper(options.getContext(), instance.mMessageManager, instance.Internal().getConfigManager(), instance.Internal().getAppStateManager(), options); instance.mIdentityApi = new IdentityApi(options.getContext(), instance.mInternal.getAppStateManager(), instance.mMessageManager, instance.mConfigManager, instance.mKitManager, options.getOperatingSystem()); + instance.rokt = new Rokt(instance.mConfigManager, instance.mKitManager); // Check if we've switched workspaces on startup UploadSettings lastUploadSettings = instance.mConfigManager.getLastUploadSettings(); @@ -1788,136 +1785,6 @@ public interface ResetListener { void onReset(); } - /** - * ### Optional callback events for when the view loads and unloads. - */ - public interface MpRoktEventCallback { - /** - * onLoad Callback will be triggered immediately when the View displays. - */ - void onLoad(); - - /** - * onUnLoad Callback will be triggered if the View failed to show or it closed. - */ - void onUnload(UnloadReasons reason); - - /** - * onShouldShowLoadingIndicator callback will be triggered if View start processing - */ - void onShouldShowLoadingIndicator(); - - /** - * onShouldHideLoadingIndicator callback will be triggered if View end processing - */ - void onShouldHideLoadingIndicator(); - } - - /** - * Enum representing the reasons for unloading. - */ - public enum UnloadReasons { - /** - * Called when there are no offers to display so the view does not get loaded in. - */ - NO_OFFERS, - - /** - * View has been rendered and has been completed. - */ - FINISHED, - - /** - * Operation to fetch view took too long to resolve. - */ - TIMEOUT, - - /** - * Some error has occurred regarding the network. - */ - NETWORK_ERROR, - - /** - * View is empty. - */ - NO_WIDGET, - - /** - * Init request was not successful. - */ - INIT_FAILED, - - /** - * Placeholder string mismatch. - */ - UNKNOWN_PLACEHOLDER, - - /** - * Catch-all for all issues. - */ - UNKNOWN; - - /** - * Returns the enum constant matching the provided string. - * If no match is found, UNKNOWN is returned. - * - * @param value the name of the enum constant to look up - * @return the corresponding UnloadReasons constant or UNKNOWN if no match is found - */ - public static UnloadReasons from(String value) { - for (UnloadReasons reason : UnloadReasons.values()) { - if (reason.name().equals(value)) { - return reason; - } - } - return UNKNOWN; - } - } - - - /** - * Rokt Integration - * */ - public class Rokt{ - protected Rokt(){ - - } - - public void selectPlacements(@NonNull String viewName, - @NonNull Map attributes, - @Nullable MpRoktEventCallback callbacks, - @Nullable Map> placeHolders, - @Nullable Map> fontTypefaces, - @Nullable RoktConfig config) { - if (mConfigManager.isEnabled()) { - mKitManager.execute(viewName, - attributes, - callbacks, - placeHolders, - fontTypefaces, - config); - } - } - - public void selectPlacements(@NonNull String viewName, - @NonNull Map attributes) { - if (mConfigManager.isEnabled()) { - mKitManager.execute(viewName, - attributes, - null, - null, - null, - null - ); - } - } - - public void purchaseFinalized(@NonNull String placementId, @NonNull String catalogItemId, boolean status) { - if (mConfigManager.isEnabled()) { - mKitManager.purchaseFinalized(placementId, catalogItemId, status); - } - } - } /** * @hidden */ diff --git a/android-core/src/main/java/com/mparticle/internal/KitFrameworkWrapper.java b/android-core/src/main/java/com/mparticle/internal/KitFrameworkWrapper.java index 132858da2..e8b3e6e54 100644 --- a/android-core/src/main/java/com/mparticle/internal/KitFrameworkWrapper.java +++ b/android-core/src/main/java/com/mparticle/internal/KitFrameworkWrapper.java @@ -17,6 +17,7 @@ import com.mparticle.MPEvent; import com.mparticle.MParticle; import com.mparticle.MParticleOptions; +import com.mparticle.MpRoktEventCallback; import com.mparticle.WrapperSdkVersion; import com.mparticle.consent.ConsentState; import com.mparticle.identity.IdentityApiRequest; @@ -654,7 +655,7 @@ public void reset() { @Override public void execute(@NonNull String viewName, @NonNull Map attributes, - @Nullable MParticle.MpRoktEventCallback mpRoktEventCallback, + @Nullable MpRoktEventCallback mpRoktEventCallback, @Nullable Map> placeHolders, @Nullable Map> fontTypefaces, @Nullable RoktConfig config) { diff --git a/android-core/src/main/java/com/mparticle/internal/KitManager.java b/android-core/src/main/java/com/mparticle/internal/KitManager.java index 88c0d5ce2..1bd9c78dd 100644 --- a/android-core/src/main/java/com/mparticle/internal/KitManager.java +++ b/android-core/src/main/java/com/mparticle/internal/KitManager.java @@ -16,6 +16,7 @@ import com.mparticle.MPEvent; import com.mparticle.MParticle; import com.mparticle.MParticleOptions; +import com.mparticle.MpRoktEventCallback; import com.mparticle.WrapperSdkVersion; import com.mparticle.consent.ConsentState; import com.mparticle.identity.IdentityApiRequest; @@ -125,10 +126,10 @@ public interface KitManager { void reset(); - void execute(@NonNull String viewName, + void execute(@NonNull String identifier, @NonNull Map attributes, - @Nullable MParticle.MpRoktEventCallback mpRoktEventCallback, - @Nullable Map> placeHolders, + @Nullable MpRoktEventCallback mpRoktEventCallback, + @Nullable Map> embeddedViews, @Nullable Map> fontTypefaces, @Nullable RoktConfig config); diff --git a/android-core/src/main/kotlin/com/mparticle/MpRoktEventCallback.kt b/android-core/src/main/kotlin/com/mparticle/MpRoktEventCallback.kt new file mode 100644 index 000000000..8fc46c28f --- /dev/null +++ b/android-core/src/main/kotlin/com/mparticle/MpRoktEventCallback.kt @@ -0,0 +1,89 @@ +package com.mparticle + +/** + * ### Optional callback events for when the view loads and unloads. + */ +interface MpRoktEventCallback { + + /** + * onLoad Callback will be triggered immediately when the View displays. + */ + fun onLoad() + + /** + * onUnLoad Callback will be triggered if the View failed to show or it closed. + */ + fun onUnload(reason: UnloadReasons) + + /** + * onShouldShowLoadingIndicator callback will be triggered if View starts processing. + */ + fun onShouldShowLoadingIndicator() + + /** + * onShouldHideLoadingIndicator callback will be triggered if View ends processing. + */ + fun onShouldHideLoadingIndicator() +} + +/** + * Enum representing the reasons for unloading. + */ +enum class UnloadReasons { + /** + * Called when there are no offers to display so the view does not get loaded in. + */ + NO_OFFERS, + + /** + * View has been rendered and has been completed. + */ + FINISHED, + + /** + * Operation to fetch view took too long to resolve. + */ + TIMEOUT, + + /** + * Some error has occurred regarding the network. + */ + NETWORK_ERROR, + + /** + * View is empty. + */ + NO_WIDGET, + + /** + * Init request was not successful. + */ + INIT_FAILED, + + /** + * Placeholder string mismatch. + */ + UNKNOWN_PLACEHOLDER, + + /** + * Catch-all for all issues. + */ + UNKNOWN; + + companion object { + /** + * Returns the enum constant matching the provided string. + * If no match is found, UNKNOWN is returned. + * + * @param value the name of the enum constant to look up + * @return the corresponding UnloadReasons constant or UNKNOWN if no match is found + */ + fun from(value: String): UnloadReasons { + return try { + valueOf(value) + } catch (e: IllegalArgumentException) { + UNKNOWN + } + } + } +} diff --git a/android-core/src/main/kotlin/com/mparticle/Rokt.kt b/android-core/src/main/kotlin/com/mparticle/Rokt.kt new file mode 100644 index 000000000..17e4df15f --- /dev/null +++ b/android-core/src/main/kotlin/com/mparticle/Rokt.kt @@ -0,0 +1,36 @@ +package com.mparticle + +import android.graphics.Typeface +import com.mparticle.internal.ConfigManager +import com.mparticle.internal.KitManager +import com.mparticle.internal.listeners.ApiClass +import com.mparticle.rokt.RoktConfig +import com.mparticle.rokt.RoktEmbeddedView +import java.lang.ref.WeakReference + +@ApiClass +class Rokt internal constructor( + private val mConfigManager: ConfigManager, + private val mKitManager: KitManager +) { + + @JvmOverloads + fun selectPlacements( + identifier: String, + attributes: Map, + callbacks: MpRoktEventCallback? = null, + embeddedViews: Map>? = null, + fontTypefaces: Map>? = null, + config: RoktConfig? = null + ) { + if (mConfigManager.isEnabled) { + mKitManager.execute(identifier, attributes, callbacks, embeddedViews, fontTypefaces, config) + } + } + + fun purchaseFinalized(placementId: String, catalogItemId: String, status: Boolean) { + if (mConfigManager.isEnabled) { + mKitManager.purchaseFinalized(placementId, catalogItemId, status) + } + } +} \ No newline at end of file diff --git a/android-core/src/test/kotlin/com/mparticle/MParticleTest.kt b/android-core/src/test/kotlin/com/mparticle/MParticleTest.kt index 78742de0e..40c8789a4 100644 --- a/android-core/src/test/kotlin/com/mparticle/MParticleTest.kt +++ b/android-core/src/test/kotlin/com/mparticle/MParticleTest.kt @@ -1,6 +1,5 @@ package com.mparticle -import android.graphics.Typeface import android.os.Looper import android.os.SystemClock import android.webkit.WebView @@ -18,8 +17,6 @@ import com.mparticle.internal.MessageManager import com.mparticle.media.MPMediaAPI import com.mparticle.messaging.MPMessagingAPI import com.mparticle.mock.MockContext -import com.mparticle.rokt.RoktConfig -import com.mparticle.rokt.RoktEmbeddedView import com.mparticle.testutils.AndroidUtils import com.mparticle.testutils.RandomUtils import org.junit.Assert @@ -28,15 +25,12 @@ import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentCaptor import org.mockito.ArgumentMatchers -import org.mockito.ArgumentMatchers.any import org.mockito.Mockito -import org.mockito.Mockito.never import org.mockito.Mockito.verify import org.mockito.Mockito.`when` import org.powermock.api.mockito.PowerMockito import org.powermock.core.classloader.annotations.PrepareForTest import org.powermock.modules.junit4.PowerMockRunner -import java.lang.ref.WeakReference import java.util.LinkedList import java.util.concurrent.ExecutorService import java.util.concurrent.Executors @@ -469,67 +463,6 @@ class MParticleTest { } } - @Test - fun testSelectPlacements_withFullParams_whenEnabled() { - var instance: MParticle = InnerMockMParticle() - MParticle.setInstance(instance) - `when`(instance.mConfigManager.isEnabled).thenReturn(true) - - val attributes = mutableMapOf() - attributes["key"] = "value" - - val placeholders: Map> = HashMap() - val fonts: Map> = HashMap() - - val config = RoktConfig.Builder().colorMode(RoktConfig.ColorMode.DARK).build() - - val callbacks = object : MParticle.MpRoktEventCallback { - override fun onLoad() { - println("View loaded") - } - - override fun onUnload(reason: MParticle.UnloadReasons) { - println("View unloaded due to: $reason") - } - - override fun onShouldShowLoadingIndicator() { - println("Show loading indicator") - } - - override fun onShouldHideLoadingIndicator() { - println("Hide loading indicator") - } - } - instance.rokt!!.selectPlacements("testView", attributes, callbacks, placeholders, fonts, config) - - verify(instance.mKitManager)?.execute("testView", attributes, callbacks, placeholders, fonts, config) - } - - @Test - fun testSelectPlacements_withBasicParams_whenEnabled() { - var instance: MParticle = InnerMockMParticle() - MParticle.setInstance(instance) - `when`(instance.mConfigManager.isEnabled()).thenReturn(true) - - val attributes = mutableMapOf() - attributes.put("a", "b") - - instance.rokt.selectPlacements("basicView", attributes) - - verify(instance.mKitManager).execute("basicView", attributes, null, null, null, null) - } - - @Test - fun testSelectPlacements_withBasicParams_whenDisabled() { - var instance: MParticle = InnerMockMParticle() - MParticle.setInstance(instance) - `when`(instance.mConfigManager.isEnabled()).thenReturn(false) - - instance.rokt.selectPlacements("basicView", HashMap()) - - verify(instance.mKitManager, never()).execute(any(), any(), any(), any(), any(), any()) - } - @Test fun testRoktSetWrapperSdk_whenEnabled() { val instance: MParticle = InnerMockMParticle() @@ -544,42 +477,6 @@ class MParticleTest { verify(instance.mKitManager).setWrapperSdkVersion(WrapperSdkVersion(expectedSdk, expectedVersion)) } - @Test - fun testRoktSetWrapperSdk_whenDisabled_kitManagerNotCalled() { - val instance: MParticle = InnerMockMParticle() - MParticle.setInstance(instance) - `when`(instance.mConfigManager.isEnabled()).thenReturn(false) - - instance.rokt.selectPlacements("basicView", HashMap()) - - verify(instance.mKitManager, never()).setWrapperSdkVersion(any()) - } - - @Test - fun testReportConversion_withBasicParams_whenEnabled() { - var instance: MParticle = InnerMockMParticle() - MParticle.setInstance(instance) - `when`(instance.mConfigManager.isEnabled()).thenReturn(true) - - val attributes = mutableMapOf() - attributes.put("a", "b") - - instance.rokt.purchaseFinalized("132", "1111", true) - - verify(instance.mKitManager).purchaseFinalized("132", "1111", true) - } - - @Test - fun testReportConversion_withBasicParams_whenDisabled() { - var instance: MParticle = InnerMockMParticle() - MParticle.setInstance(instance) - `when`(instance.mConfigManager.isEnabled()).thenReturn(false) - - instance.rokt.purchaseFinalized("132", "1111", true) - - verify(instance.mKitManager, never()).purchaseFinalized("132", "1111", true) - } - inner class InnerMockMParticle : MParticle() { init { mConfigManager = ConfigManager(MockContext()) diff --git a/android-core/src/test/kotlin/com/mparticle/RoktTest.kt b/android-core/src/test/kotlin/com/mparticle/RoktTest.kt new file mode 100644 index 000000000..a5145409d --- /dev/null +++ b/android-core/src/test/kotlin/com/mparticle/RoktTest.kt @@ -0,0 +1,136 @@ +package com.mparticle + +import android.graphics.Typeface +import android.os.Looper +import android.os.SystemClock +import com.mparticle.internal.ConfigManager +import com.mparticle.internal.KitManager +import com.mparticle.rokt.RoktConfig +import com.mparticle.rokt.RoktEmbeddedView +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.ArgumentMatchers.any +import org.mockito.Mock +import org.mockito.Mockito.never +import org.mockito.Mockito.verify +import org.mockito.Mockito.`when` +import org.mockito.MockitoAnnotations +import org.powermock.core.classloader.annotations.PrepareForTest +import org.powermock.modules.junit4.PowerMockRunner +import java.lang.ref.WeakReference + +@RunWith(PowerMockRunner::class) +@PrepareForTest(Looper::class, SystemClock::class) +class RoktTest { + @Mock + lateinit var kitManager: KitManager + + @Mock + lateinit var configManager: ConfigManager + private lateinit var rokt: Rokt + + @Before + fun setUp() { + MockitoAnnotations.initMocks(this) + rokt = Rokt(configManager, kitManager) + } + + @Test + fun testSelectPlacements_withFullParams_whenEnabled() { + `when`(configManager.isEnabled).thenReturn(true) + + val attributes = mutableMapOf() + attributes["key"] = "value" + + val placeholders: Map> = HashMap() + val fonts: Map> = HashMap() + + val config = RoktConfig.Builder().colorMode(RoktConfig.ColorMode.DARK).build() + + val callbacks = object : MpRoktEventCallback { + override fun onLoad() { + println("View loaded") + } + + override fun onUnload(reason: UnloadReasons) { + println("View unloaded due to: $reason") + } + + override fun onShouldShowLoadingIndicator() { + println("Show loading indicator") + } + + override fun onShouldHideLoadingIndicator() { + println("Hide loading indicator") + } + } + rokt.selectPlacements( + identifier = "testView", + attributes = attributes, + callbacks = callbacks, + embeddedViews = placeholders, + fontTypefaces = fonts, + config = config + ) + + verify(kitManager)?.execute("testView", attributes, callbacks, placeholders, fonts, config) + } + + @Test + fun testSelectPlacements_withBasicParams_whenEnabled() { + `when`(configManager.isEnabled()).thenReturn(true) + + val attributes = mutableMapOf() + attributes["a"] = "b" + + rokt.selectPlacements(attributes = attributes, identifier = "basicView") + + verify(kitManager).execute("basicView", attributes, null, null, null, null) + } + + @Test + fun testSelectPlacements_withBasicParams_whenDisabled() { + `when`(configManager.isEnabled()).thenReturn(false) + + rokt.selectPlacements( + identifier = "basicView", + attributes = HashMap() + ) + + verify(kitManager, never()).execute(any(), any(), any(), any(), any(), any()) + } + + @Test + fun testRoktSetWrapperSdk_whenDisabled_kitManagerNotCalled() { + `when`(configManager.isEnabled()).thenReturn(false) + + rokt.selectPlacements( + identifier = "basicView", + attributes = HashMap() + ) + + verify(kitManager, never()).setWrapperSdkVersion(any()) + } + + @Test + fun testReportConversion_withBasicParams_whenEnabled() { + `when`(configManager.isEnabled()).thenReturn(true) + + val attributes = mutableMapOf() + attributes["a"] = "b" + + rokt.purchaseFinalized("132", "1111", true) + + verify(kitManager).purchaseFinalized("132", "1111", true) + } + + @Test + fun testReportConversion_withBasicParams_whenDisabled() { + `when`(configManager.isEnabled()).thenReturn(false) + + rokt.purchaseFinalized("132", "1111", true) + + verify(kitManager, never()).purchaseFinalized("132", "1111", true) + } +} diff --git a/android-kit-base/src/main/java/com/mparticle/kits/KitIntegration.java b/android-kit-base/src/main/java/com/mparticle/kits/KitIntegration.java index b15c2cf31..8ab7c0533 100644 --- a/android-kit-base/src/main/java/com/mparticle/kits/KitIntegration.java +++ b/android-kit-base/src/main/java/com/mparticle/kits/KitIntegration.java @@ -15,6 +15,7 @@ import com.mparticle.BaseEvent; import com.mparticle.MPEvent; import com.mparticle.MParticle; +import com.mparticle.MpRoktEventCallback; import com.mparticle.WrapperSdkVersion; import com.mparticle.commerce.CommerceEvent; import com.mparticle.consent.ConsentState; @@ -616,7 +617,7 @@ public interface BatchListener { public interface RoktListener { void execute(@NonNull String viewName, @NonNull Map attributes, - @Nullable MParticle.MpRoktEventCallback mpRoktEventCallback, + @Nullable MpRoktEventCallback mpRoktEventCallback, @Nullable Map> placeHolders, @Nullable Map> fontTypefaces, @Nullable FilteredMParticleUser user, diff --git a/android-kit-base/src/main/java/com/mparticle/kits/KitManagerImpl.java b/android-kit-base/src/main/java/com/mparticle/kits/KitManagerImpl.java index 7011e9b11..d58145f3a 100644 --- a/android-kit-base/src/main/java/com/mparticle/kits/KitManagerImpl.java +++ b/android-kit-base/src/main/java/com/mparticle/kits/KitManagerImpl.java @@ -24,7 +24,7 @@ import com.mparticle.MParticle; import com.mparticle.MParticleOptions; import com.mparticle.MParticleTask; -import com.mparticle.TypedUserAttributeListener; +import com.mparticle.MpRoktEventCallback; import com.mparticle.UserAttributeListener; import com.mparticle.WrapperSdkVersion; import com.mparticle.commerce.CommerceEvent; @@ -1335,7 +1335,7 @@ public void reset() { @Override public void execute(@NonNull String viewName, @NonNull Map attributes, - @Nullable MParticle.MpRoktEventCallback mpRoktEventCallback, + @Nullable MpRoktEventCallback mpRoktEventCallback, @Nullable Map> placeHolders, @Nullable Map> fontTypefaces, @Nullable RoktConfig config) { @@ -1370,21 +1370,27 @@ public void execute(@NonNull String viewName, finalAttributes.put(mapTo, value); } } - setRoktAttributesOnUser(finalAttributes, user, () -> { - if (!finalAttributes.containsKey(Constants.MessageKey.SANDBOX_MODE_ROKT)) { - finalAttributes.put(Constants.MessageKey.SANDBOX_MODE_ROKT, String.valueOf(Objects.toString(MPUtility.isDevEnv(), "false"))); // Default value is "false" if null - } + Map objectAttributes = new HashMap<>(); + for (Map.Entry entry : finalAttributes.entrySet()) { + if(!entry.getKey().equals(Constants.MessageKey.SANDBOX_MODE_ROKT)) { + objectAttributes.put(entry.getKey(), entry.getValue()); + } + } + if (user != null) { + user.setUserAttributes(objectAttributes); + } - Long userId = (user != null) ? user.getId() : null; - FilteredMParticleUser filteredUser = FilteredMParticleUser.getInstance(userId, provider); - ((KitIntegration.RoktListener) provider).execute(viewName, - finalAttributes, - mpRoktEventCallback, - placeHolders, - fontTypefaces, - filteredUser, - config); - }); + if (!finalAttributes.containsKey(Constants.MessageKey.SANDBOX_MODE_ROKT)) { + finalAttributes.put(Constants.MessageKey.SANDBOX_MODE_ROKT, String.valueOf(Objects.toString(MPUtility.isDevEnv(), "false"))); // Default value is "false" if null + } + + ((KitIntegration.RoktListener) provider).execute(viewName, + finalAttributes, + mpRoktEventCallback, + placeHolders, + fontTypefaces, + FilteredMParticleUser.getInstance(user.getId(), provider), + config); }); } } catch (Exception e) { @@ -1419,31 +1425,6 @@ public void purchaseFinalized(@NonNull String placementId, @NonNull String catal } } - private void setRoktAttributesOnUser( - Map finalAttributes, - MParticleUser user, - Runnable runnable - ) { - Map objectAttributes = new HashMap<>(); - for (Map.Entry entry : finalAttributes.entrySet()) { - if(!entry.getKey().equals(Constants.MessageKey.SANDBOX_MODE_ROKT)) { - objectAttributes.put(entry.getKey(), entry.getValue()); - } - } - if (user != null) { - user.setUserAttributes(objectAttributes); - // Use asynchronous getUserAttributes with callback to ensure attributes are set before proceeding - user.getUserAttributes(new TypedUserAttributeListener() { - @Override - public void onUserAttributesReceived(@NonNull Map userAttributes, @NonNull Map> userAttributeLists, long mpid) { - runnable.run(); - } - }); - } else { - runnable.run(); - } - } - private void confirmEmail( @Nullable String email, @Nullable MParticleUser user, diff --git a/android-kit-base/src/test/kotlin/com/mparticle/kits/KitManagerImplTest.kt b/android-kit-base/src/test/kotlin/com/mparticle/kits/KitManagerImplTest.kt index 99b69faea..5257e3109 100644 --- a/android-kit-base/src/test/kotlin/com/mparticle/kits/KitManagerImplTest.kt +++ b/android-kit-base/src/test/kotlin/com/mparticle/kits/KitManagerImplTest.kt @@ -9,6 +9,7 @@ import com.mparticle.MPEvent import com.mparticle.MParticle import com.mparticle.MParticleOptions import com.mparticle.MParticleTask +import com.mparticle.MpRoktEventCallback import com.mparticle.WrapperSdk import com.mparticle.WrapperSdkVersion import com.mparticle.commerce.CommerceEvent @@ -1481,7 +1482,7 @@ class KitManagerImplTest { override fun execute( viewName: String, attributes: MutableMap, - mpRoktEventCallback: MParticle.MpRoktEventCallback?, + mpRoktEventCallback: MpRoktEventCallback?, placeHolders: MutableMap>?, fontTypefaces: MutableMap>?, user: FilteredMParticleUser?, diff --git a/settings.gradle b/settings.gradle index 67467c805..bdf797696 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,3 +1,17 @@ +pluginManagement { + buildscript { + repositories { + mavenCentral() + maven { + url = uri("https://storage.googleapis.com/r8-releases/raw") + } + } + dependencies { + classpath("com.android.tools:r8:8.9.35") + } + } +} + include ':android-core', ':testutils', ':android-kit-base', diff --git a/testutils/src/main/java/com/mparticle/mock/MockMParticle.java b/testutils/src/main/java/com/mparticle/mock/MockMParticle.java index ab1e34fea..31c88db10 100644 --- a/testutils/src/main/java/com/mparticle/mock/MockMParticle.java +++ b/testutils/src/main/java/com/mparticle/mock/MockMParticle.java @@ -35,11 +35,4 @@ class MockInternal extends Internal { super(); } } - - class MockRokt extends Rokt { - - MockRokt() { - super(); - } - } }