diff --git a/MIGRATING.md b/MIGRATING.md new file mode 100644 index 000000000..033b392db --- /dev/null +++ b/MIGRATING.md @@ -0,0 +1,333 @@ +# Migration Guides + +## Migrating from versions < 6.0.0 + +This guide covers the breaking changes introduced in mParticle Android SDK 6.0.0 and how to migrate your code to the new APIs. + +--- + +### Removed `isAndroidIdDisabled()` / `androidIdDisabled(boolean)` + +The `isAndroidIdDisabled()` method on `MParticle` and `MParticleOptions`, and the `androidIdDisabled(boolean)` builder method on `MParticleOptions.Builder`, have been removed. These were replaced by inverted equivalents with clearer semantics. + +Replace `isAndroidIdDisabled()` with `isAndroidIdEnabled()` and invert the logic: + +Java: + +```java +// Before +if (MParticle.isAndroidIdDisabled()) { ... } +if (options.isAndroidIdDisabled()) { ... } + +// After +if (!MParticle.isAndroidIdEnabled()) { ... } +if (!options.isAndroidIdEnabled()) { ... } +``` + +Kotlin: + +```kotlin +// Before +if (MParticle.isAndroidIdDisabled()) { ... } +if (options.isAndroidIdDisabled()) { ... } + +// After +if (!MParticle.isAndroidIdEnabled()) { ... } +if (!options.isAndroidIdEnabled()) { ... } +``` + +Replace `androidIdDisabled(boolean)` with `androidIdEnabled(boolean)` and invert the value: + +Java: + +```java +// Before +MParticleOptions.builder(context) + .androidIdDisabled(true) + .build(); + +// After +MParticleOptions.builder(context) + .androidIdEnabled(false) + .build(); +``` + +Kotlin: + +```kotlin +// Before +MParticleOptions.builder(context) + .androidIdDisabled(true) + .build() + +// After +MParticleOptions.builder(context) + .androidIdEnabled(false) + .build() +``` + +--- + +### Removed `isAutoTrackingEnabled()` + +The `isAutoTrackingEnabled()` method on `MParticle` has been removed. This method always returned `false` and automatic screen tracking via activity lifecycle hooks has been removed. + +Remove any calls to `isAutoTrackingEnabled()`. If your code depends on this value, note that it was always `false` — no screen tracking was being performed automatically. + +Java: + +```java +// Before +if (MParticle.getInstance().isAutoTrackingEnabled()) { + // this block was never executed +} + +// After +// Remove the call entirely +``` + +Kotlin: + +```kotlin +// Before +if (MParticle.getInstance()?.isAutoTrackingEnabled == true) { + // this block was never executed +} + +// After +// Remove the call entirely +``` + +--- + +### Removed `isProviderActive(int)` + +The `isProviderActive(int)` method on `MParticle` has been removed. It has been renamed to `isKitActive(int)`. + +Replace `isProviderActive(serviceProviderId)` with `isKitActive(serviceProviderId)`: + +Java: + +```java +// Before +boolean active = MParticle.getInstance().isProviderActive(MParticle.ServiceProviders.APPBOY); + +// After +boolean active = MParticle.getInstance().isKitActive(MParticle.ServiceProviders.APPBOY); +``` + +Kotlin: + +```kotlin +// Before +val active = MParticle.getInstance()?.isProviderActive(MParticle.ServiceProviders.APPBOY) + +// After +val active = MParticle.getInstance()?.isKitActive(MParticle.ServiceProviders.APPBOY) +``` + +--- + +### Removed `MPEvent.setInfo()` / `getInfo()` / `Builder.info()` + +The `setInfo(Map)`, `getInfo()`, and `Builder.info(Map)` methods on `MPEvent` have been removed. They have been renamed to `setCustomAttributes()`, `getCustomAttributes()`, and `Builder.customAttributes()`. + +Replace usages with the new method names: + +Java: + +```java +// Before +MPEvent event = new MPEvent.Builder("Event Name", MParticle.EventType.Other) + .info(attributes) + .build(); +Map info = event.getInfo(); +event.setInfo(attributes); + +// After +MPEvent event = new MPEvent.Builder("Event Name", MParticle.EventType.Other) + .customAttributes(attributes) + .build(); +Map customAttributes = event.getCustomAttributes(); +event.setCustomAttributes(attributes); +``` + +Kotlin: + +```kotlin +// Before +val event = MPEvent.Builder("Event Name", MParticle.EventType.Other) + .info(attributes) + .build() +val info = event.getInfo() +event.setInfo(attributes) + +// After +val event = MPEvent.Builder("Event Name", MParticle.EventType.Other) + .customAttributes(attributes) + .build() +val customAttributes = event.getCustomAttributes() +event.setCustomAttributes(attributes) +``` + +--- + +### Removed `UserAttributeListener` + +The `com.mparticle.UserAttributeListener` interface has been removed. It has been replaced by `com.mparticle.TypedUserAttributeListener`. + +The key difference is that `onUserAttributesReceived` now receives `Map` instead of `Map` for user attribute singles, allowing typed values (numbers, booleans) to be preserved rather than stringified. Additionally, the `mpid` parameter is non-nullable (`Long` instead of `Long?`). + +Java: + +```java +// Before +user.getUserAttributes(new UserAttributeListener() { + @Override + public void onUserAttributesReceived( + @Nullable Map userAttributes, + @Nullable Map> userAttributeLists, + @Nullable Long mpid + ) { + // handle attributes + } +}); + +// After +user.getUserAttributes(new TypedUserAttributeListener() { + @Override + public void onUserAttributesReceived( + @NonNull Map userAttributes, + @NonNull Map> userAttributeLists, + long mpid + ) { + // handle attributes — values may be String, Number, or null + } +}); +``` + +Kotlin: + +```kotlin +// Before +user.getUserAttributes(UserAttributeListener { userAttributes, userAttributeLists, mpid -> + // userAttributes: Map? +}) + +// After +user.getUserAttributes(object : TypedUserAttributeListener { + override fun onUserAttributesReceived( + userAttributes: Map, + userAttributeLists: Map?>, + mpid: Long + ) { + // userAttributes values may be String, Number, Boolean, or null + } +}) +``` + +Note: numeric and boolean attribute values are no longer automatically converted to strings. If you need string values, call `.toString()` on each value manually. + +--- + +### Removed `UserAliasHandler` / `IdentityApiRequest.Builder.userAliasHandler()` + +The `com.mparticle.identity.UserAliasHandler` interface and the `IdentityApiRequest.Builder.userAliasHandler()` method have been removed. Use a success listener on the `BaseIdentityTask` returned by identity API calls instead. + +Java: + +```java +// Before +IdentityApiRequest request = IdentityApiRequest.withEmptyUser() + .email("user@example.com") + .userAliasHandler(new UserAliasHandler() { + @Override + public void onUserAlias(MParticleUser previousUser, MParticleUser newUser) { + // copy attributes from previousUser to newUser + } + }) + .build(); +MParticle.getInstance().Identity().login(request); + +// After +IdentityApiRequest request = IdentityApiRequest.withEmptyUser() + .email("user@example.com") + .build(); +MParticle.getInstance().Identity().login(request) + .addSuccessListener(new TaskSuccessListener() { + @Override + public void onSuccess(IdentityApiResult result) { + MParticleUser newUser = result.getUser(); + MParticleUser previousUser = result.getPreviousUser(); + if (previousUser != null) { + // copy attributes from previousUser to newUser + } + } + }); +``` + +Kotlin: + +```kotlin +// Before +val request = IdentityApiRequest.withEmptyUser() + .email("user@example.com") + .userAliasHandler { previousUser, newUser -> + // copy attributes from previousUser to newUser + } + .build() +MParticle.getInstance()?.Identity()?.login(request) + +// After +val request = IdentityApiRequest.withEmptyUser() + .email("user@example.com") + .build() +MParticle.getInstance()?.Identity()?.login(request) + ?.addSuccessListener { result -> + val newUser = result.user + val previousUser = result.previousUser + // copy attributes from previousUser to newUser + } +``` + +--- + +### Removed `ConsentState.Builder.setCCPAConsent()` / `removeCCPAConsent()` + +The `setCCPAConsent(CCPAConsent)` and `removeCCPAConsent()` methods on `ConsentState.Builder` have been removed. They have been renamed to `setCCPAConsentState(CCPAConsent)` and `removeCCPAConsentState()`. + +Java: + +```java +// Before +ConsentState state = ConsentState.builder() + .setCCPAConsent(CCPAConsent.builder(true).build()) + .build(); + +ConsentState.builder().removeCCPAConsent(); + +// After +ConsentState state = ConsentState.builder() + .setCCPAConsentState(CCPAConsent.builder(true).build()) + .build(); + +ConsentState.builder().removeCCPAConsentState(); +``` + +Kotlin: + +```kotlin +// Before +val state = ConsentState.builder() + .setCCPAConsent(CCPAConsent.builder(true).build()) + .build() + +ConsentState.builder().removeCCPAConsent() + +// After +val state = ConsentState.builder() + .setCCPAConsentState(CCPAConsent.builder(true).build()) + .build() + +ConsentState.builder().removeCCPAConsentState() +``` diff --git a/android-core/src/androidTest/kotlin/com.mparticle/MPUserTest.kt b/android-core/src/androidTest/kotlin/com.mparticle/MPUserTest.kt index 663adecdb..54b939850 100644 --- a/android-core/src/androidTest/kotlin/com.mparticle/MPUserTest.kt +++ b/android-core/src/androidTest/kotlin/com.mparticle/MPUserTest.kt @@ -4,7 +4,6 @@ import com.mparticle.internal.AccessUtils import com.mparticle.testutils.BaseCleanStartedEachTest import org.junit.Test import kotlin.test.assertEquals -import kotlin.test.assertNotNull import kotlin.test.assertTrue class MPUserTest : BaseCleanStartedEachTest() { @@ -34,26 +33,6 @@ class MPUserTest : BaseCleanStartedEachTest() { this.userAttributes.put("fooNull", null) android_test_hack() - getUserAttributes( - object : UserAttributeListener { - override fun onUserAttributesReceived( - userAttributes: Map?, - userAttributeLists: Map>?, - mpid: Long?, - ) { - assertNotNull(userAttributes) - assertEquals(6, userAttributes.size) - assertEquals("bar", userAttributes["foo"]) - assertEquals("123", userAttributes["fooInt"]) - assertEquals("12345", userAttributes["fooLong"]) - assertEquals("10.15", userAttributes["fooDouble"]) - assertEquals("-10", userAttributes["fooNegInt"]) - assertEquals("-1010", userAttributes["fooNegLong"]) - assertEquals(null, userAttributes["fooNull"]) - } - }, - ) - getUserAttributes( object : TypedUserAttributeListener { override fun onUserAttributesReceived( diff --git a/android-core/src/androidTest/kotlin/com.mparticle/MParticleOptionsTest.kt b/android-core/src/androidTest/kotlin/com.mparticle/MParticleOptionsTest.kt index 826b3139b..c72065db1 100644 --- a/android-core/src/androidTest/kotlin/com.mparticle/MParticleOptionsTest.kt +++ b/android-core/src/androidTest/kotlin/com.mparticle/MParticleOptionsTest.kt @@ -156,25 +156,12 @@ class MParticleOptionsTest : BaseAbstractTest() { @Test @Throws(Exception::class) - fun testAndroidIdDisabled() { + fun testAndroidIdEnabled() { // test defaults Assert.assertFalse(MParticle.isAndroidIdEnabled()) - Assert.assertTrue(MParticle.isAndroidIdDisabled()) MParticle.setInstance(null) startMParticle(MParticleOptions.builder(mContext)) Assert.assertFalse(MParticle.isAndroidIdEnabled()) - Assert.assertTrue(MParticle.isAndroidIdDisabled()) - - // test androidIdDisabled == true - MParticle.setInstance(null) - startMParticle( - MParticleOptions - .builder(mContext) - .androidIdDisabled(true), - ) - Assert.assertFalse(MParticle.isAndroidIdEnabled()) - Assert.assertTrue(MParticle.isAndroidIdDisabled()) - MParticle.setInstance(null) // test androidIdEnabled == false MParticle.setInstance(null) @@ -184,18 +171,8 @@ class MParticleOptionsTest : BaseAbstractTest() { .androidIdEnabled(false), ) Assert.assertFalse(MParticle.isAndroidIdEnabled()) - Assert.assertTrue(MParticle.isAndroidIdDisabled()) MParticle.setInstance(null) - // test androidIdDisabled == false - startMParticle( - MParticleOptions - .builder(mContext) - .androidIdDisabled(false), - ) - Assert.assertTrue(MParticle.isAndroidIdEnabled()) - Assert.assertFalse(MParticle.isAndroidIdDisabled()) - // test androidIdEnabled == true startMParticle( MParticleOptions @@ -203,7 +180,6 @@ class MParticleOptionsTest : BaseAbstractTest() { .androidIdEnabled(true), ) Assert.assertTrue(MParticle.isAndroidIdEnabled()) - Assert.assertFalse(MParticle.isAndroidIdDisabled()) } @Test @@ -714,14 +690,14 @@ class MParticleOptionsTest : BaseAbstractTest() { MParticleOptions .builder(mContext) .credentials("this", "that") - .androidIdDisabled(true) + .androidIdEnabled(false) .build() Assert.assertTrue(infoLogs.contains("ANDROID_ID will not be collected based on MParticleOptions settings")) infoLogs.clear() MParticleOptions .builder(mContext) .credentials("this", "that") - .androidIdDisabled(false) + .androidIdEnabled(true) .build() Assert.assertTrue(infoLogs.contains("ANDROID_ID will be collected based on MParticleOptions settings")) infoLogs.clear() diff --git a/android-core/src/androidTest/kotlin/com.mparticle/identity/MParticleUserDelegateITest.kt b/android-core/src/androidTest/kotlin/com.mparticle/identity/MParticleUserDelegateITest.kt index 890b288b3..1a709d096 100644 --- a/android-core/src/androidTest/kotlin/com.mparticle/identity/MParticleUserDelegateITest.kt +++ b/android-core/src/androidTest/kotlin/com.mparticle/identity/MParticleUserDelegateITest.kt @@ -5,7 +5,7 @@ import android.os.Looper import android.util.Log import com.mparticle.MParticle import com.mparticle.MParticle.IdentityType -import com.mparticle.UserAttributeListener +import com.mparticle.TypedUserAttributeListener import com.mparticle.consent.CCPAConsent import com.mparticle.consent.ConsentState import com.mparticle.consent.GDPRConsent @@ -191,14 +191,20 @@ class MParticleUserDelegateITest : BaseCleanStartedEachTest() { mUserDelegate.setUserAttribute(key, value, mStartingMpid) } AccessUtils.awaitMessageHandler() - val userAttributesResults = AndroidUtils.Mutable?>(null) - val userAttributeListResults = AndroidUtils.Mutable>?>(null) + val userAttributesResults = AndroidUtils.Mutable?>(null) + val userAttributeListResults = AndroidUtils.Mutable?>?>(null) // fetch on the current (non-main) thread mUserDelegate.getUserAttributes( - UserAttributeListener { userAttributes, userAttributeLists, mpid -> - userAttributesResults.value = userAttributes - userAttributeListResults.value = userAttributeLists + object : TypedUserAttributeListener { + override fun onUserAttributesReceived( + userAttributes: Map, + userAttributeLists: Map?>, + mpid: Long, + ) { + userAttributesResults.value = userAttributes + userAttributeListResults.value = userAttributeLists + } }, mStartingMpid, ) @@ -211,10 +217,16 @@ class MParticleUserDelegateITest : BaseCleanStartedEachTest() { val latch: CountDownLatch = MPLatch(1) Handler(Looper.getMainLooper()).post { mUserDelegate.getUserAttributes( - UserAttributeListener { userAttributes, userAttributeLists, mpid -> - userAttributesResults.value = userAttributes - userAttributeListResults.value = userAttributeLists - latch.countDown() + object : TypedUserAttributeListener { + override fun onUserAttributesReceived( + userAttributes: Map, + userAttributeLists: Map?>, + mpid: Long, + ) { + userAttributesResults.value = userAttributes + userAttributeListResults.value = userAttributeLists + latch.countDown() + } }, mStartingMpid, ) diff --git a/android-core/src/androidTest/kotlin/com.mparticle/startup/StartupTest.kt b/android-core/src/androidTest/kotlin/com.mparticle/startup/StartupTest.kt index 3c47f9e51..f1f00d782 100644 --- a/android-core/src/androidTest/kotlin/com.mparticle/startup/StartupTest.kt +++ b/android-core/src/androidTest/kotlin/com.mparticle/startup/StartupTest.kt @@ -119,7 +119,7 @@ class StartupTest : BaseStartupTest() { .userIdentities(identityMap) .build(), ).logLevel(MParticle.LogLevel.DEBUG) - .androidIdDisabled(false) + .androidIdEnabled(true) .attributionListener( object : AttributionListener { override fun onResult(result: AttributionResult) { diff --git a/android-core/src/main/java/com/mparticle/MPEvent.java b/android-core/src/main/java/com/mparticle/MPEvent.java index 651c2b3bc..a222b56fe 100644 --- a/android-core/src/main/java/com/mparticle/MPEvent.java +++ b/android-core/src/main/java/com/mparticle/MPEvent.java @@ -96,15 +96,6 @@ public boolean equals(@Nullable Object o) { return super.equals(o) || (o != null && this.toString().equals(o.toString())); } - /** - * @param info - * @deprecated use {@link MPEvent#setCustomAttributes(Map)} instead - */ - @Deprecated - public void setInfo(@Nullable Map info) { - setCustomAttributes(info); - } - @Override public void setCustomAttributes(@NonNull Map customAttributes) { super.setCustomAttributes(customAttributes); @@ -196,16 +187,6 @@ public String getCategory() { return category; } - /** - * @return - * @deprecated use {@link MPEvent#getCustomAttributes()} instead - */ - @Deprecated - @Nullable - public Map getInfo() { - return getCustomAttributeStrings(); - } - @NonNull public MParticle.EventType getEventType() { return eventType; @@ -389,20 +370,6 @@ public Builder duration(double durationMillis) { return this; } - /** - * @param info - * @return returns this builder for easy method chaining - * @deprecated user {@link MPEvent.Builder#customAttributes} instead - * - * Data attributes to associate with the event. - */ - @Deprecated - @NonNull - public Builder info(@Nullable Map info) { - this.customAttributes = info; - return this; - } - @NonNull public Builder customAttributes(@Nullable Map customAttributes) { this.customAttributes = customAttributes; diff --git a/android-core/src/main/java/com/mparticle/MParticle.java b/android-core/src/main/java/com/mparticle/MParticle.java index 26d07c2d4..eedd06cbc 100644 --- a/android-core/src/main/java/com/mparticle/MParticle.java +++ b/android-core/src/main/java/com/mparticle/MParticle.java @@ -335,23 +335,6 @@ private static void performWorkspaceSwitch(@NonNull MParticleOptions options) { }); } - /** - * @return false if Android ID collection is enabled. (true by default) - * @see MParticleOptions.Builder#androidIdEnabled(boolean) - * @deprecated This method has been replaced as the behavior has been inverted - Android ID collection is now disabled by default. - *

