From 58945aee06efa9f73b93cda654349414fec23b07 Mon Sep 17 00:00:00 2001 From: Iván Ávalos Date: Wed, 18 Jan 2023 19:45:52 -0600 Subject: [wallet] Initial work for QuickJS migration. --- wallet/.gitignore | 2 +- wallet/build.gradle | 42 ++++----------- wallet/proguard-rules.pro | 3 ++ wallet/src/main/AndroidManifest.xml | 5 +- .../net/taler/wallet/backend/TalerWalletCore.kt | 61 ++++++++++++++++++++++ .../taler/wallet/backend/WalletBackendService.kt | 57 +++++++++++++------- 6 files changed, 116 insertions(+), 54 deletions(-) create mode 100644 wallet/src/main/java/net/taler/wallet/backend/TalerWalletCore.kt (limited to 'wallet') diff --git a/wallet/.gitignore b/wallet/.gitignore index 44ca846..5ddaed3 100644 --- a/wallet/.gitignore +++ b/wallet/.gitignore @@ -1,3 +1,3 @@ /build /.bundle -/src/main/assets/taler-wallet-*-*.js +/src/main/jniLibs \ No newline at end of file diff --git a/wallet/build.gradle b/wallet/build.gradle index fb897c6..76f909e 100644 --- a/wallet/build.gradle +++ b/wallet/build.gradle @@ -45,8 +45,8 @@ android { defaultConfig { applicationId "net.taler.wallet" - minSdkVersion 21 - targetSdkVersion 32 + minSdkVersion 24 + targetSdkVersion 33 versionCode 21 versionName walletCoreVersion testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" @@ -54,11 +54,13 @@ android { } buildTypes { release { - minifyEnabled true + // FIXME: walletcore only works when this is false + minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } debug { - minifyEnabled minify_debug + // FIXME: walletcore only works when this is false + minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } @@ -116,7 +118,6 @@ android { dependencies { implementation project(":taler-kotlin-android") - implementation 'net.taler:akono:0.2' implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" @@ -160,36 +161,15 @@ dependencies { implementation "io.noties.markwon:ext-tables:$markwon_version" implementation "io.noties.markwon:recycler:$markwon_version" + // Java Native access + implementation "net.java.dev.jna:jna:5.13.0@aar" + testImplementation "junit:junit:$junit_version" testImplementation 'org.json:json:20220320' } -def walletLibraryDir = "src/main/assets" -def walletDestFile = "${walletLibraryDir}/taler-wallet-embedded-${walletCoreVersion}.js" -task downloadWalletLibrary(type: Download, dependsOn: preBuild) { - src "https://git.taler.net/wallet-core.git/plain/${walletCoreVersion}/taler-wallet-embedded.js?h=prebuilt" - dest walletDestFile - onlyIfModified true - overwrite false - doFirst { - new File(walletLibraryDir).mkdirs() - if (!file(dest).exists()) { // delete old versions before fetching new one - delete fileTree(walletLibraryDir) { - include 'taler-wallet-embedded-*.js' - } - } - } -} -task verifyWalletLibrary(type: Verify, dependsOn: downloadWalletLibrary) { - src walletDestFile - algorithm 'SHA-256' - checksum walletCoreSha256 -} - -tasks.withType(MergeResources) { - inputs.dir walletLibraryDir - dependsOn verifyWalletLibrary -} +// FIXME: add download and verify tasks for .so files +// (They should go on src/main/jniLibs/${ANDROID_ABI}/libtalerwalletcore.so) tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach { kotlinOptions { diff --git a/wallet/proguard-rules.pro b/wallet/proguard-rules.pro index 04cb4da..f08a431 100644 --- a/wallet/proguard-rules.pro +++ b/wallet/proguard-rules.pro @@ -24,3 +24,6 @@ #noinspection ShrinkerUnresolvedReference -keep class net.taler.wallet.** {*;} + +-keep class com.sun.jna.** {*;} +-keep class * implements com.sun.jna.** {*;} \ No newline at end of file diff --git a/wallet/src/main/AndroidManifest.xml b/wallet/src/main/AndroidManifest.xml index c40b87e..6498714 100644 --- a/wallet/src/main/AndroidManifest.xml +++ b/wallet/src/main/AndroidManifest.xml @@ -24,7 +24,9 @@ + + + tools:ignore="GoogleAppIndexingWarning"> + */ + +/* + * This file is part of GNU Taler + * (C) 2023 Taler Systems S.A. + * + * GNU Taler is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 3, or (at your option) any later version. + * + * GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * GNU Taler; see the file COPYING. If not, see + */ + +package net.taler.wallet.backend + +import com.sun.jna.Callback +import com.sun.jna.Library +import com.sun.jna.Native +import com.sun.jna.Pointer + +interface TalerWalletCore: Library { + companion object { + val INSTANCE: TalerWalletCore by lazy { + Native.load("talerwalletcore", TalerWalletCore::class.java) + } + } + + interface TALER_WALLET_MessageHandlerFn: Callback { + fun invoke(handler_p: Pointer, message: String) + } + + interface TALER_LogFn: Callback { + fun invoke(cls: Pointer, stream: Int, msg: String) + } + + fun TALER_WALLET_create(): Pointer + fun TALER_WALLET_set_message_handler(twi: Pointer, handler_f: TALER_WALLET_MessageHandlerFn, handler_p: Pointer) + fun TALER_WALLET_send_request(twi: Pointer, request: String): Int + fun TALER_WALLET_run(twi: Pointer): Int + fun TALER_WALLET_join(twi: Pointer) + fun TALER_start_redirect_std(logfn: TALER_LogFn, cls: Pointer) +} \ No newline at end of file diff --git a/wallet/src/main/java/net/taler/wallet/backend/WalletBackendService.kt b/wallet/src/main/java/net/taler/wallet/backend/WalletBackendService.kt index 06e0627..7b93a21 100644 --- a/wallet/src/main/java/net/taler/wallet/backend/WalletBackendService.kt +++ b/wallet/src/main/java/net/taler/wallet/backend/WalletBackendService.kt @@ -25,8 +25,7 @@ import android.os.Message import android.os.Messenger import android.os.RemoteException import android.util.Log -import net.taler.akono.AkonoJni -import net.taler.wallet.BuildConfig.WALLET_CORE_VERSION +import com.sun.jna.Pointer import net.taler.wallet.HostCardEmulatorService import org.json.JSONObject import java.lang.ref.WeakReference @@ -46,7 +45,8 @@ class WalletBackendService : Service() { */ private val messenger: Messenger = Messenger(IncomingHandler(this)) - private lateinit var akono: AkonoJni + private lateinit var walletCore: TalerWalletCore + private lateinit var instance: Pointer private var initialized = false @@ -57,25 +57,23 @@ class WalletBackendService : Service() { private val subscribers = LinkedList() override fun onCreate() { - val talerWalletAndroidCode = - assets.open("taler-wallet-embedded-$WALLET_CORE_VERSION.js").use { - it.readBytes().toString(Charsets.UTF_8) - } - - Log.i(TAG, "onCreate in wallet backend service") - akono = AkonoJni() - akono.putModuleCode("@gnu-taler/taler-wallet-embedded", talerWalletAndroidCode) - akono.setMessageHandler(object : AkonoJni.MessageHandler { - override fun handleMessage(message: String) { + + walletCore = TalerWalletCore.INSTANCE + instance = walletCore.TALER_WALLET_create() + walletCore.TALER_WALLET_set_message_handler(instance, object: TalerWalletCore.TALER_WALLET_MessageHandlerFn { + override fun invoke(handler_p: Pointer, message: String) { this@WalletBackendService.handleAkonoMessage(message) } - }) - //akono.evalNodeCode("require('source-map-support').install();") - akono.evalNodeCode("require('akono');") - akono.evalNodeCode("tw = require('@gnu-taler/taler-wallet-embedded');") - akono.evalNodeCode("tw.installNativeWalletListener();") + }, instance) + walletCore.TALER_start_redirect_std(object: TalerWalletCore.TALER_LogFn { + override fun invoke(cls: Pointer, stream: Int, msg: String) { + Log.d(TAG, "wallet log: $msg") + } + }, instance) + walletCore.TALER_WALLET_run(instance) sendInitMessage() + // runIntegrationTest() super.onCreate() } @@ -85,7 +83,26 @@ class WalletBackendService : Service() { val args = JSONObject() msg.put("args", args) args.put("persistentStoragePath", "${application.filesDir}/$WALLET_DB") - akono.sendMessage(msg.toString()) + Log.d(TAG, "init message: ${msg.toString(2)}") + walletCore.TALER_WALLET_send_request(instance, msg.toString()) + } + + /** + * Run the integration tests for wallet-core. + */ + private fun runIntegrationTest() { + val msg = JSONObject() + msg.put("operation", "runIntegrationTest") + val args = JSONObject() + msg.put("args", args) + args.put("amountToWithdraw", "KUDOS:3") + args.put("amountToSpend", "KUDOS:1") + args.put("bankBaseUrl", "https://bank.demo.taler.net/demobanks/default/access-api/") + args.put("exchangeBaseUrl", "https://exchange.demo.taler.net/") + args.put("merchantBaseUrl", "https://backend.demo.taler.net/") + args.put("merchantAuthToken", "secret-token:sandbox") + Log.d(TAG, "integration test message: ${msg.toString(2)}") + walletCore.TALER_WALLET_send_request(instance, msg.toString()) } /** @@ -125,7 +142,7 @@ class WalletBackendService : Service() { request.put("operation", operation) request.put("id", serviceRequestID) request.put("args", argsObj) - svc.akono.sendMessage(request.toString(2)) + svc.walletCore.TALER_WALLET_send_request(svc.instance, request.toString(2)) Log.i( TAG, "mapping service request ID $serviceRequestID to client request ID $clientRequestID" -- cgit v1.2.3