Skip to content

Commit 571403a

Browse files
uc-diogoNoé Fernández
andauthored
2.7.6
Co-authored-by: Noé Fernández <[email protected]>
1 parent 2835cb6 commit 571403a

26 files changed

+311
-240
lines changed

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,15 @@
11
[Release Notes](https://docs.usercentrics.com/cmp_in_app_sdk/latest/about/history/)
2+
### 2.7.6
3+
4+
## Improvements
5+
6+
* Major improvements to main thread use.
7+
8+
## Resolved Issues
9+
10+
* [Android] Resolve NPE crash happening in edge cases.
11+
* Stability improvements.
12+
213
### 2.7.5
314

415
## Improvements

android/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
def usercentrics_version = "2.7.5"
1+
def usercentrics_version = "2.7.6"
22
version usercentrics_version
33

44
buildscript {

android/src/androidTest/java/com/usercentrics/reactnativemodule/RNUsercentricsModuleTest.kt

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,7 @@ package com.usercentrics.reactnativemodule
22

33
import androidx.test.ext.junit.runners.AndroidJUnit4
44
import androidx.test.platform.app.InstrumentationRegistry
5-
import com.facebook.react.bridge.JavaOnlyMap
6-
import com.facebook.react.bridge.ReactApplicationContext
7-
import com.facebook.react.bridge.WritableArray
8-
import com.facebook.react.bridge.WritableMap
5+
import com.facebook.react.bridge.*
96
import com.facebook.soloader.SoLoader
107
import com.usercentrics.reactnativemodule.api.FakeUsercentricsProxy
118
import com.usercentrics.reactnativemodule.fake.FakePromise
@@ -42,6 +39,26 @@ class RNUsercentricsModuleTest {
4239
putInt("networkMode", 1)
4340
}
4441

42+
private val bannerSettingsMap = mapOf(
43+
"variant" to null,
44+
"firstLayerStyleSettings" to mapOf(
45+
"layout" to "POPUP_CENTER",
46+
),
47+
"secondLayerStyleSettings" to mapOf(
48+
"showCloseButton" to true,
49+
),
50+
"generalStyleSettings" to null
51+
)
52+
53+
private val expectedBannerSettings = BannerSettings(
54+
firstLayerStyleSettings = FirstLayerStyleSettings(
55+
layout = UsercentricsLayout.Popup(
56+
PopupPosition.CENTER
57+
)
58+
),
59+
secondLayerStyleSettings = SecondLayerStyleSettings(showCloseButton = true),
60+
)
61+
4562
private val usercentricsConsentHistoryEntries = listOf(
4663
UsercentricsConsentHistoryEntry(
4764
status = false,
@@ -611,4 +628,26 @@ class RNUsercentricsModuleTest {
611628

612629
assertEquals(1, usercentricsProxy.resetCount)
613630
}
631+
632+
@Test
633+
fun testShowFirstLayer() {
634+
val usercentricsProxy = FakeUsercentricsProxy()
635+
val contextMock = mockk<ReactApplicationContext>(relaxed = true)
636+
val module = RNUsercentricsModule(contextMock, usercentricsProxy)
637+
val promise = FakePromise()
638+
module.showFirstLayer(bannerSettingsMap.toWritableMap(), promise)
639+
promise.await()
640+
assertEquals(expectedBannerSettings, usercentricsProxy.showFirstLayerBannerSettings)
641+
}
642+
643+
@Test
644+
fun testShowSecondLayer() {
645+
val usercentricsProxy = FakeUsercentricsProxy()
646+
val contextMock = mockk<ReactApplicationContext>(relaxed = true)
647+
val module = RNUsercentricsModule(contextMock, usercentricsProxy)
648+
val promise = FakePromise()
649+
module.showSecondLayer(bannerSettingsMap.toWritableMap(), promise)
650+
promise.await()
651+
assertEquals(expectedBannerSettings, usercentricsProxy.showSecondLayerBannerSettings)
652+
}
614653
}

android/src/androidTest/java/com/usercentrics/reactnativemodule/api/FakeUsercentricsProxy.kt

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,16 +49,17 @@ internal class FakeUsercentricsProxy(
4949
resetCount++
5050
}
5151

52-
var showFirstLayerLayout: UsercentricsLayout? = null
5352
var showFirstLayerBannerSettings: BannerSettings? = null
54-
var showFirstLayerStyle: FirstLayerStyleSettings? = null
5553

56-
override fun showFirstLayer(activity: Activity, layout: UsercentricsLayout, bannerSettings: BannerSettings?, promise: Promise) {
57-
this.showFirstLayerLayout = layout
54+
override fun showFirstLayer(activity: Activity, bannerSettings: BannerSettings?, promise: Promise) {
5855
this.showFirstLayerBannerSettings = bannerSettings
59-
this.showFirstLayerStyle = bannerSettings?.firstLayerStyleSettings
56+
promise.resolve(null)
6057
}
6158

59+
var showSecondLayerBannerSettings: BannerSettings? = null
60+
6261
override fun showSecondLayer(activity: Activity, bannerSettings: BannerSettings?, promise: Promise) {
62+
this.showSecondLayerBannerSettings = bannerSettings
63+
promise.resolve(null)
6364
}
6465
}

android/src/androidTest/java/com/usercentrics/reactnativemodule/fake/FakePromise.kt

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,22 @@ package com.usercentrics.reactnativemodule.fake
22

33
import com.facebook.react.bridge.Promise
44
import com.facebook.react.bridge.WritableMap
5+
import java.util.concurrent.CountDownLatch
56

6-
internal class FakePromise: Promise {
7+
internal class FakePromise : Promise {
78

89
var resolveValue: Any? = null
910
var rejectThrowable: Throwable? = null
1011

12+
val lock = CountDownLatch(1)
13+
14+
fun await() {
15+
lock.await()
16+
}
17+
1118
override fun resolve(value: Any?) {
1219
this.resolveValue = value
20+
lock.countDown()
1321
}
1422

1523
override fun reject(code: String?, message: String?) {

android/src/main/java/com/usercentrics/reactnativeusercentrics/RNUsercentricsModule.kt

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ internal class RNUsercentricsModule(
1616

1717
@ReactMethod
1818
fun configure(options: ReadableMap) {
19-
val usercentricsOptions = options.usercentricsOptionsFromMap() ?: return
19+
val usercentricsOptions = options.usercentricsOptionsFromMap()
2020
usercentricsProxy.initialize(reactApplicationContext, usercentricsOptions)
2121
}
2222

@@ -35,10 +35,8 @@ internal class RNUsercentricsModule(
3535
try {
3636
val assetManager = currentActivity!!.assets
3737

38-
val layout = options.getString("layout")!!.usercentricsLayoutFromEnumString()
39-
val bannerSettings =
40-
options.getMap("bannerSettings")?.bannerSettingsFromMap(assetManager)
41-
usercentricsProxy.showFirstLayer(currentActivity!!, layout, bannerSettings, promise)
38+
val bannerSettings = options.bannerSettingsFromMap(assetManager)
39+
usercentricsProxy.showFirstLayer(currentActivity!!, bannerSettings, promise)
4240

4341
} catch (e: Exception) {
4442
promise.reject(e)
@@ -52,8 +50,7 @@ internal class RNUsercentricsModule(
5250
try {
5351
val assetManager = currentActivity!!.assets
5452

55-
val bannerSettings =
56-
options.getMap("bannerSettings")?.bannerSettingsFromMap(assetManager)
53+
val bannerSettings = options.bannerSettingsFromMap(assetManager)
5754
usercentricsProxy.showSecondLayer(currentActivity!!, bannerSettings, promise)
5855
} catch (e: Exception) {
5956
promise.reject(e)

android/src/main/java/com/usercentrics/reactnativeusercentrics/api/UsercentricsProxy.kt

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,12 @@ interface UsercentricsProxy {
1212
val instance: UsercentricsSDK
1313

1414
fun initialize(context: Context, options: UsercentricsOptions)
15-
fun isReady(onSuccess: (UsercentricsReadyStatus) -> Unit, onFailure: (UsercentricsError) -> Unit)
16-
fun showFirstLayer(activity: Activity, layout: UsercentricsLayout, bannerSettings: BannerSettings?, promise: Promise)
15+
fun isReady(
16+
onSuccess: (UsercentricsReadyStatus) -> Unit,
17+
onFailure: (UsercentricsError) -> Unit
18+
)
19+
20+
fun showFirstLayer(activity: Activity, bannerSettings: BannerSettings?, promise: Promise)
1721
fun showSecondLayer(activity: Activity, bannerSettings: BannerSettings?, promise: Promise)
1822
fun reset()
1923
}
@@ -31,15 +35,26 @@ internal class UsercentricsProxyImpl : UsercentricsProxy {
3135
}
3236
}
3337

34-
override fun isReady(onSuccess: (UsercentricsReadyStatus) -> Unit, onFailure: (UsercentricsError) -> Unit) = Usercentrics.isReady(onSuccess, onFailure)
38+
override fun isReady(
39+
onSuccess: (UsercentricsReadyStatus) -> Unit,
40+
onFailure: (UsercentricsError) -> Unit
41+
) = Usercentrics.isReady(onSuccess, onFailure)
3542

36-
override fun showFirstLayer(activity: Activity, layout: UsercentricsLayout, bannerSettings: BannerSettings?, promise: Promise) {
37-
UsercentricsBanner(activity, bannerSettings).showFirstLayer(layout) {
43+
override fun showFirstLayer(
44+
activity: Activity,
45+
bannerSettings: BannerSettings?,
46+
promise: Promise,
47+
) {
48+
UsercentricsBanner(activity, bannerSettings).showFirstLayer {
3849
promise.resolve(it?.toWritableMap())
3950
}
4051
}
4152

42-
override fun showSecondLayer(activity: Activity, bannerSettings: BannerSettings?, promise: Promise) {
53+
override fun showSecondLayer(
54+
activity: Activity,
55+
bannerSettings: BannerSettings?,
56+
promise: Promise,
57+
) {
4358
UsercentricsBanner(activity, bannerSettings).showSecondLayer {
4459
promise.resolve(it?.toWritableMap())
4560
}

android/src/main/java/com/usercentrics/reactnativeusercentrics/extensions/FirstLayerOptionsExtensions.kt renamed to android/src/main/java/com/usercentrics/reactnativeusercentrics/extensions/BannerSettingsExtensions.kt

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@ import androidx.annotation.ColorInt
66
import com.facebook.react.bridge.ReadableMap
77
import com.usercentrics.sdk.*
88

9-
internal fun String.usercentricsLayoutFromEnumString(): UsercentricsLayout {
9+
internal fun String.usercentricsLayoutFromEnumString(): UsercentricsLayout? {
1010
return when (this) {
1111
"FULL" -> UsercentricsLayout.Full
1212
"SHEET" -> UsercentricsLayout.Sheet
1313
"POPUP_BOTTOM" -> UsercentricsLayout.Popup(PopupPosition.BOTTOM)
1414
"POPUP_CENTER" -> UsercentricsLayout.Popup(PopupPosition.CENTER)
15-
else -> throw IllegalArgumentException("Invalid layout: $this")
15+
else -> null
1616
}
1717
}
1818

@@ -22,8 +22,12 @@ internal fun ReadableMap.bannerSettingsFromMap(assetManager: AssetManager): Bann
2222
val rawGeneralStyleSettings = getMap("generalStyleSettings")
2323

2424
return BannerSettings(
25-
firstLayerStyleSettings = rawFirstLayerStyleSettings?.firstLayerStyleSettingsFromMap(assetManager),
26-
secondLayerStyleSettings = rawSecondLayerStyleSettings?.secondLayerStyleSettingsFromMap(assetManager),
25+
firstLayerStyleSettings = rawFirstLayerStyleSettings?.firstLayerStyleSettingsFromMap(
26+
assetManager
27+
),
28+
secondLayerStyleSettings = rawSecondLayerStyleSettings?.secondLayerStyleSettingsFromMap(
29+
assetManager
30+
),
2731
generalStyleSettings = rawGeneralStyleSettings?.generalStyleSettingsFromMap(assetManager),
2832
)
2933
}
@@ -35,6 +39,7 @@ internal fun ReadableMap.bannerLogoFromMap(): UsercentricsImage? {
3539

3640
internal fun ReadableMap.firstLayerStyleSettingsFromMap(assetManager: AssetManager): FirstLayerStyleSettings {
3741
return FirstLayerStyleSettings(
42+
layout = getString("layout")?.usercentricsLayoutFromEnumString(),
3843
headerImage = getMap("headerImage")?.headerImageFromMap(),
3944
title = getMap("title")?.titleFromMap(assetManager),
4045
message = getMap("message")?.messageFromMap(assetManager),

android/src/main/java/com/usercentrics/reactnativeusercentrics/extensions/CCPADataExtensions.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import com.usercentrics.ccpa.CCPAData
55

66
internal fun CCPAData.serialize(): WritableMap {
77
return mapOf(
8-
"uspString" to toUSPString(),
8+
"uspString" to uspString,
99
"version" to version,
1010
"noticeGiven" to noticeGiven,
1111
"optedOut" to optedOut,

android/src/main/java/com/usercentrics/reactnativeusercentrics/extensions/ReadableMapExtensions.kt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ import com.facebook.react.bridge.Arguments
44
import com.facebook.react.bridge.ReadableMap
55
import com.facebook.react.bridge.WritableArray
66
import com.facebook.react.bridge.WritableMap
7-
import com.usercentrics.sdk.UsercentricsOptions
8-
import com.usercentrics.sdk.models.common.UsercentricsLoggerLevel
97

108
internal fun ReadableMap.getIntOrNull(key: String): Int? {
119
return if (hasKey(key) && !isNull(key)) {

0 commit comments

Comments
 (0)