fix(wear): keep the Wear capability resource from being shrunk in release - #23
Merged
PonceGL merged 1 commit intoAug 11, 2026
Conversation
…ease
Real hardware testing with release builds on both sides showed the
phone's "send playlist to watch" dialog always reporting "no watch
connected" and the button disabled — even right after confirming the
watch was reachable (phone->watch remote-control mode worked fine).
Waiting, toggling Bluetooth, and reinstalling didn't help, which ruled
out a capability-sync timing issue.
Root cause, confirmed via wear/build/outputs/mapping/release/resources.txt:
array:android_wear_capabilities:... is not reachable.
isShrinkResources=true (release only) strips
res/values/wear_capabilities.xml's <string-array
name="android_wear_capabilities"> because nothing in the app's own code
ever references it by R.array id — it's discovered purely by resource
NAME convention by Play Services, to advertise this app's
"pixelplay_wear_app" capability (WearCapabilities.PIXELPLAY_WEAR_APP).
The shrinker's reachability analysis has no way to know that, so it
correctly-by-its-own-rules but wrongly-for-us marks it unused and
removes it — meaning the release watch app never advertised the
capability the phone's CapabilityClient.getCapability(FILTER_REACHABLE)
call looks for at all. Remote-control mode kept working because that
uses DataItem/message sync to connected nodes directly, unrelated to
capability advertisement.
Added res/raw/keep.xml with tools:keep, the standard AGP resource-
shrinker escape hatch for resources reached only by reflection/naming
convention rather than code reference. Verified against the rebuilt
release mapping report: the same line now reads "reachable from keep
xml file".
PonceGL
changed the base branch from
feature/wear-playback-stall-watchdog
to
feature/wear-playlist-transfer
August 11, 2026 23:15
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.
Bug encontrado probando release en ambos dispositivos
Con builds release instaladas en teléfono y reloj, el modo controlador remoto funcionaba bien, pero el diálogo de "enviar playlist al reloj" siempre decía "no watch connected" con el botón deshabilitado. Esperar, apagar/prender Bluetooth y reinstalar no cambió nada — eso descartó mi primera teoría (retraso de sincronización de capacidades).
Causa confirmada
wear/build/outputs/mapping/release/resources.txt(el reporte del resource shrinker) lo dice directamente:isShrinkResources = true(solo en release) eliminares/values/wear_capabilities.xmlporque nada en el código lo referencia porR.array— Google Play Services lo descubre únicamente por convención de nombre del recurso, para anunciar la capacidadpixelplay_wear_appqueWearPhoneTransferSender.isPixelPlayWatchAvailable()busca desde el teléfono. El shrinker no tiene forma de saber eso, así que lo marca como no usado y lo quita — el reloj release simplemente nunca anuncia la capacidad. El modo remoto seguía funcionando porque usa sincronización deDataItem/mensajes directos a nodos conectados, que no depende de esto.Fix
res/raw/keep.xmlcontools:keep="@array/android_wear_capabilities"— la vía estándar de AGP para decirle al shrinker que un recurso alcanzado solo por reflexión/convención debe conservarse. Verificado reconstruyendo release: la misma línea del reporte ahora dice"reachable from keep xml file".Verificación
:wear:assembleReleasecompila limpio y el reporte del shrinker confirma el recurso conservado. No hay forma de verificar esto con un test unitario (es un artefacto de build, no lógica) — queda pendiente de confirmación en hardware: que el diálogo de "enviar a reloj" ya vea el reloj como disponible con ambos en release.