From fe1ef66637142a338eee5c435d58eb0b28eaf815 Mon Sep 17 00:00:00 2001 From: Zihe Jia Date: Wed, 13 Jul 2022 10:10:23 -0700 Subject: [PATCH] remove decide api check and make track automatic events a required param during init --- acceptance/README.txt | 11 +- gradle.properties | 2 +- .../mpmetrics/AutomaticEventsTest.java | 59 +----- .../mixpanel/android/mpmetrics/HttpTest.java | 27 +-- .../android/mpmetrics/MPConfigTest.java | 6 +- .../android/mpmetrics/MixpanelBasicTest.java | 24 +-- .../android/mpmetrics/OptOutTest.java | 10 +- .../mixpanel/android/mpmetrics/TestUtils.java | 8 +- .../android/mpmetrics/AnalyticsMessages.java | 74 +------ .../android/mpmetrics/DecideChecker.java | 197 ------------------ .../android/mpmetrics/DecideMessages.java | 51 ----- .../android/mpmetrics/ExceptionHandler.java | 7 - .../mixpanel/android/mpmetrics/MPConfig.java | 44 +--- .../android/mpmetrics/MixpanelAPI.java | 102 ++++----- .../mixpanel/android/util/HttpService.java | 5 +- .../mixpanel/android/util/MPConstants.java | 2 - 16 files changed, 85 insertions(+), 544 deletions(-) delete mode 100644 src/main/java/com/mixpanel/android/mpmetrics/DecideChecker.java delete mode 100644 src/main/java/com/mixpanel/android/mpmetrics/DecideMessages.java diff --git a/acceptance/README.txt b/acceptance/README.txt index 59f85d661..b5ed814fe 100644 --- a/acceptance/README.txt +++ b/acceptance/README.txt @@ -1,10 +1,5 @@ 1. install selenium webdriver lib by "pip install selenium" -2. change mDecideEndpoint and mEditorUrl to your IP address with port 8000. - eg. my IP is 172.16.20.43, so add - - - to AndroidManifest.xml of mixpanel-android. -3. change the android library location to your local library location in the build.gradle of the test app -4. launch emulator or hook up your Android device (make sure there's only 1 device/emulator connected to your +2. change the android library location to your local library location in the build.gradle of the test app +3. launch emulator or hook up your Android device (make sure there's only 1 device/emulator connected to your machine -5. now run "run.sh" +4. now run "run.sh" diff --git a/gradle.properties b/gradle.properties index 0ac18c14d..dd086160b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -VERSION_NAME=6.4.1-SNAPSHOT +VERSION_NAME=7.0.0-SNAPSHOT POM_PACKAGING=aar GROUP=com.mixpanel.android diff --git a/src/androidTest/java/com/mixpanel/android/mpmetrics/AutomaticEventsTest.java b/src/androidTest/java/com/mixpanel/android/mpmetrics/AutomaticEventsTest.java index d08f8a1b1..b66323786 100644 --- a/src/androidTest/java/com/mixpanel/android/mpmetrics/AutomaticEventsTest.java +++ b/src/androidTest/java/com/mixpanel/android/mpmetrics/AutomaticEventsTest.java @@ -47,11 +47,8 @@ public class AutomaticEventsTest { private static final int MAX_TIMEOUT_POLL = 6500; final private BlockingQueue mPerformRequestEvents = new LinkedBlockingQueue<>(); private Future mMockReferrerPreferences; - private byte[] mDecideResponse; private int mTrackedEvents; private CountDownLatch mLatch = new CountDownLatch(1); - private boolean mCanRunDecide; - private boolean mCanRunSecondDecideInstance; private MPDbAdapter mockAdapter; private CountDownLatch mMinRequestsLatch; @@ -59,19 +56,14 @@ public class AutomaticEventsTest { public void setUp() { mMockReferrerPreferences = new TestUtils.EmptyPreferences(InstrumentationRegistry.getInstrumentation().getContext()); mTrackedEvents = 0; - mCanRunDecide = true; mMinRequestsLatch = new CountDownLatch(2); // First Time Open and Update + } + + private void setUpInstance(boolean trackAutomaticEvents) { final RemoteService mockPoster = new HttpService() { @Override public byte[] performRequest(String endpointUrl, Map params, SSLSocketFactory socketFactory) { - if (null == params) { - if (mDecideResponse == null) { - return TestUtils.bytes("{\"automatic_events\": true}"); - } - return mDecideResponse; - } - final String jsonData = Base64Coder.decodeString(params.get("data").toString()); assertTrue(params.containsKey("data")); try { @@ -90,7 +82,6 @@ public byte[] performRequest(String endpointUrl, Map params, SSL }; InstrumentationRegistry.getInstrumentation().getContext().deleteDatabase("mixpanel"); - mockAdapter = new MPDbAdapter(InstrumentationRegistry.getInstrumentation().getContext()) { @Override public void cleanupEvents(String last_id, Table table, String token, boolean includeAutomaticEvents) { @@ -131,17 +122,6 @@ protected Handler restartWorkerThread() { final HandlerThread thread = new HandlerThread("com.mixpanel.android.AnalyticsWorker", Process.THREAD_PRIORITY_BACKGROUND); thread.start(); final Handler ret = new AnalyticsMessageHandler(thread.getLooper()) { - @Override - protected DecideChecker createDecideChecker() { - return new DecideChecker(mContext, mConfig) { - @Override - public void runDecideCheck(String token, RemoteService poster) throws RemoteService.ServiceUnavailableException { - if (mCanRunDecide) { - super.runDecideCheck(token, poster); - } - } - }; - } }; return ret; } @@ -149,7 +129,7 @@ public void runDecideCheck(String token, RemoteService poster) throws RemoteServ } }; - mCleanMixpanelAPI = new MixpanelAPI(InstrumentationRegistry.getInstrumentation().getContext(), mMockReferrerPreferences, TOKEN, false, null) { + mCleanMixpanelAPI = new MixpanelAPI(InstrumentationRegistry.getInstrumentation().getContext(), mMockReferrerPreferences, TOKEN, false, null, trackAutomaticEvents) { @Override /* package */ PersistentIdentity getPersistentIdentity(final Context context, final Future referrerPreferences, final String token, final String instanceName) { @@ -185,6 +165,7 @@ public void tearDown() throws Exception { public void testAutomaticOneInstance() throws InterruptedException { int calls = 3; // First Time Open, App Update, An Event One mLatch = new CountDownLatch(calls); + setUpInstance(true); mCleanMixpanelAPI.track("An event One"); mCleanMixpanelAPI.flush(); assertTrue(mLatch.await(MAX_TIMEOUT_POLL, TimeUnit.MILLISECONDS)); @@ -197,17 +178,13 @@ public void testAutomaticOneInstance() throws InterruptedException { @Test public void testDisableAutomaticEvents() throws InterruptedException { - mCanRunDecide = false; - - mDecideResponse = TestUtils.bytes("{\"automatic_events\": false}"); - int calls = 3; // First Time Open, App Update, An Event Three + setUpInstance(false); mLatch = new CountDownLatch(calls); mCleanMixpanelAPI.track("An Event Three"); assertTrue(mLatch.await(MAX_TIMEOUT_POLL, TimeUnit.MILLISECONDS)); assertEquals(calls, mTrackedEvents); - mCanRunDecide = true; mCleanMixpanelAPI.track("Automatic Event Two", null, true); // dropped mCleanMixpanelAPI.track("Automatic Event Three", null, true); // dropped mCleanMixpanelAPI.track("Automatic Event Four", null, true); // dropped @@ -215,7 +192,7 @@ public void testDisableAutomaticEvents() throws InterruptedException { assertEquals("An Event Three", mPerformRequestEvents.poll(MAX_TIMEOUT_POLL, TimeUnit.MILLISECONDS)); assertEquals(null, mPerformRequestEvents.poll(MAX_TIMEOUT_POLL, TimeUnit.MILLISECONDS)); - String[] noEvents = mockAdapter.generateDataString(MPDbAdapter.Table.EVENTS, TOKEN, true); + String[] noEvents = mockAdapter.generateDataString(MPDbAdapter.Table.EVENTS, TOKEN, false); assertNull(noEvents); mCleanMixpanelAPI.flush(); @@ -225,9 +202,8 @@ public void testDisableAutomaticEvents() throws InterruptedException { @Test public void testAutomaticMultipleInstances() throws InterruptedException { final String SECOND_TOKEN = "Automatic Events Token Two"; - mCanRunDecide = true; - mDecideResponse = TestUtils.bytes("{\"automatic_events\": true}"); int initialCalls = 2; + setUpInstance(false); mLatch = new CountDownLatch(initialCalls); final CountDownLatch secondLatch = new CountDownLatch(initialCalls); final BlockingQueue secondPerformedRequests = new LinkedBlockingQueue<>(); @@ -235,10 +211,6 @@ public void testAutomaticMultipleInstances() throws InterruptedException { final HttpService mpSecondPoster = new HttpService() { @Override public byte[] performRequest(String endpointUrl, Map params, SSLSocketFactory socketFactory) { - if (null == params) { - return TestUtils.bytes("{\"automatic_events\": false}"); - } - final String jsonData = Base64Coder.decodeString(params.get("data").toString()); assertTrue(params.containsKey("data")); try { @@ -293,17 +265,6 @@ protected Handler restartWorkerThread() { final HandlerThread thread = new HandlerThread("com.mixpanel.android.AnalyticsWorker", Process.THREAD_PRIORITY_BACKGROUND); thread.start(); final Handler ret = new AnalyticsMessageHandler(thread.getLooper()) { - @Override - protected DecideChecker createDecideChecker() { - return new DecideChecker(mContext, mConfig) { - @Override - public void runDecideCheck(String token, RemoteService poster) throws RemoteService.ServiceUnavailableException { - if (mCanRunSecondDecideInstance) { - super.runDecideCheck(token, poster); - } - } - }; - } }; return ret; } @@ -311,7 +272,7 @@ public void runDecideCheck(String token, RemoteService poster) throws RemoteServ } }; - MixpanelAPI mpSecondInstance = new TestUtils.CleanMixpanelAPI(InstrumentationRegistry.getInstrumentation().getContext(), new TestUtils.EmptyPreferences(InstrumentationRegistry.getInstrumentation().getContext()), SECOND_TOKEN) { + MixpanelAPI mpSecondInstance = new TestUtils.CleanMixpanelAPI(InstrumentationRegistry.getInstrumentation().getContext(), new TestUtils.EmptyPreferences(InstrumentationRegistry.getInstrumentation().getContext()), SECOND_TOKEN, true) { @Override AnalyticsMessages getAnalyticsMessages() { return mpSecondAnalyticsMessages; @@ -321,7 +282,6 @@ AnalyticsMessages getAnalyticsMessages() { assertTrue(mLatch.await(MAX_TIMEOUT_POLL, TimeUnit.MILLISECONDS)); assertEquals(initialCalls, mTrackedEvents); - assertTrue(secondLatch.await(MAX_TIMEOUT_POLL, TimeUnit.MILLISECONDS)); mLatch = new CountDownLatch(MPConfig.getInstance(InstrumentationRegistry.getInstrumentation().getContext()).getBulkUploadLimit() - initialCalls); for (int i = 0; i < MPConfig.getInstance(InstrumentationRegistry.getInstrumentation().getContext()).getBulkUploadLimit() - initialCalls; i++) { mCleanMixpanelAPI.track("Track event " + i); @@ -338,7 +298,6 @@ AnalyticsMessages getAnalyticsMessages() { assertNull(secondPerformedRequests.poll(MAX_TIMEOUT_POLL, TimeUnit.MILLISECONDS)); - mCanRunSecondDecideInstance = true; mpSecondInstance.flush(); mCleanMixpanelAPI.track("First Instance Event One"); mpSecondInstance.track("Second Instance Event One"); diff --git a/src/androidTest/java/com/mixpanel/android/mpmetrics/HttpTest.java b/src/androidTest/java/com/mixpanel/android/mpmetrics/HttpTest.java index f9bf86ae6..c1a871ed7 100644 --- a/src/androidTest/java/com/mixpanel/android/mpmetrics/HttpTest.java +++ b/src/androidTest/java/com/mixpanel/android/mpmetrics/HttpTest.java @@ -39,8 +39,8 @@ @RunWith(AndroidJUnit4.class) public class HttpTest { private Future mMockPreferences; - private List mFlushResults, mDecideResults; - private BlockingQueue mPerformRequestCalls, mDecideCalls; + private List mFlushResults; + private BlockingQueue mPerformRequestCalls; private List mCleanupCalls; private MixpanelAPI mMetrics; private volatile int mFlushInterval; @@ -56,9 +56,7 @@ public void setUp() { mMockPreferences = new TestUtils.EmptyPreferences(InstrumentationRegistry.getInstrumentation().getContext()); mFlushResults = new ArrayList(); mPerformRequestCalls = new LinkedBlockingQueue(); - mDecideCalls = new LinkedBlockingQueue(); mCleanupCalls = new ArrayList(); - mDecideResults = new ArrayList(); mForceOverMemThreshold = false; final RemoteService mockPoster = new HttpService() { @@ -66,23 +64,6 @@ public void setUp() { public byte[] performRequest(String endpointUrl, Map params, SSLSocketFactory socketFactory) throws ServiceUnavailableException, IOException { try { - if (null == params) { - mDecideCalls.put(endpointUrl); - - if (mDecideResults.isEmpty()) { - return TestUtils.bytes("{}"); - } - - final Object obj = mDecideResults.remove(0); - if (obj instanceof IOException) { - throw (IOException)obj; - } else if (obj instanceof MalformedURLException) { - throw (MalformedURLException)obj; - } else if (obj instanceof ServiceUnavailableException) { - throw (ServiceUnavailableException)obj; - } - return (byte[])obj; - } if (mFlushResults.isEmpty()) { mFlushResults.add(TestUtils.bytes("1\n")); } @@ -114,10 +95,6 @@ public byte[] performRequest(String endpointUrl, Map params, SSL }; final MPConfig config = new MPConfig(new Bundle(), InstrumentationRegistry.getInstrumentation().getContext()) { - @Override - public String getDecideEndpoint() { - return "DECIDE ENDPOINT"; - } @Override public String getEventsEndpoint() { diff --git a/src/androidTest/java/com/mixpanel/android/mpmetrics/MPConfigTest.java b/src/androidTest/java/com/mixpanel/android/mpmetrics/MPConfigTest.java index 6d486aa75..24c01b168 100644 --- a/src/androidTest/java/com/mixpanel/android/mpmetrics/MPConfigTest.java +++ b/src/androidTest/java/com/mixpanel/android/mpmetrics/MPConfigTest.java @@ -27,13 +27,11 @@ public void testSetServerURL() throws Exception { assertEquals("https://api.mixpanel.com/track/?ip=1", config.getEventsEndpoint()); assertEquals("https://api.mixpanel.com/engage/?ip=1", config.getPeopleEndpoint()); assertEquals("https://api.mixpanel.com/groups/?ip=1", config.getGroupsEndpoint()); - assertEquals("https://api.mixpanel.com/decide", config.getDecideEndpoint()); mixpanelAPI.setServerURL("https://api-eu.mixpanel.com"); assertEquals("https://api-eu.mixpanel.com/track/?ip=1", config.getEventsEndpoint()); assertEquals("https://api-eu.mixpanel.com/engage/?ip=1", config.getPeopleEndpoint()); assertEquals("https://api-eu.mixpanel.com/groups/?ip=1", config.getGroupsEndpoint()); - assertEquals("https://api-eu.mixpanel.com/decide", config.getDecideEndpoint()); } @Test @@ -49,13 +47,11 @@ public void testSetUseIpAddressForGeolocation() { assertEquals("https://api.mixpanel.com/track/?ip=0", config.getEventsEndpoint()); assertEquals("https://api.mixpanel.com/engage/?ip=0", config.getPeopleEndpoint()); assertEquals("https://api.mixpanel.com/groups/?ip=0", config.getGroupsEndpoint()); - assertEquals("https://api.mixpanel.com/decide", config.getDecideEndpoint()); mixpanelAPI.setUseIpAddressForGeolocation(true); assertEquals("https://api.mixpanel.com/track/?ip=1", config.getEventsEndpoint()); assertEquals("https://api.mixpanel.com/engage/?ip=1", config.getPeopleEndpoint()); assertEquals("https://api.mixpanel.com/groups/?ip=1", config.getGroupsEndpoint()); - assertEquals("https://api.mixpanel.com/decide", config.getDecideEndpoint()); } @Test @@ -148,6 +144,6 @@ private MPConfig mpConfig(final Bundle metaData) { } private MixpanelAPI mixpanelApi(final MPConfig config) { - return new MixpanelAPI(InstrumentationRegistry.getInstrumentation().getContext(), new TestUtils.EmptyPreferences(InstrumentationRegistry.getInstrumentation().getContext()), TOKEN, config, false, null,null); + return new MixpanelAPI(InstrumentationRegistry.getInstrumentation().getContext(), new TestUtils.EmptyPreferences(InstrumentationRegistry.getInstrumentation().getContext()), TOKEN, config, false, null,null, true); } } diff --git a/src/androidTest/java/com/mixpanel/android/mpmetrics/MixpanelBasicTest.java b/src/androidTest/java/com/mixpanel/android/mpmetrics/MixpanelBasicTest.java index 74b0ed54d..939a7816c 100644 --- a/src/androidTest/java/com/mixpanel/android/mpmetrics/MixpanelBasicTest.java +++ b/src/androidTest/java/com/mixpanel/android/mpmetrics/MixpanelBasicTest.java @@ -615,15 +615,6 @@ public int addJSON(JSONObject message, String token, MPDbAdapter.Table table, bo @Override public byte[] performRequest(String endpointUrl, Map params, SSLSocketFactory socketFactory) { final boolean isIdentified = isIdentifiedRef.get(); - if (null == params) { - if (isIdentified) { - assertEquals("DECIDE_ENDPOINT?version=1&lib=android&token=Test+Message+Queuing&distinct_id=PEOPLE+ID" + mAppProperties, endpointUrl); - } else { - assertEquals("DECIDE_ENDPOINT?version=1&lib=android&token=Test+Message+Queuing&distinct_id=EVENTS+ID" + mAppProperties, endpointUrl); - } - return TestUtils.bytes("{}"); - } - assertTrue(params.containsKey("data")); final String decoded = Base64Coder.decodeString(params.get("data").toString()); @@ -665,11 +656,6 @@ public String getGroupsEndpoint() { return "GROUPS_ENDPOINT"; } - @Override - public String getDecideEndpoint() { - return "DECIDE_ENDPOINT"; - } - @Override public boolean getDisableAppOpenEvent() { return true; } }; @@ -883,7 +869,7 @@ public void peopleMessage(PeopleDescription heard) { class TestMixpanelAPI extends MixpanelAPI { public TestMixpanelAPI(Context c, Future prefs, String token) { - super(c, prefs, token, false, null); + super(c, prefs, token, false, null, true); } @Override @@ -963,7 +949,7 @@ public void peopleMessage(PeopleDescription heard) { class TestMixpanelAPI extends MixpanelAPI { public TestMixpanelAPI(Context c, Future prefs, String token) { - super(c, prefs, token, false, null); + super(c, prefs, token, false, null, true); } @Override @@ -1156,7 +1142,7 @@ protected AnalyticsMessages getAnalyticsMessages() { @Test public void testPersistence() { - MixpanelAPI metricsOne = new MixpanelAPI(InstrumentationRegistry.getInstrumentation().getContext(), mMockPreferences, "SAME TOKEN", false, null); + MixpanelAPI metricsOne = new MixpanelAPI(InstrumentationRegistry.getInstrumentation().getContext(), mMockPreferences, "SAME TOKEN", false, null, true); metricsOne.reset(); JSONObject props; @@ -1190,7 +1176,7 @@ public void peopleMessage(PeopleDescription heard) { class ListeningAPI extends MixpanelAPI { public ListeningAPI(Context c, Future prefs, String token) { - super(c, prefs, token, false, null); + super(c, prefs, token, false, null, true); } @Override @@ -1478,7 +1464,7 @@ public void testEventTiming() throws InterruptedException { Future mMockReferrerPreferences; final BlockingQueue mStoredEvents = new LinkedBlockingQueue<>(); mMockReferrerPreferences = new TestUtils.EmptyPreferences(InstrumentationRegistry.getInstrumentation().getContext()); - MixpanelAPI mMixpanelAPI = new MixpanelAPI(InstrumentationRegistry.getInstrumentation().getContext(), mMockReferrerPreferences, "TESTTOKEN", false, null) { + MixpanelAPI mMixpanelAPI = new MixpanelAPI(InstrumentationRegistry.getInstrumentation().getContext(), mMockReferrerPreferences, "TESTTOKEN", false, null, true) { @Override PersistentIdentity getPersistentIdentity(Context context, Future referrerPreferences, String token, String instanceName) { mPersistentIdentity = super.getPersistentIdentity(context, referrerPreferences, token, instanceName); diff --git a/src/androidTest/java/com/mixpanel/android/mpmetrics/OptOutTest.java b/src/androidTest/java/com/mixpanel/android/mpmetrics/OptOutTest.java index 8ffe81547..f3ddab64e 100644 --- a/src/androidTest/java/com/mixpanel/android/mpmetrics/OptOutTest.java +++ b/src/androidTest/java/com/mixpanel/android/mpmetrics/OptOutTest.java @@ -116,7 +116,7 @@ public void tearDown() throws Exception { @Test public void testOptOutDefaultFlag() throws InterruptedException { mCleanUpCalls = new CountDownLatch(2); // optOutTrack calls - mMixpanelAPI = new MixpanelAPI(InstrumentationRegistry.getInstrumentation().getContext(), mMockReferrerPreferences, TOKEN, true, null) { + mMixpanelAPI = new MixpanelAPI(InstrumentationRegistry.getInstrumentation().getContext(), mMockReferrerPreferences, TOKEN, true, null, true) { @Override PersistentIdentity getPersistentIdentity(Context context, Future referrerPreferences, String token, String instanceName) { mPersistentIdentity = super.getPersistentIdentity(context, referrerPreferences, token, instanceName); @@ -146,7 +146,7 @@ AnalyticsMessages getAnalyticsMessages() { @Test public void testHasOptOutTrackingOrNot() throws InterruptedException { mCleanUpCalls = new CountDownLatch(4); // optOutTrack calls - MixpanelAPI mixpanel = new MixpanelAPI(InstrumentationRegistry.getInstrumentation().getContext(), mMockReferrerPreferences, "TOKEN", true, null) { + MixpanelAPI mixpanel = new MixpanelAPI(InstrumentationRegistry.getInstrumentation().getContext(), mMockReferrerPreferences, "TOKEN", true, null, true) { @Override PersistentIdentity getPersistentIdentity(Context context, Future referrerPreferences, String token, String instanceName) { mPersistentIdentity = super.getPersistentIdentity(context, referrerPreferences, token, instanceName); @@ -177,7 +177,7 @@ AnalyticsMessages getAnalyticsMessages() { @Test public void testPeopleUpdates() throws InterruptedException, JSONException { mCleanUpCalls = new CountDownLatch(2); - mMixpanelAPI = new MixpanelAPI(InstrumentationRegistry.getInstrumentation().getContext(), mMockReferrerPreferences, TOKEN,false, null) { + mMixpanelAPI = new MixpanelAPI(InstrumentationRegistry.getInstrumentation().getContext(), mMockReferrerPreferences, TOKEN,false, null, true) { @Override PersistentIdentity getPersistentIdentity(Context context, Future referrerPreferences, String token, String instanceName) { mPersistentIdentity = super.getPersistentIdentity(context, referrerPreferences, token, instanceName); @@ -294,7 +294,7 @@ AnalyticsMessages getAnalyticsMessages() { */ @Test public void testTrackCalls() throws InterruptedException, JSONException { - mMixpanelAPI = new MixpanelAPI(InstrumentationRegistry.getInstrumentation().getContext(), mMockReferrerPreferences, TOKEN, false, null) { + mMixpanelAPI = new MixpanelAPI(InstrumentationRegistry.getInstrumentation().getContext(), mMockReferrerPreferences, TOKEN, false, null, true) { @Override PersistentIdentity getPersistentIdentity(Context context, Future referrerPreferences, String token, String instanceName) { mPersistentIdentity = super.getPersistentIdentity(context, referrerPreferences, token, instanceName); @@ -352,7 +352,7 @@ AnalyticsMessages getAnalyticsMessages() { } private void forceFlush() { - mAnalyticsMessages.postToServer(new AnalyticsMessages.FlushDescription(TOKEN, false)); + mAnalyticsMessages.postToServer(new AnalyticsMessages.MixpanelDescription(TOKEN)); } private MPDbAdapter getMockDBAdapter() { diff --git a/src/androidTest/java/com/mixpanel/android/mpmetrics/TestUtils.java b/src/androidTest/java/com/mixpanel/android/mpmetrics/TestUtils.java index 85fd04fb9..fc077930c 100644 --- a/src/androidTest/java/com/mixpanel/android/mpmetrics/TestUtils.java +++ b/src/androidTest/java/com/mixpanel/android/mpmetrics/TestUtils.java @@ -20,12 +20,16 @@ public static byte[] bytes(String s) { } public static class CleanMixpanelAPI extends MixpanelAPI { + public CleanMixpanelAPI(final Context context, final Future referrerPreferences, final String token, final boolean trackAutomaticEvents) { + super(context, referrerPreferences, token, false, null, trackAutomaticEvents); + } + public CleanMixpanelAPI(final Context context, final Future referrerPreferences, final String token) { - super(context, referrerPreferences, token, false, null); + super(context, referrerPreferences, token, false, null, false); } public CleanMixpanelAPI(final Context context, final Future referrerPreferences, final String token, final String instanceName) { - super(context, referrerPreferences, token, false, null, instanceName); + super(context, referrerPreferences, token, false, null, instanceName, false); } @Override diff --git a/src/main/java/com/mixpanel/android/mpmetrics/AnalyticsMessages.java b/src/main/java/com/mixpanel/android/mpmetrics/AnalyticsMessages.java index 8bca7e839..e7ff79970 100644 --- a/src/main/java/com/mixpanel/android/mpmetrics/AnalyticsMessages.java +++ b/src/main/java/com/mixpanel/android/mpmetrics/AnalyticsMessages.java @@ -114,19 +114,11 @@ public void clearAnonymousUpdatesMessage(final MixpanelDescription clearAnonymou mWorker.runMessage(m); } - public void postToServer(final FlushDescription flushDescription) { + public void postToServer(final MixpanelDescription flushDescription) { final Message m = Message.obtain(); m.what = FLUSH_QUEUE; m.obj = flushDescription.getToken(); - m.arg1 = flushDescription.shouldCheckDecide() ? 1 : 0; - - mWorker.runMessage(m); - } - - public void installDecideCheck(final DecideMessages check) { - final Message m = Message.obtain(); - m.what = INSTALL_DECIDE_CHECK; - m.obj = check; + m.arg1 = 0; mWorker.runMessage(m); } @@ -258,23 +250,6 @@ public String getDistinctId() { private final String mDistinctId; } - static class FlushDescription extends MixpanelDescription { - public FlushDescription(String token) { - this(token, true); - } - - protected FlushDescription(String token, boolean checkDecide) { - super(token); - this.checkDecide = checkDecide; - } - - public boolean shouldCheckDecide() { - return checkDecide; - } - - private final boolean checkDecide; - } - static class MixpanelMessageDescription extends MixpanelDescription { public MixpanelMessageDescription(String token, JSONObject message) { super(token); @@ -375,14 +350,9 @@ public AnalyticsMessageHandler(Looper looper) { super(looper); mDbAdapter = null; mSystemInformation = SystemInformation.getInstance(mContext); - mDecideChecker = createDecideChecker(); mFlushInterval = mConfig.getFlushInterval(); } - protected DecideChecker createDecideChecker() { - return new DecideChecker(mContext, mConfig); - } - @Override public void handleMessage(Message msg) { if (mDbAdapter == null) { @@ -418,11 +388,6 @@ public void handleMessage(Message msg) { logAboutMessageToMixpanel("Queuing event for sending later"); logAboutMessageToMixpanel(" " + message.toString()); token = eventDescription.getToken(); - - DecideMessages decide = mDecideChecker.getDecideMessages(token); - if (decide != null && eventDescription.isAutomatic() && !decide.shouldTrackAutomaticEvent()) { - return; - } returnCode = mDbAdapter.addJSON(message, token, MPDbAdapter.Table.EVENTS, eventDescription.isAutomatic()); } catch (final JSONException e) { MPLog.e(LOGTAG, "Exception tracking event " + eventDescription.getEventName(), e); @@ -444,26 +409,7 @@ public void handleMessage(Message msg) { logAboutMessageToMixpanel("Flushing queue due to scheduled or forced flush"); updateFlushFrequency(); token = (String) msg.obj; - boolean shouldCheckDecide = msg.arg1 == 1; sendAllData(mDbAdapter, token); - if (shouldCheckDecide && SystemClock.elapsedRealtime() >= mDecideRetryAfter) { - try { - mDecideChecker.runDecideCheck(token, getPoster()); - } catch (RemoteService.ServiceUnavailableException e) { - mDecideRetryAfter = SystemClock.elapsedRealtime() + e.getRetryAfter() * 1000; - } - } - } else if (msg.what == INSTALL_DECIDE_CHECK) { - logAboutMessageToMixpanel("Installing a check for decide"); - final DecideMessages check = (DecideMessages) msg.obj; - mDecideChecker.addDecideCheck(check); - if (SystemClock.elapsedRealtime() >= mDecideRetryAfter) { - try { - mDecideChecker.runDecideCheck(check.getToken(), getPoster()); - } catch (RemoteService.ServiceUnavailableException e) { - mDecideRetryAfter = SystemClock.elapsedRealtime() + e.getRetryAfter() * 1000; - } - } } else if (msg.what == EMPTY_QUEUES) { final MixpanelDescription message = (MixpanelDescription) msg.obj; token = message.getToken(); @@ -487,13 +433,6 @@ public void handleMessage(Message msg) { logAboutMessageToMixpanel("Flushing queue due to bulk upload limit (" + returnCode + ") for project " + token); updateFlushFrequency(); sendAllData(mDbAdapter, token); - if (SystemClock.elapsedRealtime() >= mDecideRetryAfter) { - try { - mDecideChecker.runDecideCheck(token, getPoster()); - } catch (RemoteService.ServiceUnavailableException e) { - mDecideRetryAfter = SystemClock.elapsedRealtime() + e.getRetryAfter() * 1000; - } - } } else if (returnCode > 0 && !hasMessages(FLUSH_QUEUE, token)) { // The !hasMessages(FLUSH_QUEUE, token) check is a courtesy for the common case // of delayed flushes already enqueued from inside of this thread. @@ -542,11 +481,7 @@ private void sendAllData(MPDbAdapter dbAdapter, String token) { private void sendData(MPDbAdapter dbAdapter, String token, MPDbAdapter.Table table, String url) { final RemoteService poster = getPoster(); - DecideMessages decideMessages = mDecideChecker.getDecideMessages(token); - boolean includeAutomaticEvents = true; - if (decideMessages == null || decideMessages.isAutomaticEventsEnabled() == null) { - includeAutomaticEvents = false; - } + boolean includeAutomaticEvents = mConfig.getTrackAutomaticEvents(); String[] eventsData = dbAdapter.generateDataString(table, token, includeAutomaticEvents); Integer queueCount = 0; if (eventsData != null) { @@ -705,9 +640,7 @@ private JSONObject prepareEventObject(EventDescription eventDescription) throws } private MPDbAdapter mDbAdapter; - private final DecideChecker mDecideChecker; private final long mFlushInterval; - private long mDecideRetryAfter; private long mTrackEngageRetryAfter; private int mFailedRetries; }// AnalyticsMessageHandler @@ -757,7 +690,6 @@ public long getTrackEngageRetryAfter() { private static final int EMPTY_QUEUES = 6; // Remove any local (and pending to be flushed) events or people/group updates from the db private static final int CLEAR_ANONYMOUS_UPDATES = 7; // Remove anonymous people updates from DB private static final int REWRITE_EVENT_PROPERTIES = 8; // Update or add properties to existing queued events - private static final int INSTALL_DECIDE_CHECK = 12; // Run this DecideCheck at intervals until it isDestroyed() private static final String LOGTAG = "MixpanelAPI.Messages"; diff --git a/src/main/java/com/mixpanel/android/mpmetrics/DecideChecker.java b/src/main/java/com/mixpanel/android/mpmetrics/DecideChecker.java deleted file mode 100644 index dd34dd463..000000000 --- a/src/main/java/com/mixpanel/android/mpmetrics/DecideChecker.java +++ /dev/null @@ -1,197 +0,0 @@ -package com.mixpanel.android.mpmetrics; - -import android.content.Context; -import android.os.Build; - -import com.mixpanel.android.util.MPLog; -import com.mixpanel.android.util.RemoteService; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.net.MalformedURLException; -import java.net.URLEncoder; -import java.util.HashMap; -import java.util.Map; - -import javax.net.ssl.SSLSocketFactory; - -/* package */ class DecideChecker { - - private static final String LOGTAG = "MixpanelAPI.DChecker"; - - private final MPConfig mConfig; - private final Context mContext; - private final Map mChecks; - private final SystemInformation mSystemInformation; - - private static final JSONArray EMPTY_JSON_ARRAY = new JSONArray(); - - private static final String AUTOMATIC_EVENTS = "automatic_events"; - - /* package */ static class Result { - public Result() { - automaticEvents = false; - } - - public boolean automaticEvents; - } - - public DecideChecker(final Context context, final MPConfig config) { - mContext = context; - mConfig = config; - mChecks = new HashMap(); - mSystemInformation = SystemInformation.getInstance(context); - } - - public void addDecideCheck(final DecideMessages check) { - mChecks.put(check.getToken(), check); - } - - public void runDecideCheck(final String token, final RemoteService poster) throws RemoteService.ServiceUnavailableException { - DecideMessages updates = mChecks.get(token); - if (updates != null) { - final String distinctId = updates.getDistinctId(); - try { - final Result result = runDecideCheck(updates.getToken(), distinctId, poster); - if (result != null) { - updates.reportResults(result.automaticEvents); - } - } catch (final UnintelligibleMessageException e) { - MPLog.e(LOGTAG, e.getMessage(), e); - } - } - } - - /* package */ static class UnintelligibleMessageException extends Exception { - private static final long serialVersionUID = -6501269367559104957L; - - public UnintelligibleMessageException(String message, JSONException cause) { - super(message, cause); - } - } - - - private Result runDecideCheck(final String token, final String distinctId, final RemoteService poster) - throws RemoteService.ServiceUnavailableException, UnintelligibleMessageException { - final String responseString = getDecideResponseFromServer(token, distinctId, poster); - - MPLog.v(LOGTAG, "Mixpanel decide server response was:\n" + responseString); - - Result parsedResult = null; - if (responseString != null) { - parsedResult = parseDecideResponse(responseString); - } - - return parsedResult; - }// runDecideCheck - - /* package */ static Result parseDecideResponse(String responseString) - throws UnintelligibleMessageException { - JSONObject response; - final Result ret = new Result(); - - try { - response = new JSONObject(responseString); - } catch (final JSONException e) { - final String message = "Mixpanel endpoint returned unparsable result:\n" + responseString; - throw new UnintelligibleMessageException(message, e); - } - - if (response.has(AUTOMATIC_EVENTS)) { - try { - ret.automaticEvents = response.getBoolean(AUTOMATIC_EVENTS); - } catch (JSONException e) { - MPLog.e(LOGTAG, "Mixpanel endpoint returned a non boolean value for automatic events: " + response); - } - } - - return ret; - } - - private String getDecideResponseFromServer(String unescapedToken, String unescapedDistinctId, RemoteService poster) - throws RemoteService.ServiceUnavailableException { - final String escapedToken; - final String escapedId; - try { - escapedToken = URLEncoder.encode(unescapedToken, "utf-8"); - if (null != unescapedDistinctId) { - escapedId = URLEncoder.encode(unescapedDistinctId, "utf-8"); - } else { - escapedId = null; - } - } catch (final UnsupportedEncodingException e) { - throw new RuntimeException("Mixpanel library requires utf-8 string encoding to be available", e); - } - - final StringBuilder queryBuilder = new StringBuilder() - .append("?version=1&lib=android&token=") - .append(escapedToken); - - if (null != escapedId) { - queryBuilder.append("&distinct_id=").append(escapedId); - } - - queryBuilder.append("&properties="); - - JSONObject properties = new JSONObject(); - try { - properties.putOpt("$android_lib_version", MPConfig.VERSION); - properties.putOpt("$android_app_version", mSystemInformation.getAppVersionName()); - properties.putOpt("$android_version", Build.VERSION.RELEASE); - properties.putOpt("$android_app_release", mSystemInformation.getAppVersionCode()); - properties.putOpt("$android_device_model", Build.MODEL); - queryBuilder.append(URLEncoder.encode(properties.toString(), "utf-8")); - } catch (Exception e) { - MPLog.e(LOGTAG, "Exception constructing properties JSON", e.getCause()); - } - - final String checkQuery = queryBuilder.toString(); - final String url = mConfig.getDecideEndpoint() + checkQuery; - - MPLog.v(LOGTAG, "Querying decide server, url: " + url); - - final byte[] response = checkDecide(poster, mContext, url); - if (null == response) { - return null; - } - try { - return new String(response, "UTF-8"); - } catch (final UnsupportedEncodingException e) { - throw new RuntimeException("UTF not supported on this platform?", e); - } - } - - private static byte[] checkDecide(RemoteService poster, Context context, String url) - throws RemoteService.ServiceUnavailableException { - final MPConfig config = MPConfig.getInstance(context); - - if (!poster.isOnline(context, config.getOfflineMode())) { - return null; - } - - byte[] response = null; - try { - final SSLSocketFactory socketFactory = config.getSSLSocketFactory(); - response = poster.performRequest(url, null, socketFactory); - } catch (final MalformedURLException e) { - MPLog.e(LOGTAG, "Cannot interpret " + url + " as a URL.", e); - } catch (final FileNotFoundException e) { - MPLog.v(LOGTAG, "Cannot get " + url + ", file not found.", e); - } catch (final IOException e) { - MPLog.v(LOGTAG, "Cannot get " + url + ".", e); - } catch (final OutOfMemoryError e) { - MPLog.e(LOGTAG, "Out of memory when getting to " + url + ".", e); - } - - return response; - } - - public DecideMessages getDecideMessages(String token) { - return mChecks.get(token); - } -} diff --git a/src/main/java/com/mixpanel/android/mpmetrics/DecideMessages.java b/src/main/java/com/mixpanel/android/mpmetrics/DecideMessages.java deleted file mode 100644 index ad787f646..000000000 --- a/src/main/java/com/mixpanel/android/mpmetrics/DecideMessages.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.mixpanel.android.mpmetrics; - -import android.content.Context; - - -// Will be called from both customer threads and the Mixpanel worker thread. -/* package */ class DecideMessages { - public DecideMessages(Context context, String token) { - mContext = context; - mToken = token; - } - - public String getToken() { - return mToken; - } - - // Called from other synchronized code. Do not call into other synchronized code or you'll - // risk deadlock - public synchronized void setDistinctId(String distinctId) { - mDistinctId = distinctId; - } - - public synchronized String getDistinctId() { - return mDistinctId; - } - - public synchronized void reportResults(boolean automaticEvents) { - if (mAutomaticEventsEnabled == null && !automaticEvents) { - MPDbAdapter.getInstance(mContext).cleanupAutomaticEvents(mToken); - } - mAutomaticEventsEnabled = automaticEvents; - } - - public Boolean isAutomaticEventsEnabled() { - return mAutomaticEventsEnabled; - } - - public boolean shouldTrackAutomaticEvent() { - return isAutomaticEventsEnabled() == null ? true : isAutomaticEventsEnabled(); - } - - // Mutable, must be synchronized - private String mDistinctId; - - private final String mToken; - private Boolean mAutomaticEventsEnabled; - private final Context mContext; - - @SuppressWarnings("unused") - private static final String LOGTAG = "MixpanelAPI.DecideUpdts"; -} diff --git a/src/main/java/com/mixpanel/android/mpmetrics/ExceptionHandler.java b/src/main/java/com/mixpanel/android/mpmetrics/ExceptionHandler.java index b5a6abfeb..607cf065c 100644 --- a/src/main/java/com/mixpanel/android/mpmetrics/ExceptionHandler.java +++ b/src/main/java/com/mixpanel/android/mpmetrics/ExceptionHandler.java @@ -40,13 +40,6 @@ public void process(MixpanelAPI mixpanel) { } }); - MixpanelAPI.allInstances(new MixpanelAPI.InstanceProcessor() { - @Override - public void process(MixpanelAPI mixpanel) { - mixpanel.flushNoDecideCheck(); - } - }); - if (mDefaultExceptionHandler != null) { mDefaultExceptionHandler.uncaughtException(t, e); } else { diff --git a/src/main/java/com/mixpanel/android/mpmetrics/MPConfig.java b/src/main/java/com/mixpanel/android/mpmetrics/MPConfig.java index 2d64ee846..e1a0d56e2 100644 --- a/src/main/java/com/mixpanel/android/mpmetrics/MPConfig.java +++ b/src/main/java/com/mixpanel/android/mpmetrics/MPConfig.java @@ -67,12 +67,6 @@ *
com.mixpanel.android.MPConfig.GroupsEndpoint
*
A string URL. If present, the library will attempt to send group updates to this endpoint rather than to the default Mixpanel endpoint.
* - *
com.mixpanel.android.MPConfig.DecideEndpoint
- *
A string URL. If present, the library will attempt to get the settings of enabling Mixpanel to automatically collect common mobile events from this url rather than the default Mixpanel endpoint.
- * - *
com.mixpanel.android.MPConfig.DisableDecideChecker
- *
A boolean value. If true, the library will not query our decide endpoint for the settings of enabling Mixpanel to automatically collect common mobile events. Defaults to false.
- * *
com.mixpanel.android.MPConfig.MinimumSessionDuration
*
An integer number. The minimum session duration (ms) that is tracked in automatic events. Defaults to 10000 (10 seconds).
* @@ -186,14 +180,12 @@ public synchronized void setOfflineMode(OfflineMode offlineMode) { mFlushOnBackground = metaData.getBoolean("com.mixpanel.android.MPConfig.FlushOnBackground", true); mMinimumDatabaseLimit = metaData.getInt("com.mixpanel.android.MPConfig.MinimumDatabaseLimit", 20 * 1024 * 1024); // 20 Mb mResourcePackageName = metaData.getString("com.mixpanel.android.MPConfig.ResourcePackageName"); // default is null - mDisableDecideChecker = metaData.getBoolean("com.mixpanel.android.MPConfig.DisableDecideChecker", false); mDisableAppOpenEvent = metaData.getBoolean("com.mixpanel.android.MPConfig.DisableAppOpenEvent", true); mDisableExceptionHandler = metaData.getBoolean("com.mixpanel.android.MPConfig.DisableExceptionHandler", false); mMinSessionDuration = metaData.getInt("com.mixpanel.android.MPConfig.MinimumSessionDuration", 10 * 1000); // 10 seconds mSessionTimeoutDuration = metaData.getInt("com.mixpanel.android.MPConfig.SessionTimeoutDuration", Integer.MAX_VALUE); // no timeout by default mUseIpAddressForGeolocation = metaData.getBoolean("com.mixpanel.android.MPConfig.UseIpAddressForGeolocation", true); - Object dataExpirationMetaData = metaData.get("com.mixpanel.android.MPConfig.DataExpiration"); long dataExpirationLong = 1000 * 60 * 60 * 24 * 5; // 5 days default if (dataExpirationMetaData != null) { @@ -233,13 +225,6 @@ public synchronized void setOfflineMode(OfflineMode offlineMode) { setGroupsEndpointWithBaseURL(MPConstants.URL.MIXPANEL_API); } - String decideEndpoint = metaData.getString("com.mixpanel.android.MPConfig.DecideEndpoint"); - if (decideEndpoint != null) { - setDecideEndpoint(decideEndpoint); - } else { - setDecideEndpointWithBaseURL(MPConstants.URL.MIXPANEL_API); - } - MPLog.v(LOGTAG, toString()); } @@ -274,12 +259,13 @@ public String getEventsEndpoint() { return mEventsEndpoint; } + public boolean getTrackAutomaticEvents() { return mTrackAutomaticEvents; } + // In parity with iOS SDK public void setServerURL(String serverURL) { setEventsEndpointWithBaseURL(serverURL); setPeopleEndpointWithBaseURL(serverURL); setGroupsEndpointWithBaseURL(serverURL); - setDecideEndpointWithBaseURL(serverURL); } private String getEndPointWithIpTrackingParam(String endPoint, boolean ifUseIpAddressForGeolocation) { @@ -324,19 +310,6 @@ private void setGroupsEndpoint(String groupsEndpoint) { mGroupsEndpoint = groupsEndpoint; } - // Preferred URL for pulling decide data - public String getDecideEndpoint() { - return mDecideEndpoint; - } - - private void setDecideEndpointWithBaseURL(String baseURL) { - setDecideEndpoint(baseURL + MPConstants.URL.DECIDE); - } - - private void setDecideEndpoint(String decideEndpoint) { - mDecideEndpoint = decideEndpoint; - } - public int getMinimumSessionDuration() { return mMinSessionDuration; } @@ -349,10 +322,6 @@ public boolean getDisableExceptionHandler() { return mDisableExceptionHandler; } - public boolean getDisableDecideChecker() { - return mDisableDecideChecker; - } - private boolean getUseIpAddressForGeolocation() { return mUseIpAddressForGeolocation; } @@ -369,6 +338,9 @@ public void setEnableLogging(boolean enableLogging) { MPLog.setLevel(DEBUG ? MPLog.VERBOSE : MPLog.NONE); } + public void setTrackAutomaticEvents(boolean trackAutomaticEvents) { + mTrackAutomaticEvents = trackAutomaticEvents; + } // Pre-configured package name for resources, if they differ from the application package name // // mContext.getPackageName() actually returns the "application id", which @@ -415,6 +387,7 @@ public synchronized OfflineMode getOfflineMode() { @Override public String toString() { return "Mixpanel (" + VERSION + ") configured with:\n" + + " TrackAutomaticEvents: " + getTrackAutomaticEvents() + "\n" + " BulkUploadLimit " + getBulkUploadLimit() + "\n" + " FlushInterval " + getFlushInterval() + "\n" + " DataExpiration " + getDataExpiration() + "\n" + @@ -423,8 +396,6 @@ public String toString() { " EnableDebugLogging " + DEBUG + "\n" + " EventsEndpoint " + getEventsEndpoint() + "\n" + " PeopleEndpoint " + getPeopleEndpoint() + "\n" + - " DecideEndpoint " + getDecideEndpoint() + "\n" + - " DisableDecideChecker " + getDisableDecideChecker() + "\n" + " MinimumSessionDuration: " + getMinimumSessionDuration() + "\n" + " SessionTimeoutDuration: " + getSessionTimeoutDuration() + "\n" + " DisableExceptionHandler: " + getDisableExceptionHandler() + "\n" + @@ -436,13 +407,12 @@ public String toString() { private final boolean mFlushOnBackground; private final long mDataExpiration; private final int mMinimumDatabaseLimit; - private final boolean mDisableDecideChecker; private final boolean mDisableAppOpenEvent; private final boolean mDisableExceptionHandler; + private boolean mTrackAutomaticEvents = true; private String mEventsEndpoint; private String mPeopleEndpoint; private String mGroupsEndpoint; - private String mDecideEndpoint; private final String mResourcePackageName; private final int mMinSessionDuration; diff --git a/src/main/java/com/mixpanel/android/mpmetrics/MixpanelAPI.java b/src/main/java/com/mixpanel/android/mpmetrics/MixpanelAPI.java index dd4071665..b4b850473 100644 --- a/src/main/java/com/mixpanel/android/mpmetrics/MixpanelAPI.java +++ b/src/main/java/com/mixpanel/android/mpmetrics/MixpanelAPI.java @@ -40,7 +40,7 @@ /** * Core class for interacting with Mixpanel Analytics. * - *

Call {@link #getInstance(Context, String)} with + *

Call {@link #getInstance(Context, String, boolean)} with * your main application activity and your Mixpanel API token as arguments * an to get an instance you can use to report how users are using your * application. @@ -109,28 +109,29 @@ public class MixpanelAPI { * You shouldn't instantiate MixpanelAPI objects directly. * Use MixpanelAPI.getInstance to get an instance. */ - MixpanelAPI(Context context, Future referrerPreferences, String token, boolean optOutTrackingDefault, JSONObject superProperties) { - this(context, referrerPreferences, token, MPConfig.getInstance(context), optOutTrackingDefault, superProperties, null); + MixpanelAPI(Context context, Future referrerPreferences, String token, boolean optOutTrackingDefault, JSONObject superProperties, boolean trackAutomaticEvents) { + this(context, referrerPreferences, token, MPConfig.getInstance(context), optOutTrackingDefault, superProperties, null, trackAutomaticEvents); } /** * You shouldn't instantiate MixpanelAPI objects directly. * Use MixpanelAPI.getInstance to get an instance. */ - MixpanelAPI(Context context, Future referrerPreferences, String token, boolean optOutTrackingDefault, JSONObject superProperties, String instanceName) { - this(context, referrerPreferences, token, MPConfig.getInstance(context), optOutTrackingDefault, superProperties, instanceName); + MixpanelAPI(Context context, Future referrerPreferences, String token, boolean optOutTrackingDefault, JSONObject superProperties, String instanceName, boolean trackAutomaticEvents) { + this(context, referrerPreferences, token, MPConfig.getInstance(context), optOutTrackingDefault, superProperties, instanceName, trackAutomaticEvents); } /** * You shouldn't instantiate MixpanelAPI objects directly. * Use MixpanelAPI.getInstance to get an instance. */ - MixpanelAPI(Context context, Future referrerPreferences, String token, MPConfig config, boolean optOutTrackingDefault, JSONObject superProperties, String instanceName) { + MixpanelAPI(Context context, Future referrerPreferences, String token, MPConfig config, boolean optOutTrackingDefault, JSONObject superProperties, String instanceName, boolean trackAutomaticEvents) { mContext = context; mToken = token; mPeople = new PeopleImpl(); mGroups = new HashMap(); mConfig = config; + mConfig.setTrackAutomaticEvents(trackAutomaticEvents); final Map deviceInfo = new HashMap(); deviceInfo.put("$android_lib_version", MPConfig.VERSION); @@ -161,29 +162,17 @@ public class MixpanelAPI { if (superProperties != null) { registerSuperProperties(superProperties); } - mDecideMessages = constructDecideUpdates(token); - // TODO reading persistent identify immediately forces the lazy load of the preferences, and defeats the - // purpose of PersistentIdentity's laziness. - String decideId = mPersistentIdentity.getPeopleDistinctId(); - if (null == decideId) { - decideId = mPersistentIdentity.getEventsDistinctId(); - } - mDecideMessages.setDistinctId(decideId); final boolean dbExists = MPDbAdapter.getInstance(mContext).getDatabaseFile().exists(); registerMixpanelActivityLifecycleCallbacks(); - if (mPersistentIdentity.isFirstLaunch(dbExists, mToken)) { + if (mPersistentIdentity.isFirstLaunch(dbExists, mToken) && trackAutomaticEvents) { track(AutomaticEvents.FIRST_OPEN, null, true); mPersistentIdentity.setHasLaunched(mToken); } - if (!mConfig.getDisableDecideChecker()) { - mMessages.installDecideCheck(mDecideMessages); - } - - if (sendAppOpen()) { + if (sendAppOpen() && trackAutomaticEvents) { track("$app_open", null); } @@ -297,7 +286,7 @@ private void sendHttpEvent(String eventName, String token, String distinctId, JS peopleMessageProps.put("$distinct_id", distinctId); mMessages.peopleMessage(new AnalyticsMessages.PeopleDescription(peopleMessageProps, token)); } - mMessages.postToServer(new AnalyticsMessages.FlushDescription(token, false)); + mMessages.postToServer(new AnalyticsMessages.MixpanelDescription(token)); } /** @@ -324,10 +313,12 @@ private void sendHttpEvent(String eventName, String token, String distinctId, JS * @param context The application context you are tracking * @param token Your Mixpanel project token. You can get your project token on the Mixpanel web site, * in the settings dialog. + * @param trackAutomaticEvents Whether or not to collect common mobile events + * include app sessions, first app opens, app updated, etc. * @return an instance of MixpanelAPI associated with your project */ - public static MixpanelAPI getInstance(Context context, String token) { - return getInstance(context, token, false, null, null); + public static MixpanelAPI getInstance(Context context, String token, boolean trackAutomaticEvents) { + return getInstance(context, token, false, null, null, trackAutomaticEvents); } /** @@ -356,10 +347,12 @@ public static MixpanelAPI getInstance(Context context, String token) { * in the settings dialog. * @param instanceName The name you want to uniquely identify the Mixpanel Instance. * It is useful when you want more than one Mixpanel instance under the same project token + * @param trackAutomaticEvents Whether or not to collect common mobile events + * include app sessions, first app opens, app updated, etc. * @return an instance of MixpanelAPI associated with your project */ - public static MixpanelAPI getInstance(Context context, String token, String instanceName) { - return getInstance(context, token, false, null, instanceName); + public static MixpanelAPI getInstance(Context context, String token, String instanceName, boolean trackAutomaticEvents) { + return getInstance(context, token, false, null, instanceName, trackAutomaticEvents); } /** @@ -388,10 +381,12 @@ public static MixpanelAPI getInstance(Context context, String token, String inst * in the settings dialog. * @param optOutTrackingDefault Whether or not Mixpanel can start tracking by default. See * {@link #optOutTracking()}. + * @param trackAutomaticEvents Whether or not to collect common mobile events + * include app sessions, first app opens, app updated, etc. * @return an instance of MixpanelAPI associated with your project */ - public static MixpanelAPI getInstance(Context context, String token, boolean optOutTrackingDefault) { - return getInstance(context, token, optOutTrackingDefault, null, null); + public static MixpanelAPI getInstance(Context context, String token, boolean optOutTrackingDefault, boolean trackAutomaticEvents) { + return getInstance(context, token, optOutTrackingDefault, null, null, trackAutomaticEvents); } /** @@ -422,10 +417,12 @@ public static MixpanelAPI getInstance(Context context, String token, boolean opt * {@link #optOutTracking()}. * @param instanceName The name you want to uniquely identify the Mixpanel Instance. It is useful when you want more than one Mixpanel instance under the same project token. + * @param trackAutomaticEvents Whether or not to collect common mobile events + * include app sessions, first app opens, app updated, etc. * @return an instance of MixpanelAPI associated with your project */ - public static MixpanelAPI getInstance(Context context, String token, boolean optOutTrackingDefault, String instanceName) { - return getInstance(context, token, optOutTrackingDefault, null, instanceName); + public static MixpanelAPI getInstance(Context context, String token, boolean optOutTrackingDefault, String instanceName, boolean trackAutomaticEvents) { + return getInstance(context, token, optOutTrackingDefault, null, instanceName, trackAutomaticEvents); } /** @@ -453,10 +450,12 @@ public static MixpanelAPI getInstance(Context context, String token, boolean opt * @param token Your Mixpanel project token. You can get your project token on the Mixpanel web site, * in the settings dialog. * @param superProperties A JSONObject containing super properties to register. + * @param trackAutomaticEvents Whether or not to collect common mobile events + * include app sessions, first app opens, app updated, etc. * @return an instance of MixpanelAPI associated with your project */ - public static MixpanelAPI getInstance(Context context, String token, JSONObject superProperties) { - return getInstance(context, token, false, superProperties, null); + public static MixpanelAPI getInstance(Context context, String token, JSONObject superProperties, boolean trackAutomaticEvents) { + return getInstance(context, token, false, superProperties, null, trackAutomaticEvents); } /** @@ -486,10 +485,12 @@ public static MixpanelAPI getInstance(Context context, String token, JSONObject * @param superProperties A JSONObject containing super properties to register. * @param instanceName The name you want to uniquely identify the Mixpanel Instance. * It is useful when you want more than one Mixpanel instance under the same project token + * @param trackAutomaticEvents Whether or not to collect common mobile events + * include app sessions, first app opens, app updated, etc. * @return an instance of MixpanelAPI associated with your project */ - public static MixpanelAPI getInstance(Context context, String token, JSONObject superProperties, String instanceName) { - return getInstance(context, token, false, superProperties, instanceName); + public static MixpanelAPI getInstance(Context context, String token, JSONObject superProperties, String instanceName, boolean trackAutomaticEvents) { + return getInstance(context, token, false, superProperties, instanceName, trackAutomaticEvents); } /** @@ -521,9 +522,11 @@ public static MixpanelAPI getInstance(Context context, String token, JSONObject * @param superProperties A JSONObject containing super properties to register. * @param instanceName The name you want to uniquely identify the Mixpanel Instance. * It is useful when you want more than one Mixpanel instance under the same project token + * @param trackAutomaticEvents Whether or not to collect common mobile events + * include app sessions, first app opens, app updated, etc. * @return an instance of MixpanelAPI associated with your project */ - public static MixpanelAPI getInstance(Context context, String token, boolean optOutTrackingDefault, JSONObject superProperties, String instanceName) { + public static MixpanelAPI getInstance(Context context, String token, boolean optOutTrackingDefault, JSONObject superProperties, String instanceName, boolean trackAutomaticEvents) { if (null == token || null == context) { return null; } @@ -542,7 +545,7 @@ public static MixpanelAPI getInstance(Context context, String token, boolean opt MixpanelAPI instance = instances.get(appContext); if (null == instance && ConfigurationChecker.checkBasicConfiguration(appContext)) { - instance = new MixpanelAPI(appContext, sReferrerPrefs, token, optOutTrackingDefault, superProperties, instanceName); + instance = new MixpanelAPI(appContext, sReferrerPrefs, token, optOutTrackingDefault, superProperties, instanceName, trackAutomaticEvents); registerAppLinksListeners(context, instance); instances.put(appContext, instance); } @@ -684,11 +687,6 @@ private void identify(String distinctId, boolean markAsUserId, boolean usePeople if(markAsUserId) { mPersistentIdentity.markEventsUserIdPresent(); } - String decideId = mPersistentIdentity.getPeopleDistinctId(); - if (null == decideId) { - decideId = mPersistentIdentity.getEventsDistinctId(); - } - mDecideMessages.setDistinctId(decideId); if (!distinctId.equals(currentEventsDistinctId)) { try { @@ -864,7 +862,7 @@ public void track(String eventName) { */ public void flush() { if (hasOptedOutTracking()) return; - mMessages.postToServer(new AnalyticsMessages.FlushDescription(mToken)); + mMessages.postToServer(new AnalyticsMessages.MixpanelDescription(mToken)); } /** @@ -1304,7 +1302,8 @@ public void optInTracking(String distinctId, JSONObject properties) { } /** * Will return true if the user has opted out from tracking. See {@link #optOutTracking()} and - * {@link MixpanelAPI#getInstance(Context, String, boolean, JSONObject, String)} for more information. + * {@link + * MixpanelAPI#getInstance(Context, String, boolean, JSONObject, String, boolean)} for more information. * * @return true if user has opted out from tracking. Defaults to false. */ @@ -1544,7 +1543,6 @@ public interface People { /** * Return an instance of Mixpanel people with a temporary distinct id. - * Instances returned by withIdentity will not check decide with the given distinctId. * * @param distinctId Unique identifier (distinct_id) that the people object will have * @@ -1758,9 +1756,6 @@ public boolean isAppInForeground() { return AnalyticsMessages.getInstance(mContext); } - /* package */ DecideMessages getDecideMessages() { - return mDecideMessages; - } /* package */ PersistentIdentity getPersistentIdentity(final Context context, Future referrerPreferences, final String token) { return getPersistentIdentity(context, referrerPreferences, token, null); @@ -1790,11 +1785,6 @@ public void onPrefsLoaded(SharedPreferences preferences) { return new PersistentIdentity(referrerPreferences, storedPreferences, timeEventsPrefs, mixpanelPrefs); } - /* package */ DecideMessages constructDecideUpdates(final String token) { - - return new DecideMessages(mContext, token); - } - /* package */ boolean sendAppOpen() { return !mConfig.getDisableAppOpenEvent(); } @@ -1821,7 +1811,6 @@ public void identify(String distinctId) { private void identify_people(String distinctId) { synchronized (mPersistentIdentity) { mPersistentIdentity.setPeopleDistinctId(distinctId); - mDecideMessages.setDistinctId(distinctId); } pushWaitingPeopleRecord(distinctId); } @@ -2236,14 +2225,8 @@ private JSONObject stdGroupMessage(String actionType, Object properties) } }// GroupImpl - //////////////////////////////////////////////////// - protected void flushNoDecideCheck() { - if (hasOptedOutTracking()) return; - mMessages.postToServer(new AnalyticsMessages.FlushDescription(mToken, false)); - } - protected void track(String eventName, JSONObject properties, boolean isAutomaticEvent) { - if (hasOptedOutTracking() || (isAutomaticEvent && !mDecideMessages.shouldTrackAutomaticEvent())) { + if (hasOptedOutTracking() || isAutomaticEvent && !mConfig.getTrackAutomaticEvents()) { return; } @@ -2398,7 +2381,6 @@ private static void checkIntentForInboundAppLink(Context context) { private final PeopleImpl mPeople; private final Map mGroups; private final PersistentIdentity mPersistentIdentity; - private final DecideMessages mDecideMessages; private final Map mDeviceInfo; private final Map mEventTimings; private MixpanelActivityLifecycleCallbacks mMixpanelActivityLifecycleCallbacks; diff --git a/src/main/java/com/mixpanel/android/util/HttpService.java b/src/main/java/com/mixpanel/android/util/HttpService.java index dd59a1c00..97e0a5d28 100644 --- a/src/main/java/com/mixpanel/android/util/HttpService.java +++ b/src/main/java/com/mixpanel/android/util/HttpService.java @@ -35,11 +35,8 @@ public void checkIsMixpanelBlocked() { public void run() { try { InetAddress apiMixpanelInet = InetAddress.getByName("api.mixpanel.com"); - InetAddress decideMixpanelInet = InetAddress.getByName("decide.mixpanel.com"); sIsMixpanelBlocked = apiMixpanelInet.isLoopbackAddress() || - apiMixpanelInet.isAnyLocalAddress() || - decideMixpanelInet.isLoopbackAddress() || - decideMixpanelInet.isAnyLocalAddress(); + apiMixpanelInet.isAnyLocalAddress(); if (sIsMixpanelBlocked) { MPLog.v(LOGTAG, "AdBlocker is enabled. Won't be able to use Mixpanel services."); } diff --git a/src/main/java/com/mixpanel/android/util/MPConstants.java b/src/main/java/com/mixpanel/android/util/MPConstants.java index 9b6766399..53345f4ff 100644 --- a/src/main/java/com/mixpanel/android/util/MPConstants.java +++ b/src/main/java/com/mixpanel/android/util/MPConstants.java @@ -7,10 +7,8 @@ public class MPConstants { public static class URL { public static final String MIXPANEL_API = "https://api.mixpanel.com"; - public static final String DECIDE = "/decide"; public static final String EVENT = "/track/"; public static final String PEOPLE = "/engage/"; public static final String GROUPS = "/groups/"; - public static final String SWITCHBOARD = "wss://switchboard.mixpanel.com/connect/"; } }