Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 27 additions & 4 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
buildscript {
ext.kotlin_version = '1.8.10'
ext.kotlin_version = '2.0.20'
if (!project.hasProperty('version') || project.version.equals('unspecified')) {
project.version = '+'
}
Expand All @@ -9,16 +9,17 @@ buildscript {
mavenLocal()
mavenCentral()
}

dependencies {
classpath 'com.android.tools.build:gradle:7.4.1'
classpath 'com.android.tools.build:gradle:8.1.4'
classpath 'com.mparticle:android-kit-plugin:' + project.version
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}

plugins {
id "org.sonarqube" version "3.5.0.2730"
id "org.jlleitschuh.gradle.ktlint" version "11.2.0"
id "org.jlleitschuh.gradle.ktlint" version "13.0.0"
}

sonarqube {
Expand All @@ -30,5 +31,27 @@ sonarqube {
}

apply plugin: 'org.jlleitschuh.gradle.ktlint'
apply plugin: 'com.mparticle.kit'
apply plugin: 'kotlin-android'
apply plugin: 'com.mparticle.kit'

android {
namespace 'com.mparticle.kits.tune'
buildFeatures {
buildConfig = true
}
defaultConfig {
minSdkVersion 21
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = '17'
}
testOptions {
unitTests.all {
jvmArgs += ['--add-opens', 'java.base/java.lang=ALL-UNNAMED']
}
}
}
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
2 changes: 1 addition & 1 deletion src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<manifest package="com.mparticle.kits.tune"/>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"/>
49 changes: 28 additions & 21 deletions src/main/kotlin/com/mparticle/kits/TuneKit.kt
Original file line number Diff line number Diff line change
@@ -1,35 +1,39 @@
package com.mparticle.kits

import android.content.Context
import com.mparticle.AttributionError
import com.mparticle.AttributionResult
import com.mparticle.kits.KitIntegration
import com.mparticle.kits.mobileapptracker.MATDeeplinkListener
import com.mparticle.kits.KitIntegration.ApplicationStateListener
import com.mparticle.kits.mobileapptracker.MATDeferredDplinkr
import java.util.concurrent.atomic.AtomicBoolean
import com.mparticle.kits.KitUtils
import com.mparticle.kits.ReportingMessage
import com.mparticle.kits.mobileapptracker.MATUtils
import com.mparticle.kits.TuneKit
import com.mparticle.kits.KitUtils
import com.mparticle.kits.mobileapptracker.MATDeeplinkListener
import com.mparticle.kits.mobileapptracker.MATDeferredDplinkr
import com.mparticle.kits.mobileapptracker.MATUrlRequester
import com.mparticle.AttributionResult
import com.mparticle.AttributionError
import com.mparticle.kits.mobileapptracker.MATUtils
import java.util.concurrent.atomic.AtomicBoolean

/**
* Tune Kit implementing Tune's post-install deep-link feature. Different from other Kits, the Tune Kit
* does not actually wrap the full Tune SDK - only a small subset of classes required to query the Tune server
* for deep links that match the given user.
*/
class TuneKit : KitIntegration(), MATDeeplinkListener, ApplicationStateListener {
class TuneKit :
KitIntegration(),
MATDeeplinkListener,
ApplicationStateListener {
private var settingAdvertiserId: String? = null
private var settingConversionKey: String? = null
var packageName: String? = null
private var deepLinker: MATDeferredDplinkr? = null
private val listenerWaiting = AtomicBoolean(false)

override fun getName(): String = KIT_NAME

override fun onKitCreate(
settings: Map<String, String>,
context: Context
context: Context,
): List<ReportingMessage> {
if (MATUtils.firstInstall(getContext())) {
settingAdvertiserId = getSettings()[SETTING_ADVERTISER_ID]
Expand All @@ -38,11 +42,12 @@ class TuneKit : KitIntegration(), MATDeeplinkListener, ApplicationStateListener
if (KitUtils.isEmpty(packageName)) {
packageName = getContext().packageName
}
deepLinker = MATDeferredDplinkr.initialize(
settingAdvertiserId,
settingConversionKey,
packageName
)
deepLinker =
MATDeferredDplinkr.initialize(
settingAdvertiserId,
settingConversionKey,
packageName,
)
deepLinker?.listener = this
checkForAttribution()
}
Expand Down Expand Up @@ -73,17 +78,19 @@ class TuneKit : KitIntegration(), MATDeeplinkListener, ApplicationStateListener

override fun didReceiveDeeplink(deeplink: String?) {
listenerWaiting.set(false)
val result = AttributionResult()
.setLink(deeplink)
.setServiceProviderId(configuration.kitId)
val result =
AttributionResult()
.setLink(deeplink)
.setServiceProviderId(configuration.kitId)
kitManager.onResult(result)
}

override fun didFailDeeplink(error: String?) {
listenerWaiting.set(false)
val deepLinkError = AttributionError()
.setMessage(error)
.setServiceProviderId(configuration.kitId)
val deepLinkError =
AttributionError()
.setMessage(error)
.setServiceProviderId(configuration.kitId)
kitManager.onError(deepLinkError)
}

Expand All @@ -99,4 +106,4 @@ class TuneKit : KitIntegration(), MATDeeplinkListener, ApplicationStateListener
private const val SETTING_PACKAGE_NAME_OVERRIDE = "overridePackageName"
private const val KIT_NAME = "Tune"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ object MATConstants {

// MAT Android SDK version number
const val SDK_VERSION = "3.11.4"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@ package com.mparticle.kits.mobileapptracker

interface MATDeeplinkListener {
fun didReceiveDeeplink(deeplink: String?)

fun didFailDeeplink(error: String?)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,28 @@ class MATDeferredDplinkr private constructor() {
var conversionKey: String? = null
var packageName: String? = null
var googleAdvertisingId: String? = null
private set
private set

var googleAdTrackingLimited = 0

var androidId: String? = null
var userAgent: String? = null
var listener: MATDeeplinkListener? = null



fun setGoogleAdvertisingId(googleAdvertisingId: String?, isLATEnabled: Int) {
fun setGoogleAdvertisingId(
googleAdvertisingId: String?,
isLATEnabled: Int,
) {
dplinkr?.googleAdvertisingId = googleAdvertisingId
dplinkr?.googleAdTrackingLimited = isLATEnabled
}




fun checkForDeferredDeeplink(context: Context?, urlRequester: MATUrlRequester) {
Thread { // If advertiser ID, conversion key, or package name were not set, return
fun checkForDeferredDeeplink(
context: Context?,
urlRequester: MATUrlRequester,
) {
Thread {
// If advertiser ID, conversion key, or package name were not set, return
if (dplinkr?.advertiserId == null || dplinkr?.conversionKey == null || dplinkr?.packageName == null) {
if (listener != null) {
listener?.didFailDeeplink("Advertiser ID, conversion key, or package name not set")
Expand Down Expand Up @@ -58,11 +60,12 @@ class MATDeferredDplinkr private constructor() {
companion object {
@Volatile
private var dplinkr: MATDeferredDplinkr? = null

@Synchronized
fun initialize(
advertiserId: String?,
conversionKey: String?,
packageName: String?
packageName: String?,
): MATDeferredDplinkr? {
dplinkr = MATDeferredDplinkr()
dplinkr?.advertiserId = advertiserId
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ class MATUrlRequester {

// Construct deeplink endpoint url
val uri = Uri.Builder()
uri.scheme("https")
uri
.scheme("https")
.authority(dplinkr.advertiserId + "." + MATConstants.DEEPLINK_DOMAIN)
.appendPath("v1")
.appendPath("link.txt")
Expand All @@ -23,13 +24,12 @@ class MATUrlRequester {
.appendQueryParameter("package_name", dplinkr.packageName)
.appendQueryParameter(
"ad_id",
if (dplinkr.googleAdvertisingId != null) dplinkr.googleAdvertisingId else dplinkr.androidId
)
.appendQueryParameter("user_agent", dplinkr.userAgent)
if (dplinkr.googleAdvertisingId != null) dplinkr.googleAdvertisingId else dplinkr.androidId,
).appendQueryParameter("user_agent", dplinkr.userAgent)
if (dplinkr.googleAdvertisingId != null) {
uri.appendQueryParameter(
"google_ad_tracking_disabled",
dplinkr.googleAdTrackingLimited.toString()
dplinkr.googleAdTrackingLimited.toString(),
)
}
try {
Expand Down
19 changes: 15 additions & 4 deletions src/main/kotlin/com/mparticle/kits/mobileapptracker/MATUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ import android.webkit.WebSettings
import android.webkit.WebView
import com.mparticle.kits.KitUtils
import com.mparticle.kits.TuneKit
import java.io.*
import java.io.BufferedReader
import java.io.IOException
import java.io.InputStream
import java.io.InputStreamReader
import java.io.UnsupportedEncodingException
import java.lang.ref.WeakReference

object MATUtils {
Expand Down Expand Up @@ -38,7 +42,10 @@ object MATUtils {
/**
* Determine the device's user agent and set the corresponding field.
*/
fun calculateUserAgent(context: Context?, tuneKit: TuneKit) {
fun calculateUserAgent(
context: Context?,
tuneKit: TuneKit,
) {
val userAgent = System.getProperty("http.agent", "")
if (!KitUtils.isEmpty(userAgent)) {
tuneKit.setUserAgent(userAgent)
Expand Down Expand Up @@ -66,9 +73,13 @@ object MATUtils {
* Runnable for getting the WebView user agent
*/
@SuppressLint("NewApi")
private class GetWebViewUserAgent(context: Context?, tuneKit: TuneKit) : Runnable {
private class GetWebViewUserAgent(
context: Context?,
tuneKit: TuneKit,
) : Runnable {
private val weakContext: WeakReference<Context?>
private val tuneKit: TuneKit

override fun run() {
try {
Class.forName("android.os.AsyncTask") // prevents WebView from crashing on certain devices
Expand All @@ -93,4 +104,4 @@ object MATUtils {
this.tuneKit = tuneKit
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import org.mockito.Mockito

class TuneKitTests {
private val kit: KitIntegration
get() = TuneKit()
get() = TuneKit()

@Test
@Throws(Exception::class)
Expand Down Expand Up @@ -50,4 +50,4 @@ class TuneKitTests {
}
Assert.fail("$className not found as a known integration.")
}
}
}