Skip to content

Commit 297c579

Browse files
Merge pull request #1056 from BranchMetrics/SDK-1801
[patch][SDK-1801] Collect, Persist, and Forward 'gclid' value on downstream events
2 parents 50d68f0 + a19a37f commit 297c579

File tree

11 files changed

+551
-92
lines changed

11 files changed

+551
-92
lines changed
Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
package io.branch.referral
2+
3+
import androidx.test.ext.junit.runners.AndroidJUnit4
4+
5+
import org.json.JSONObject
6+
import org.junit.Assert.*
7+
import org.junit.Before
8+
import org.junit.Test
9+
import org.junit.runner.RunWith
10+
import java.util.*
11+
12+
@RunWith(AndroidJUnit4::class)
13+
class ReferringUrlUtilityTests : BranchTest() {
14+
15+
private lateinit var referringUrlUtility: ReferringUrlUtility
16+
17+
private fun openServerRequest(): ServerRequest {
18+
val jsonString = "{\"REQ_POST\":{\"randomized_device_token\":\"1144756305514505535\",\"randomized_bundle_token\":\"1160050998451292762\",\"hardware_id\":\"90570b07852c65e1\",\"is_hardware_id_real\":true,\"brand\":\"Google\",\"model\":\"sdk_gphone64_arm64\",\"screen_dpi\":440,\"screen_height\":2236,\"screen_width\":1080,\"wifi\":true,\"ui_mode\":\"UI_MODE_TYPE_NORMAL\",\"os\":\"Android\",\"os_version\":32,\"cpu_type\":\"aarch64\",\"build\":\"TPP2.220218.008\",\"locale\":\"en_US\",\"connection_type\":\"wifi\",\"device_carrier\":\"T-Mobile\",\"os_version_android\":\"12\",\"country\":\"US\",\"language\":\"en\",\"local_ip\":\"10.0.2.16\"},\"REQ_POST_PATH\":\"v1\\/open\",\"INITIATED_BY_CLIENT\":true}"
19+
val jsonObject = JSONObject(jsonString)
20+
return ServerRequest.fromJSON(jsonObject, Branch.getInstance().applicationContext)
21+
}
22+
23+
@Before
24+
fun initializeValues() {
25+
initBranchInstance()
26+
referringUrlUtility = ReferringUrlUtility(PrefHelper.getInstance(Branch.getInstance().applicationContext))
27+
}
28+
29+
@Test
30+
fun testReferringURLWithNoParams() {
31+
val url = "https://bnctestbed.app.link"
32+
val expected = JSONObject()
33+
34+
referringUrlUtility.parseReferringURL(url)
35+
val params = referringUrlUtility.getURLQueryParamsForRequest(openServerRequest())
36+
37+
assertTrue(areJSONObjectsEqual(expected, params))
38+
}
39+
40+
@Test
41+
fun testReferringURLIgnoredParam() {
42+
val url = "https://bnctestbed.app.link?other=12345"
43+
val expected = JSONObject()
44+
45+
referringUrlUtility.parseReferringURL(url)
46+
val params = referringUrlUtility.getURLQueryParamsForRequest(openServerRequest())
47+
48+
assertTrue(areJSONObjectsEqual(expected, params))
49+
}
50+
51+
@Test
52+
fun testReferringURLWithGclid() {
53+
val url = "https://bnctestbed.app.link?gclid=12345"
54+
val expected = JSONObject("""{"gclid": "12345", "is_deeplink_gclid": true}""")
55+
56+
referringUrlUtility.parseReferringURL(url)
57+
val params = referringUrlUtility.getURLQueryParamsForRequest(openServerRequest())
58+
59+
assertTrue(areJSONObjectsEqual(expected, params))
60+
}
61+
62+
@Test
63+
fun testReferringURLWithURISchemeSanityCheck() {
64+
val url = "branchtest://?gclid=12345"
65+
val expected = JSONObject("""{"gclid": "12345", "is_deeplink_gclid": true}""")
66+
67+
referringUrlUtility.parseReferringURL(url)
68+
val params = referringUrlUtility.getURLQueryParamsForRequest(openServerRequest())
69+
70+
assertTrue(areJSONObjectsEqual(expected, params))
71+
}
72+
73+
@Test
74+
fun testReferringURLWithGclidCapitalized() {
75+
val url = "https://bnctestbed.app.link?GCLID=12345"
76+
val expected = JSONObject("""{"gclid": "12345", "is_deeplink_gclid": true}""")
77+
78+
referringUrlUtility.parseReferringURL(url)
79+
val params = referringUrlUtility.getURLQueryParamsForRequest(openServerRequest())
80+
81+
assertTrue(areJSONObjectsEqual(expected, params))
82+
}
83+
84+
@Test
85+
fun testReferringURLWithGclidMixedCase() {
86+
val url = "https://bnctestbed.app.link?GcLiD=12345"
87+
val expected = JSONObject("""{"gclid": "12345", "is_deeplink_gclid": true}""")
88+
89+
referringUrlUtility.parseReferringURL(url)
90+
val params = referringUrlUtility.getURLQueryParamsForRequest(openServerRequest())
91+
92+
assertTrue(areJSONObjectsEqual(expected, params))
93+
}
94+
95+
@Test
96+
fun testReferringURLWithGclidNoValue() {
97+
val url = "https://bnctestbed.app.link?gclid="
98+
val expected = JSONObject("""{"gclid": "", "is_deeplink_gclid": true}""")
99+
100+
referringUrlUtility.parseReferringURL(url)
101+
val params = referringUrlUtility.getURLQueryParamsForRequest(openServerRequest())
102+
103+
assertTrue(areJSONObjectsEqual(expected, params))
104+
}
105+
106+
@Test
107+
fun testReferringURLWithGclidValueCasePreserved() {
108+
val url = "https://bnctestbed.app.link?gclid=aAbBcC"
109+
val expected = JSONObject("""{"gclid": "aAbBcC", "is_deeplink_gclid": true}""")
110+
111+
referringUrlUtility.parseReferringURL(url)
112+
val params = referringUrlUtility.getURLQueryParamsForRequest(openServerRequest())
113+
114+
assertTrue(areJSONObjectsEqual(expected, params))
115+
}
116+
117+
@Test
118+
fun testReferringURLWithGclidIgnoredParam() {
119+
val url = "https://bnctestbed.app.link?gclid=12345&other=abcde"
120+
val expected = JSONObject("""{"gclid": "12345", "is_deeplink_gclid": true}""")
121+
122+
referringUrlUtility.parseReferringURL(url)
123+
val params = referringUrlUtility.getURLQueryParamsForRequest(openServerRequest())
124+
125+
assertTrue(areJSONObjectsEqual(expected, params))
126+
}
127+
128+
@Test
129+
fun testReferringURLWithGclidFragment() {
130+
val url = "https://bnctestbed.app.link?gclid=12345#header"
131+
val expected = JSONObject("""{"gclid": "12345", "is_deeplink_gclid": true}""")
132+
133+
referringUrlUtility.parseReferringURL(url)
134+
val params = referringUrlUtility.getURLQueryParamsForRequest(openServerRequest())
135+
136+
assertTrue(areJSONObjectsEqual(expected, params))
137+
}
138+
139+
@Test
140+
fun testReferringURLWithGclidAsFragment() {
141+
val url = "https://bnctestbed.app.link?other=abcde#gclid=12345"
142+
val expected = JSONObject()
143+
144+
referringUrlUtility.parseReferringURL(url)
145+
val params = referringUrlUtility.getURLQueryParamsForRequest(openServerRequest())
146+
147+
assertTrue(areJSONObjectsEqual(expected, params))
148+
}
149+
150+
@Test
151+
fun testReferringURLWithGclidOverwritesValue() {
152+
val url1 = "https://bnctestbed.app.link?gclid=12345"
153+
val expected1 = JSONObject("""{"gclid": "12345", "is_deeplink_gclid": true}""")
154+
155+
val url2 = "https://bnctestbed.app.link?gclid=abcde"
156+
val expected2 = JSONObject("""{"gclid": "abcde", "is_deeplink_gclid": true}""")
157+
158+
referringUrlUtility.parseReferringURL(url1)
159+
val params1 = referringUrlUtility.getURLQueryParamsForRequest(openServerRequest())
160+
assertTrue(areJSONObjectsEqual(expected1, params1))
161+
162+
referringUrlUtility.parseReferringURL(url2)
163+
val params2 = referringUrlUtility.getURLQueryParamsForRequest(openServerRequest())
164+
assertTrue(areJSONObjectsEqual(expected2, params2))
165+
}
166+
167+
@Test
168+
fun testCheckForAndMigrateOldGclid() {
169+
PrefHelper.getInstance(Branch.getInstance().applicationContext).setReferringUrlQueryParameters(null);
170+
val expected = JSONObject("""{"gclid": "12345", "is_deeplink_gclid": false}""")
171+
172+
PrefHelper.getInstance(Branch.getInstance().applicationContext).referrerGclid = "12345"
173+
PrefHelper.getInstance(Branch.getInstance().applicationContext).referrerGclidValidForWindow = 2592000;
174+
175+
val utility = ReferringUrlUtility(PrefHelper.getInstance(Branch.getInstance().applicationContext))
176+
val params = utility.getURLQueryParamsForRequest(openServerRequest())
177+
178+
assertTrue(areJSONObjectsEqual(expected, params))
179+
}
180+
181+
//Helper functions
182+
fun areJSONObjectsEqual(json1: JSONObject, json2: JSONObject): Boolean {
183+
if (json1.length() != json2.length()) return false
184+
185+
for (keyAny in json1.keys()) {
186+
val key = keyAny as String
187+
if (!json2.has(key) || json1[key] != json2[key]) {
188+
return false
189+
}
190+
}
191+
192+
return true
193+
}
194+
}

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

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,6 @@ protected static void processReferrerInfo(Context context, String rawReferrerStr
6666
BranchPreinstall.setBranchPreInstallGoogleReferrer(context, referrerMap);
6767
}
6868

