From e9f9b5098a9830d8396fceda9b8d45f5c849f8e7 Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Wed, 12 Aug 2020 13:50:39 -0300 Subject: [wallet] remove remaining deserialization off the UI thread --- .../main/java/net/taler/wallet/MainViewModel.kt | 2 +- .../net/taler/wallet/exchanges/ExchangeManager.kt | 47 +++++++++------- .../wallet/transactions/TransactionManager.kt | 64 +++++++++------------- .../net/taler/wallet/transactions/Transactions.kt | 3 +- .../net/taler/wallet/withdraw/WithdrawManager.kt | 6 +- 5 files changed, 58 insertions(+), 64 deletions(-) (limited to 'wallet/src/main/java/net/taler') diff --git a/wallet/src/main/java/net/taler/wallet/MainViewModel.kt b/wallet/src/main/java/net/taler/wallet/MainViewModel.kt index 6249551..b4aa1dc 100644 --- a/wallet/src/main/java/net/taler/wallet/MainViewModel.kt +++ b/wallet/src/main/java/net/taler/wallet/MainViewModel.kt @@ -103,7 +103,7 @@ class MainViewModel(val app: Application) : AndroidViewModel(app) { val pendingOperationsManager: PendingOperationsManager = PendingOperationsManager(api) val transactionManager: TransactionManager = TransactionManager(api, viewModelScope, mapper) val refundManager = RefundManager(api, viewModelScope) - val exchangeManager: ExchangeManager = ExchangeManager(api, mapper) + val exchangeManager: ExchangeManager = ExchangeManager(api, viewModelScope) private val mTransactionsEvent = MutableLiveData>() val transactionsEvent: LiveData> = mTransactionsEvent diff --git a/wallet/src/main/java/net/taler/wallet/exchanges/ExchangeManager.kt b/wallet/src/main/java/net/taler/wallet/exchanges/ExchangeManager.kt index 9d31b5f..8205eb7 100644 --- a/wallet/src/main/java/net/taler/wallet/exchanges/ExchangeManager.kt +++ b/wallet/src/main/java/net/taler/wallet/exchanges/ExchangeManager.kt @@ -19,17 +19,22 @@ package net.taler.wallet.exchanges import android.util.Log import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData -import com.fasterxml.jackson.databind.ObjectMapper -import com.fasterxml.jackson.module.kotlin.readValue +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.launch +import kotlinx.serialization.Serializable import net.taler.common.Event import net.taler.common.toEvent import net.taler.wallet.TAG import net.taler.wallet.backend.WalletBackendApi -import org.json.JSONObject + +@Serializable +data class ExchangeListResponse( + val exchanges: List +) class ExchangeManager( - private val walletBackendApi: WalletBackendApi, - private val mapper: ObjectMapper + private val api: WalletBackendApi, + private val scope: CoroutineScope ) { private val mProgress = MutableLiveData() @@ -45,31 +50,31 @@ class ExchangeManager( private fun list(): LiveData> { mProgress.value = true - walletBackendApi.sendRequest("listExchanges") { isError, result -> - if (isError) { + scope.launch { + val response = api.request("listExchanges", ExchangeListResponse.serializer()) + response.onError { throw AssertionError("Wallet core failed to return exchanges!") - } else { - val exchanges: List = mapper.readValue(result.getString("exchanges")) - Log.d(TAG, "Exchange list: $exchanges") + }.onSuccess { + Log.d(TAG, "Exchange list: ${it.exchanges}") mProgress.value = false - mExchanges.value = exchanges + mExchanges.value = it.exchanges } } return mExchanges } - fun add(exchangeUrl: String) { + fun add(exchangeUrl: String) = scope.launch { mProgress.value = true - val args = JSONObject().apply { put("exchangeBaseUrl", exchangeUrl) } - walletBackendApi.sendRequest("addExchange", args) { isError, result -> + api.request("addExchange") { + put("exchangeBaseUrl", exchangeUrl) + }.onError { mProgress.value = false - if (isError) { - Log.e(TAG, "$result") - mAddError.value = true.toEvent() - } else { - Log.d(TAG, "Exchange $exchangeUrl added") - list() - } + Log.e(TAG, "Error adding exchange: $it") + mAddError.value = true.toEvent() + }.onSuccess { + mProgress.value = false + Log.d(TAG, "Exchange $exchangeUrl added") + list() } } diff --git a/wallet/src/main/java/net/taler/wallet/transactions/TransactionManager.kt b/wallet/src/main/java/net/taler/wallet/transactions/TransactionManager.kt index d398f57..e9b1b71 100644 --- a/wallet/src/main/java/net/taler/wallet/transactions/TransactionManager.kt +++ b/wallet/src/main/java/net/taler/wallet/transactions/TransactionManager.kt @@ -17,20 +17,14 @@ package net.taler.wallet.transactions import androidx.annotation.UiThread -import androidx.annotation.WorkerThread import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.switchMap import com.fasterxml.jackson.databind.ObjectMapper -import com.fasterxml.jackson.module.kotlin.readValue import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import net.taler.wallet.backend.WalletBackendApi -import net.taler.wallet.getErrorString -import org.json.JSONObject import java.util.HashMap -import java.util.LinkedList sealed class TransactionsResult { class Error(val msg: String) : TransactionsResult() @@ -38,7 +32,7 @@ sealed class TransactionsResult { } class TransactionManager( - private val walletBackendApi: WalletBackendApi, + private val api: WalletBackendApi, private val scope: CoroutineScope, private val mapper: ObjectMapper ) { @@ -62,44 +56,36 @@ class TransactionManager( } @UiThread - fun loadTransactions(searchQuery: String? = null) { - val currency = selectedCurrency ?: return + fun loadTransactions(searchQuery: String? = null) = scope.launch { + val currency = selectedCurrency ?: return@launch val liveData = mTransactions.getOrPut(currency) { MutableLiveData() } if (searchQuery == null && allTransactions.containsKey(currency)) { liveData.value = TransactionsResult.Success(allTransactions[currency]!!) } if (liveData.value == null) mProgress.value = true - val request = JSONObject(mapOf("currency" to currency)) - searchQuery?.let { request.put("search", it) } - walletBackendApi.sendRequest("getTransactions", request) { isError, result -> - if (isError) { - liveData.postValue(TransactionsResult.Error(getErrorString(result))) - mProgress.postValue(false) - } else { - val currencyToUpdate = if (searchQuery == null) currency else null - scope.launch(Dispatchers.Default) { - onTransactionsLoaded(liveData, currencyToUpdate, result) - } - } - } - } - @WorkerThread - private fun onTransactionsLoaded( - liveData: MutableLiveData, - currency: String?, // only non-null if we should update all transactions cache - result: JSONObject - ) { - val transactionsArray = result.getString("transactions") - val transactions: LinkedList = mapper.readValue(transactionsArray) - // TODO remove when fixed in wallet-core - transactions.sortWith(compareBy({ it.pending }, { it.timestamp.ms }, { it.transactionId })) - transactions.reverse() // show latest first - mProgress.postValue(false) - liveData.postValue(TransactionsResult.Success(transactions)) - // update all transactions on UiThread if there was a currency - currency?.let { - scope.launch(Dispatchers.Main) { allTransactions[currency] = transactions } + api.request("getTransactions", mapper) { + if (searchQuery != null) put("search", searchQuery) + put("currency", currency) + }.onError { + liveData.postValue(TransactionsResult.Error(it.userFacingMsg)) + mProgress.postValue(false) + }.onSuccess { result -> + val transactions = result.transactions + // TODO remove when fixed in wallet-core + val comparator = compareBy( + { it.pending }, + { it.timestamp.ms }, + { it.transactionId } + ) + transactions.sortWith(comparator) + transactions.reverse() // show latest first + + mProgress.value = false + liveData.value = TransactionsResult.Success(transactions) + + // update all transactions on UiThread if there was a currency + if (searchQuery == null) allTransactions[currency] = transactions } } diff --git a/wallet/src/main/java/net/taler/wallet/transactions/Transactions.kt b/wallet/src/main/java/net/taler/wallet/transactions/Transactions.kt index 08f02fc..d227183 100644 --- a/wallet/src/main/java/net/taler/wallet/transactions/Transactions.kt +++ b/wallet/src/main/java/net/taler/wallet/transactions/Transactions.kt @@ -36,8 +36,9 @@ import net.taler.wallet.R import net.taler.wallet.cleanExchange import net.taler.wallet.transactions.WithdrawalDetails.ManualTransfer import net.taler.wallet.transactions.WithdrawalDetails.TalerBankIntegrationApi +import java.util.LinkedList -data class Transactions(val transactions: List) +data class Transactions(val transactions: LinkedList) @JsonTypeInfo(use = NAME, include = PROPERTY, property = "type") @JsonSubTypes( diff --git a/wallet/src/main/java/net/taler/wallet/withdraw/WithdrawManager.kt b/wallet/src/main/java/net/taler/wallet/withdraw/WithdrawManager.kt index 1066550..2aaa5dc 100644 --- a/wallet/src/main/java/net/taler/wallet/withdraw/WithdrawManager.kt +++ b/wallet/src/main/java/net/taler/wallet/withdraw/WithdrawManager.kt @@ -78,9 +78,11 @@ class WithdrawManager( var exchangeFees: ExchangeFees? = null private set - fun withdrawTestkudos() { + fun withdrawTestkudos() = scope.launch { testWithdrawalInProgress.value = true - api.sendRequest("withdrawTestkudos") { _, _ -> + api.request("withdrawTestkudos").onError { + testWithdrawalInProgress.postValue(false) + }.onSuccess { testWithdrawalInProgress.postValue(false) } } -- cgit v1.2.3