|
|
@@ -11,17 +11,40 @@ import kotlinx.coroutines.Job
|
|
|
import kotlinx.coroutines.SupervisorJob
|
|
|
import kotlinx.coroutines.delay
|
|
|
import kotlinx.coroutines.launch
|
|
|
-import org.slf4j.Logger
|
|
|
-import org.slf4j.LoggerFactory
|
|
|
|
|
|
+/**
|
|
|
+ * 蓝牙队列调度器
|
|
|
+ */
|
|
|
abstract class BleQueueDispatcher {
|
|
|
+ /**
|
|
|
+ * 任务队列
|
|
|
+ */
|
|
|
private val taskQueue =
|
|
|
ArrayDeque<Pair<String, MutableList<(Boolean) -> Unit>>>() // mac + callback
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 正在连接的设备
|
|
|
+ */
|
|
|
private val activeMacs = mutableMapOf<String, MutableList<(Boolean) -> Unit>>()
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 已连接的设备
|
|
|
+ */
|
|
|
private val connectedMacs = mutableSetOf<String>()
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 断连计划
|
|
|
+ */
|
|
|
private val pendingDisconnectJobs = mutableMapOf<String, Job>()
|
|
|
|
|
|
+ /**
|
|
|
+ * 最大连接数
|
|
|
+ */
|
|
|
open val maxConnections: Int = 1
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 协程作用域
|
|
|
+ */
|
|
|
private val dispatcherScope = CoroutineScope(Dispatchers.IO + SupervisorJob())
|
|
|
|
|
|
/**
|
|
|
@@ -30,7 +53,6 @@ abstract class BleQueueDispatcher {
|
|
|
@Synchronized
|
|
|
fun submit(mac: String, onResult: (Boolean) -> Unit) {
|
|
|
LogUtil.i("开始检查钥匙状态:${mac}")
|
|
|
-
|
|
|
if (activeMacs.containsKey(mac) || taskQueue.any { it.first == mac } || connectedMacs.contains(
|
|
|
mac
|
|
|
)) {
|
|
|
@@ -74,8 +96,14 @@ abstract class BleQueueDispatcher {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 连接
|
|
|
+ */
|
|
|
protected abstract fun doConnect(mac: String, callback: (Boolean) -> Unit)
|
|
|
|
|
|
+ /**
|
|
|
+ * 移除设备
|
|
|
+ */
|
|
|
@Synchronized
|
|
|
fun clear(mac: String) {
|
|
|
taskQueue.removeIf { it.first == mac }
|
|
|
@@ -84,6 +112,9 @@ abstract class BleQueueDispatcher {
|
|
|
pendingDisconnectJobs.remove(mac)?.cancel()
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 计划断连
|
|
|
+ */
|
|
|
@SuppressLint("MissingPermission")
|
|
|
@Synchronized
|
|
|
fun scheduleDisconnect(mac: String, delayMillis: Long = 0) {
|
|
|
@@ -112,14 +143,21 @@ abstract class BleQueueDispatcher {
|
|
|
pendingDisconnectJobs[mac] = job
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 断开设备连接
|
|
|
+ */
|
|
|
@SuppressLint("MissingPermission")
|
|
|
private fun disconnectDeviceByMac(mac: String) {
|
|
|
val device = BleManager.getAllConnectedDevice().find { it.mac == mac }
|
|
|
if (device != null) {
|
|
|
+ BleCmdManager.bleDisconnectReq(mac, null)
|
|
|
BleManager.disconnect(device)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 断开所有连接
|
|
|
+ */
|
|
|
@Synchronized
|
|
|
fun disconnectAll(delayMillis: Long = 0) {
|
|
|
val allMacs = connectedMacs.toList()
|
|
|
@@ -128,17 +166,29 @@ abstract class BleQueueDispatcher {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-
|
|
|
+ /**
|
|
|
+ * 是否正在连接
|
|
|
+ */
|
|
|
fun isConnecting(mac: String): Boolean = activeMacs.containsKey(mac)
|
|
|
- fun isQueued(mac: String): Boolean = taskQueue.any { it.first == mac }
|
|
|
- fun isConnected(mac: String): Boolean = connectedMacs.contains(mac)
|
|
|
|
|
|
- fun getConnectedMacs(): List<String> = connectedMacs.toList()
|
|
|
+ /**
|
|
|
+ * 是否在队列中
|
|
|
+ */
|
|
|
+ fun isQueued(mac: String): Boolean = taskQueue.any { it.first == mac }
|
|
|
|
|
|
- fun getActiveMacs(): List<String> = activeMacs.keys.toList()
|
|
|
+ /**
|
|
|
+ * 是否已经连接
|
|
|
+ */
|
|
|
+ fun isConnected(mac: String): Boolean = connectedMacs.contains(mac)
|
|
|
|
|
|
+ /**
|
|
|
+ * 是否可以连接
|
|
|
+ */
|
|
|
fun canConnect(): Boolean = (activeMacs.size + connectedMacs.size) <= maxConnections
|
|
|
|
|
|
+ /**
|
|
|
+ * 是否可以断连
|
|
|
+ */
|
|
|
fun shouldDisconnect(mac: String): Boolean =
|
|
|
isConnecting(mac) || isQueued(mac) || isConnected(mac)
|
|
|
}
|