очки: не гасить экран при закрытии посторонней WS-сессии

Экран залипал в «Нет связи», хотя телефон был подключён и команды
доходили. Причина: currentConn — одна ссылка на все сессии, и ЛЮБОЙ
onDisconnected переводил экран в NoConnection. Лишние сессии создаёт
в т.ч. mDNS-фоллбек телефона (probeWebSocket делает полный WS-апгрейд
для проверки кандидата и сразу рвёт соединение).

Теперь очки ведут набор живых сессий и гасят экран только когда
закрылась последняя.
This commit is contained in:
2026-10-01 14:10:34 +03:00
parent 8be9afb592
commit c02e126bc6
@@ -174,6 +174,16 @@ class VmService : LifecycleService() {
*/
private val currentConn = java.util.concurrent.atomic.AtomicReference<String?>(null)
/**
* Все живые WS-сессии. Связь с телефоном считаем живой, пока жива ХОТЬ ОДНА.
*
* Нельзя вешать `NoConnection` на закрытие конкретной сессии: помимо телефона сюда
* прилетают короткоживущие сессии (mDNS-фоллбек телефона делает полный WS-апгрейд
* для проверки кандидата и сразу рвёт соединение). Из-за этого экран очков залипал
* в «Нет связи», хотя телефон был подключён и команды доходили.
*/
private val liveConns = java.util.concurrent.ConcurrentHashMap.newKeySet<String>()
/** Ресивер `ACTION_SCREEN_ON/OFF`: сообщаем телефону реальное состояние экрана очков. */
private var screenReceiver: BroadcastReceiver? = null
@@ -186,7 +196,8 @@ class VmService : LifecycleService() {
handleIncoming(connId, json)
},
onConnected = { connId ->
Log.i(TAG, "Phone connected: $connId")
liveConns.add(connId)
Log.i(TAG, "Phone connected: $connId (всего сессий: ${liveConns.size})")
currentConn.set(connId)
// Переподключение: снять залипшее «Нет связи с телефоном».
controller.onPhoneConnected()
@@ -196,11 +207,15 @@ class VmService : LifecycleService() {
lifecycleScope.launch { sendScreenState(connId) }
},
onDisconnected = { connId ->
Log.i(TAG, "Phone disconnected: $connId")
if (currentConn.compareAndSet(connId, null)) {
liveConns.remove(connId)
Log.i(TAG, "Session closed: $connId (осталось: ${liveConns.size})")
// «Push»-сессию переводим на любую живую, если ушла именно она.
if (currentConn.get() == connId) {
currentConn.set(liveConns.firstOrNull())
}
// Экран гасим ТОЛЬКО когда не осталось ни одной сессии.
if (liveConns.isEmpty()) {
controller.setState(GlassesScreenState.NoConnection)
} else {
Log.i(TAG, "Ignoring disconnect of stale session $connId")
}
},
)