69-
if(referrerMap.containsKey(Defines.Jsonkey.ReferrerExtraGclidParam.getKey())){
70-
prefHelper.setReferrerGclid(referrerMap.get(Defines.Jsonkey.ReferrerExtraGclidParam.getKey()));
71-
}
7269
} catch (UnsupportedEncodingException e) {
7370
e.printStackTrace();
7471
} catch (IllegalArgumentException e) {

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3054,6 +3054,7 @@ private void extractExternalUriAndIntentExtras(Uri data, Activity activity) {
30543054
if (extrasJson.length() > 0) {
30553055
prefHelper_.setExternalIntentExtra(extrasJson.toString());
30563056
}
3057+
30573058
}
30583059
}
30593060
} catch (Exception ignore) {

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,10 @@ public enum Jsonkey {
1616
GoogleSearchInstallReferrer("google_search_install_referrer"),
1717
GooglePlayInstallReferrer("install_referrer_extras"),
1818
ClickedReferrerTimeStamp("clicked_referrer_ts"),
19-
ReferrerExtraGclidParam("gclid"), //The parameter that is passed in the url
19+
Gclid("gclid"), //The parameter that is passed in the url
20+
IsDeeplinkGclid("is_deeplink_gclid"),
2021
ReferrerGclid("referrer_gclid"), //Key APIOpen expects for gclid in event
22+
ReferringUrlQueryParameters("bnc_referringUrlQueryParameters"),
2123
InstallBeginTimeStamp("install_begin_ts"),
2224
FaceBookAppLinkChecked("facebook_app_link_checked"),
2325
@Deprecated BranchLinkUsed("branch_used"), //use Defines.IntentKeys.BranchLinkUsed

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

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import android.os.Looper;
99
import android.text.TextUtils;
1010
import android.util.DisplayMetrics;
11+
import android.util.Log;
1112
import android.webkit.WebSettings;
1213
import android.webkit.WebView;
1314

@@ -17,6 +18,8 @@
1718
import static android.content.Context.UI_MODE_SERVICE;
1819
import static io.branch.referral.PrefHelper.NO_STRING_VALUE;
1920

21+
import java.util.Iterator;
22+
2023
/**
2124
* <p>
2225
* Class for handling the device params with Branch server requests. responsible for capturing device info and updating
@@ -222,15 +225,6 @@ void updateRequestWithV2Params(ServerRequest serverRequest, PrefHelper prefHelpe
222225
*/
223226
void updateRequestWithParamsAllEvents(ServerRequest serverRequest, PrefHelper prefHelper, JSONObject requestObj){
224227
try {
225-
// For install events, referrer GCLID is already contained in `install_referrer_extras`
226-
// Otherwise, for all other v1 and v2 events, add referrer_gclid to top level
227-
if (!(serverRequest instanceof ServerRequestRegisterInstall)) {
228-
String gclid = prefHelper.getReferrerGclid();
229-
if (gclid != null && !gclid.equals(NO_STRING_VALUE)) {
230-
requestObj.put(Defines.Jsonkey.ReferrerGclid.getKey(), gclid);
231-
}
232-
}
233-
234228
requestObj.put(Defines.Jsonkey.Debug.getKey(), Branch.isDeviceIDFetchDisabled());
235229
}
236230
catch (JSONException ignore){

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

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,8 @@ public class PrefHelper {
126126
static final String KEY_AD_NETWORK_CALLOUTS_DISABLED = "bnc_ad_network_callouts_disabled";
127127

128128
static final String KEY_RANDOMLY_GENERATED_UUID = "bnc_randomly_generated_uuid";
129+
130+
static final String KEY_REFERRING_URL_QUERY_PARAMETERS = "bnc_referringUrlQueryParameters";
129131
static final String KEY_ANON_ID = "bnc_anon_id";
130132

131133
/**
@@ -723,6 +725,33 @@ public String getAppStoreSource(){
723725
return getString(KEY_APP_STORE_SOURCE);
724726
}
725727

728+
/**
729+
* Sets the referring URL query parameters.
730+
* @param referringUrlQueryParameters
731+
*/
732+
public void setReferringUrlQueryParameters(JSONObject referringUrlQueryParameters) {
733+
setString(KEY_REFERRING_URL_QUERY_PARAMETERS, String.valueOf(referringUrlQueryParameters));
734+
}
735+
736+
/**
737+
* Returns the referring URL query parameters.
738+
* @return
739+
*/
740+
public JSONObject getReferringURLQueryParameters() {
741+
742+
String string = getString(KEY_REFERRING_URL_QUERY_PARAMETERS);
743+
JSONObject params = new JSONObject();
744+
try {
745+
params = new JSONObject(string);
746+
}
747+
catch (JSONException e) {
748+
e.printStackTrace();
749+
//TODO: Log e with Prefhelper.Error
750+
}
751+
752+
return params;
753+
}
754+
726755
/**
727756
* Sets the referrer Google Click ID with an expiration date computed by time set + expiration window
728757
* @param referrerGclid
@@ -774,6 +803,10 @@ public String getReferrerGclid(){
774803
return gclid;
775804
}
776805

806+
public void clearGclid() {
807+
removePrefValue(KEY_GCLID_JSON_OBJECT);
808+
}
809+
777810
/**
778811
* Sets the GCLID expiration window in milliseconds
779812
* @param window

0 commit comments

Comments
 (0)