Repository navigation
Headphone buttons control PC media (protocol v3), Windows window fix, global switch; release 0.4.0 - #4
Merged
Conversation
- Protocol v3: PcRequest::Media(MediaCommand) phone -> PC, ControlMsg::PcMedia (playback, app, title, artist) PC -> phone. - Desktop: GSMTC media transport on its own MTA thread (explicit play/pause, prefers the playing session, redundant commands are no-ops, SendInput media keys only without a session); reports the current session via Server::set_media. - Android: MediaSession in BridgeService receives headset media keys, mirrors the target PC's playback state and sends each press exactly once to exactly one PC (chosen or automatic). Single-earbud mode maps the play/pause group and next/previous to user-chosen actions; volume taps are not remappable on Android and the UI says so. - Tests: proto, statusJson, controlPc mapping, integration (target-only, exactly once, state, disconnect), desktop routing, JVM key mapping/target/persistence. Docs updated.
…d blocks boot/app restarts)
…switch - Cause: every show request made before the window existed queued a MainCmd::Show (tray sends UP + DBLCLK + UP), and the main thread only drained them after the blocking window loop returned, so each X close opened the next queued window. Show requests now coalesce (Closed/Opening/Open); commands run on a service supervisor thread. - Switch in the window and tray: off shuts the Server down (endpoint, phone, audio/mic/media workers), restores defaults, keeps identity and settings; persisted as service_enabled in settings.json (missing = on). - Debug-only AUDIOBRIDGE_DEV_DIR for an isolated instance (data dir, logs, instance objects).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Три изменения: кнопки наушников управляют музыкой на ПК (протокол v3), исправлено самопроизвольное повторное открытие окна на Windows, общий выключатель AudioBridge на телефоне и на ПК.
1. Кнопки наушников → музыка на ПК
(эмулятор Android 14 + тестовый ПК
local_server --media; QR и секретов нет)Как это работает
HeadsetControl.ktдержитMediaSessionвBridgeService(новых FGS-типов и разрешений не нужно, работает с выключенным экраном).PcMedia: играет/пауза, плеер, трек), поэтому наушник сам выбирает «play» или «pause».ACTION_DOWN) = одна команда →PcRequest::Media→ ПК.media.rs): GSMTC на отдельном MTA-потоке, по событиям, без опроса. ЯвныеTryPlay/TryPause(Chromium/Electron, включая YandexMusicBetaMod черезnavigator.mediaSession, часто не включает toggle); PlayPause решается по реальному статусу. «Play, когда уже играет» ничего не делает: наушники шлют play при подключении. SendInput-медиаклавиша — только когда медиасессии нет или GSMTC упал; отказ сессии не дублируется клавишей.«Один наушник» — настраиваются 2 и 3 касания (пауза/продолжить, следующий, предыдущий, громкость +/−, ничего); оба наушника ведут себя одинаково. Настройки сохраняются (после переустановки APK выбранное «3 касания → Громкость +» осталось).
Ограничения (Android API, не баг):
MediaSessionService(isMediaSessionKey), а absolute volume меняетSTREAM_MUSICнапрямую. Приложение этого не видит; перехват всех изменений громкости не добавлялся (циклы/дубли). Это написано в UI и README.2. Windows: окно само открывалось после крестика
Причина: каждое открытие до создания окна ставило в очередь
MainCmd::Show, а трей на клик шлётWM_LBUTTONUP+WM_LBUTTONDBLCLK+WM_LBUTTONUP(tray.rs). Главный поток разбирал очередь только после возврата блокирующегоrun_window()(main.rs), поэтому каждое закрытие крестиком открывало следующее окно из очереди — примерно три раза. Исправление: открытия схлопываются (Closed/Opening/Open), а команды обрабатывает отдельный поток-супервизор, независимо от UI-цикла.3. Общий выключатель AudioBridge
BridgeService, hub, соединения, аудио, медиасессию и постоянное уведомление. Состояние сохраняется (service_enabled, запись черезcommit); ни загрузка, ни обновление, ни sticky-перезапуск, ни открытие приложения службу не включают. ПК и настройки сохраняются.Server(endpoint, телефон, захват/микрофон/media-потоки), возвращает устройства по умолчанию и сохраняетservice_enabledвsettings.json(нет поля = вкл). При включении поднимается тот же ключ, и QR не меняется.Проверки
cargo clippy -p core -p desktop -p android --all-targets -D warnings+cargo ndk … clippyrt_alloc(push/fill без аллокаций)--test-threads=1(10, в т.ч. новыйmedia_commands_reach_only_the_target_pc_exactly_once)media,PC_MEDIAкоды)MediaKeysTest,ServiceSwitchTest,BridgeStatusTest,PairedPcTest) / lint 0 errorscargo build --releasedesktop,assembleDebugЖивые проверки:
cmd media_session dispatch pause/play/next/previous→ ПК получилMedia(Pause/Play/Next/Previous)ровно по одному разу. Экран выключен + forced deep Doze:PlayPause,Nextдошли. В режиме «Один наушник» previous → Next, pause/play → PlayPause. Выключатель: служба, уведомление и медиасессия исчезли, ПК →WaitingForPeer;BOOT_COMPLETED/QUICKBOOT_POWERONи открытие приложения службу не подняли; включение → снова connected.PcMediaрепортится. Чужие сессии не трогались.AUDIOBRIDGE_DEV_DIR, установленный AudioBridge не трогался). Инъекция UP/DBLCLK/UP в окно трея открыла одно окно; один X — окно не возвращалось ≥10 с; повторный запуск открывает окно. Выкл/вкл: UDP-endpoint исчезает и появляется, хэшиserver.key/pairing.secret/pairing.txtсовпадают, после перезапуска остаётся «Выключено».Не проверено (честно):
Media button session is app.audiobridge). Сами касания (2/3 касания, режим «Один наушник») вручную не проверялись, так что реальная раскладка касаний этой модели не подтверждена.navigator.mediaSession: play→resume, pause/stop→pause, next/prev) и проверки GSMTC на собственной сессии.libndk_translation) native hub дважды не стартовал после переустановки APK: процесс висел на fork-потомке внутри транслятора (поdebuggerd). После свежей загрузки эмулятора стартовал сразу. Наmain-APK за одну попытку это не воспроизвелось, поэтому связь с PR не исключена до конца, но место зависания — слой трансляции, которого на arm64-телефоне нет. Стоит проверить на телефоне.Артефакты
Версия 0.4.0 (Rust workspace, Android versionName 0.4.0 / versionCode 4, протокол v3).
AudioBridge.exeиAudioBridge.apkдля GitHub Release собираются из merge-коммита вmain; APK подписан тем же ключом, что и прошлые релизы.