Use {@link MParticle#isAndroidIdEnabled()} instead. - *

- *

- * Query the status of Android ID collection. - *

- * By default, the SDK will NOT collect Android Id for the purpose - * of anonymous analytics. If you're not using an mParticle integration that consumes Android ID and you would like to collect it, use this API to enable collection - */ - @Deprecated - public static boolean isAndroidIdDisabled() { - return !sAndroidIdEnabled; - } - /** * Query the status of Android ID collection. *

@@ -948,16 +931,6 @@ public void disableUncaughtExceptionLogging() { mConfigManager.disableUncaughtExceptionLogging(true); } - /** - * @return The current setting of automatic screen tracking. - * @deprecated Retrieves the current setting of automatic screen tracking. - */ - @NonNull - @Deprecated - public Boolean isAutoTrackingEnabled() { - return false; - } - /** * Retrieves the current session timeout setting in seconds * @@ -1068,28 +1041,6 @@ public void onAudioStopped() { return mMedia; } - /** - * Detect whether the given service provider is active. Use this method - * only when you need to make direct calls to an embedded SDK. - *

- * You can also register a {@link android.content.BroadcastReceiver} with an {@link android.content.IntentFilter}, using an action of - * {@link MParticle.ServiceProviders#BROADCAST_ACTIVE} or {@link MParticle.ServiceProviders#BROADCAST_DISABLED} - * concatenated with the service provider ID: - * - *

-     * {@code
-     * Context.registerReceiver(yourReceiver, new IntentFilter(MParticle.ServiceProviders.BROADCAST_ACTIVE + MParticle.ServiceProviders.APPBOY));}
-     * 
- * - * @param serviceProviderId - * @return True if you can safely make direct calls to the given service provider. - * @see MParticle.ServiceProviders - * @deprecated - */ - public boolean isProviderActive(int serviceProviderId) { - return isKitActive(serviceProviderId); - } - /** * Detect whether the given service provider kit is active. Use this method * only when you need to make direct calls to an embedded SDK. diff --git a/android-core/src/main/java/com/mparticle/MParticleOptions.java b/android-core/src/main/java/com/mparticle/MParticleOptions.java index e6fd4c123..712d15122 100644 --- a/android-core/src/main/java/com/mparticle/MParticleOptions.java +++ b/android-core/src/main/java/com/mparticle/MParticleOptions.java @@ -246,19 +246,6 @@ public Boolean isDevicePerformanceMetricsDisabled() { return mDevicePerformanceMetricsDisabled; } - /** - * @return true if collection is disabled, false if it is enabled - * @deprecated This method has been replaced as the behavior has been inverted - Android ID collection is now disabled by default. - *

Use {@link MParticle#isAndroidIdEnabled()} instead. - *

- * Query whether Android Id collection is enabled or disabled. - */ - @NonNull - @Deprecated - public Boolean isAndroidIdDisabled() { - return !mAndroidIdEnabled; - } - /** * Query whether Android Id collection is enabled or disabled. * @@ -545,23 +532,6 @@ public Builder devicePerformanceMetricsDisabled(boolean disabled) { return this; } - /** - * @param disabled false to enable collection (true by default) - * @return the instance of the builder, for chaining calls - * @deprecated This method has been replaced as the behavior has been inverted - Android ID collection is now disabled by default. - *

Use {@link androidIdEnabled(boolean)} instead. - *

- *

- * By default, the SDK will NOT collect Android Id for the purpose - * of anonymous analytics. If you're not using an mParticle integration that consumes Android ID and you would like to collect it, use this API to enable collection. - */ - @NonNull - @Deprecated - public Builder androidIdDisabled(boolean disabled) { - this.androidIdEnabled = !disabled; - return this; - } - /** * By default, the SDK will NOT collect Android Id for the purpose * of anonymous analytics. If you're not using an mParticle integration that consumes Android ID and you would like to collect it, use this API to enable collection diff --git a/android-core/src/main/java/com/mparticle/UserAttributeListener.java b/android-core/src/main/java/com/mparticle/UserAttributeListener.java deleted file mode 100644 index 2b79fecca..000000000 --- a/android-core/src/main/java/com/mparticle/UserAttributeListener.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.mparticle; - -import androidx.annotation.Nullable; - -import java.util.List; -import java.util.Map; - -/** - * @deprecated Use TypedUserAttributeListener instead - */ -@Deprecated -public interface UserAttributeListener extends UserAttributeListenerType { - void onUserAttributesReceived(@Nullable Map userAttributes, @Nullable Map> userAttributeLists, @Nullable Long mpid); -} diff --git a/android-core/src/main/java/com/mparticle/consent/ConsentState.java b/android-core/src/main/java/com/mparticle/consent/ConsentState.java index 7297266c4..499e0ef31 100644 --- a/android-core/src/main/java/com/mparticle/consent/ConsentState.java +++ b/android-core/src/main/java/com/mparticle/consent/ConsentState.java @@ -201,24 +201,12 @@ public Builder removeGDPRConsentState(@NonNull String purpose) { return this; } - @Deprecated - @NonNull - public Builder setCCPAConsent(@NonNull CCPAConsent ccpaConsent) { - return setCCPAConsentState(ccpaConsent); - } - @NonNull public Builder setCCPAConsentState(@NonNull CCPAConsent ccpaConsent) { this.ccpaConsent = ccpaConsent; return this; } - @Deprecated - @NonNull - public Builder removeCCPAConsent() { - return removeCCPAConsentState(); - } - @NonNull public Builder removeCCPAConsentState() { ccpaConsent = null; diff --git a/android-core/src/main/java/com/mparticle/identity/IdentityApi.java b/android-core/src/main/java/com/mparticle/identity/IdentityApi.java index c1a5246ad..0f0253e9a 100644 --- a/android-core/src/main/java/com/mparticle/identity/IdentityApi.java +++ b/android-core/src/main/java/com/mparticle/identity/IdentityApi.java @@ -373,7 +373,7 @@ public void run() { long newMpid = result.getMpId(); boolean isLoggedIn = result.isLoggedIn(); ConfigManager.setIdentityRequestInProgress(false); - mUserDelegate.setUser(mContext, startingMpid, newMpid, identityApiRequest.getUserIdentities(), identityApiRequest.getUserAliasHandler(), isLoggedIn); + mUserDelegate.setUser(mContext, startingMpid, newMpid, identityApiRequest.getUserIdentities(), isLoggedIn); final MParticleUser previousUser = startingMpid != newMpid ? getUser(startingMpid) : null; task.setSuccessful(new IdentityApiResult(MParticleUserImpl.getInstance(mContext, newMpid, mUserDelegate), previousUser)); new Handler(Looper.getMainLooper()).post(new Runnable() { diff --git a/android-core/src/main/java/com/mparticle/identity/IdentityApiRequest.java b/android-core/src/main/java/com/mparticle/identity/IdentityApiRequest.java index 1a8c42cdc..f7e071a3d 100644 --- a/android-core/src/main/java/com/mparticle/identity/IdentityApiRequest.java +++ b/android-core/src/main/java/com/mparticle/identity/IdentityApiRequest.java @@ -22,7 +22,6 @@ * @see IdentityApi#modify(IdentityApiRequest) */ public final class IdentityApiRequest { - private UserAliasHandler userAliasHandler = null; private Map userIdentities = new HashMap(); // for /modify requests private Map otherOldIdentities = new HashMap(); @@ -33,9 +32,6 @@ private IdentityApiRequest(IdentityApiRequest.Builder builder) { if (builder.userIdentities != null) { this.userIdentities = builder.userIdentities; } - if (builder.userAliasHandler != null) { - this.userAliasHandler = builder.userAliasHandler; - } if (builder.otherOldIdentities.size() == builder.otherNewIdentities.size()) { this.otherNewIdentities = builder.otherNewIdentities; this.otherOldIdentities = builder.otherOldIdentities; @@ -83,11 +79,6 @@ protected Map getOtherNewIdentities() { return otherNewIdentities; } - @Nullable - public UserAliasHandler getUserAliasHandler() { - return userAliasHandler; - } - /** * A class used for constructing IdentityApiRequest. */ @@ -96,7 +87,6 @@ public static class Builder { private Map userIdentities = new HashMap(); private Map otherOldIdentities = new HashMap(); private Map otherNewIdentities = new HashMap(); - private UserAliasHandler userAliasHandler; protected Builder(@Nullable MParticleUser currentUser) { if (currentUser != null) { @@ -192,23 +182,5 @@ public Builder userIdentities(@NonNull Map userI public IdentityApiRequest build() { return new IdentityApiRequest(this); } - - /** - * Deprecated. To easily migrate your existing code, add a success listener - * to the {@link BaseIdentityTask} that is being returned from this method ){@link BaseIdentityTask#addSuccessListener(TaskSuccessListener)}. Within the - * {@link IdentityApiResult} returned by the success listener, you can run the same code you do - * in you {@link UserAliasHandler}, using the {@link MParticleUser}s returned by - * {@link IdentityApiResult#getUser()} and {@link IdentityApiResult#getPreviousUser()} in place - * of "newUser" and "previousUser" respectively - * - * @param userAliasHandler - * @return - */ - @Deprecated - @NonNull - public Builder userAliasHandler(@Nullable UserAliasHandler userAliasHandler) { - this.userAliasHandler = userAliasHandler; - return this; - } } } \ No newline at end of file diff --git a/android-core/src/main/java/com/mparticle/identity/MParticleUserDelegate.java b/android-core/src/main/java/com/mparticle/identity/MParticleUserDelegate.java index 4f78591c5..172051a45 100644 --- a/android-core/src/main/java/com/mparticle/identity/MParticleUserDelegate.java +++ b/android-core/src/main/java/com/mparticle/identity/MParticleUserDelegate.java @@ -249,7 +249,7 @@ static void setUserIdentities(MParticleUserDelegate userDelegate, Map identities, UserAliasHandler userAliasHandler, boolean isLoggedIn) { + boolean setUser(Context context, long previousMpid, long newMpid, Map identities, boolean isLoggedIn) { setUserIdentities(this, identities, newMpid); // if the mpid remains equal to the temporary_mpid, as the case could be when a network request fails // or on startup, then there is no reason to do anything @@ -259,17 +259,6 @@ boolean setUser(Context context, long previousMpid, long newMpid, Map?, lists: Map?>?, mpid: Long?) { when (listener) { - is UserAttributeListener -> - (singles ?: mutableMapOf()) - .entries - .associate { it.key to it.value?.toString() } - .let { listener.onUserAttributesReceived(it, lists, mpid) } is TypedUserAttributeListener -> mpid?.let { listener.onUserAttributesReceived( diff --git a/android-core/src/main/kotlin/com/mparticle/internal/AppStateManager.kt b/android-core/src/main/kotlin/com/mparticle/internal/AppStateManager.kt index 0387841f4..5df1e47e7 100644 --- a/android-core/src/main/kotlin/com/mparticle/internal/AppStateManager.kt +++ b/android-core/src/main/kotlin/com/mparticle/internal/AppStateManager.kt @@ -11,7 +11,6 @@ import android.os.Bundle import android.os.Handler import android.os.Looper import android.os.SystemClock -import com.mparticle.MPEvent import com.mparticle.MParticle import com.mparticle.identity.IdentityApi.SingleUserIdentificationCallback import com.mparticle.identity.IdentityApiRequest @@ -182,11 +181,6 @@ constructor(context: Context, unitTesting: Boolean = false) { val instance = MParticle.getInstance() if (instance != null) { - if (instance.isAutoTrackingEnabled) { - currentActivityName?.let { - instance.logScreen(it) - } - } if (isBackToForeground) { instance.Internal().kitManager.onApplicationForeground() Logger.debug("App foregrounded.") @@ -223,14 +217,6 @@ constructor(context: Context, unitTesting: Boolean = false) { val instance = MParticle.getInstance() if (instance != null) { - if (instance.isAutoTrackingEnabled) { - instance.logScreen( - MPEvent - .Builder(getActivityName(activity)) - .internalNavigationDirection(false) - .build(), - ) - } instance.Internal().kitManager.onActivityPaused(activity) } } catch (e: Exception) { diff --git a/android-core/src/test/kotlin/com/mparticle/external/ApiVisibilityTest.kt b/android-core/src/test/kotlin/com/mparticle/external/ApiVisibilityTest.kt index 7f5b88619..3d2019a31 100644 --- a/android-core/src/test/kotlin/com/mparticle/external/ApiVisibilityTest.kt +++ b/android-core/src/test/kotlin/com/mparticle/external/ApiVisibilityTest.kt @@ -17,7 +17,7 @@ class ApiVisibilityTest { publicMethodCount++ } } - Assert.assertEquals(66, publicMethodCount) + Assert.assertEquals(63, publicMethodCount) } @Test diff --git a/android-core/src/test/kotlin/com/mparticle/identity/MParticleUserTest.kt b/android-core/src/test/kotlin/com/mparticle/identity/MParticleUserTest.kt index b1ca27fd7..89427cb4b 100644 --- a/android-core/src/test/kotlin/com/mparticle/identity/MParticleUserTest.kt +++ b/android-core/src/test/kotlin/com/mparticle/identity/MParticleUserTest.kt @@ -4,7 +4,6 @@ import com.mparticle.MParticle import com.mparticle.MParticle.IdentityType import com.mparticle.MockMParticle import com.mparticle.TypedUserAttributeListener -import com.mparticle.UserAttributeListener import org.json.JSONArray import org.json.JSONObject import org.junit.Assert @@ -153,7 +152,7 @@ class MParticleUserTest { fun testGetAllUserAttributes() { val listener = Mockito.mock( - UserAttributeListener::class.java, + TypedUserAttributeListener::class.java, ) id?.currentUser?.getUserAttributes(listener) Mockito @@ -166,21 +165,6 @@ class MParticleUserTest { ), ArgumentMatchers.eq(defaultMpId), ) - val typedListener = - Mockito.mock( - TypedUserAttributeListener::class.java, - ) - id?.currentUser?.getUserAttributes(typedListener) - Mockito - .verify( - mp?.Identity()?.mMessageManager, - Mockito.times(2), - )?.getUserAttributes( - ArgumentMatchers.any( - UserAttributeListenerWrapper::class.java, - ), - ArgumentMatchers.eq(defaultMpId), - ) } @Test diff --git a/android-kit-base/src/main/java/com/mparticle/kits/FilteredMParticleUser.java b/android-kit-base/src/main/java/com/mparticle/kits/FilteredMParticleUser.java index 359bafd85..b57b6df03 100644 --- a/android-kit-base/src/main/java/com/mparticle/kits/FilteredMParticleUser.java +++ b/android-kit-base/src/main/java/com/mparticle/kits/FilteredMParticleUser.java @@ -6,7 +6,6 @@ import com.mparticle.MParticle; import com.mparticle.TypedUserAttributeListener; -import com.mparticle.UserAttributeListener; import com.mparticle.UserAttributeListenerType; import com.mparticle.consent.ConsentState; import com.mparticle.audience.AudienceResponse; @@ -82,20 +81,6 @@ public void onUserAttributesReceived(@NonNull Map userAttributes, @No if (userAttributes == null) { userAttributes = new HashMap<>(); } - if (listener instanceof UserAttributeListener) { - Map stringifiedAttributes = new HashMap<>(); - for (Map.Entry entry : userAttributes.entrySet()) { - if (entry.getValue() != null) { - stringifiedAttributes.put(entry.getKey(), entry.getValue().toString()); - } else { - stringifiedAttributes.put(entry.getKey(), null); - } - } - ((UserAttributeListener) listener).onUserAttributesReceived( - (Map) KitConfiguration.filterAttributes(filters, stringifiedAttributes), - (Map>) KitConfiguration.filterAttributes(filters, userAttributeLists), - mpid); - } if (listener instanceof TypedUserAttributeListener) { ((TypedUserAttributeListener) listener).onUserAttributesReceived( KitConfiguration.filterAttributes(filters, userAttributes), 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 ef151ee9e..ccabd7f0d 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 @@ -19,6 +19,7 @@ import com.mparticle.AttributionError; import com.mparticle.AttributionListener; +import com.mparticle.TypedUserAttributeListener; import com.mparticle.AttributionResult; import com.mparticle.BaseEvent; import com.mparticle.Configuration; @@ -26,7 +27,6 @@ import com.mparticle.MParticle; import com.mparticle.MParticleOptions; import com.mparticle.internal.RoktKitApi; -import com.mparticle.UserAttributeListener; import com.mparticle.WrapperSdkVersion; import com.mparticle.commerce.CommerceEvent; import com.mparticle.consent.ConsentState; @@ -59,7 +59,7 @@ import java.util.TreeMap; import java.util.concurrent.ConcurrentHashMap; -public class KitManagerImpl implements KitManager, AttributionListener, UserAttributeListener, IdentityStateListener { +public class KitManagerImpl implements KitManager, AttributionListener, IdentityStateListener { private static HandlerThread kitHandlerThread; @@ -593,7 +593,6 @@ public boolean onPushRegistration(String token, String senderId) { //================================================================================ // KitIntegration.AttributeListener forwarding //================================================================================ - @Override public void onUserAttributesReceived(Map userAttributes, Map> userAttributeLists, Long mpid) { userAttributes = mDataplanFilter.transformUserAttributes(userAttributes); userAttributeLists = mDataplanFilter.transformUserAttributes(userAttributeLists); @@ -1255,7 +1254,20 @@ public void onUserIdentified(MParticleUser mParticleUser, MParticleUser previous } } - mParticleUser.getUserAttributes(this); + mParticleUser.getUserAttributes(new TypedUserAttributeListener() { + @Override + public void onUserAttributesReceived(@NonNull Map userAttributes, @NonNull Map> userAttributeLists, long mpid) { + Map stringAttributes = new HashMap<>(); + for (Map.Entry entry : userAttributes.entrySet()) { + if (entry.getValue() != null) { + stringAttributes.put(entry.getKey(), entry.getValue().toString()); + } else { + stringAttributes.put(entry.getKey(), null); + } + } + onUserAttributesReceived(stringAttributes, (Map>) userAttributeLists, mpid); + } + }); } @Override diff --git a/android-kit-base/src/main/java/com/mparticle/kits/KitUtils.java b/android-kit-base/src/main/java/com/mparticle/kits/KitUtils.java index 6b7cb4834..aba68c7a5 100644 --- a/android-kit-base/src/main/java/com/mparticle/kits/KitUtils.java +++ b/android-kit-base/src/main/java/com/mparticle/kits/KitUtils.java @@ -166,7 +166,7 @@ public static boolean parseBooleanSetting(Map settings, String k @TargetApi(Build.VERSION_CODES.CUPCAKE) @Nullable public static String getAndroidID(Context context) { - if (!MParticle.isAndroidIdDisabled()) { + if (MParticle.isAndroidIdEnabled()) { return Settings.Secure.getString(context.getContentResolver(), "android_id"); } else { return null; diff --git a/kits/branch/branch-5/SampleApplication/app/src/main/java/com/mparticle/branchsample/activities/HomeActivity.java b/kits/branch/branch-5/SampleApplication/app/src/main/java/com/mparticle/branchsample/activities/HomeActivity.java index ee1e49062..dd8a9ac04 100644 --- a/kits/branch/branch-5/SampleApplication/app/src/main/java/com/mparticle/branchsample/activities/HomeActivity.java +++ b/kits/branch/branch-5/SampleApplication/app/src/main/java/com/mparticle/branchsample/activities/HomeActivity.java @@ -142,7 +142,7 @@ private void logSimpleEvent() { MPEvent event = new MPEvent.Builder("Simple Event", MParticle.EventType.Transaction) .duration(100) - .info(eventInfo) + .customAttributes(eventInfo) .category("Food and Beverages") .build(); MParticle.getInstance().logEvent(event); diff --git a/kits/branch/branch-5/SampleApplication/app/src/main/java/com/mparticle/branchsample/activities/SplashActivity.java b/kits/branch/branch-5/SampleApplication/app/src/main/java/com/mparticle/branchsample/activities/SplashActivity.java index 3e9b42f95..ee688119b 100644 --- a/kits/branch/branch-5/SampleApplication/app/src/main/java/com/mparticle/branchsample/activities/SplashActivity.java +++ b/kits/branch/branch-5/SampleApplication/app/src/main/java/com/mparticle/branchsample/activities/SplashActivity.java @@ -64,7 +64,7 @@ public void onBranchInitialised(JSONObject params) { MPEvent event = new MPEvent.Builder("Referred Session", MParticle.EventType.UserContent) .duration(300) - .info(infoMap) + .customAttributes(infoMap) .category("Session").build(); MParticle.getInstance().logEvent(event); intent.putExtra(HomeActivity.BRANCH_PARAMS, params.toString()); diff --git a/kits/ga/ga-23/src/main/kotlin/com/mparticle/kits/GoogleAnalyticsFirebaseKit.kt b/kits/ga/ga-23/src/main/kotlin/com/mparticle/kits/GoogleAnalyticsFirebaseKit.kt index e6449b48e..c1e8293c2 100644 --- a/kits/ga/ga-23/src/main/kotlin/com/mparticle/kits/GoogleAnalyticsFirebaseKit.kt +++ b/kits/ga/ga-23/src/main/kotlin/com/mparticle/kits/GoogleAnalyticsFirebaseKit.kt @@ -6,7 +6,7 @@ import com.google.firebase.analytics.FirebaseAnalytics import com.mparticle.MPEvent import com.mparticle.MParticle import com.mparticle.MParticle.EventType -import com.mparticle.UserAttributeListener +import com.mparticle.TypedUserAttributeListener import com.mparticle.commerce.CommerceEvent import com.mparticle.commerce.Product import com.mparticle.consent.ConsentState @@ -156,9 +156,16 @@ class GoogleAnalyticsFirebaseKit : setUserId(mParticleUser) try { mParticleUser.getUserAttributes( - UserAttributeListener { userAttributeSingles, userAttributeLists, mpid -> - val userAttributes: MutableMap = HashMap(userAttributeSingles) - onSetAllUserAttributes(userAttributes, null, null) + object : TypedUserAttributeListener { + override fun onUserAttributesReceived( + userAttributes: Map, + userAttributeLists: Map?>, + mpid: Long, + ) { + @Suppress("UNCHECKED_CAST") + val stringAttributes = userAttributes.mapValues { it.value?.toString() }.filterValues { it != null } as Map + onSetAllUserAttributes(stringAttributes, null, null) + } }, ) } catch (e: Exception) { @@ -173,9 +180,16 @@ class GoogleAnalyticsFirebaseKit : setUserId(mParticleUser) try { mParticleUser.getUserAttributes( - UserAttributeListener { userAttributeSingles, userAttributeLists, mpid -> - val userAttributes: MutableMap = HashMap(userAttributeSingles) - onSetAllUserAttributes(userAttributes, null, null) + object : TypedUserAttributeListener { + override fun onUserAttributesReceived( + userAttributes: Map, + userAttributeLists: Map?>, + mpid: Long, + ) { + @Suppress("UNCHECKED_CAST") + val stringAttributes = userAttributes.mapValues { it.value?.toString() }.filterValues { it != null } as Map + onSetAllUserAttributes(stringAttributes, null, null) + } }, ) } catch (e: Exception) { @@ -197,9 +211,16 @@ class GoogleAnalyticsFirebaseKit : setUserId(mParticleUser) try { mParticleUser.getUserAttributes( - UserAttributeListener { userAttributeSingles, userAttributeLists, mpid -> - val userAttributes: MutableMap = HashMap(userAttributeSingles) - onSetAllUserAttributes(userAttributes, null, null) + object : TypedUserAttributeListener { + override fun onUserAttributesReceived( + userAttributes: Map, + userAttributeLists: Map?>, + mpid: Long, + ) { + @Suppress("UNCHECKED_CAST") + val stringAttributes = userAttributes.mapValues { it.value?.toString() }.filterValues { it != null } as Map + onSetAllUserAttributes(stringAttributes, null, null) + } }, ) } catch (e: Exception) { diff --git a/kits/ga4/ga4-23/src/main/kotlin/com/mparticle/kits/GoogleAnalyticsFirebaseGA4Kit.kt b/kits/ga4/ga4-23/src/main/kotlin/com/mparticle/kits/GoogleAnalyticsFirebaseGA4Kit.kt index 44ff1fa45..d8c0e31d3 100644 --- a/kits/ga4/ga4-23/src/main/kotlin/com/mparticle/kits/GoogleAnalyticsFirebaseGA4Kit.kt +++ b/kits/ga4/ga4-23/src/main/kotlin/com/mparticle/kits/GoogleAnalyticsFirebaseGA4Kit.kt @@ -6,7 +6,7 @@ import com.google.firebase.analytics.FirebaseAnalytics import com.mparticle.MPEvent import com.mparticle.MParticle import com.mparticle.MParticle.EventType -import com.mparticle.UserAttributeListener +import com.mparticle.TypedUserAttributeListener import com.mparticle.commerce.CommerceEvent import com.mparticle.commerce.Product import com.mparticle.commerce.Promotion @@ -222,9 +222,16 @@ class GoogleAnalyticsFirebaseGA4Kit : setUserId(mParticleUser) try { mParticleUser.getUserAttributes( - UserAttributeListener { userAttributeSingles, userAttributeLists, mpid -> - val userAttributes: MutableMap = HashMap(userAttributeSingles) - onSetAllUserAttributes(userAttributes, null, null) + object : TypedUserAttributeListener { + override fun onUserAttributesReceived( + userAttributes: Map, + userAttributeLists: Map?>, + mpid: Long, + ) { + @Suppress("UNCHECKED_CAST") + val stringAttributes = userAttributes.mapValues { it.value?.toString() }.filterValues { it != null } as Map + onSetAllUserAttributes(stringAttributes, null, null) + } }, ) } catch (e: Exception) { @@ -241,9 +248,16 @@ class GoogleAnalyticsFirebaseGA4Kit : setUserId(mParticleUser) try { mParticleUser.getUserAttributes( - UserAttributeListener { userAttributeSingles, userAttributeLists, mpid -> - val userAttributes: MutableMap = HashMap(userAttributeSingles) - onSetAllUserAttributes(userAttributes, null, null) + object : TypedUserAttributeListener { + override fun onUserAttributesReceived( + userAttributes: Map, + userAttributeLists: Map?>, + mpid: Long, + ) { + @Suppress("UNCHECKED_CAST") + val stringAttributes = userAttributes.mapValues { it.value?.toString() }.filterValues { it != null } as Map + onSetAllUserAttributes(stringAttributes, null, null) + } }, ) } catch (e: Exception) { @@ -269,9 +283,16 @@ class GoogleAnalyticsFirebaseGA4Kit : setUserId(mParticleUser) try { mParticleUser.getUserAttributes( - UserAttributeListener { userAttributeSingles, userAttributeLists, mpid -> - val userAttributes: MutableMap = HashMap(userAttributeSingles) - onSetAllUserAttributes(userAttributes, null, null) + object : TypedUserAttributeListener { + override fun onUserAttributesReceived( + userAttributes: Map, + userAttributeLists: Map?>, + mpid: Long, + ) { + @Suppress("UNCHECKED_CAST") + val stringAttributes = userAttributes.mapValues { it.value?.toString() }.filterValues { it != null } as Map + onSetAllUserAttributes(stringAttributes, null, null) + } }, ) } catch (e: Exception) { diff --git a/kits/optimizely/optimizely-3/src/test/kotlin/com/mparticle/kits/OptimizelyKitTests.kt b/kits/optimizely/optimizely-3/src/test/kotlin/com/mparticle/kits/OptimizelyKitTests.kt index cde9e310b..7ce60a487 100644 --- a/kits/optimizely/optimizely-3/src/test/kotlin/com/mparticle/kits/OptimizelyKitTests.kt +++ b/kits/optimizely/optimizely-3/src/test/kotlin/com/mparticle/kits/OptimizelyKitTests.kt @@ -4,7 +4,6 @@ import com.mparticle.MPEvent import com.mparticle.MParticle import com.mparticle.MParticle.IdentityType import com.mparticle.TypedUserAttributeListener -import com.mparticle.UserAttributeListener import com.mparticle.UserAttributeListenerType import com.mparticle.audience.AudienceResponse import com.mparticle.audience.AudienceTask @@ -562,13 +561,6 @@ class OptimizelyKitTests { id, ) } - if (userAttributeListener is UserAttributeListener) { - userAttributeListener.onUserAttributesReceived( - HashMap(), - HashMap(), - id, - ) - } return null }