Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Centralize IO dispatcher usage in example app #1893

Merged
merged 1 commit into from
Nov 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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