Skip to content

Commit

Permalink
Merge pull request #1893 from Adyen/chore/centralize-dispatcher-provider
Browse files Browse the repository at this point in the history
Centralize IO dispatcher usage in example app
  • Loading branch information
OscarSpruit authored Nov 15, 2024
2 parents 357cf03 + f6748f3 commit 80d8585
Show file tree
Hide file tree
Showing 13 changed files with 63 additions and 84 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* 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 oscars on 14/11/2024.
*/

package com.adyen.checkout.example.extensions

import com.adyen.checkout.core.DispatcherProvider
import kotlinx.coroutines.CoroutineDispatcher

@Suppress("RestrictedApi")
val IODispatcher: CoroutineDispatcher get() = DispatcherProvider.IO
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@
package com.adyen.checkout.example.repositories

import android.util.Log
import com.adyen.checkout.core.DispatcherProvider
import com.adyen.checkout.example.extensions.IODispatcher
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.withContext

@Suppress("TooGenericExceptionCaught", "RestrictedApi")
internal suspend fun <T> safeApiCall(call: suspend () -> T): T? = withContext(DispatcherProvider.IO) {
@Suppress("TooGenericExceptionCaught")
internal suspend fun <T> safeApiCall(call: suspend () -> T): T? = withContext(IODispatcher) {
return@withContext try {
call()
} catch (e: CancellationException) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import com.adyen.checkout.components.core.PaymentComponentState
import com.adyen.checkout.components.core.StoredPaymentMethod
import com.adyen.checkout.components.core.action.Action
import com.adyen.checkout.components.core.paymentmethod.PaymentMethodDetails
import com.adyen.checkout.core.DispatcherProvider
import com.adyen.checkout.core.exception.ModelSerializationException
import com.adyen.checkout.dropin.AddressLookupDropInServiceResult
import com.adyen.checkout.dropin.BalanceDropInServiceResult
Expand All @@ -33,6 +32,7 @@ import com.adyen.checkout.dropin.FinishedDialog
import com.adyen.checkout.dropin.OrderDropInServiceResult
import com.adyen.checkout.dropin.RecurringDropInServiceResult
import com.adyen.checkout.example.data.storage.KeyValueStorage
import com.adyen.checkout.example.extensions.IODispatcher
import com.adyen.checkout.example.extensions.getLogTag
import com.adyen.checkout.example.extensions.toStringPretty
import com.adyen.checkout.example.repositories.AddressLookupCompletionResult
Expand Down Expand Up @@ -75,11 +75,10 @@ class ExampleAdvancedDropInService : DropInService() {
}.launchIn(this)
}

@Suppress("RestrictedApi")
override fun onSubmit(
state: PaymentComponentState<*>,
) {
launch(DispatcherProvider.IO) {
launch(IODispatcher) {
Log.d(TAG, "onPaymentsCallRequested")

checkPaymentState(state)
Expand Down Expand Up @@ -125,9 +124,8 @@ class ExampleAdvancedDropInService : DropInService() {
// read bundle and handle it
}

@Suppress("RestrictedApi")
override fun onAdditionalDetails(actionComponentData: ActionComponentData) {
launch(DispatcherProvider.IO) {
launch(IODispatcher) {
Log.d(TAG, "onDetailsCallRequested")

val actionComponentJson = ActionComponentData.SERIALIZER.serialize(actionComponentData)
Expand Down Expand Up @@ -199,10 +197,9 @@ class ExampleAdvancedDropInService : DropInService() {
return OrderResponse.SERIALIZER.deserialize(orderJSON)
}

@Suppress("RestrictedApi")
private fun fetchPaymentMethods(orderResponse: OrderResponse? = null) {
Log.d(TAG, "fetchPaymentMethods")
launch(DispatcherProvider.IO) {
launch(IODispatcher) {
val order = orderResponse?.let {
Order(
pspReference = it.pspReference,
Expand All @@ -229,9 +226,8 @@ class ExampleAdvancedDropInService : DropInService() {
}
}

@Suppress("RestrictedApi")
override fun onBalanceCheck(paymentComponentState: PaymentComponentState<*>) {
launch(DispatcherProvider.IO) {
launch(IODispatcher) {
Log.d(TAG, "checkBalance")
val amount = paymentComponentState.data.amount
val paymentMethod = paymentComponentState.data.paymentMethod
Expand Down Expand Up @@ -284,9 +280,8 @@ class ExampleAdvancedDropInService : DropInService() {
}
}

@Suppress("RestrictedApi")
override fun onOrderRequest() {
launch(DispatcherProvider.IO) {
launch(IODispatcher) {
Log.d(TAG, "createOrder")

val paymentRequest = createOrderRequest(
Expand Down Expand Up @@ -316,9 +311,8 @@ class ExampleAdvancedDropInService : DropInService() {
}
}

@Suppress("RestrictedApi")
override fun onOrderCancel(order: Order, shouldUpdatePaymentMethods: Boolean) {
launch(DispatcherProvider.IO) {
launch(IODispatcher) {
Log.d(TAG, "cancelOrder")
val orderJson = Order.SERIALIZER.serialize(order)
val request = createCancelOrderRequest(
Expand Down Expand Up @@ -355,11 +349,10 @@ class ExampleAdvancedDropInService : DropInService() {
}
}

@Suppress("RestrictedApi")
override fun onRemoveStoredPaymentMethod(
storedPaymentMethod: StoredPaymentMethod,
) {
launch(DispatcherProvider.IO) {
launch(IODispatcher) {
val storedPaymentMethodId = storedPaymentMethod.id.orEmpty()
val isSuccessfullyRemoved = paymentsRepository.removeStoredPaymentMethod(
storedPaymentMethodId = storedPaymentMethodId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ import com.adyen.checkout.components.core.PaymentComponentData
import com.adyen.checkout.components.core.PaymentComponentState
import com.adyen.checkout.components.core.StoredPaymentMethod
import com.adyen.checkout.components.core.action.Action
import com.adyen.checkout.core.DispatcherProvider
import com.adyen.checkout.dropin.DropInService
import com.adyen.checkout.dropin.DropInServiceResult
import com.adyen.checkout.dropin.ErrorDialog
import com.adyen.checkout.dropin.RecurringDropInServiceResult
import com.adyen.checkout.example.data.storage.KeyValueStorage
import com.adyen.checkout.example.extensions.IODispatcher
import com.adyen.checkout.example.extensions.getLogTag
import com.adyen.checkout.example.extensions.toStringPretty
import com.adyen.checkout.example.repositories.PaymentsRepository
Expand All @@ -43,11 +43,10 @@ class ExampleDropInService : DropInService() {
@Inject
lateinit var keyValueStorage: KeyValueStorage

@Suppress("RestrictedApi")
override fun onSubmit(
state: PaymentComponentState<*>
) {
launch(DispatcherProvider.IO) {
launch(IODispatcher) {
Log.d(TAG, "onPaymentsCallRequested")

checkPaymentState(state)
Expand Down Expand Up @@ -83,9 +82,8 @@ class ExampleDropInService : DropInService() {
}
}

@Suppress("RestrictedApi")
override fun onAdditionalDetails(actionComponentData: ActionComponentData) {
launch(DispatcherProvider.IO) {
launch(IODispatcher) {
Log.d(TAG, "onDetailsCallRequested")

val actionComponentJson = ActionComponentData.SERIALIZER.serialize(actionComponentData)
Expand Down Expand Up @@ -128,11 +126,10 @@ class ExampleDropInService : DropInService() {
return jsonResponse.has("action")
}

@Suppress("RestrictedApi")
override fun onRemoveStoredPaymentMethod(
storedPaymentMethod: StoredPaymentMethod,
) {
launch(DispatcherProvider.IO) {
launch(IODispatcher) {
val storedPaymentMethodId = storedPaymentMethod.id.orEmpty()
val isSuccessfullyRemoved = paymentsRepository.removeStoredPaymentMethod(
storedPaymentMethodId = storedPaymentMethodId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ import com.adyen.checkout.components.core.ActionComponentData
import com.adyen.checkout.components.core.PaymentComponentData
import com.adyen.checkout.components.core.PaymentComponentState
import com.adyen.checkout.components.core.action.Action
import com.adyen.checkout.core.DispatcherProvider
import com.adyen.checkout.dropin.DropInServiceResult
import com.adyen.checkout.dropin.ErrorDialog
import com.adyen.checkout.dropin.SessionDropInService
import com.adyen.checkout.example.data.storage.KeyValueStorage
import com.adyen.checkout.example.extensions.IODispatcher
import com.adyen.checkout.example.extensions.getLogTag
import com.adyen.checkout.example.extensions.toStringPretty
import com.adyen.checkout.example.repositories.PaymentsRepository
Expand All @@ -38,15 +38,14 @@ class ExampleSessionsDropInService : SessionDropInService() {
@Inject
lateinit var keyValueStorage: KeyValueStorage

@Suppress("RestrictedApi")
override fun onSubmit(
state: PaymentComponentState<*>,
): Boolean {
return if (
state is BlikComponentState ||
state is CardComponentState
) {
launch(DispatcherProvider.IO) {
launch(IODispatcher) {
Log.d(TAG, "onPaymentsCallRequested")

// Check out the documentation of this method on the parent DropInService class
Expand Down Expand Up @@ -74,12 +73,11 @@ class ExampleSessionsDropInService : SessionDropInService() {
}
}

@Suppress("RestrictedApi")
override fun onAdditionalDetails(
actionComponentData: ActionComponentData,
): Boolean {
return if (isFlowTakenOver) {
launch(DispatcherProvider.IO) {
launch(IODispatcher) {
Log.d(TAG, "onDetailsCallRequested")

val response = paymentsRepository.makeDetailsRequest(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ import com.adyen.checkout.components.core.ComponentCallback
import com.adyen.checkout.components.core.ComponentError
import com.adyen.checkout.components.core.PaymentComponentData
import com.adyen.checkout.components.core.action.Action
import com.adyen.checkout.core.DispatcherProvider
import com.adyen.checkout.example.R
import com.adyen.checkout.example.data.storage.KeyValueStorage
import com.adyen.checkout.example.extensions.IODispatcher
import com.adyen.checkout.example.repositories.PaymentsRepository
import com.adyen.checkout.example.service.createPaymentRequest
import com.adyen.checkout.example.service.getPaymentMethodRequest
Expand Down Expand Up @@ -57,8 +57,7 @@ internal class BacsViewModel @Inject constructor(
viewModelScope.launch { fetchPaymentMethods() }
}

@Suppress("RestrictedApi")
private suspend fun fetchPaymentMethods() = withContext(DispatcherProvider.IO) {
private suspend fun fetchPaymentMethods() = withContext(IODispatcher) {
val validationError = if (keyValueStorage.getAmount().currency != CheckoutCurrency.GBP.name) {
BacsViewState.Error(R.string.currency_code_error, CheckoutCurrency.GBP.name)
} else if (keyValueStorage.getCountry() != Locale.UK.country) {
Expand Down Expand Up @@ -116,9 +115,8 @@ internal class BacsViewModel @Inject constructor(
viewModelScope.launch { _events.emit(BacsEvent.PaymentResult("Failed: ${error.errorMessage}")) }
}

@Suppress("RestrictedApi")
private fun sendPaymentDetails(actionComponentData: ActionComponentData) {
viewModelScope.launch(DispatcherProvider.IO) {
viewModelScope.launch(IODispatcher) {
val json = ActionComponentData.SERIALIZER.serialize(actionComponentData)
handlePaymentResponse(paymentsRepository.makeDetailsRequest(json))
}
Expand Down Expand Up @@ -147,8 +145,7 @@ internal class BacsViewModel @Inject constructor(

val paymentComponentData = PaymentComponentData.SERIALIZER.serialize(data)

@Suppress("RestrictedApi")
viewModelScope.launch(DispatcherProvider.IO) {
viewModelScope.launch(IODispatcher) {
val paymentRequest = createPaymentRequest(
paymentComponentData = paymentComponentData,
shopperReference = keyValueStorage.getShopperReference(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ import com.adyen.checkout.components.core.ComponentError
import com.adyen.checkout.components.core.PaymentComponentData
import com.adyen.checkout.components.core.action.Action
import com.adyen.checkout.components.core.paymentmethod.BlikPaymentMethod
import com.adyen.checkout.core.DispatcherProvider
import com.adyen.checkout.example.R
import com.adyen.checkout.example.data.storage.KeyValueStorage
import com.adyen.checkout.example.extensions.IODispatcher
import com.adyen.checkout.example.repositories.PaymentsRepository
import com.adyen.checkout.example.service.createPaymentRequest
import com.adyen.checkout.example.service.getPaymentMethodRequest
Expand Down Expand Up @@ -55,8 +55,7 @@ class BlikViewModel @Inject constructor(
viewModelScope.launch { _blikViewState.emit(fetchPaymentMethods()) }
}

@Suppress("RestrictedApi")
private suspend fun fetchPaymentMethods(): BlikViewState = withContext(DispatcherProvider.IO) {
private suspend fun fetchPaymentMethods(): BlikViewState = withContext(IODispatcher) {
if (keyValueStorage.getAmount().currency != CheckoutCurrency.PLN.name) {
return@withContext BlikViewState.Error(R.string.currency_code_error, CheckoutCurrency.PLN.name)
} else if (keyValueStorage.getCountry() != POLAND_COUNTRY_CODE) {
Expand Down Expand Up @@ -139,9 +138,8 @@ class BlikViewModel @Inject constructor(
} ?: _events.emit(BlikEvent.PaymentResult("Failed"))
}

@Suppress("RestrictedApi")
private fun sendPaymentDetails(actionComponentData: ActionComponentData) {
viewModelScope.launch(DispatcherProvider.IO) {
viewModelScope.launch(IODispatcher) {
val json = ActionComponentData.SERIALIZER.serialize(actionComponentData)
handlePaymentResponse(paymentsRepository.makeDetailsRequest(json))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import com.adyen.checkout.components.core.ComponentError
import com.adyen.checkout.components.core.LookupAddress
import com.adyen.checkout.components.core.PaymentComponentData
import com.adyen.checkout.components.core.action.Action
import com.adyen.checkout.core.DispatcherProvider
import com.adyen.checkout.example.data.storage.KeyValueStorage
import com.adyen.checkout.example.extensions.IODispatcher
import com.adyen.checkout.example.repositories.AddressLookupCompletionResult
import com.adyen.checkout.example.repositories.AddressLookupRepository
import com.adyen.checkout.example.repositories.PaymentsRepository
Expand Down Expand Up @@ -56,8 +56,7 @@ internal class CardViewModel @Inject constructor(
}.launchIn(viewModelScope)
}

@Suppress("RestrictedApi")
private suspend fun fetchPaymentMethods() = withContext(DispatcherProvider.IO) {
private suspend fun fetchPaymentMethods() = withContext(IODispatcher) {
val paymentMethodResponse = paymentsRepository.getPaymentMethods(
getPaymentMethodRequest(
merchantAccount = keyValueStorage.getMerchantAccount(),
Expand Down Expand Up @@ -129,8 +128,7 @@ internal class CardViewModel @Inject constructor(

val paymentComponentData = PaymentComponentData.SERIALIZER.serialize(data)

@Suppress("RestrictedApi")
viewModelScope.launch(DispatcherProvider.IO) {
viewModelScope.launch(IODispatcher) {
val paymentRequest = createPaymentRequest(
paymentComponentData = paymentComponentData,
shopperReference = keyValueStorage.getShopperReference(),
Expand Down Expand Up @@ -164,9 +162,8 @@ internal class CardViewModel @Inject constructor(
_events.emit(CardEvent.AdditionalAction(action))
}

@Suppress("RestrictedApi")
private fun sendPaymentDetails(actionComponentData: ActionComponentData) {
viewModelScope.launch(DispatcherProvider.IO) {
viewModelScope.launch(IODispatcher) {
val json = ActionComponentData.SERIALIZER.serialize(actionComponentData)
handlePaymentResponse(paymentsRepository.makeDetailsRequest(json))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ import com.adyen.checkout.components.core.LookupAddress
import com.adyen.checkout.components.core.PaymentComponentData
import com.adyen.checkout.components.core.PaymentMethodTypes
import com.adyen.checkout.components.core.action.Action
import com.adyen.checkout.core.DispatcherProvider
import com.adyen.checkout.example.data.storage.KeyValueStorage
import com.adyen.checkout.example.extensions.IODispatcher
import com.adyen.checkout.example.extensions.getLogTag
import com.adyen.checkout.example.repositories.AddressLookupCompletionResult
import com.adyen.checkout.example.repositories.AddressLookupRepository
Expand All @@ -39,7 +39,6 @@ import com.adyen.checkout.sessions.core.SessionComponentCallback
import com.adyen.checkout.sessions.core.SessionModel
import com.adyen.checkout.sessions.core.SessionPaymentResult
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
Expand All @@ -50,7 +49,6 @@ import kotlinx.coroutines.launch
import org.json.JSONObject
import javax.inject.Inject

@OptIn(FlowPreview::class)
@Suppress("TooManyFunctions")
@HiltViewModel
internal class SessionsCardTakenOverViewModel @Inject constructor(
Expand Down Expand Up @@ -174,13 +172,12 @@ internal class SessionsCardTakenOverViewModel @Inject constructor(
return isFlowTakenOver
}

@Suppress("RestrictedApi")
private fun makePayment(data: PaymentComponentData<*>) {
_cardViewState.value = CardViewState.Loading

val paymentComponentData = PaymentComponentData.SERIALIZER.serialize(data)

viewModelScope.launch(DispatcherProvider.IO) {
viewModelScope.launch(IODispatcher) {
val paymentRequest = createPaymentRequest(
paymentComponentData = paymentComponentData,
shopperReference = keyValueStorage.getShopperReference(),
Expand Down Expand Up @@ -214,9 +211,8 @@ internal class SessionsCardTakenOverViewModel @Inject constructor(
_events.emit(CardEvent.AdditionalAction(action))
}

@Suppress("RestrictedApi")
private fun sendPaymentDetails(actionComponentData: ActionComponentData) {
viewModelScope.launch(DispatcherProvider.IO) {
viewModelScope.launch(IODispatcher) {
val json = ActionComponentData.SERIALIZER.serialize(actionComponentData)
handlePaymentResponse(paymentsRepository.makeDetailsRequest(json))
}
Expand Down
Loading

0 comments on commit 80d8585

Please sign in to comment.