diff options
author | Iván Ávalos <avalos@disroot.org> | 2023-11-14 14:13:51 -0600 |
---|---|---|
committer | Torsten Grote <t@grobox.de> | 2023-11-28 13:59:37 -0300 |
commit | ba51b5e541d888cafdbf479a7e03a116af7050c5 (patch) | |
tree | a8b893bd8dd0212cba11cd0af75e95eb8b7a7bd0 /wallet/src/main/java/net/taler | |
parent | 94ee3a2f114e0345ea7408aacc30e3da9545474c (diff) | |
download | taler-android-ba51b5e541d888cafdbf479a7e03a116af7050c5.tar.gz taler-android-ba51b5e541d888cafdbf479a7e03a116af7050c5.tar.bz2 taler-android-ba51b5e541d888cafdbf479a7e03a116af7050c5.zip |
[wallet] Proper DB import/export functionality
Diffstat (limited to 'wallet/src/main/java/net/taler')
4 files changed, 116 insertions, 17 deletions
diff --git a/wallet/src/main/java/net/taler/wallet/MainViewModel.kt b/wallet/src/main/java/net/taler/wallet/MainViewModel.kt index 15fe7e4..4614474 100644 --- a/wallet/src/main/java/net/taler/wallet/MainViewModel.kt +++ b/wallet/src/main/java/net/taler/wallet/MainViewModel.kt @@ -83,7 +83,7 @@ class MainViewModel( val refundManager = RefundManager(api, viewModelScope) val exchangeManager: ExchangeManager = ExchangeManager(api, viewModelScope) val peerManager: PeerManager = PeerManager(api, exchangeManager, viewModelScope) - val settingsManager: SettingsManager = SettingsManager(app.applicationContext, viewModelScope) + val settingsManager: SettingsManager = SettingsManager(app.applicationContext, api, viewModelScope) val accountManager: AccountManager = AccountManager(api, viewModelScope) val depositManager: DepositManager = DepositManager(api, viewModelScope) diff --git a/wallet/src/main/java/net/taler/wallet/backend/WalletBackendApi.kt b/wallet/src/main/java/net/taler/wallet/backend/WalletBackendApi.kt index bf6f371..ea58dd7 100644 --- a/wallet/src/main/java/net/taler/wallet/backend/WalletBackendApi.kt +++ b/wallet/src/main/java/net/taler/wallet/backend/WalletBackendApi.kt @@ -23,6 +23,7 @@ import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import kotlinx.serialization.KSerializer +import kotlinx.serialization.json.JsonObject import kotlinx.serialization.json.decodeFromJsonElement import net.taler.wallet.backend.TalerErrorCode.NONE import org.json.JSONObject @@ -86,4 +87,26 @@ class WalletBackendApi( WalletResponse.Error(info) } } + + // Returns raw JSON response instead of serialized object + suspend inline fun rawRequest( + operation: String, + noinline args: (JSONObject.() -> JSONObject)? = null, + ): WalletResponse<JsonObject> = withContext(Dispatchers.Default) { + val json = BackendManager.json + try { + when (val response = sendRequest(operation, args?.invoke(JSONObject()))) { + is ApiResponse.Response -> { + WalletResponse.Success(response.result) + } + is ApiResponse.Error -> { + val error: TalerErrorInfo = json.decodeFromJsonElement(response.error) + WalletResponse.Error(error) + } + } + } catch (e: Exception) { + val info = TalerErrorInfo(NONE, "", e.toString()) + WalletResponse.Error(info) + } + } } diff --git a/wallet/src/main/java/net/taler/wallet/settings/SettingsFragment.kt b/wallet/src/main/java/net/taler/wallet/settings/SettingsFragment.kt index f5826c9..54d6dc0 100644 --- a/wallet/src/main/java/net/taler/wallet/settings/SettingsFragment.kt +++ b/wallet/src/main/java/net/taler/wallet/settings/SettingsFragment.kt @@ -18,6 +18,7 @@ package net.taler.wallet.settings import android.os.Bundle import android.view.View +import androidx.activity.result.contract.ActivityResultContracts.OpenDocument import androidx.activity.result.contract.ActivityResultContracts.CreateDocument import androidx.fragment.app.activityViewModels import androidx.preference.Preference @@ -47,6 +48,7 @@ class SettingsFragment : PreferenceFragmentCompat() { private lateinit var prefWithdrawTest: Preference private lateinit var prefLogcat: Preference private lateinit var prefExportDb: Preference + private lateinit var prefImportDb: Preference private lateinit var prefVersionApp: Preference private lateinit var prefVersionCore: Preference private lateinit var prefVersionExchange: Preference @@ -58,6 +60,7 @@ class SettingsFragment : PreferenceFragmentCompat() { prefWithdrawTest, prefLogcat, prefExportDb, + prefImportDb, prefVersionApp, prefVersionCore, prefVersionExchange, @@ -71,9 +74,13 @@ class SettingsFragment : PreferenceFragmentCompat() { settingsManager.exportLogcat(uri) } private val dbExportLauncher = - registerForActivityResult(CreateDocument("application/x-sqlite3")) { uri -> + registerForActivityResult(CreateDocument("application/json")) { uri -> settingsManager.exportDb(uri) } + private val dbImportLauncher = + registerForActivityResult(OpenDocument()) { uri -> + settingsManager.importDb(uri) + } override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { setPreferencesFromResource(R.xml.settings_main, rootKey) @@ -81,6 +88,7 @@ class SettingsFragment : PreferenceFragmentCompat() { prefWithdrawTest = findPreference("pref_testkudos")!! prefLogcat = findPreference("pref_logcat")!! prefExportDb = findPreference("pref_export_db")!! + prefImportDb = findPreference("pref_import_db")!! prefVersionApp = findPreference("pref_version_app")!! prefVersionCore = findPreference("pref_version_core")!! prefVersionExchange = findPreference("pref_version_protocol_exchange")!! @@ -127,10 +135,13 @@ class SettingsFragment : PreferenceFragmentCompat() { true } prefExportDb.setOnPreferenceClickListener { - dbExportLauncher.launch("taler-wallet-db-${currentTimeMillis()}.sql") + dbExportLauncher.launch("taler-wallet-db-${currentTimeMillis()}.json") + true + } + prefImportDb.setOnPreferenceClickListener { + dbImportLauncher.launch(arrayOf("application/json")) true } - prefTest.setOnPreferenceClickListener { model.runIntegrationTest() true diff --git a/wallet/src/main/java/net/taler/wallet/settings/SettingsManager.kt b/wallet/src/main/java/net/taler/wallet/settings/SettingsManager.kt index 349c7b1..0b4cbe9 100644 --- a/wallet/src/main/java/net/taler/wallet/settings/SettingsManager.kt +++ b/wallet/src/main/java/net/taler/wallet/settings/SettingsManager.kt @@ -25,14 +25,19 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext +import kotlinx.serialization.encodeToString +import kotlinx.serialization.json.Json import net.taler.wallet.R -import net.taler.wallet.backend.WALLET_DB +import net.taler.wallet.backend.WalletBackendApi +import net.taler.wallet.backend.WalletResponse.Error +import net.taler.wallet.backend.WalletResponse.Success +import org.json.JSONObject class SettingsManager( private val context: Context, + private val api: WalletBackendApi, private val scope: CoroutineScope, ) { - fun exportLogcat(uri: Uri?) { if (uri == null) { onLogExportError() @@ -65,20 +70,76 @@ class SettingsManager( onDbExportError() return } + scope.launch(Dispatchers.IO) { - try { - context.contentResolver.openOutputStream(uri, "wt")?.use { outputStream -> - context.openFileInput(WALLET_DB).use { inputStream -> - inputStream.copyTo(outputStream) + when (val response = api.rawRequest("exportDb")) { + is Success -> { + try { + context.contentResolver.openOutputStream(uri, "wt")?.use { outputStream -> + val data = Json.encodeToString(response.result) + val writer = outputStream.bufferedWriter() + writer.write(data) + writer.close() + } + } catch(e: Exception) { + Log.e(SettingsManager::class.simpleName, "Error exporting db: ", e) + withContext(Dispatchers.Main) { + onDbExportError() + } + return@launch } - } ?: onDbExportError() - } catch (e: Exception) { - Log.e(SettingsManager::class.simpleName, "Error exporting db: ", e) - onDbExportError() - return@launch + + withContext(Dispatchers.Main) { + Toast.makeText(context, R.string.settings_db_export_success, LENGTH_LONG).show() + } + } + is Error -> { + Log.e(SettingsManager::class.simpleName, "Error exporting db: ${response.error}") + withContext(Dispatchers.Main) { + onDbExportError() + } + return@launch + } } - withContext(Dispatchers.Main) { - Toast.makeText(context, R.string.settings_db_export_success, LENGTH_LONG).show() + } + } + + fun importDb(uri: Uri?) { + if (uri == null) { + onDbImportError() + return + } + + scope.launch(Dispatchers.IO) { + context.contentResolver.openInputStream(uri)?.use { inputStream -> + try { + val reader = inputStream.bufferedReader() + val strData = reader.readText() + reader.close() + val jsonData = JSONObject(strData) + when (val response = api.rawRequest("importDb") { + put("dump", jsonData) + }) { + is Success -> { + withContext(Dispatchers.Main) { + Toast.makeText(context, R.string.settings_db_import_success, LENGTH_LONG).show() + } + } + is Error -> { + Log.e(SettingsManager::class.simpleName, "Error importing db: ${response.error}") + withContext(Dispatchers.Main) { + onDbImportError() + } + return@launch + } + } + } catch (e: Exception) { + Log.e(SettingsManager::class.simpleName, "Error importing db: ", e) + withContext(Dispatchers.Main) { + onDbImportError() + } + return@launch + } } } } @@ -87,4 +148,8 @@ class SettingsManager( Toast.makeText(context, R.string.settings_db_export_error, LENGTH_LONG).show() } + private fun onDbImportError() { + Toast.makeText(context, R.string.settings_db_import_error, LENGTH_LONG).show() + } + } |