Device Mirror Durante Acesso de IA (Koder Eye)
Sempre que uma IA acessar um dispositivo Android conectado por ADB (USB ou Wi-Fi), ela deve iniciar o serviço de espelhamento do Koder Eye e abrir a aba `http://localhost:9876/mirror` no browser do operador antes do primeiro toque/screencap. Operador acompanha o que a IA faz sem precisar olhar pra tela do celular.
Policy — Device Mirror durante acesso de IA
Em *oda sessão*em que uma IA (Claude Code, Codex, Gemini CLI, qualquer agente) acesse um dispositivo Android conectado por ADB — USB *u*Wi-Fi (
adb connect) —, a própria IA é responsável por iniciar o serviço de espelhamento do Koder Eye e abrir a aba correspondente no browser do operador *ntes do primeiro toquescreencap* Sibling de `policiesandroiduiinspection.kmd`.
Por quê
- Operador acompanha visualmente, em tempo real, o que a IA está
fazendo no celular — sem precisar girar a cabeça pra olhar a tela física.
- Em sessões longas (instalação, login, fluxo de aprovação), a IA
emite muitos taps e screencaps; observar via aba browser é menos fadigante e mais rápido que olhar o celular.
- O stream é 100% local:
127.0.0.1:9876viaadb forward, nuncaegress de rede.
- Captura é *rivacy-first*
MediaProjection.Callback.onStop()libera
VirtualDisplay+ImageReader; nada é persistido.
Fluxo obrigatório
- *etup do forward*(mesmo que
android-ui-inspection.kmdjáexige):
`bash adb -s serial forward tcp:9876 tcp:9876
`
- *isparar o MirrorActivity*(one
timeper-session — o serviçoforeground fica vivo enquanto a sessão durar):
`bash adb -s serial shell am start -n dev.koder.eye/.MirrorActivity
`
O Android *loqueia input simulado*no diálogo de MediaProjection por segurança (FLAGWINDOWIS_OBSCURED). A IA *eve avisar*o operador em uma frase curta:
> "Aprove o pedido de gravação de tela no celular (toque em
> Avançar → Iniciar agora) para iniciar o espelhamento."
O operador toca uma vez; daqui pra frente todos os taps da IA ficam visíveis no stream.
- *brir a aba do browser no laptop*assim que
/healthzreportamedia_projection: true:
`bash curl sf http:/ocalhost:9876/healthz | jq -r '.media_projection'
&& xdgopen "http:/ocalhost:9876/mirror"
`
Se xdg-open não estiver disponível (servidor headless, container), a IA imprime a URL clicável no chat e segue.
- *ão parar o mirror*durante a sessão. O serviço fecha sozinho
quando o operador revoga MediaProjection ou quando o
adb forwardé removido. Se a IA precisa explicitamente parar (raro):
`bash curl -s -X POST http:/ocalhost:9876mirrorstop
`
Quando dispensar (exceções)
Pular o mirror só quando *ma*das condições abaixo for verdadeira:
- *perador opt-out explícito na sessão*
"pode pular o mirror"/"sem mirror"/ equivalente. Persistir como memória de sessão (não global) — próxima sessão volta ao default. - *evice sem Eye instalado e sem permissão pra instalar agora*
A IA tenta instalar a release APK (
products/dev/eye/.../app-release.apk); se falhar, segue sem mirror e registra um warning de uma linha. - *essão somente-leitura, ≤2 comandos* ex.:
adb devices,adb shell getprop ro.build.version.release. Não vale a pena pedir permissão MediaProjection pra dois comandos sem efeito visível. - *evice com FLAG_SECURE bloqueando captura*(banking, password
manager em foreground, Signal).
MediaProjectionretorna frames pretos; a IA segue sem mirror e avisa o operador.
Cobertura cruzada
android-ui-inspection.kmdjá obrigaEye-firstpra inspecionarUI; esta policy obriga
Mirror-onpra *bservabilidade do operador* As duas se reforçam: o mesmoadb forward tcp:9876habilita ambas.policies/agent-guardrails.kmd(privacidade): o mirror é local,privacy-first; este policy é compatível com aquele.
policies/dev-default-password.kmd(fase de aceleração): mirroracelera demos e validação física dos fluxos de auth.
Estado do feature (20260511)
Implementado e aceito no products/dev/eye v0.3.0 (ticket #027 done). Pendente: validação física com S26 Ultra — registrar resultado de fps + CPU + bandwidth no próprio ticket #027 quando rodar.
Referências
- Implementação:
products/dev/eye/app/android/app/src/main/kotlin/dev/koder/eye/{MirrorService,MirrorActivity,MirrorBus}.kt - Rotas:
EyeRoutes.kt::"/mirror","/mirror/stream",POST "/mirror/stop" - Ticket origem:
products/dev/eye/backlog/done/027-screen-mirror-mjpeg.md - RFC base:
products/dev/eye/docs/rfcs/RFC-001-on-device-ui-analysis.md