From fa3f4a2ddec237bbec20d9f3b2236ee82e814766 Mon Sep 17 00:00:00 2001
From: Zihe Jia <zihe.jia@mixpanel.com>
Date: Sat, 20 Jan 2024 16:07:26 -0800
Subject: [PATCH 1/2] make MPConfig no longer a Singleton in favor of
 supporting multiple configs

---
 .../android/mpmetrics/MPConfigTest.java       | 16 +++++++++-
 .../mixpanel/android/mpmetrics/MPConfig.java  | 32 ++++++++++++-------
 2 files changed, 35 insertions(+), 13 deletions(-)

diff --git a/src/androidTest/java/com/mixpanel/android/mpmetrics/MPConfigTest.java b/src/androidTest/java/com/mixpanel/android/mpmetrics/MPConfigTest.java
index 67318a2bb..85fcdd883 100644
--- a/src/androidTest/java/com/mixpanel/android/mpmetrics/MPConfigTest.java
+++ b/src/androidTest/java/com/mixpanel/android/mpmetrics/MPConfigTest.java
@@ -12,6 +12,8 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
+import java.util.UUID;
+
 @RunWith(AndroidJUnit4.class)
 public class MPConfigTest {
 
@@ -138,7 +140,19 @@ public void testSetEnableLogging() throws Exception {
         assertFalse(config.DEBUG);
     }
 
-
+    @Test
+    public void testMulptipleConfigs() {
+        String fakeToken = UUID.randomUUID().toString();
+        MixpanelAPI mixpanel1 = MixpanelAPI.getInstance(InstrumentationRegistry.getInstrumentation().getContext(), fakeToken, false);
+        mixpanel1.setServerURL("https://api-eu.mixpanel.com");
+        assertEquals("https://api-eu.mixpanel.com/track/?ip=1", mixpanel1.getEventEndpoint());
+
+        String fakeToken2 = UUID.randomUUID().toString();
+        MixpanelAPI mixpanel2 = MixpanelAPI.getInstance(InstrumentationRegistry.getInstrumentation().getContext(), fakeToken2, false);
+        mixpanel2.setServerURL("https://api.mixpanel.com");
+        assertEquals("https://api.mixpanel.com/track/?ip=1", mixpanel2.getEventEndpoint());
+        assertEquals("https://api-eu.mixpanel.com/track/?ip=1", mixpanel1.getEventEndpoint());
+    }
 
     @Test
     public void testSetFlushBatchSize() {
diff --git a/src/main/java/com/mixpanel/android/mpmetrics/MPConfig.java b/src/main/java/com/mixpanel/android/mpmetrics/MPConfig.java
index fcb7a0838..ca16076a8 100644
--- a/src/main/java/com/mixpanel/android/mpmetrics/MPConfig.java
+++ b/src/main/java/com/mixpanel/android/mpmetrics/MPConfig.java
@@ -96,16 +96,27 @@ public class MPConfig {
     // Name for persistent storage of app referral SharedPreferences
     /* package */ static final String REFERRER_PREFS_NAME = "com.mixpanel.android.mpmetrics.ReferralInfo";
 
-    // Instances are safe to store, since they're immutable and always the same.
+    /**
+     * Retrieves a new instance of MPConfig with configuration settings loaded from the provided context.
+     * This method creates a new instance each time it is called, allowing for multiple configurations
+     * within the same application.
+     *
+     * Since version 7.4.0, MPConfig is no longer a Singleton, in favor of supporting multiple,
+     * distinct configurations for different Mixpanel instances. This change allows greater flexibility
+     * in scenarios where different parts of an application require different Mixpanel configurations,
+     * such as different endpoints or settings.
+     *
+     * It's important for users of this method to manage the lifecycle of the returned MPConfig instances
+     * themselves. Each call will result in a new configuration instance based on the application's
+     * metadata, and it's the responsibility of the caller to maintain any necessary references to these
+     * instances to use them later in their application.
+     *
+     * @param context The context used to load Mixpanel configuration. It's recommended to provide
+     *                an ApplicationContext to avoid potential memory leaks.
+     * @return A new instance of MPConfig with settings loaded from the context's application metadata.
+     */
     public static MPConfig getInstance(Context context) {
-        synchronized (sInstanceLock) {
-            if (null == sInstance) {
-                final Context appContext = context.getApplicationContext();
-                sInstance = readConfig(appContext);
-            }
-        }
-
-        return sInstance;
+        return readConfig(context.getApplicationContext());
     }
 
     /**
@@ -457,8 +468,5 @@ public String toString() {
     // Mutable, with synchronized accessor and mutator
     private SSLSocketFactory mSSLSocketFactory;
     private OfflineMode mOfflineMode;
-
-    private static MPConfig sInstance;
-    private static final Object sInstanceLock = new Object();
     private static final String LOGTAG = "MixpanelAPI.Conf";
 }

From a181e8da6dd2b3a533dadb607a349677e472186b Mon Sep 17 00:00:00 2001
From: Zihe Jia <zihe.jia@mixpanel.com>
Date: Sat, 20 Jan 2024 21:35:22 -0800
Subject: [PATCH 2/2] test the settings(MPConfig) are not shared between
 mixpanel instances

---
 .../android/mpmetrics/MPConfigTest.java       | 29 ++++++++++---------
 1 file changed, 16 insertions(+), 13 deletions(-)

diff --git a/src/androidTest/java/com/mixpanel/android/mpmetrics/MPConfigTest.java b/src/androidTest/java/com/mixpanel/android/mpmetrics/MPConfigTest.java
index 85fcdd883..dec330382 100644
--- a/src/androidTest/java/com/mixpanel/android/mpmetrics/MPConfigTest.java
+++ b/src/androidTest/java/com/mixpanel/android/mpmetrics/MPConfigTest.java
@@ -140,19 +140,6 @@ public void testSetEnableLogging() throws Exception {
         assertFalse(config.DEBUG);
     }
 
-    @Test
-    public void testMulptipleConfigs() {
-        String fakeToken = UUID.randomUUID().toString();
-        MixpanelAPI mixpanel1 = MixpanelAPI.getInstance(InstrumentationRegistry.getInstrumentation().getContext(), fakeToken, false);
-        mixpanel1.setServerURL("https://api-eu.mixpanel.com");
-        assertEquals("https://api-eu.mixpanel.com/track/?ip=1", mixpanel1.getEventEndpoint());
-
-        String fakeToken2 = UUID.randomUUID().toString();
-        MixpanelAPI mixpanel2 = MixpanelAPI.getInstance(InstrumentationRegistry.getInstrumentation().getContext(), fakeToken2, false);
-        mixpanel2.setServerURL("https://api.mixpanel.com");
-        assertEquals("https://api.mixpanel.com/track/?ip=1", mixpanel2.getEventEndpoint());
-        assertEquals("https://api-eu.mixpanel.com/track/?ip=1", mixpanel1.getEventEndpoint());
-    }
 
     @Test
     public void testSetFlushBatchSize() {
@@ -174,6 +161,22 @@ public void testSetFlushBatchSize2() {
         assertEquals(5, mixpanelAPI.getFlushBatchSize());
     }
 
+    @Test
+    public void testSetFlushBatchSizeMulptipleConfigs() {
+        String fakeToken = UUID.randomUUID().toString();
+        MixpanelAPI mixpanel1 = MixpanelAPI.getInstance(InstrumentationRegistry.getInstrumentation().getContext(), fakeToken, false);
+        mixpanel1.setFlushBatchSize(10);
+        assertEquals(10, mixpanel1.getFlushBatchSize());
+
+        String fakeToken2 = UUID.randomUUID().toString();
+        MixpanelAPI mixpanel2 = MixpanelAPI.getInstance(InstrumentationRegistry.getInstrumentation().getContext(), fakeToken2, false);
+        mixpanel2.setFlushBatchSize(20);
+        assertEquals(20, mixpanel2.getFlushBatchSize());
+        // mixpanel2 should not overwrite the settings to mixpanel1
+        assertEquals(10, mixpanel1.getFlushBatchSize());
+    }
+
+
     @Test
     public void testSetMaximumDatabaseLimit() {
         final Bundle metaData = new Bundle();