Skip to content

Commit

Permalink
Merge pull request #1842 from Adyen/chore/dispatcher-provider
Browse files Browse the repository at this point in the history
Introduce DispatcherProvider
  • Loading branch information
ozgur00 authored Oct 25, 2024
2 parents 8b9f809 + b703418 commit c45a6ee
Show file tree
Hide file tree
Showing 20 changed files with 101 additions and 50 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ package com.adyen.checkout.adyen3ds2.internal.data.api

import com.adyen.checkout.adyen3ds2.internal.data.model.SubmitFingerprintRequest
import com.adyen.checkout.adyen3ds2.internal.data.model.SubmitFingerprintResponse
import com.adyen.checkout.core.DispatcherProvider
import com.adyen.checkout.core.internal.data.api.HttpClient
import com.adyen.checkout.core.internal.data.api.post
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext

internal class SubmitFingerprintService(
private val httpClient: HttpClient,
private val coroutineDispatcher: CoroutineDispatcher = Dispatchers.IO,
private val coroutineDispatcher: CoroutineDispatcher = DispatcherProvider.IO,
) {

suspend fun submitFingerprint(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,11 @@ import com.adyen.checkout.components.core.internal.ui.model.CommonComponentParam
import com.adyen.checkout.components.core.internal.ui.model.DropInOverrideParams
import com.adyen.checkout.components.core.internal.util.get
import com.adyen.checkout.components.core.internal.util.viewModelFactory
import com.adyen.checkout.core.DispatcherProvider
import com.adyen.checkout.core.internal.data.api.HttpClientFactory
import com.adyen.checkout.core.internal.util.LocaleProvider
import com.adyen.checkout.ui.core.internal.DefaultRedirectHandler
import com.adyen.threeds2.ThreeDS2Service
import kotlinx.coroutines.Dispatchers

class Adyen3DS2ComponentProvider
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
Expand Down Expand Up @@ -105,7 +105,7 @@ constructor(
adyen3DS2Serializer = adyen3DS2DetailsParser,
redirectHandler = redirectHandler,
threeDS2Service = ThreeDS2Service.INSTANCE,
coroutineDispatcher = Dispatchers.Default,
coroutineDispatcher = DispatcherProvider.Default,
application = application,
analyticsManager = analyticsManager,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,16 @@ package com.adyen.checkout.card.internal.data.api
import androidx.annotation.RestrictTo
import com.adyen.checkout.card.internal.data.model.BinLookupRequest
import com.adyen.checkout.card.internal.data.model.BinLookupResponse
import com.adyen.checkout.core.DispatcherProvider
import com.adyen.checkout.core.internal.data.api.HttpClient
import com.adyen.checkout.core.internal.data.api.post
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext

@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
class BinLookupService(
private val httpClient: HttpClient,
private val coroutineDispatcher: CoroutineDispatcher = Dispatchers.IO,
private val coroutineDispatcher: CoroutineDispatcher = DispatcherProvider.IO,
) {

suspend fun makeBinLookup(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import com.adyen.checkout.components.core.internal.analytics.GenericEvents
import com.adyen.checkout.components.core.internal.util.bufferedChannel
import com.adyen.checkout.components.core.paymentmethod.CashAppPayPaymentMethod
import com.adyen.checkout.core.AdyenLogLevel
import com.adyen.checkout.core.DispatcherProvider
import com.adyen.checkout.core.exception.CheckoutException
import com.adyen.checkout.core.exception.ComponentException
import com.adyen.checkout.core.internal.util.adyenLog
Expand All @@ -47,7 +48,6 @@ import com.adyen.checkout.ui.core.internal.ui.ComponentViewType
import com.adyen.checkout.ui.core.internal.ui.SubmitHandler
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
Expand All @@ -65,7 +65,7 @@ constructor(
private val order: OrderRequest?,
override val componentParams: CashAppPayComponentParams,
private val cashAppPayFactory: CashAppPayFactory,
private val coroutineDispatcher: CoroutineDispatcher = Dispatchers.IO,
private val coroutineDispatcher: CoroutineDispatcher = DispatcherProvider.IO,
) : CashAppPayDelegate, ButtonDelegate, CashAppPayListener {

private val inputData = CashAppPayInputData()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* Copyright (c) 2024 Adyen N.V.
*
* This file is open source and available under the MIT license. See the LICENSE file for more info.
*
* Created by ozgur on 16/10/2024.
*/

package com.adyen.checkout.core

import androidx.annotation.RestrictTo
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.MainCoroutineDispatcher

@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
object DispatcherProvider {

private var mainFactory = { Dispatchers.Main }
val Main: MainCoroutineDispatcher get() = mainFactory()

private var defaultFactory = { Dispatchers.Default }
val Default: CoroutineDispatcher get() = defaultFactory()

private var ioFactory = { Dispatchers.IO }
val IO: CoroutineDispatcher get() = ioFactory()

fun overrideMain(dispatcher: MainCoroutineDispatcher) {
mainFactory = { dispatcher }
}

fun overrideIO(dispatcher: CoroutineDispatcher) {
ioFactory = { dispatcher }
}

fun overrideDefault(dispatcher: CoroutineDispatcher) {
defaultFactory = { dispatcher }
}

fun resetMain() {
mainFactory = { Dispatchers.Main }
}

fun resetIO() {
ioFactory = { Dispatchers.IO }
}

fun resetDefault() {
defaultFactory = { Dispatchers.Default }
}

fun resetAll() {
resetMain()
resetIO()
resetDefault()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ import android.content.pm.ApplicationInfo
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import androidx.annotation.RestrictTo
import com.adyen.checkout.core.DispatcherProvider
import com.adyen.checkout.core.exception.HttpException
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import okhttp3.OkHttpClient
import okhttp3.Request
Expand All @@ -43,10 +43,10 @@ class DefaultImageLoader(context: Context) : ImageLoader {
url: String,
onSuccess: suspend (Bitmap) -> Unit,
onError: suspend (Throwable) -> Unit
) = withContext(Dispatchers.IO) {
) = withContext(DispatcherProvider.IO) {
val cachedBitmap = cache[url]
if (cachedBitmap != null) {
withContext(Dispatchers.Main) {
withContext(DispatcherProvider.Main) {
onSuccess(cachedBitmap)
}
return@withContext
Expand All @@ -72,11 +72,11 @@ class DefaultImageLoader(context: Context) : ImageLoader {

cache[url] = bitmap

withContext(Dispatchers.Main) {
withContext(DispatcherProvider.Main) {
onSuccess(bitmap)
}
} else {
withContext(Dispatchers.Main) {
withContext(DispatcherProvider.Main) {
onError(HttpException(response.code, response.message, null))
}
}
Expand All @@ -85,7 +85,7 @@ class DefaultImageLoader(context: Context) : ImageLoader {
} catch (e: CancellationException) {
call.cancel()
} catch (e: IOException) {
withContext(Dispatchers.Main) {
withContext(DispatcherProvider.Main) {
onError(e)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ import com.adyen.checkout.components.core.internal.analytics.data.AnalyticsRepos
import com.adyen.checkout.components.core.internal.ui.model.AnalyticsParams
import com.adyen.checkout.components.core.internal.ui.model.AnalyticsParamsLevel
import com.adyen.checkout.core.AdyenLogLevel
import com.adyen.checkout.core.DispatcherProvider
import com.adyen.checkout.core.internal.util.adyenLog
import com.adyen.checkout.core.internal.util.runSuspendCatching
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.isActive
Expand All @@ -27,7 +27,7 @@ import kotlin.time.Duration.Companion.seconds
internal class DefaultAnalyticsManager(
private val analyticsRepository: AnalyticsRepository,
private val analyticsParams: AnalyticsParams,
private val coroutineDispatcher: CoroutineDispatcher = Dispatchers.IO,
private val coroutineDispatcher: CoroutineDispatcher = DispatcherProvider.IO,
) : AnalyticsManager {

private var checkoutAttemptIdState: CheckoutAttemptIdState = CheckoutAttemptIdState.NotAvailable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,17 @@ import androidx.annotation.RestrictTo
import com.adyen.checkout.components.core.internal.data.model.AnalyticsSetupRequest
import com.adyen.checkout.components.core.internal.data.model.AnalyticsSetupResponse
import com.adyen.checkout.components.core.internal.data.model.AnalyticsTrackRequest
import com.adyen.checkout.core.DispatcherProvider
import com.adyen.checkout.core.internal.data.api.HttpClient
import com.adyen.checkout.core.internal.data.api.post
import com.adyen.checkout.core.internal.data.model.EmptyResponse
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext

@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
class AnalyticsService(
private val httpClient: HttpClient,
private val coroutineDispatcher: CoroutineDispatcher = Dispatchers.IO,
private val coroutineDispatcher: CoroutineDispatcher = DispatcherProvider.IO,
) {

internal suspend fun setupAnalytics(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,16 @@ package com.adyen.checkout.components.core.internal.data.api
import androidx.annotation.RestrictTo
import com.adyen.checkout.components.core.internal.data.model.OrderStatusRequest
import com.adyen.checkout.components.core.internal.data.model.OrderStatusResponse
import com.adyen.checkout.core.DispatcherProvider
import com.adyen.checkout.core.internal.data.api.HttpClient
import com.adyen.checkout.core.internal.data.api.post
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext

@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
class OrderStatusService(
private val httpClient: HttpClient,
private val coroutineDispatcher: CoroutineDispatcher = Dispatchers.IO,
private val coroutineDispatcher: CoroutineDispatcher = DispatcherProvider.IO,
) {

internal suspend fun getOrderStatus(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,16 @@ package com.adyen.checkout.components.core.internal.data.api

import androidx.annotation.RestrictTo
import com.adyen.checkout.components.core.internal.data.model.PublicKeyResponse
import com.adyen.checkout.core.DispatcherProvider
import com.adyen.checkout.core.internal.data.api.HttpClient
import com.adyen.checkout.core.internal.data.api.get
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext

@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
class PublicKeyService(
private val httpClient: HttpClient,
private val coroutineDispatcher: CoroutineDispatcher = Dispatchers.IO,
private val coroutineDispatcher: CoroutineDispatcher = DispatcherProvider.IO,
) {

internal suspend fun getPublicKey(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ import com.adyen.checkout.components.core.internal.data.model.StatusResponse
import com.adyen.checkout.components.core.internal.util.StatusResponseUtils
import com.adyen.checkout.components.core.internal.util.bufferedChannel
import com.adyen.checkout.core.AdyenLogLevel
import com.adyen.checkout.core.DispatcherProvider
import com.adyen.checkout.core.internal.util.adyenLog
import com.adyen.checkout.core.internal.util.runSuspendCatching
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.cancel
import kotlinx.coroutines.currentCoroutineContext
Expand Down Expand Up @@ -51,7 +51,7 @@ class DefaultStatusRepository(
private val statusService: StatusService,
private val clientKey: String,
private val timeSource: TimeSource = TimeSource.Monotonic,
private val coroutineDispatcher: CoroutineDispatcher = Dispatchers.IO,
private val coroutineDispatcher: CoroutineDispatcher = DispatcherProvider.IO,
) : StatusRepository {

private var delay: Long = 0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import com.adyen.checkout.components.core.LookupAddress
import com.adyen.checkout.components.core.StoredPaymentMethod
import com.adyen.checkout.components.core.internal.util.bufferedChannel
import com.adyen.checkout.core.AdyenLogLevel
import com.adyen.checkout.core.DispatcherProvider
import com.adyen.checkout.core.internal.util.adyenLog
import com.adyen.checkout.dropin.AddressLookupDropInServiceResult
import com.adyen.checkout.dropin.BalanceDropInServiceResult
Expand All @@ -31,7 +32,6 @@ import com.adyen.checkout.dropin.DropInServiceResult
import com.adyen.checkout.dropin.OrderDropInServiceResult
import com.adyen.checkout.dropin.RecurringDropInServiceResult
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.cancel
import kotlinx.coroutines.channels.Channel
Expand All @@ -46,7 +46,7 @@ abstract class BaseDropInService
constructor() : Service(), CoroutineScope, BaseDropInServiceInterface, BaseDropInServiceContract {

private val coroutineJob: Job = Job()
final override val coroutineContext: CoroutineContext get() = Dispatchers.Main + coroutineJob
final override val coroutineContext: CoroutineContext get() = DispatcherProvider.Main + coroutineJob

@Suppress("LeakingThis")
private val binder = DropInBinder(this)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import com.adyen.checkout.components.core.internal.ui.model.DropInOverrideParams
import com.adyen.checkout.components.core.internal.util.bufferedChannel
import com.adyen.checkout.components.core.paymentmethod.GiftCardPaymentMethod
import com.adyen.checkout.core.AdyenLogLevel
import com.adyen.checkout.core.DispatcherProvider
import com.adyen.checkout.core.exception.CheckoutException
import com.adyen.checkout.core.internal.util.adyenLog
import com.adyen.checkout.dropin.R
Expand All @@ -47,7 +48,6 @@ import com.adyen.checkout.giftcard.internal.util.GiftCardBalanceUtils
import com.adyen.checkout.sessions.core.internal.data.model.SessionDetails
import com.adyen.checkout.sessions.core.internal.data.model.mapToModel
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.receiveAsFlow
Expand All @@ -60,7 +60,7 @@ internal class DropInViewModel(
internal val analyticsManager: AnalyticsManager,
private val initialDropInParams: DropInParams,
private val dropInConfigDataGenerator: DropInConfigDataGenerator,
private val coroutineDispatcher: CoroutineDispatcher = Dispatchers.IO,
private val coroutineDispatcher: CoroutineDispatcher = DispatcherProvider.IO,
) : ViewModel() {

private val eventChannel: Channel<DropInActivityEvent> = bufferedChannel()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ package com.adyen.checkout.test.rule

import androidx.test.espresso.IdlingRegistry
import androidx.test.espresso.idling.CountingIdlingResource
import com.adyen.checkout.core.DispatcherProvider
import com.adyen.checkout.test.util.IdlingResourceDispatcher
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
Expand Down Expand Up @@ -45,7 +46,7 @@ class IdlingDispatcherRule : TestRule {
unregister(defaultIdlingResource)
unregister(ioIdlingResource)
}
overrideDispatchers(defaultDispatcher, ioDispatcher)
DispatcherProvider.resetAll()
}
}
}
Expand All @@ -54,14 +55,7 @@ class IdlingDispatcherRule : TestRule {
default: CoroutineDispatcher,
io: CoroutineDispatcher,
) {
fun setField(name: String, value: CoroutineDispatcher) {
Dispatchers::class.java.getDeclaredField(name).apply {
isAccessible = true
set(Dispatchers, value)
}
}

setField("Default", default)
setField("IO", io)
DispatcherProvider.overrideDefault(default)
DispatcherProvider.overrideIO(io)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,17 @@

package com.adyen.checkout.redirect.internal.data.api

import com.adyen.checkout.core.DispatcherProvider
import com.adyen.checkout.core.internal.data.api.HttpClient
import com.adyen.checkout.core.internal.data.api.post
import com.adyen.checkout.redirect.internal.data.model.NativeRedirectRequest
import com.adyen.checkout.redirect.internal.data.model.NativeRedirectResponse
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext

internal class NativeRedirectService(
private val httpClient: HttpClient,
private val dispatcher: CoroutineDispatcher = Dispatchers.IO
private val dispatcher: CoroutineDispatcher = DispatcherProvider.IO
) {

suspend fun makeNativeRedirect(
Expand Down
Loading

0 comments on commit c45a6ee

Please sign in to comment.