From a59f38d794ae6b3c3e71dfadaca09d083cf38d76 Mon Sep 17 00:00:00 2001 From: Jared McFarland Date: Thu, 29 Aug 2024 10:12:23 -0700 Subject: [PATCH 1/5] add and use SessionReplayBroadcastReceiver --- build.gradle | 3 +- .../android/mpmetrics/MixpanelAPI.java | 9 +++- .../SessionReplayBroadcastReceiver.java | 45 +++++++++++++++++++ 3 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/mixpanel/android/mpmetrics/SessionReplayBroadcastReceiver.java diff --git a/build.gradle b/build.gradle index 7f29c0ec..8163e6d8 100644 --- a/build.gradle +++ b/build.gradle @@ -81,7 +81,8 @@ allprojects { // have to change the bit in uploadArchives that marks all dependencies as optional. dependencies { implementation "androidx.annotation:annotation:1.1.0" - + implementation 'androidx.core:core:1.12.0' + // AndroidJUnitRunner and JUnit Rules testImplementation 'junit:junit:4.12' androidTestImplementation 'androidx.test:core:1.4.0' diff --git a/src/main/java/com/mixpanel/android/mpmetrics/MixpanelAPI.java b/src/main/java/com/mixpanel/android/mpmetrics/MixpanelAPI.java index ffd7ce11..3636802a 100644 --- a/src/main/java/com/mixpanel/android/mpmetrics/MixpanelAPI.java +++ b/src/main/java/com/mixpanel/android/mpmetrics/MixpanelAPI.java @@ -12,6 +12,7 @@ import android.content.pm.PackageManager; import android.os.Build; import android.os.Bundle; +import androidx.core.content.ContextCompat; import com.mixpanel.android.util.MPLog; import com.mixpanel.android.util.ProxyServerInteractor; @@ -105,7 +106,6 @@ public class MixpanelAPI { */ public static final String VERSION = MPConfig.VERSION; - /** * You shouldn't instantiate MixpanelAPI objects directly. * Use MixpanelAPI.getInstance to get an instance. @@ -193,6 +193,13 @@ public class MixpanelAPI { if (mConfig.getRemoveLegacyResidualFiles()) { mMessages.removeResidualImageFiles(new File(mContext.getApplicationInfo().dataDir)); } + + BroadcastReceiver sessionReplayReceiver = new SessionReplayBroadcastReceiver(this); + IntentFilter filter = new IntentFilter(); + filter.addAction(SessionReplayBroadcastReceiver.REGISTER_ACTION); + filter.addAction(SessionReplayBroadcastReceiver.UNREGISTER_ACTION); + Context appCtx = mContext.getApplicationContext(); + ContextCompat.registerReceiver(appCtx, sessionReplayReceiver, filter, ContextCompat.RECEIVER_NOT_EXPORTED); } /** diff --git a/src/main/java/com/mixpanel/android/mpmetrics/SessionReplayBroadcastReceiver.java b/src/main/java/com/mixpanel/android/mpmetrics/SessionReplayBroadcastReceiver.java new file mode 100644 index 00000000..82976014 --- /dev/null +++ b/src/main/java/com/mixpanel/android/mpmetrics/SessionReplayBroadcastReceiver.java @@ -0,0 +1,45 @@ +package com.mixpanel.android.mpmetrics; + +import static com.mixpanel.android.mpmetrics.ConfigurationChecker.LOGTAG; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; + +import com.mixpanel.android.util.MPLog; + +import java.io.Serializable; +import java.util.HashMap; + +public class SessionReplayBroadcastReceiver extends BroadcastReceiver { + private final MixpanelAPI sdkInstance; + + public static final String REGISTER_ACTION = "com.mixpanel.properties.register"; + public static final String UNREGISTER_ACTION = "com.mixpanel.properties.unregister"; + + public SessionReplayBroadcastReceiver(MixpanelAPI instance) { + this.sdkInstance = instance; + } + + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + if (REGISTER_ACTION.equals(action)) { + HashMap data = null; + Serializable serializableData = intent.getSerializableExtra("data"); + if (serializableData instanceof HashMap) { + try { + data = (HashMap) serializableData; + } catch (ClassCastException e) { + MPLog.e(LOGTAG, "Failed to cast broadcast extras data to HashMap", e); + MPLog.d(LOGTAG, "Broadcast extras data: " + serializableData); + } + } + if (data != null && data.containsKey("$mp_replay_id")) { + sdkInstance.registerSuperPropertiesMap(data); + } + } else if (UNREGISTER_ACTION.equals(action)) { + sdkInstance.unregisterSuperProperty("$mp_replay_id"); + } + } +} From 6dfbed45eb0a5baee88ad5ecc90a071f8c547a4d Mon Sep 17 00:00:00 2001 From: Jared McFarland Date: Thu, 29 Aug 2024 10:31:38 -0700 Subject: [PATCH 2/5] move actions and key to constants --- .../mixpanel/android/mpmetrics/MixpanelAPI.java | 5 +++-- .../mpmetrics/SessionReplayBroadcastReceiver.java | 15 ++++++--------- .../com/mixpanel/android/util/MPConstants.java | 5 +++++ 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/mixpanel/android/mpmetrics/MixpanelAPI.java b/src/main/java/com/mixpanel/android/mpmetrics/MixpanelAPI.java index 3636802a..d63117f2 100644 --- a/src/main/java/com/mixpanel/android/mpmetrics/MixpanelAPI.java +++ b/src/main/java/com/mixpanel/android/mpmetrics/MixpanelAPI.java @@ -14,6 +14,7 @@ import android.os.Bundle; import androidx.core.content.ContextCompat; +import com.mixpanel.android.util.MPConstants.SessionReplay; import com.mixpanel.android.util.MPLog; import com.mixpanel.android.util.ProxyServerInteractor; @@ -196,8 +197,8 @@ public class MixpanelAPI { BroadcastReceiver sessionReplayReceiver = new SessionReplayBroadcastReceiver(this); IntentFilter filter = new IntentFilter(); - filter.addAction(SessionReplayBroadcastReceiver.REGISTER_ACTION); - filter.addAction(SessionReplayBroadcastReceiver.UNREGISTER_ACTION); + filter.addAction(SessionReplay.REGISTER_ACTION); + filter.addAction(SessionReplay.UNREGISTER_ACTION); Context appCtx = mContext.getApplicationContext(); ContextCompat.registerReceiver(appCtx, sessionReplayReceiver, filter, ContextCompat.RECEIVER_NOT_EXPORTED); } diff --git a/src/main/java/com/mixpanel/android/mpmetrics/SessionReplayBroadcastReceiver.java b/src/main/java/com/mixpanel/android/mpmetrics/SessionReplayBroadcastReceiver.java index 82976014..971ced30 100644 --- a/src/main/java/com/mixpanel/android/mpmetrics/SessionReplayBroadcastReceiver.java +++ b/src/main/java/com/mixpanel/android/mpmetrics/SessionReplayBroadcastReceiver.java @@ -1,22 +1,19 @@ package com.mixpanel.android.mpmetrics; -import static com.mixpanel.android.mpmetrics.ConfigurationChecker.LOGTAG; - import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; +import com.mixpanel.android.util.MPConstants.SessionReplay; import com.mixpanel.android.util.MPLog; import java.io.Serializable; import java.util.HashMap; public class SessionReplayBroadcastReceiver extends BroadcastReceiver { + private static final String LOGTAG = "SessionReplayBroadcastReceiver"; private final MixpanelAPI sdkInstance; - public static final String REGISTER_ACTION = "com.mixpanel.properties.register"; - public static final String UNREGISTER_ACTION = "com.mixpanel.properties.unregister"; - public SessionReplayBroadcastReceiver(MixpanelAPI instance) { this.sdkInstance = instance; } @@ -24,7 +21,7 @@ public SessionReplayBroadcastReceiver(MixpanelAPI instance) { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); - if (REGISTER_ACTION.equals(action)) { + if (SessionReplay.REGISTER_ACTION.equals(action)) { HashMap data = null; Serializable serializableData = intent.getSerializableExtra("data"); if (serializableData instanceof HashMap) { @@ -35,11 +32,11 @@ public void onReceive(Context context, Intent intent) { MPLog.d(LOGTAG, "Broadcast extras data: " + serializableData); } } - if (data != null && data.containsKey("$mp_replay_id")) { + if (data != null && data.containsKey(SessionReplay.REPLAY_ID_KEY)) { sdkInstance.registerSuperPropertiesMap(data); } - } else if (UNREGISTER_ACTION.equals(action)) { - sdkInstance.unregisterSuperProperty("$mp_replay_id"); + } else if (SessionReplay.UNREGISTER_ACTION.equals(action)) { + sdkInstance.unregisterSuperProperty(SessionReplay.REPLAY_ID_KEY); } } } diff --git a/src/main/java/com/mixpanel/android/util/MPConstants.java b/src/main/java/com/mixpanel/android/util/MPConstants.java index 53345f4f..6b0c66a5 100644 --- a/src/main/java/com/mixpanel/android/util/MPConstants.java +++ b/src/main/java/com/mixpanel/android/util/MPConstants.java @@ -5,6 +5,11 @@ */ public class MPConstants { + public static class SessionReplay { + public static final String REGISTER_ACTION = "com.mixpanel.properties.register"; + public static final String UNREGISTER_ACTION = "com.mixpanel.properties.unregister"; + public static final String REPLAY_ID_KEY = "$mp_replay_id"; + } public static class URL { public static final String MIXPANEL_API = "https://api.mixpanel.com"; public static final String EVENT = "/track/"; From eda01906a8201a0a54cfbf3e499f2d7d879cb745 Mon Sep 17 00:00:00 2001 From: Jared McFarland Date: Thu, 29 Aug 2024 10:46:26 -0700 Subject: [PATCH 3/5] make intent filter static --- .../com/mixpanel/android/mpmetrics/MixpanelAPI.java | 11 ++++++----- .../mpmetrics/SessionReplayBroadcastReceiver.java | 7 +++++++ 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/mixpanel/android/mpmetrics/MixpanelAPI.java b/src/main/java/com/mixpanel/android/mpmetrics/MixpanelAPI.java index d63117f2..2e0321b9 100644 --- a/src/main/java/com/mixpanel/android/mpmetrics/MixpanelAPI.java +++ b/src/main/java/com/mixpanel/android/mpmetrics/MixpanelAPI.java @@ -196,11 +196,12 @@ public class MixpanelAPI { } BroadcastReceiver sessionReplayReceiver = new SessionReplayBroadcastReceiver(this); - IntentFilter filter = new IntentFilter(); - filter.addAction(SessionReplay.REGISTER_ACTION); - filter.addAction(SessionReplay.UNREGISTER_ACTION); - Context appCtx = mContext.getApplicationContext(); - ContextCompat.registerReceiver(appCtx, sessionReplayReceiver, filter, ContextCompat.RECEIVER_NOT_EXPORTED); + ContextCompat.registerReceiver( + mContext.getApplicationContext(), + sessionReplayReceiver, + SessionReplayBroadcastReceiver.INTENT_FILTER, + ContextCompat.RECEIVER_NOT_EXPORTED + ); } /** diff --git a/src/main/java/com/mixpanel/android/mpmetrics/SessionReplayBroadcastReceiver.java b/src/main/java/com/mixpanel/android/mpmetrics/SessionReplayBroadcastReceiver.java index 971ced30..5a9538a1 100644 --- a/src/main/java/com/mixpanel/android/mpmetrics/SessionReplayBroadcastReceiver.java +++ b/src/main/java/com/mixpanel/android/mpmetrics/SessionReplayBroadcastReceiver.java @@ -3,6 +3,7 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; +import android.content.IntentFilter; import com.mixpanel.android.util.MPConstants.SessionReplay; import com.mixpanel.android.util.MPLog; @@ -14,6 +15,12 @@ public class SessionReplayBroadcastReceiver extends BroadcastReceiver { private static final String LOGTAG = "SessionReplayBroadcastReceiver"; private final MixpanelAPI sdkInstance; + public static final IntentFilter INTENT_FILTER = new IntentFilter(); + static { + INTENT_FILTER.addAction(SessionReplay.REGISTER_ACTION); + INTENT_FILTER.addAction(SessionReplay.UNREGISTER_ACTION); + } + public SessionReplayBroadcastReceiver(MixpanelAPI instance) { this.sdkInstance = instance; } From 960b38b673d86fde85a84ca864563be697456b50 Mon Sep 17 00:00:00 2001 From: Jared McFarland Date: Thu, 29 Aug 2024 11:38:55 -0700 Subject: [PATCH 4/5] bump PR workflow macos version --- .github/workflows/android.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml index 52997b26..5ae83382 100644 --- a/.github/workflows/android.yml +++ b/.github/workflows/android.yml @@ -8,7 +8,7 @@ on: jobs: build: - runs-on: macos-11 + runs-on: macos-13 steps: - name: Checkout the code uses: actions/checkout@v2 From bf72d4505e1daaf719e455e7faa9565eae81be0b Mon Sep 17 00:00:00 2001 From: Jared McFarland Date: Thu, 29 Aug 2024 12:33:41 -0700 Subject: [PATCH 5/5] review workflow change --- .github/workflows/android.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml index 5ae83382..52997b26 100644 --- a/.github/workflows/android.yml +++ b/.github/workflows/android.yml @@ -8,7 +8,7 @@ on: jobs: build: - runs-on: macos-13 + runs-on: macos-11 steps: - name: Checkout the code uses: actions/checkout@v2