Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion android/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
/build
/.tauri
/.tauri
/.gradle
67 changes: 57 additions & 10 deletions android/src/main/kotlin/app/tauri/serialplugin/SerialPlugin.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
@file:Suppress("unused")

package app.tauri.serialplugin

import android.app.Activity
import android.content.Context
import app.tauri.annotation.Command
import app.tauri.annotation.InvokeArg
import app.tauri.annotation.TauriPlugin
Expand All @@ -13,7 +14,45 @@ import app.tauri.serialplugin.models.*
import android.webkit.WebView
import android.util.Log
import java.util.concurrent.ConcurrentHashMap
import app.tauri.plugin.JSArray
// --- Reused from previous answer (Converts a Map to a JSObject) ---
fun Map<String, Any?>.toJSObject(): JSObject {
val jsObject = JSObject()
for ((key, value) in this) {
val convertedValue: Any? = when (value) {
is Map<*, *> -> @Suppress("UNCHECKED_CAST") (value as Map<String, Any?>).toJSObject()
is List<*> -> @Suppress("UNCHECKED_CAST") value.toJSArray() // Call the new list utility
else -> value
}
jsObject.put(key, convertedValue)
}
return jsObject
}

// --- NEW Utility: Converts a List to a JSArray ---
fun List<Any?>.toJSArray(): JSArray {
val jsArray = JSArray()

for (item in this) {
val convertedItem: Any? = when (item) {
is Map<*, *> -> {
// If the item is a Map, convert it to a JSObject
@Suppress("UNCHECKED_CAST")
(item as Map<String, Any?>).toJSObject()
}
is List<*> -> {
// If the item is a nested List, convert it to a JSArray (for list of lists)
@Suppress("UNCHECKED_CAST")
item.toJSArray()
}
else -> item // Primitives (String, Int, Boolean, etc.) can be put directly
}
// Add the converted item to the JSArray
jsArray.put(convertedItem)
}

return jsArray
}
@InvokeArg
class PortConfigArgs {
lateinit var path: String
Expand All @@ -32,6 +71,12 @@ class WriteArgs {
lateinit var value: String
}

@InvokeArg
class WriteBinaryArgs {
lateinit var path: String
lateinit var value: List<Int>
}

@InvokeArg
class CloseArgs {
lateinit var path: String
Expand All @@ -51,14 +96,14 @@ class SerialPlugin(private val activity: Activity) : Plugin(activity) {
Log.d("SerialPlugin", "SerialPlugin loaded successfully")
}

override fun onDetach() {
override fun onDestroy() {
try {
Log.d("SerialPlugin", "SerialPlugin detaching, cleaning up resources")
serialPortManager.cleanup()
} catch (e: Exception) {
Log.e("SerialPlugin", "Failed to cleanup: ${e.message}", e)
}
super.onDetach()
super.onDestroy()
}

@Command
Expand All @@ -68,7 +113,8 @@ class SerialPlugin(private val activity: Activity) : Plugin(activity) {
val ports = serialPortManager.getAvailablePorts()
Log.d("SerialPlugin", "Available ports fetched successfully: ${ports.size} ports")
val result = JSObject()
result.put("ports", ports)

result.put("ports", ports.toJSObject())
invoke.resolve(result)
} catch (e: Exception) {
Log.e("SerialPlugin", "Failed to get available ports: ${e.message}", e)
Expand Down Expand Up @@ -208,9 +254,10 @@ class SerialPlugin(private val activity: Activity) : Plugin(activity) {
@Command
fun writeBinary(invoke: Invoke) {
try {
val args = invoke.parseArgs(WriteArgs::class.java)
val args = invoke.parseArgs(WriteBinaryArgs::class.java)
Log.d("SerialPlugin", "Writing binary to port: ${args.path}")
val bytesWritten = serialPortManager.writeToPort(args.path, args.value.toByteArray())
val bytesToSend = args.value.map { it.toByte() }.toByteArray()
val bytesWritten = serialPortManager.writeToPort(args.path, bytesToSend)
val result = JSObject()
result.put("bytesWritten", bytesWritten)
Log.d("SerialPlugin", "Binary write successful: $bytesWritten bytes written")
Expand All @@ -226,7 +273,7 @@ class SerialPlugin(private val activity: Activity) : Plugin(activity) {
try {
val args = invoke.parseArgs(PortConfigArgs::class.java)
Log.d("SerialPlugin", "Reading from port: ${args.path}")
val data = serialPortManager.readFromPort(args.path, args.timeout, 1024)
val data = serialPortManager.readFromPort(args.path, args.timeout, args.size)
val result = JSObject()
result.put("data", String(data))
Log.d("SerialPlugin", "Read successful: ${data.size} bytes read")
Expand All @@ -242,9 +289,9 @@ class SerialPlugin(private val activity: Activity) : Plugin(activity) {
try {
val args = invoke.parseArgs(PortConfigArgs::class.java)
Log.d("SerialPlugin", "Reading binary from port: ${args.path}")
val data = serialPortManager.readFullyFromPort(args.path, args.timeout, args.size)
val data = serialPortManager.readFromPort(args.path, args.timeout, args.size)
val result = JSObject().apply {
put("data", data.toList())
put("data", data.toList().map { it.toInt() and 0xFF }.toJSArray())
}
Log.d("SerialPlugin", "Binary read successful: ${data.size} bytes read")
invoke.resolve(result)
Expand All @@ -260,7 +307,7 @@ class SerialPlugin(private val activity: Activity) : Plugin(activity) {
val args = invoke.parseArgs(CloseArgs::class.java)
Log.d("SerialPlugin", "Starting listening on port: ${args.path}")

val listener = { data: ByteArray ->
val listener: (ByteArray) -> Unit = { data: ByteArray ->
try {
val eventData = JSObject()
eventData.put("path", args.path)
Expand Down
Loading
Loading