From ca9bde580d778138cddf280e4273939494ca8c97 Mon Sep 17 00:00:00 2001 From: "Merlin (they/them)" <421960+merlinpatt@users.noreply.github.com> Date: Fri, 5 Apr 2024 10:42:00 -0400 Subject: [PATCH] Use localStorage for deviceId --- library/build.gradle | 2 +- .../paypal/messages/io/LocalStorageTest.kt | 17 ++++++++ .../com/paypal/messages/io/LocalStorage.kt | 19 ++++++++- .../java/com/paypal/messages/logger/Logger.kt | 40 ++++++++++--------- 4 files changed, 57 insertions(+), 21 deletions(-) diff --git a/library/build.gradle b/library/build.gradle index ec57174f..36980b02 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -93,7 +93,7 @@ preBuild.doFirst { ignoreFilesOnBuild } -tasks.withType(Test) { +tasks.withType(Test).configureEach { useJUnitPlatform() } diff --git a/library/src/androidTest/java/com/paypal/messages/io/LocalStorageTest.kt b/library/src/androidTest/java/com/paypal/messages/io/LocalStorageTest.kt index 4d6ff446..55e21825 100644 --- a/library/src/androidTest/java/com/paypal/messages/io/LocalStorageTest.kt +++ b/library/src/androidTest/java/com/paypal/messages/io/LocalStorageTest.kt @@ -5,6 +5,8 @@ import android.content.SharedPreferences import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.platform.app.InstrumentationRegistry import org.junit.Assert.assertEquals +import org.junit.Assert.assertNotNull +import org.junit.Assert.assertTrue import org.junit.Before import org.junit.Test import org.junit.runner.RunWith @@ -114,4 +116,19 @@ class LocalStorageTest { val actualHashState = localStorage.getMerchantHashState() assertEquals(LocalStorage.State.CACHE_DISABLED, actualHashState) } + + @Test + fun testDeviceId() { + val localStorage = LocalStorage(context) + val deviceIdFirstRetrieval = localStorage.deviceId + + assertNotNull(deviceIdFirstRetrieval) + assertTrue(deviceIdFirstRetrieval != "") + + val deviceIdSecondRetrieval = localStorage.deviceId + assertEquals(deviceIdFirstRetrieval, deviceIdSecondRetrieval) + + val deviceIdThirdRetrieval = localStorage.deviceId + assertEquals(deviceIdFirstRetrieval, deviceIdThirdRetrieval) + } } diff --git a/library/src/main/java/com/paypal/messages/io/LocalStorage.kt b/library/src/main/java/com/paypal/messages/io/LocalStorage.kt index e5fb6c2c..fee9cc6b 100644 --- a/library/src/main/java/com/paypal/messages/io/LocalStorage.kt +++ b/library/src/main/java/com/paypal/messages/io/LocalStorage.kt @@ -3,8 +3,9 @@ package com.paypal.messages.io import android.content.Context import com.google.gson.Gson import com.paypal.messages.utils.LogCat +import java.util.UUID -class LocalStorage constructor(context: Context) { +class LocalStorage(context: Context) { private val TAG = this::class.java.simpleName private val key = "PayPalUpstreamLocalStorage" private val sharedPrefs = context.getSharedPreferences(key, Context.MODE_PRIVATE) @@ -15,6 +16,7 @@ class LocalStorage constructor(context: Context) { enum class StorageKeys(private val keyName: String) { MERCHANT_HASH_DATA("merchantProfileHashData"), TIMESTAMP("timestamp"), + DEVICE_ID("deviceId"), ; override fun toString(): String { @@ -22,6 +24,21 @@ class LocalStorage constructor(context: Context) { } } + val deviceId: String + get() { + val deviceId = sharedPrefs.getString("${StorageKeys.DEVICE_ID}", null) + return if (deviceId == null) { + val newDeviceId = UUID.randomUUID().toString() + val editor = sharedPrefs.edit() + LogCat.debug(TAG, "No device ID found, setting device ID to: $newDeviceId") + editor.putString("${StorageKeys.DEVICE_ID}", newDeviceId) + editor.apply() + newDeviceId + } else { + deviceId + } + } + var merchantHashData: ApiHashData.Response? get() { val storage = sharedPrefs.getString("${StorageKeys.MERCHANT_HASH_DATA}", null) diff --git a/library/src/main/java/com/paypal/messages/logger/Logger.kt b/library/src/main/java/com/paypal/messages/logger/Logger.kt index 8ea5a509..e81dc007 100644 --- a/library/src/main/java/com/paypal/messages/logger/Logger.kt +++ b/library/src/main/java/com/paypal/messages/logger/Logger.kt @@ -1,7 +1,6 @@ package com.paypal.messages.logger import android.content.Context -import android.provider.Settings import com.paypal.messages.config.GlobalAnalytics import com.paypal.messages.io.Api import com.paypal.messages.io.LocalStorage @@ -47,15 +46,14 @@ class Logger private constructor() { private fun resetBasePayload(isInit: Boolean = false) { LogCat.debug(TAG, if (isInit) "initBasePayload" else "resetBasePayload") - val deviceId = GlobalAnalytics.deviceId val sessionId = GlobalAnalytics.sessionId this.payload = TrackingPayload( clientId = clientId, merchantId = null, partnerAttributionId = null, - // merchantProfileHash will be later defined by pulling from LocalStorage + // merchantProfileHash and deviceId will be later defined by pulling from LocalStorage merchantProfileHash = null, - deviceId = if (deviceId == "") Settings.Secure.ANDROID_ID else deviceId, + deviceId = "", sessionId = if (sessionId == "") uuidSessionId else sessionId, integrationName = GlobalAnalytics.integrationName, integrationVersion = GlobalAnalytics.integrationVersion, @@ -85,26 +83,30 @@ class Logger private constructor() { // If we have an active call, we need to pull the current payload and modify it // Check for an existing component payload for this component - val oldComponent = this.payload?.components?.find { it.instanceId == component.instanceId } + this.payload?.run { + val oldComponent = components.find { it.instanceId == component.instanceId } - if (oldComponent != null) { - val oldEvents = oldComponent.componentEvents - component.componentEvents.addAll(0, oldEvents) + if (oldComponent != null) { + val oldEvents = oldComponent.componentEvents + component.componentEvents.addAll(0, oldEvents) - val index = this.payload?.components?.indexOfFirst { it.instanceId == component.instanceId } + val index = components.indexOfFirst { it.instanceId == component.instanceId } - if (index != -1 && index != null) { - // Replace the old component payload with our newly created one - this.payload?.components?.set(index, component) + if (index != -1) { + // Replace the old component payload with our newly created one + components[index] = component + } + } + else { + // This will be the first instance for this specific component + components.add(component) } - } - else { - // This will be the first instance for this specific component - this.payload?.components?.add(component) - } - this.payload?.merchantProfileHash = LocalStorage(context).merchantHash - this.payload?.let { sendEvent(context, it) } + val localStorage = LocalStorage(context) + merchantProfileHash = localStorage.merchantHash + deviceId = if (GlobalAnalytics.deviceId == "") localStorage.deviceId else GlobalAnalytics.deviceId + sendEvent(context, this) + } } private var job: Job? = null