11package com.hoc.node_auth
22
3+ import android.util.Log
4+ import com.google.crypto.tink.subtle.Base64
35import io.flutter.embedding.android.FlutterActivity
6+ import io.flutter.embedding.engine.FlutterEngine
7+ import io.flutter.plugin.common.MethodCall
8+ import io.flutter.plugin.common.MethodChannel
9+ import kotlinx.coroutines.*
410
5- class MainActivity : FlutterActivity () {
11+ class MainActivity : FlutterActivity () {
12+ private lateinit var cryptoChannel: MethodChannel
13+ private lateinit var mainScope: CoroutineScope
14+
15+ // region Lifecycle
16+ override fun configureFlutterEngine (flutterEngine : FlutterEngine ) {
17+ super .configureFlutterEngine(flutterEngine)
18+ Log .d(" Flutter" , " configureFlutterEngine flutterEngine=$flutterEngine $this " )
19+
20+ mainScope = MainScope ()
21+ cryptoChannel = MethodChannel (
22+ flutterEngine.dartExecutor.binaryMessenger,
23+ CRYPTO_CHANNEL ,
24+ ).apply { setMethodCallHandler(MethodCallHandlerImpl ()) }
25+ }
26+
27+ override fun cleanUpFlutterEngine (flutterEngine : FlutterEngine ) {
28+ super .cleanUpFlutterEngine(flutterEngine)
29+ Log .d(" Flutter" , " cleanUpFlutterEngine flutterEngine=$flutterEngine $this " )
30+
31+ cryptoChannel.setMethodCallHandler(null )
32+ mainScope.cancel()
33+ }
34+ // endregion
35+
36+ private inner class MethodCallHandlerImpl : MethodChannel .MethodCallHandler {
37+ override fun onMethodCall (call : MethodCall , result : MethodChannel .Result ) {
38+ when (call.method) {
39+ ENCRYPT_METHOD -> encrypt(call, result)
40+ DECRYPT_METHOD -> decrypt(call, result)
41+ else -> result.notImplemented()
42+ }
43+ }
44+ }
45+
46+ // region Handlers
47+ private fun encrypt (
48+ call : MethodCall ,
49+ result : MethodChannel .Result
50+ ) {
51+ val plaintext = checkNotNull(call.arguments<String ?>()) { " plaintext must be not null" }
52+
53+ mainScope.launch {
54+ runCatching {
55+ withContext(Dispatchers .IO ) {
56+ plaintext
57+ .encodeToByteArray()
58+ .let { myApp.aead.encrypt(it, null ) }
59+ .let { Base64 .encode(it) }
60+ }
61+ }
62+ .onSuccess { result.success(it) }
63+ .onFailureExceptCancellationException {
64+ Log .e(" Flutter" , " encrypt" , it)
65+ result.error(CRYPTO_ERROR_CODE , it.message, null )
66+ }
67+ }
68+ }
69+
70+ private fun decrypt (
71+ call : MethodCall ,
72+ result : MethodChannel .Result
73+ ) {
74+ val ciphertext = checkNotNull(call.arguments<String ?>()) { " ciphertext must be not null" }
75+
76+ mainScope.launch {
77+ runCatching {
78+ withContext(Dispatchers .IO ) {
79+ Base64
80+ .decode(ciphertext, Base64 .DEFAULT )
81+ .let { myApp.aead.decrypt(it, null ) }
82+ .decodeToString()
83+ }
84+ }
85+ .onSuccess { result.success(it) }
86+ .onFailureExceptCancellationException {
87+ Log .e(" Flutter" , " decrypt" , it)
88+ result.error(CRYPTO_ERROR_CODE , it.message, null )
89+ }
90+ }
91+ }
92+ // endregion
93+
94+ private companion object {
95+ const val CRYPTO_CHANNEL = " com.hoc.node_auth/crypto"
96+ const val CRYPTO_ERROR_CODE = " com.hoc.node_auth/crypto_error"
97+ const val ENCRYPT_METHOD = " encrypt"
98+ const val DECRYPT_METHOD = " decrypt"
99+ }
6100}
101+
102+ private inline fun <T > Result<T>.onFailureExceptCancellationException (action : (throwable: Throwable ) -> Unit ): Result <T > {
103+ return onFailure {
104+ if (it is CancellationException ) throw it
105+ action(it)
106+ }
107+ }
0 commit comments