Skip to content

Commit cb39dc5

Browse files
Fix quick consecutive init race condition (#1149)
1 parent 5bfde96 commit cb39dc5

File tree

10 files changed

+127
-39
lines changed

10 files changed

+127
-39
lines changed

Branch-SDK/src/main/java/io/branch/referral/Branch.java

Lines changed: 46 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package io.branch.referral;
22

3-
import static io.branch.referral.BranchError.ERR_BRANCH_TASK_TIMEOUT;
43
import static io.branch.referral.BranchError.ERR_IMPROPER_REINITIALIZATION;
54
import static io.branch.referral.BranchPreinstall.getPreinstallSystemData;
65
import static io.branch.referral.BranchUtil.isTestModeEnabled;
@@ -20,7 +19,6 @@
2019
import android.os.AsyncTask;
2120
import android.os.Bundle;
2221
import android.os.Handler;
23-
import android.os.Looper;
2422
import android.text.TextUtils;
2523

2624
import androidx.annotation.NonNull;
@@ -37,7 +35,6 @@
3735
import java.lang.ref.WeakReference;
3836
import java.net.HttpURLConnection;
3937
import java.net.URLEncoder;
40-
import java.util.HashMap;
4138
import java.util.Iterator;
4239
import java.util.List;
4340
import java.util.Set;
@@ -54,7 +51,6 @@
5451
import io.branch.referral.network.BranchRemoteInterfaceUrlConnection;
5552
import io.branch.referral.util.BRANCH_STANDARD_EVENT;
5653
import io.branch.referral.util.BranchEvent;
57-
import io.branch.referral.util.CommerceEvent;
5854
import io.branch.referral.util.LinkProperties;
5955

6056
/**
@@ -811,6 +807,7 @@ static String getPluginName() {
811807
}
812808

813809
private void readAndStripParam(Uri data, Activity activity) {
810+
BranchLogger.v("Read params uri: " + data + " bypassCurrentActivityIntentState: " + bypassCurrentActivityIntentState_ + " intent state: " + intentState_);
814811
if (enableInstantDeepLinking) {
815812

816813
// If activity is launched anew (i.e. not from stack), then its intent can be readily consumed.
@@ -852,13 +849,16 @@ private void readAndStripParam(Uri data, Activity activity) {
852849

853850
void unlockSDKInitWaitLock() {
854851
if (requestQueue_ == null) return;
852+
requestQueue_.postInitClear();
855853
requestQueue_.unlockProcessWait(ServerRequest.PROCESS_WAIT_LOCK.SDK_INIT_WAIT_LOCK);
856-
requestQueue_.processNextQueueItem();
854+
requestQueue_.processNextQueueItem("unlockSDKInitWaitLock");
857855
}
858856

859857
private boolean isIntentParamsAlreadyConsumed(Activity activity) {
860-
return activity != null && activity.getIntent() != null &&
858+
boolean result = activity != null && activity.getIntent() != null &&
861859
activity.getIntent().getBooleanExtra(Defines.IntentKeys.BranchLinkUsed.getKey(), false);
860+
BranchLogger.v("isIntentParamsAlreadyConsumed " + result);
861+
return result;
862862
}
863863

864864
private boolean isActivityLaunchedFromHistory(Activity activity) {
@@ -1050,7 +1050,7 @@ public JSONObject getFirstReferringParams() {
10501050
@SuppressWarnings("WeakerAccess")
10511051
public void removeSessionInitializationDelay() {
10521052
requestQueue_.unlockProcessWait(ServerRequest.PROCESS_WAIT_LOCK.USER_SET_WAIT_LOCK);
1053-
requestQueue_.processNextQueueItem();
1053+
requestQueue_.processNextQueueItem("removeSessionInitializationDelay");
10541054
}
10551055

10561056
/**
@@ -1333,6 +1333,7 @@ public boolean isInstantDeepLinkPossible() {
13331333
}
13341334

13351335
private void initializeSession(ServerRequestInitSession initRequest, int delay) {
1336+
BranchLogger.v("initializeSession " + initRequest + " delay " + delay);
13361337
if ((prefHelper_.getBranchKey() == null || prefHelper_.getBranchKey().equalsIgnoreCase(PrefHelper.NO_STRING_VALUE))) {
13371338
setInitState(SESSION_STATE.UNINITIALISED);
13381339
//Report Key error on callback
@@ -1365,11 +1366,13 @@ private void initializeSession(ServerRequestInitSession initRequest, int delay)
13651366
Intent intent = getCurrentActivity() != null ? getCurrentActivity().getIntent() : null;
13661367
boolean forceBranchSession = isRestartSessionRequested(intent);
13671368

1368-
if (getInitState() == SESSION_STATE.UNINITIALISED || forceBranchSession) {
1369+
SESSION_STATE sessionState = getInitState();
1370+
BranchLogger.v("Intent: " + intent + " forceBranchSession: " + forceBranchSession + " initState: " + sessionState);
1371+
if (sessionState == SESSION_STATE.UNINITIALISED || forceBranchSession) {
13691372
if (forceBranchSession && intent != null) {
13701373
intent.removeExtra(Defines.IntentKeys.ForceNewBranchSession.getKey()); // SDK-881, avoid double initialization
13711374
}
1372-
registerAppInit(initRequest, false);
1375+
registerAppInit(initRequest, false, forceBranchSession);
13731376
} else if (initRequest.callback_ != null) {
13741377
// Else, let the user know session initialization failed because it's already initialized.
13751378
initRequest.callback_.onInitFinished(null, new BranchError("Warning.", BranchError.ERR_BRANCH_ALREADY_INITIALIZED));
@@ -1380,26 +1383,40 @@ private void initializeSession(ServerRequestInitSession initRequest, int delay)
13801383
* Registers app init with params filtered from the intent. Unless ignoreIntent = true, this
13811384
* will wait on the wait locks to complete any pending operations
13821385
*/
1383-
void registerAppInit(@NonNull ServerRequestInitSession request, boolean ignoreWaitLocks) {
1386+
void registerAppInit(@NonNull ServerRequestInitSession request, boolean ignoreWaitLocks, boolean forceBranchSession) {
1387+
BranchLogger.v("registerAppInit " + request);
13841388
setInitState(SESSION_STATE.INITIALISING);
13851389

13861390
ServerRequestInitSession r = requestQueue_.getSelfInitRequest();
1387-
if (r == null) {
1391+
BranchLogger.v("Ordering init calls");
1392+
requestQueue_.printQueue();
1393+
1394+
// if forceBranchSession aka reInit is true, we want to preserve the callback order in case
1395+
// there is one still in flight
1396+
if (r == null || forceBranchSession) {
1397+
BranchLogger.v("Moving " + request + " " + " to front of the queue or behind network-in-progress request");
13881398
requestQueue_.insertRequestAtFront(request);
13891399
}
13901400
else {
1401+
// if false, maintain previous behavior
1402+
BranchLogger.v("Retrieved " + r + " with callback " + r.callback_ + " in queue currently");
13911403
r.callback_ = request.callback_;
1404+
BranchLogger.v(r + " now has callback " + request.callback_);
13921405
}
1406+
BranchLogger.v("Finished ordering init calls");
1407+
requestQueue_.printQueue();
13931408
initTasks(request, ignoreWaitLocks);
13941409

1395-
requestQueue_.processNextQueueItem();
1410+
requestQueue_.processNextQueueItem("registerAppInit");
13961411
}
13971412

13981413
private void initTasks(ServerRequest request, boolean ignoreWaitLocks) {
1414+
BranchLogger.v("initTasks " + request + " ignoreWaitLocks " + ignoreWaitLocks);
13991415
if (!ignoreWaitLocks) {
14001416
// Single top activities can be launched from stack and there may be a new intent provided with onNewIntent() call.
14011417
// In this case need to wait till onResume to get the latest intent. Bypass this if bypassWaitingForIntent_ is true.
14021418
if (intentState_ != INTENT_STATE.READY && isWaitingForIntent()) {
1419+
BranchLogger.v("Adding INTENT_PENDING_WAIT_LOCK");
14031420
request.addProcessWaitLock(ServerRequest.PROCESS_WAIT_LOCK.INTENT_PENDING_WAIT_LOCK);
14041421
}
14051422

@@ -1412,8 +1429,7 @@ private void initTasks(ServerRequest request, boolean ignoreWaitLocks) {
14121429
@Override
14131430
public void onInstallReferrersFinished() {
14141431
request.removeProcessWaitLock(ServerRequest.PROCESS_WAIT_LOCK.INSTALL_REFERRER_FETCH_WAIT_LOCK);
1415-
BranchLogger.v("calling processNextQueueItem from onInstallReferrersFinished");
1416-
requestQueue_.processNextQueueItem();
1432+
requestQueue_.processNextQueueItem("onInstallReferrersFinished");
14171433
}
14181434
});
14191435
}
@@ -1423,7 +1439,7 @@ public void onInstallReferrersFinished() {
14231439
@Override
14241440
public void onAdsParamsFetchFinished() {
14251441
requestQueue_.unlockProcessWait(ServerRequest.PROCESS_WAIT_LOCK.GAID_FETCH_WAIT_LOCK);
1426-
requestQueue_.processNextQueueItem();
1442+
requestQueue_.processNextQueueItem("onAdsParamsFetchFinished");
14271443
}
14281444
});
14291445
}
@@ -1441,6 +1457,7 @@ ServerRequestInitSession getInstallOrOpenRequest(BranchReferralInitListener call
14411457
}
14421458

14431459
void onIntentReady(@NonNull Activity activity) {
1460+
BranchLogger.v("onIntentReady " + activity + " removing INTENT_PENDING_WAIT_LOCK");
14441461
setIntentState(Branch.INTENT_STATE.READY);
14451462
requestQueue_.unlockProcessWait(ServerRequest.PROCESS_WAIT_LOCK.INTENT_PENDING_WAIT_LOCK);
14461463

@@ -1450,14 +1467,14 @@ void onIntentReady(@NonNull Activity activity) {
14501467
Uri intentData = activity.getIntent().getData();
14511468
readAndStripParam(intentData, activity);
14521469
}
1453-
requestQueue_.processNextQueueItem();
1470+
requestQueue_.processNextQueueItem("onIntentReady");
14541471
}
14551472

14561473
/**
14571474
* Notify Branch when network is available in order to process the next request in the queue.
14581475
*/
14591476
public void notifyNetworkAvailable() {
1460-
requestQueue_.processNextQueueItem();
1477+
requestQueue_.processNextQueueItem("notifyNetworkAvailable");
14611478
}
14621479

14631480
private void setActivityLifeCycleObserver(Application application) {
@@ -1696,6 +1713,7 @@ void checkForAutoDeepLinkConfiguration() {
16961713
//Check if the application is launched by clicking a Branch link.
16971714
if (!latestParams.has(Defines.Jsonkey.Clicked_Branch_Link.getKey())
16981715
|| !latestParams.getBoolean(Defines.Jsonkey.Clicked_Branch_Link.getKey())) {
1716+
BranchLogger.v("Does not have Clicked_Branch_Link or Clicked_Branch_Link is false, returning");
16991717
return;
17001718
}
17011719
if (latestParams.length() > 0) {
@@ -1720,6 +1738,7 @@ void checkForAutoDeepLinkConfiguration() {
17201738
}
17211739
}
17221740
if (deepLinkActivity != null && getCurrentActivity() != null) {
1741+
BranchLogger.v("deepLinkActivity " + deepLinkActivity + " getCurrentActivity " + getCurrentActivity());
17231742
Activity currentActivity = getCurrentActivity();
17241743

17251744
Intent intent = new Intent(currentActivity, Class.forName(deepLinkActivity));
@@ -2054,6 +2073,7 @@ private boolean extractClickID(Uri data, Activity activity) {
20542073
}
20552074

20562075
private boolean extractBranchLinkFromIntentExtra(Activity activity) {
2076+
BranchLogger.v("extractBranchLinkFromIntentExtra " + activity);
20572077
//Check for any push identifier in case app is launched by a push notification
20582078
try {
20592079
if (activity != null && activity.getIntent() != null && activity.getIntent().getExtras() != null) {
@@ -2084,6 +2104,7 @@ private boolean extractBranchLinkFromIntentExtra(Activity activity) {
20842104
}
20852105

20862106
private void extractExternalUriAndIntentExtras(Uri data, Activity activity) {
2107+
BranchLogger.v("extractExternalUriAndIntentExtras " + data + " " + activity);
20872108
try {
20882109
if (!isIntentParamsAlreadyConsumed(activity)) {
20892110
String strippedUrl = UniversalResourceAnalyser.getInstance(context_).getStrippedURL(data.toString());
@@ -2156,6 +2177,7 @@ InitSessionBuilder isAutoInitialization(boolean isAuto) {
21562177
*/
21572178
@SuppressWarnings("WeakerAccess")
21582179
public InitSessionBuilder withCallback(BranchUniversalReferralInitListener callback) {
2180+
BranchLogger.v("InitSessionBuilder setting BranchUniversalReferralInitListener withCallback with " + callback);
21592181
this.callback = new BranchUniversalReferralInitWrapper(callback);
21602182
return this;
21612183
}
@@ -2184,6 +2206,7 @@ public InitSessionBuilder withDelay(int delayMillis) {
21842206
*/
21852207
@SuppressWarnings("WeakerAccess")
21862208
public InitSessionBuilder withCallback(BranchReferralInitListener callback) {
2209+
BranchLogger.v("InitSessionBuilder setting BranchReferralInitListener withCallback with " + callback);
21872210
this.callback = callback;
21882211
return this;
21892212
}
@@ -2196,6 +2219,7 @@ public InitSessionBuilder withCallback(BranchReferralInitListener callback) {
21962219
*/
21972220
@SuppressWarnings("WeakerAccess")
21982221
public InitSessionBuilder withData(Uri uri) {
2222+
BranchLogger.v("InitSessionBuilder setting withData with " + uri);
21992223
this.uri = uri;
22002224
return this;
22012225
}
@@ -2236,6 +2260,10 @@ public InitSessionBuilder ignoreIntent(boolean ignore) {
22362260
public void init() {
22372261
BranchLogger.v("Beginning session initialization");
22382262
BranchLogger.v("Session uri is " + uri);
2263+
BranchLogger.v("Callback is " + callback);
2264+
BranchLogger.v("Is auto init " + isAutoInitialization);
2265+
BranchLogger.v("Will ignore intent " + ignoreIntent);
2266+
BranchLogger.v("Is reinitializing " + isReInitializing);
22392267

22402268
if(deferInitForPluginRuntime){
22412269
BranchLogger.v("Session init is deferred until signaled by plugin.");
@@ -2275,6 +2303,7 @@ else if (isReInitializing) {
22752303
return;
22762304
}
22772305

2306+
BranchLogger.v("isInstantDeepLinkPossible " + branch.isInstantDeepLinkPossible);
22782307
// readAndStripParams (above) may set isInstantDeepLinkPossible to true
22792308
if (branch.isInstantDeepLinkPossible) {
22802309
// reset state

Branch-SDK/src/main/java/io/branch/referral/PrefHelper.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -611,7 +611,8 @@ public void setExternalIntentUri(String uri) {
611611
* @return A {@link String} value containing external URI set.
612612
*/
613613
public String getExternalIntentUri() {
614-
return getString(KEY_EXTERNAL_INTENT_URI);
614+
String result = getString(KEY_EXTERNAL_INTENT_URI);
615+
return result;
615616
}
616617

617618

Branch-SDK/src/main/java/io/branch/referral/ServerRequest.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import org.json.JSONException;
1313
import org.json.JSONObject;
1414

15+
import java.util.Arrays;
1516
import java.util.ConcurrentModificationException;
1617
import java.util.HashSet;
1718
import java.util.Iterator;
@@ -667,6 +668,10 @@ public void addProcessWaitLock(PROCESS_WAIT_LOCK lock) {
667668
public void removeProcessWaitLock(PROCESS_WAIT_LOCK lock) {
668669
locks_.remove(lock);
669670
}
671+
672+
public String printWaitLocks(){
673+
return Arrays.toString(locks_.toArray());
674+
}
670675

671676

672677
/**
@@ -683,6 +688,7 @@ public boolean isWaitingOnProcessToFinish() {
683688
* Also attaches any required URL query parameters based on the request type.
684689
*/
685690
public void onPreExecute() {
691+
BranchLogger.v("onPreExecute " + this);
686692
if (this instanceof ServerRequestRegisterOpen || this instanceof ServerRequestLogEvent) {
687693
try {
688694
ReferringUrlUtility utility = new ReferringUrlUtility(prefHelper_);

Branch-SDK/src/main/java/io/branch/referral/ServerRequestInitSession.java

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -84,21 +84,6 @@ static boolean isInitSessionAction(String actionName) {
8484
@Override
8585
public void onRequestSucceeded(ServerResponse response, Branch branch) {
8686
Branch.getInstance().unlockSDKInitWaitLock();
87-
// Check for any Third party SDK for data handling
88-
prefHelper_.setLinkClickIdentifier(PrefHelper.NO_STRING_VALUE);
89-
prefHelper_.setGoogleSearchInstallIdentifier(PrefHelper.NO_STRING_VALUE);
90-
prefHelper_.setAppStoreReferrer(PrefHelper.NO_STRING_VALUE);
91-
prefHelper_.setExternalIntentUri(PrefHelper.NO_STRING_VALUE);
92-
prefHelper_.setExternalIntentExtra(PrefHelper.NO_STRING_VALUE);
93-
prefHelper_.setAppLink(PrefHelper.NO_STRING_VALUE);
94-
prefHelper_.setPushIdentifier(PrefHelper.NO_STRING_VALUE);
95-
prefHelper_.setInstallReferrerParams(PrefHelper.NO_STRING_VALUE);
96-
prefHelper_.setIsFullAppConversion(false);
97-
prefHelper_.setInitialReferrer(PrefHelper.NO_STRING_VALUE);
98-
99-
if (prefHelper_.getLong(PrefHelper.KEY_PREVIOUS_UPDATE_TIME) == 0) {
100-
prefHelper_.setLong(PrefHelper.KEY_PREVIOUS_UPDATE_TIME, prefHelper_.getLong(PrefHelper.KEY_LAST_KNOWN_UPDATE_TIME));
101-
}
10287
}
10388

10489
void onInitSessionCompleted(ServerResponse response, Branch branch) {

0 commit comments

Comments
 (0)