Skip to content

Commit eec224d

Browse files
authored
Merge pull request #9 from Optable/issue-8
Explicitly support an optional PPID in identify()
2 parents 11cd712 + fda2e22 commit eec224d

4 files changed

Lines changed: 61 additions & 12 deletions

File tree

DemoApp/DemoAppKotlin/app/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ android {
1515
minSdkVersion 16
1616
targetSdkVersion 29
1717

18+
// Here we get version code and version name from latest git release tags:
1819
versionCode versioning.getVersionCode()
1920
versionName versioning.getVersionName(false)
2021
archivesBaseName = "optable-android-sdk-demo-kotlin"

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,10 @@ import android.util.Log
8181

8282
val emailString = "some.email@address.com"
8383
val sendGoogleAdIDBoolean = true
84+
val ppid = "my-id-123"
8485

8586
MainActivity.OPTABLE!!
86-
.identify(emailString, sendGoogleAdIDBoolean)
87+
.identify(emailString, sendGoogleAdIDBoolean, ppid)
8788
.observe(viewLifecycleOwner, Observer
8889
{ result ->
8990
if (result.status == OptableSDK.Status.SUCCESS) {
@@ -96,7 +97,7 @@ MainActivity.OPTABLE!!
9697
})
9798
```
9899

99-
The SDK `identify()` method will asynchronously connect to the configured sandbox and send IDs for resolution. You can register an observer to understand successful completion or errors.
100+
The SDK `identify()` method will asynchronously connect to the configured sandbox and send IDs for resolution. The second (`sendGoogleAdIDBoolean`) and third (`ppid`) arguments to `identify()` are optional. You can register an observer to understand successful completion or errors.
100101

101102
> :warning: **Client-Side Email Hashing**: The SDK will compute the SHA-256 hash of the Email address on the client-side and send the hashed value to the sandbox. The Email address is **not** sent by the device in plain text.
102103

android_sdk/src/main/java/co/optable/android_sdk/OptableSDK.kt

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -124,28 +124,33 @@ class OptableSDK(context: Context, host: String, app: String, insecure: Boolean
124124
}
125125

126126
/*
127-
* identify(email, gaid?) calls the Optable Sandbox "identify" API, passing it the SHA-256 of
128-
* the caller-provided 'email' and, when specified via the 'gaid' Boolean, the Google
129-
* Advertising ID of the device.
127+
* identify(email, gaid?, ppid?) calls the Optable Sandbox "identify" API, passing it the
128+
* SHA-256 of the caller-provided 'email' and, when specified via the 'gaid' Boolean, the
129+
* Google Advertising ID of the device. If the 'ppid' String is specified, it will also be
130+
* sent for identity resolution.
130131
*
131-
* It is asynchronous, so the caller may call observe() on the returned LiveData and expect
132+
* The function is async, so the caller may call observe() on the returned LiveData and expect
132133
* an instance of Response<OptableIdentifyResponse> in the result. Success can be checked by
133134
* comparing result.status to OptableSDK.Status.SUCCESS. Note that result.data!! will point
134135
* to an empty HashMap on success, and can therefore be ignored.
135136
*/
136-
fun identify(email: String, gaid: Boolean? = false):
137+
fun identify(email: String, gaid: Boolean? = false, ppid: String? = null):
137138
LiveData<Response<OptableIdentifyResponse>>
138139
{
139140
var idList: OptableIdentifyInput = listOf()
140141

141142
if (!TextUtils.isEmpty(email) &&
142143
android.util.Patterns.EMAIL_ADDRESS.matcher(email).matches())
143144
{
144-
idList += "e:" + Companion.eid(email)
145+
idList += Companion.eid(email)
145146
}
146147

147148
if (gaid!! && this.client.hasGAID()) {
148-
idList += "g:" + this.client.GAID()
149+
idList += Companion.gaid(this.client.GAID()!!)
150+
}
151+
152+
if ((ppid != null) && (ppid.length > 0)) {
153+
idList += Companion.cid(ppid)
149154
}
150155

151156
return this.identify(idList)
@@ -189,12 +194,26 @@ class OptableSDK(context: Context, host: String, app: String, insecure: Boolean
189194

190195
companion object {
191196
/*
192-
* eid(email) is a helper that returns SHA256(downcase(email))
197+
* eid(email) is a helper that returns type-prefixed SHA256(downcase(email))
193198
*/
194199
fun eid(email: String): String {
195-
return MessageDigest.getInstance("SHA-256")
200+
return "e:" + MessageDigest.getInstance("SHA-256")
196201
.digest(email.toLowerCase().trim().toByteArray())
197202
.fold("", { str, it -> str + "%02x".format(it) })
198203
}
204+
205+
/*
206+
* gaid(gaid) is a helper that returns the type-prefixed Google Advertising ID
207+
*/
208+
fun gaid(gaid: String): String {
209+
return "g:" + gaid.toLowerCase().trim()
210+
}
211+
212+
/*
213+
* cid(ppid) is a helper that returns custom type-prefixed origin-provided PPID
214+
*/
215+
fun cid(ppid: String): String {
216+
return "c:" + ppid.trim()
217+
}
199218
}
200219
}

android_sdk/src/test/java/co/optable/android_sdk/OptableSDKUnitTest.kt

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import org.junit.Assert.*
1313
class OptableSDKUnitTest {
1414
@Test
1515
fun eid_isCorrect() {
16-
val expected = "a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3"
16+
val expected = "e:a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3"
1717

1818
assertEquals(expected, OptableSDK.eid("123"))
1919
assertEquals(expected, OptableSDK.eid(" 123"))
@@ -33,4 +33,32 @@ class OptableSDKUnitTest {
3333
assertEquals(eid, OptableSDK.eid(var3))
3434
assertEquals(eid, OptableSDK.eid(var4))
3535
}
36+
37+
@Test
38+
fun gaid_isCorrectAndIgnoresCase() {
39+
val expected = "g:38400000-8cf0-11bd-b23e-10b96e40000d"
40+
41+
assertEquals(expected, OptableSDK.gaid("38400000-8cf0-11bd-b23e-10b96e40000d"))
42+
assertEquals(expected, OptableSDK.gaid(" 38400000-8cf0-11bd-b23e-10b96e40000d"))
43+
assertEquals(expected, OptableSDK.gaid("38400000-8cf0-11bd-b23e-10b96e40000d "))
44+
assertEquals(expected, OptableSDK.gaid(" 38400000-8cf0-11bd-b23e-10b96e40000d "))
45+
assertEquals(expected, OptableSDK.gaid("38400000-8CF0-11BD-B23E-10B96E40000D"))
46+
}
47+
48+
@Test
49+
fun cid_isCorrect() {
50+
val expected = "c:FooBarBAZ-01234#98765.!!!"
51+
52+
assertEquals(expected, OptableSDK.cid("FooBarBAZ-01234#98765.!!!"))
53+
assertEquals(expected, OptableSDK.cid(" FooBarBAZ-01234#98765.!!!"))
54+
assertEquals(expected, OptableSDK.cid("FooBarBAZ-01234#98765.!!! "))
55+
assertEquals(expected, OptableSDK.cid(" FooBarBAZ-01234#98765.!!! "))
56+
}
57+
58+
@Test
59+
fun cid_isCaseSensitive() {
60+
val unexpected = "c:FooBarBAZ-01234#98765.!!!"
61+
62+
assertNotEquals(unexpected, OptableSDK.cid("foobarBAZ-01234#98765.!!!"))
63+
}
3664
}

0 commit comments

Comments
 (0)