Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
# Added
- Added pigeon generated classes for FsManager methods.
- Added FsManagerPlugin native classes to handle method channel calls for the FsManager class.
  • Loading branch information
keith-lytc committed Jul 17, 2025
commit 84e493aa0d3d2c0f7096aac1f492bde45366157c
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
package no.nordicsemi.android.mcumgr_flutter

import android.bluetooth.BluetoothAdapter
import android.content.Context
import android.os.Handler
import io.flutter.plugin.common.BinaryMessenger
import io.runtime.mcumgr.McuMgrCallback
import io.runtime.mcumgr.exception.McuMgrException
import io.runtime.mcumgr.managers.FsManager
import io.runtime.mcumgr.response.fs.McuMgrFsStatusResponse
import io.runtime.mcumgr.transfer.DownloadCallback
import io.runtime.mcumgr.transfer.TransferController
import no.nordicsemi.android.mcumgr_flutter.logging.LoggableMcuMgrBleTransport
import no.nordicsemi.android.mcumgr_flutter.utils.StreamHandler
import no.nordicsemi.android.mcumgr_flutter.utils.FsDownloadStreamHandler

class FsManagerPlugin(
private val context: Context,
private val logStreamHandler: StreamHandler,
binaryMessenger: BinaryMessenger,
private val mainHandler: Handler,
) : FsManagerApi {

private val fsDownloadStreamHandler = FsDownloadStreamHandler()
private var fsManagers: MutableMap<String, FsManager> = mutableMapOf()
private var controllers = mutableMapOf<String, TransferController>()

init {
GetFileDownloadEventsStreamHandler.register(binaryMessenger, fsDownloadStreamHandler)
FsManagerApi.setUp(
binaryMessenger,
this
)
}

private fun getFsManager(remoteId: String): FsManager {
synchronized(this) {
return fsManagers[remoteId]
?: run {
val device = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(remoteId)
val transport = LoggableMcuMgrBleTransport(context, device, logStreamHandler)
.apply { setLoggingEnabled(true) }
val mgr = FsManager(transport)
fsManagers[remoteId] = mgr
mgr
}
}
}

override fun download(remoteId: String, path: String) {
if (controllers[remoteId] != null) {
throw FlutterError("TODO code", "A transfer is already ongoing for $remoteId.")
}
val mgr = getFsManager(remoteId)
mgr.fileDownload(
path,
object : DownloadCallback {
override fun onDownloadProgressChanged(current: Int, total: Int, timestamp: Long) {
mainHandler.post {
fsDownloadStreamHandler.onEvent(
OnDownloadProgressChangedEvent(current.toLong(), total.toLong(), timestamp, remoteId, path)
)
}
}

override fun onDownloadFailed(p0: McuMgrException) {
controllers.remove(remoteId)
mainHandler.post {
fsDownloadStreamHandler.onEvent(
OnDownloadFailedEvent(p0.message, remoteId, path)
)
}
}

override fun onDownloadCanceled() {
controllers.remove(remoteId)
mainHandler.post {
fsDownloadStreamHandler.onEvent(
OnDownloadCancelledEvent(remoteId, path)
)
}
}

override fun onDownloadCompleted(p0: ByteArray) {
controllers.remove(remoteId)
mainHandler.post {
fsDownloadStreamHandler.onEvent(
OnDownloadCompletedEvent(remoteId, path, p0)
)
}
}
}
)
}

override fun pauseTransfer(remoteId: String) {
fsManagers[remoteId]?.pauseTransfer()
}

override fun continueTransfer(remoteId: String) {
fsManagers[remoteId]?.continueTransfer()
}

override fun cancelTransfer(remoteId: String) {
fsManagers[remoteId]?.cancelTransfer()
}

override fun status(remoteId: String, path: String, callback: (Result<Long>) -> Unit) {
val mgr = getFsManager(remoteId)
mgr.status(
path,
object : McuMgrCallback<McuMgrFsStatusResponse> {
override fun onResponse(p0: McuMgrFsStatusResponse) {
callback(Result.success(p0.len.toLong()))
}

override fun onError(p0: McuMgrException) {
callback(Result.failure(p0))
}
}
)
}

override fun kill(remoteId: String) {
fsManagers.remove(remoteId)?.transporter?.release()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package no.nordicsemi.android.mcumgr_flutter

import android.bluetooth.BluetoothAdapter
import android.content.Context
import android.os.Handler
import android.os.Looper
import android.util.Pair
import androidx.annotation.NonNull
import com.google.protobuf.kotlin.toByteString
Expand All @@ -16,6 +18,7 @@ import io.runtime.mcumgr.dfu.mcuboot.FirmwareUpgradeManager
import io.runtime.mcumgr.exception.McuMgrException
import io.runtime.mcumgr.response.img.McuMgrImageStateResponse
import no.nordicsemi.android.mcumgr_flutter.ext.toProto
import io.runtime.mcumgr.managers.FsManager

import no.nordicsemi.android.mcumgr_flutter.logging.LoggableMcuMgrBleTransport
import no.nordicsemi.android.mcumgr_flutter.utils.*
Expand All @@ -31,6 +34,8 @@ class McumgrFlutterPlugin : FlutterPlugin, MethodCallHandler {
/// when the Flutter Engine is detached from the Activity
private lateinit var methodChannel: MethodChannel

private lateinit var mainHandler: Handler

private lateinit var updateStateEventChannel: EventChannel
private lateinit var updateProgressEventChannel: EventChannel
private lateinit var logEventChannel: EventChannel
Expand All @@ -42,9 +47,11 @@ class McumgrFlutterPlugin : FlutterPlugin, MethodCallHandler {
private lateinit var context: Context

private var managers: MutableMap<String, UpdateManager> = mutableMapOf()
private lateinit var fsManagerPlugin: FsManagerPlugin

override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
context = flutterPluginBinding.applicationContext
mainHandler = Handler(Looper.getMainLooper())

methodChannel = MethodChannel(flutterPluginBinding.binaryMessenger, "$namespace/method_channel")
methodChannel.setMethodCallHandler(this)
Expand All @@ -55,6 +62,13 @@ class McumgrFlutterPlugin : FlutterPlugin, MethodCallHandler {
updateProgressEventChannel.setStreamHandler(updateProgressStreamHandler)
logEventChannel = EventChannel(flutterPluginBinding.binaryMessenger, "$namespace/log_event_channel")
logEventChannel.setStreamHandler(logStreamHandler)

fsManagerPlugin = FsManagerPlugin(
context,
logStreamHandler,
flutterPluginBinding.binaryMessenger,
mainHandler
)
}

override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) {
Expand Down
Loading