Skip to content

Commit

Permalink
useragent override and skipAdvertisingIdDetection (#17)
Browse files Browse the repository at this point in the history
* Improve unit tests for eidFromURI

* skipAdvertisingIdDetection and useragent override

- OptableSDK constructor now accepts a useragent String argument,
  null by default. When not null, disables WebView based user
  agent detection and overrides with provided value.

- OptableSDK constructor now accepts a skipAdvertisingIdDetection
  Boolean argument, false by default. When true, disables
  AdvertisingIdClient ad info detection which runs in a background
  coroutine. If the caller doesn't use the identify(email: String,
  gaid: Boolean, ppid: String) variant then ad ID detection is
  not needed and can be skipped.

- Document in README
  • Loading branch information
bmilekic authored Dec 9, 2020
1 parent 67281ed commit f37129c
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 8 deletions.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,18 @@ MainActivity.OPTABLE = OptableSDK(this, "sandbox.customer.com", "my-app", true)

However, since production sandboxes only listen to TLS traffic, the above is really only useful for developers of `optable-sandbox` running the sandbox locally for testing.

By default, the SDK detects the application user agent by sniffing `settings.userAgentString` from a `WebView`. The resulting user agent string is sent to your sandbox for analytics purposes. To disable this behavior, you can provide an optional fifth string parameter `useragent`, which allows you to set whatever user agent string you would like to send instead. For example, in Kotlin:

```kotlin
MainActivity.OPTABLE = OptableSDK(this, "sandbox.customer.com", "my-app", false, "custom-ua")
```

Finally, an optional sixth boolean parameter `skipAdvertisingIdDetection` can be used to skip any ID info detection from `AdvertisingIdClient` which by default runs in a background co-routine. Disabling ad ID detection means that the SDK will not be able to automatically obtain the Google Advertising ID. For example, to disable ad ID detection, in Kotlin:

```kotlin
MainActivity.OPTABLE = OptableSDK(this, "sandbox.customer.com", "my-app", false, null, true)
```

### Identify API

To associate a user device with an authenticated identifier such as an Email address, or with other known IDs such as the Google Advertising ID, or even your own vendor or app level `PPID`, you can call the `identify` API as follows:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,9 @@ typealias OptableTargetingResponse = HashMap<String, List<String>>
* unique to the app across devices.
*/

class OptableSDK @JvmOverloads constructor(context: Context, host: String, app: String, insecure: Boolean = false) {
class OptableSDK @JvmOverloads constructor(context: Context, host: String, app: String, insecure: Boolean = false, useragent: String? = null, skipAdvertisingIdDetection: Boolean = false) {
val config = Config(host, app, insecure)
val client = Client(config, context)
val client = Client(config, context, useragent, skipAdvertisingIdDetection)

/*
* OptableSDK.Status lists all of the possible OptableSDK API result statuses.
Expand Down
16 changes: 11 additions & 5 deletions android_sdk/src/main/java/co/optable/android_sdk/core/Client.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ import okhttp3.*
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory

class Client(private val config: Config, private val context: Context) {
class Client(private val config: Config, private val context: Context, private val useragent: String?, private val skipAdvertisingIdDetection: Boolean) {
var gaid: String? = null
var gaidLAT: Boolean? = true

private val edgeService: EdgeService?
private val userAgent = this.userAgent()
private val storage = LocalStorage(this.config, this.context)
private var userAgent: String? = this.useragent

private class RequestInterceptor(private val userAgent: String, private val storage: LocalStorage): Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
Expand Down Expand Up @@ -59,10 +59,16 @@ class Client(private val config: Config, private val context: Context) {
}

init {
this.determineAdvertisingInfo()
if (!this.skipAdvertisingIdDetection) {
this.determineAdvertisingInfo()
}

if (this.userAgent == null) {
this.userAgent = this.userAgent()
}

val client = OkHttpClient.Builder()
.addInterceptor(RequestInterceptor(userAgent, storage))
.addInterceptor(RequestInterceptor(this.userAgent!!, storage))
.addInterceptor(ResponseInterceptor(storage))
.build()

Expand Down Expand Up @@ -122,7 +128,7 @@ class Client(private val config: Config, private val context: Context) {
}

fun GAID(): String? {
return gaid!!
return gaid
}

private fun userAgent(): String {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,29 @@ class OptableSDKUnitTest {
}

@Test
fun eidFromURI_returnsEmptyWhenOeidAbsent() {
fun eidFromURI_returnsEmptyWhenOeidAbsentFromQuerystr() {
val url = "http://some.domain.com/some/path?some=query&something=else"
val expected = ""

assertEquals(expected, OptableSDK.eidFromURI(Uri.parse(url)))
}

@Test
fun eidFromURI_returnsEmptyWhenQuerystrAbsent() {
val url = "http://some.domain.com/some/path"
val expected = ""

assertEquals(expected, OptableSDK.eidFromURI(Uri.parse(url)))
}

@Test
fun eidFromURI_returnsEmptyWhenInputEmptyString() {
val url = ""
val expected = ""

assertEquals(expected, OptableSDK.eidFromURI(Uri.parse(url)))
}

@Test
fun eidFromURI_expectsSHA256() {
val url = "http://some.domain.com/some/path?some=query&something=else&oeid=AAAAAAAa665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3&foo=bar&baz"
Expand Down

0 comments on commit f37129c

Please sign in to comment.