diff --git a/build.gradle b/build.gradle index 50f518b3e..06be3f5c2 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,7 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { - ext.kotlin_version = '1.9.25' + ext.kotlin_version = "2.1.21" repositories { google() @@ -23,7 +23,7 @@ plugins { id 'io.github.dryrum.replace-in-file' version '0.7.0' id 'io.github.dryrum.git-utils' version '0.7.0' id 'io.github.dryrum.bump-version-code' version '0.7.0' - id 'org.jetbrains.kotlin.plugin.serialization' version '2.0.21' + id 'org.jetbrains.kotlin.plugin.serialization' version "2.1.21" } allprojects { diff --git a/cmplibrary/build.gradle.kts b/cmplibrary/build.gradle.kts index 7931101ff..bbd4ce5e4 100644 --- a/cmplibrary/build.gradle.kts +++ b/cmplibrary/build.gradle.kts @@ -54,7 +54,7 @@ android { } dependencies { - implementation("com.sourcepoint:core:0.1.11") + implementation("com.sourcepoint:core:0.1.12-beta-3") implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.6.1") implementation("com.squareup.okhttp3:okhttp:4.12.0") implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.3") diff --git a/cmplibrary/src/main/java/com/sourcepoint/cmplibrary/SpConsentLib.kt b/cmplibrary/src/main/java/com/sourcepoint/cmplibrary/SpConsentLib.kt index e1291ec6b..ea9abd66a 100644 --- a/cmplibrary/src/main/java/com/sourcepoint/cmplibrary/SpConsentLib.kt +++ b/cmplibrary/src/main/java/com/sourcepoint/cmplibrary/SpConsentLib.kt @@ -28,6 +28,7 @@ interface SpConsentLib { */ fun loadMessage(cmpViewId: Int) + // TODO: remove authId from loadMessages and move it to SpConfig in the next major release /** * Load the First Layer Message (FLM) * @param authId is used to get an already saved consent diff --git a/cmplibrary/src/main/java/com/sourcepoint/cmplibrary/legacy/TransferFromNativeSDK.kt b/cmplibrary/src/main/java/com/sourcepoint/cmplibrary/legacy/TransferFromNativeSDK.kt index c661ba731..a6fb7dc60 100644 --- a/cmplibrary/src/main/java/com/sourcepoint/cmplibrary/legacy/TransferFromNativeSDK.kt +++ b/cmplibrary/src/main/java/com/sourcepoint/cmplibrary/legacy/TransferFromNativeSDK.kt @@ -24,20 +24,17 @@ fun migrateLegacyToNewState( propertyId: Int ): State? { if (preferences.contains(LegacyLocalState.PREFS_KEY)) { - try { - val newState = LegacyState(preferences).toState(accountId, propertyId) - removeLegacyData(preferences) - return newState - } catch (_: Exception) { - return null - } - } else { - return null + val legacyState = LegacyState(preferences) + val newState = legacyState.toState(accountId, propertyId) + removeLegacyData(preferences) + return newState } + return null } fun removeLegacyData(preferences: SharedPreferences) { preferences.edit().apply { + remove(LegacyState.AUTH_ID_PREFS_KEY) remove(GDPRLegacyConsent.PREFS_KEY) remove(CCPALegacyConsent.PREFS_KEY) remove(USNatLegacyConsent.PREFS_KEY) @@ -57,6 +54,7 @@ fun removeLegacyData(preferences: SharedPreferences) { @Serializable data class LegacyState( + val authId: String? = null, val gdpr: GDPRLegacyConsent? = null, val usnat: USNatLegacyConsent? = null, val ccpa: CCPALegacyConsent? = null, @@ -70,24 +68,36 @@ data class LegacyState( val localState: JsonObject? = null, val nonKeyedLocalState: JsonObject? = null ) { + companion object { + const val AUTH_ID_PREFS_KEY = "sp.gdpr.authId" + + private inline fun decodeWithLogging(jsonString: String, name: String): T? = runCatching { + json.decodeFromString(jsonString) + }.onFailure { e -> + println("Failed to decode $name: ${e.message}") + }.getOrNull() + } + constructor(sharedPrefs: SharedPreferences) : this( - gdpr = sharedPrefs.getString(GDPRLegacyConsent.PREFS_KEY, null)?.let { json.decodeFromString(it) }, - ccpa = sharedPrefs.getString(CCPALegacyConsent.PREFS_KEY, null)?.let { json.decodeFromString(it) }, - usnat = sharedPrefs.getString(USNatLegacyConsent.PREFS_KEY, null)?.let { json.decodeFromString(it) }, - metaData = sharedPrefs.getString(LegacyMetaData.PREFS_KEY, null)?.let { json.decodeFromString(it) }, + authId = sharedPrefs.getString(AUTH_ID_PREFS_KEY, null), + gdpr = sharedPrefs.getString(GDPRLegacyConsent.PREFS_KEY, null)?.let { decodeWithLogging(it, "GDPRLegacyConsent") }, + ccpa = sharedPrefs.getString(CCPALegacyConsent.PREFS_KEY, null)?.let { decodeWithLogging(it, "CCPALegacyConsent") }, + usnat = sharedPrefs.getString(USNatLegacyConsent.PREFS_KEY, null)?.let { decodeWithLogging(it, "USNatLegacyConsent") }, + metaData = sharedPrefs.getString(LegacyMetaData.PREFS_KEY, null)?.let { decodeWithLogging(it, "LegacyMetaData") }, gdprSampled = sharedPrefs.getBoolean(LegacyGDPRSampled.PREFS_KEY, false), usnatSampled = sharedPrefs.getBoolean(LegacyUSNATSampled.PREFS_KEY, false), ccpaSampled = sharedPrefs.getBoolean(LegacyCCPASampled.PREFS_KEY, false), gdprChildPmId = sharedPrefs.getString(LegacyGDPRChildPmId.PREFS_KEY, null), ccpaChildPmId = sharedPrefs.getString(LegacyCCPAChildPmId.PREFS_KEY, null), usnatChildPmId = sharedPrefs.getString(LegacyUSNATChildPmId.PREFS_KEY, null), - localState = sharedPrefs.getString(LegacyLocalState.PREFS_KEY, null)?.let { json.decodeFromString(it) }, - nonKeyedLocalState = sharedPrefs.getString(LegacyNonKeyedLocalState.PREFS_KEY, null)?.let { json.decodeFromString(it) } + localState = sharedPrefs.getString(LegacyLocalState.PREFS_KEY, null)?.let { decodeWithLogging(it, "LegacyLocalState") }, + nonKeyedLocalState = sharedPrefs.getString(LegacyNonKeyedLocalState.PREFS_KEY, null)?.let { decodeWithLogging(it, "LegacyNonKeyedLocalState") } ) fun toState(accountId: Int, propertyId: Int) = State( accountId = accountId, propertyId = propertyId, + authId = authId, gdpr = State.GDPRState( consents = gdpr?.toCore() ?: GDPRConsent(), childPmId = gdprChildPmId, diff --git a/integration_tests/src/androidTest/java/com/sourcepoint/cmplibrary/legacy/LegacyStateTest.kt b/integration_tests/src/androidTest/java/com/sourcepoint/cmplibrary/legacy/LegacyStateTest.kt index 5de7e4cce..6faedf3f4 100644 --- a/integration_tests/src/androidTest/java/com/sourcepoint/cmplibrary/legacy/LegacyStateTest.kt +++ b/integration_tests/src/androidTest/java/com/sourcepoint/cmplibrary/legacy/LegacyStateTest.kt @@ -106,7 +106,15 @@ class LegacyStateTest { @Test fun testMigratingLegacyStateDoesntThrowEvenWhenInvalid() { loadLegacySharedPrefs(preferences, faultyLegacySharedPrefsXML) + migrateLegacyToNewState(preferences, accountId, propertyId).assertNotNull() + preferences.getString(LegacyLocalState.PREFS_KEY, null).assertNull() + } + + @Test + fun testMigratingLegacyStateReturnsNullIfLegacyStateIsNotPresent() { + loadLegacySharedPrefs(preferences, sharedPrefsWithoutLegacyState) migrateLegacyToNewState(preferences, accountId, propertyId).assertNull() - preferences.getString(LegacyLocalState.PREFS_KEY, null).assertNotNull() + preferences.getString(LegacyLocalState.PREFS_KEY, null).assertNull() + preferences.getString("foo", null).assertEquals("bar") } } diff --git a/integration_tests/src/androidTest/java/com/sourcepoint/cmplibrary/legacy/SharedPrefsImporter.kt b/integration_tests/src/androidTest/java/com/sourcepoint/cmplibrary/legacy/SharedPrefsImporter.kt index fbdefc58b..be238f032 100644 --- a/integration_tests/src/androidTest/java/com/sourcepoint/cmplibrary/legacy/SharedPrefsImporter.kt +++ b/integration_tests/src/androidTest/java/com/sourcepoint/cmplibrary/legacy/SharedPrefsImporter.kt @@ -60,3 +60,9 @@ const val faultyLegacySharedPrefsXML = """{} """ + +const val sharedPrefsWithoutLegacyState = """ + + bar + +""" diff --git a/samples/metaapp/build.gradle.kts b/samples/metaapp/build.gradle.kts index 580345d9a..9565e82b6 100644 --- a/samples/metaapp/build.gradle.kts +++ b/samples/metaapp/build.gradle.kts @@ -72,11 +72,6 @@ android { sourceCompatibility = JavaVersion.VERSION_11 targetCompatibility = JavaVersion.VERSION_11 } - tasks { - withType { - kotlinOptions.jvmTarget = "11" - } - } testOptions { // JSONObject return null during unit tests @@ -89,10 +84,6 @@ android { // https://stackoverflow.com/questions/44751469/kotlin-extension-functions-suddenly-require-api-level-24/44752239 abortOnError = false } - - kotlinOptions { - jvmTarget = "11" - } } sqldelight {