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