/
PluginManager.kt
121 lines (103 loc) · 3.75 KB
/
PluginManager.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
package app.tauri.plugin
import android.content.Intent
import android.webkit.WebView
import androidx.activity.result.ActivityResult
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import app.tauri.JniMethod
import app.tauri.Logger
class PluginManager(val activity: AppCompatActivity) {
fun interface RequestPermissionsCallback {
fun onResult(permissions: Map<String, Boolean>)
}
fun interface ActivityResultCallback {
fun onResult(result: ActivityResult)
}
private val plugins: HashMap<String, PluginHandle> = HashMap()
private val startActivityForResultLauncher: ActivityResultLauncher<Intent>
private val requestPermissionsLauncher: ActivityResultLauncher<Array<String>>
private var requestPermissionsCallback: RequestPermissionsCallback? = null
private var startActivityForResultCallback: ActivityResultCallback? = null
init {
startActivityForResultLauncher =
activity.registerForActivityResult(ActivityResultContracts.StartActivityForResult()
) { result ->
if (startActivityForResultCallback != null) {
startActivityForResultCallback!!.onResult(result)
}
}
requestPermissionsLauncher =
activity.registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()
) { result ->
if (requestPermissionsCallback != null) {
requestPermissionsCallback!!.onResult(result)
}
}
}
fun startActivityForResult(intent: Intent, callback: ActivityResultCallback) {
startActivityForResultCallback = callback
startActivityForResultLauncher.launch(intent)
}
fun requestPermissions(
permissionStrings: Array<String>,
callback: RequestPermissionsCallback
) {
requestPermissionsCallback = callback
requestPermissionsLauncher.launch(permissionStrings)
}
@JniMethod
fun onWebViewCreated(webView: WebView) {
for ((_, plugin) in plugins) {
if (!plugin.loaded) {
plugin.load(webView)
}
}
}
@JniMethod
fun load(webView: WebView?, name: String, plugin: Plugin, config: JSObject) {
val handle = PluginHandle(this, name, plugin, config)
plugins[name] = handle
if (webView != null) {
plugin.load(webView)
}
}
@JniMethod
fun postIpcMessage(webView: WebView, pluginId: String, command: String, data: JSObject, callback: Long, error: Long) {
val invoke = Invoke(callback, command, { successResult, errorResult ->
val (fn, result) = if (errorResult == null) Pair(callback, successResult) else Pair(
error,
errorResult
)
webView.evaluateJavascript("window['_$fn']($result)", null)
}, data)
dispatchPluginMessage(invoke, pluginId)
}
@JniMethod
fun runCommand(id: Int, pluginId: String, command: String, data: JSObject) {
val invoke = Invoke(id.toLong(), command, { successResult, errorResult ->
handlePluginResponse(id, successResult?.toString(), errorResult?.toString())
}, data)
dispatchPluginMessage(invoke, pluginId)
}
private fun dispatchPluginMessage(invoke: Invoke, pluginId: String) {
Logger.verbose(
Logger.tags("Plugin"),
"Tauri plugin: pluginId: $pluginId, command: ${invoke.command}"
)
try {
val plugin = plugins[pluginId]
if (plugin == null) {
invoke.reject("Plugin $pluginId not initialized")
} else {
plugins[pluginId]?.invoke(invoke)
}
} catch (e: Exception) {
invoke.reject(e.toString())
}
}
private external fun handlePluginResponse(id: Int, success: String?, error: String?)
}