@@ -39,6 +39,7 @@ import kotlinx.coroutines.launch
39
39
import kotlinx.coroutines.runBlocking
40
40
import kotlinx.coroutines.suspendCancellableCoroutine
41
41
import kotlinx.coroutines.sync.Mutex
42
+ import kotlinx.coroutines.sync.withLock
42
43
import kotlinx.coroutines.withContext
43
44
import java.util.UUID
44
45
import kotlin.coroutines.resume
@@ -109,9 +110,7 @@ internal object ApphudInternal {
109
110
internal var didRegisterCustomerAtThisLaunch = false
110
111
private var isNew = true
111
112
private lateinit var apiKey: ApiKey
112
- lateinit var deviceId: DeviceId
113
113
internal var fallbackMode = false
114
- internal lateinit var userId: UserId
115
114
internal lateinit var context: Context
116
115
internal val userRepository: UserRepository by lazy {
117
116
ServiceLocator .instance.userRepository
@@ -222,41 +221,33 @@ internal object ApphudInternal {
222
221
val cachedPlacements = if (ignoreCache || ! isValid || observerMode) null else readPlacementsFromCache()
223
222
val cachedGroups = if (isValid) readGroupsFromCache() else mutableListOf ()
224
223
val cachedDeviceId = ServiceLocator .instance.sharedPreferencesStorage.deviceId
225
- val cachedUserId = ServiceLocator .instance.sharedPreferencesStorage.userId
226
224
227
225
sdkLaunchedAt = System .currentTimeMillis()
228
226
229
227
val generatedUUID = UUID .randomUUID().toString()
230
228
231
- val newUserId =
232
- if (inputUserId.isNullOrBlank()) {
233
- cachedUserId ? : generatedUUID
234
- } else {
235
- inputUserId
236
- }
237
- val newDeviceId =
238
- if (inputDeviceId.isNullOrBlank()) {
239
- cachedDeviceId ? : generatedUUID
240
- } else {
241
- inputDeviceId
242
- }
243
-
244
- val credentialsChanged = cachedUserId != newUserId || cachedDeviceId != newDeviceId
229
+ val newUserId = if (inputUserId.isNullOrBlank()) {
230
+ cachedUser?.userId ? : generatedUUID
231
+ } else {
232
+ inputUserId
233
+ }
245
234
246
- if (credentialsChanged) {
247
- ServiceLocator .instance.sharedPreferencesStorage.userId = newUserId
248
- ServiceLocator .instance.sharedPreferencesStorage.deviceId = newDeviceId
235
+ val newDeviceId = if (inputDeviceId.isNullOrBlank()) {
236
+ cachedDeviceId ? : generatedUUID
237
+ } else {
238
+ inputDeviceId
249
239
}
250
240
241
+ val credentialsChanged = cachedUser?.userId != newUserId || cachedDeviceId != newDeviceId
242
+
251
243
/* *
252
244
* We cannot get paywalls and placements from paying current user,
253
245
* because paying currentUser doesn't have cache timeout because it has
254
246
* purchases history
255
247
*
256
248
* But paywalls and placements must have cache timeout
257
249
*/
258
- this .userId = newUserId
259
- this .deviceId = newDeviceId
250
+ ServiceLocator .instance.sharedPreferencesStorage.deviceId = newDeviceId
260
251
this .productGroups = cachedGroups
261
252
cachedPaywalls?.let { this .paywalls = it }
262
253
cachedPlacements?.let { this .placements = it }
@@ -274,13 +265,13 @@ internal object ApphudInternal {
274
265
val ruleController = ServiceLocator .instance.ruleController
275
266
if (needRegistration) {
276
267
isRegisteringUser = true
277
- registration(true ) { u, e ->
268
+ registration(true ) { _, _ ->
278
269
if (shouldLoadProducts()) {
279
270
loadProducts()
280
271
}
281
272
coroutineScope.launch {
282
273
fetchNativePurchases()
283
- ruleController.start(deviceId )
274
+ ruleController.start(newUserId )
284
275
}
285
276
}
286
277
} else {
@@ -291,7 +282,7 @@ internal object ApphudInternal {
291
282
}
292
283
coroutineScope.launch {
293
284
fetchNativePurchases()
294
- ruleController.start(deviceId )
285
+ ruleController.start(newUserId )
295
286
}
296
287
}
297
288
}
@@ -402,7 +393,7 @@ internal object ApphudInternal {
402
393
}
403
394
coroutineScope.launch {
404
395
val userIdChanged = ServiceLocator .instance.updateCustomerUseCase(it)
405
-
396
+
406
397
if (userIdChanged) {
407
398
mainScope.launch {
408
399
apphudListener?.apphudDidChangeUserID(it.userId)
@@ -577,43 +568,18 @@ internal object ApphudInternal {
577
568
578
569
private val mutex = Mutex ()
579
570
580
- private fun registration (
571
+ private suspend fun registration (
581
572
forceRegistration : Boolean = false,
582
- completionHandler : ((ApphudUser ? , ApphudError ? ) -> Unit )? ,
583
- ) {
584
- coroutineScope.launch(errorHandler) {
585
- val shouldUnlockMutex =
586
- (currentUser == null || currentUser?.isTemporary == true || forceRegistration) && offeringsPreparedCallbacks.isNotEmpty() && ! isRegisteringUser && mutex.isLocked
587
- if (shouldUnlockMutex) {
588
- try {
589
- ApphudLog .log(" Unlocking the mutex" )
590
- mutex.unlock()
591
- } catch (e: Exception ) {
592
- ApphudLog .log(" Failed to unlock the mutex, force registration" )
593
- runCatchingCancellable { startRegistrationCall(forceRegistration) }
594
- .onSuccess { completionHandler?.invoke(it, null ) }
595
- .onFailure { completionHandler?.invoke(null , it.toApphudError()) }
596
- }
597
- }
598
- mutex.lock()
599
- try {
600
- if (currentUser == null || forceRegistration) {
601
- runCatchingCancellable { startRegistrationCall(forceRegistration) }
602
- .onSuccess { completionHandler?.invoke(it, null ) }
603
- .onFailure { completionHandler?.invoke(null , it.toApphudError()) }
604
- } else {
605
- mainScope.launch {
606
- isRegisteringUser = false
607
- completionHandler?.invoke(currentUser, null )
608
- }
609
- }
610
- } finally {
611
- if (mutex.isLocked) {
612
- mutex.unlock()
613
- }
573
+ ): ApphudUser =
574
+ mutex.withLock {
575
+ val cached = userRepository.getCurrentUser()
576
+ if (cached != null && ! forceRegistration) {
577
+ return @withLock cached
614
578
}
579
+
580
+ runCatchingCancellable { startRegistrationCall(forceRegistration) }
581
+ .getOrElse { throw it.toApphudError() }
615
582
}
616
- }
617
583
618
584
private suspend fun startRegistrationCall (
619
585
forceRegistration : Boolean = false,
@@ -889,7 +855,8 @@ internal object ApphudInternal {
889
855
.fold(
890
856
onSuccess = { userProperties ->
891
857
if (userProperties.success) {
892
- val propertiesInStorage = ServiceLocator .instance.sharedPreferencesStorage.properties
858
+ val propertiesInStorage =
859
+ ServiceLocator .instance.sharedPreferencesStorage.properties
893
860
sentPropertiesForSave.forEach {
894
861
propertiesInStorage?.put(it.key, it)
895
862
}
@@ -988,7 +955,8 @@ internal object ApphudInternal {
988
955
callback?.invoke(false )
989
956
} ? : run {
990
957
coroutineScope.launch(errorHandler) {
991
- val grantPromotionalResult = RequestManager .grantPromotional(daysCount, productId, permissionGroup)
958
+ val grantPromotionalResult =
959
+ RequestManager .grantPromotional(daysCount, productId, permissionGroup)
992
960
withContext(Dispatchers .Main ) {
993
961
grantPromotionalResult
994
962
.onSuccess {
0 commit comments