Дерево экрана
Окно, узлы, роли, состояния, границы и позиции. Сервер получает слепок, а не картинку, и дальше работает с ним.
- tree
мэри / мост и узлы
Управление телефоном живёт внутри APK: служба доступности держит свой HTTP-мост, отдаёт дерево экрана и выполняет действия по узлам. Go-сервер разговаривает с этим мостом, а не с внешними приложениями, поэтому чтение экрана, нажатия, ввод, уведомления и буфер обмена работают на одном контракте — и одинаково доступны голосом и агенту.
Мост и узлы
ControlBridgeService — служба доступности с собственным HTTP-мостом. Она не рисует и не решает, а читает состояние и исполняет действие.
Окно, узлы, роли, состояния, границы и позиции. Сервер получает слепок, а не картинку, и дальше работает с ним.
14 действий: tap и long-press, свайп, ключи, click, tap, long-click и scroll-to по узлу, ввод текста, открытие приложения, URI и браузера, Intent, буфер обмена.
Скриншот берётся через AccessibilityService, уведомления читаются и открываются, список приложений и буфер обмена доступны штатно; watchdog поднимает мост, если он отвалился.
22 маршрутов /api/control на стороне Go — то, чем пользуются голосовые навыки, UI-фолбэк и браузерный агент. Отдельного «второго пути» для каждого сценария нет.
Мост и узлы
Модель и навыки видят не координаты, а узлы: так действие остаётся понятным и проверяемым.
Узел находится по id, тексту, описанию или классу — точным совпадением или подстрокой.
hit_test по координатам отвечает, что находится в точке, а wait дожидается появления узла — вместо слепой паузы «подожди секунду».
control/read отдаёт список с ролями, состояниями и позициями, control/semantic — короткое семантическое представление. Сырые координаты и служебные атрибуты остаются серверу.
Узел можно подписать словами, а журнал действий хранит, что нажали, когда и к чему это привело — история видна и человеку, и агенту.
Мост и узлы
Путь один: найти узел, сделать, проверить.
Действия идут по узлу с отступом от края и гравитацией (центр, слева, справа) — попадание не зависит от плотности экрана и темы приложения.
После действия экран снимается заново и сравнивается фингерпринт. Если он не изменился, Мэри говорит об этом, а не делает вид, что всё сработало.
Открытая шторка уведомлений, отсутствие кликабельных узлов и неизвестный жест возвращаются понятной причиной, а не тихим отказом.
В момент действия сервер отправляет кадр по SSE, и оверлей рисует тап-кольцо или свайп «пальцем» — видно, что именно произошло.
Мост и узлы
Подсказка выбора и правила поведения приходят с сервера одним пакетом.
Кликабельные узлы получают номера, и оверлей рисует их поверх интерфейса. Список живёт 16 секунд под свежий слепок, APK опрашивает его раз в две секунды.
«Нажми 3» разрешается тем же списком узлов: сервер нажимает третий и отвечает, изменился ли экран.
Состояние экрана, тихий режим, разрешение рисовать номера, озвучка, длина окна прослушки, повторы «не услышала», уровень приглушения медиа и доступные команды — одно решение сервера.
Тип страницы (каталог, главная, поиск, плеер, Shorts, комментарии) определяется по слепку. В каталоге — номера и выбор голосом, в плеере и на Shorts — тихий режим, а следующий шортс подставляется по таймеру конца ролика.
проверяемое