Skip to content

Setting to choose the pushed watchface, and CWF rendering only while it is shown - #7

Merged
Philoul merged 3 commits into
Philoul:wear/cwf_wfffrom
olorinmaia:wear/cwf_wff_add_setting_aapsv4_wfs_wff
Sep 13, 2026
Merged

Philoul merged 3 commits into
Philoul:wear/cwf_wfffrom
olorinmaia:wear/cwf_wff_add_setting_aapsv4_wfs_wff

Conversation

@olorinmaia

@olorinmaia olorinmaia commented Sep 13, 2026 •

Copy link
Copy Markdown

Three commits on top of wear/cwf_wff, tested on a Galaxy Watch 5 (Wear OS 6).

  1. Setting to choose which Watch Face Format face AAPS installs
    Both faces are built and embedded; the wearer picks one on the Wear plugin's main page (default: Custom watchface). The watch updates its one slot with the other APK, which keeps the face active on the wrist. Also fixes two things found while testing: installs could overlap (startup sync vs. the preferences from the phone) and the picker listed the face twice after an uninstall and reinstall (MultipleInstancesAllowed is now off).
image image image
  1. Render the Custom watchface picture only while a face shows it
    CwfComplicationUpdater ran on every watch from app start. It now renders only while a face has bound the image sources, and stops the moment the runtime deactivates the last slot. This also idles it on Wear OS 5 watches running the code-based CWF.

  2. Hide the Custom watchface picture sources from the complication chooser
    The three image data sources (CwfImageComplication, CwfFaceComplication, CwfAmbientFaceComplication) carry the HIDDEN meta-data now.

The face id aapsv4 becomes wfs; an existing installation gets one config reset on the first sync, as the package name changes.

The commit messages already carry the details, so the description can stay at this level.

Watch Face Push gives one app one slot, so the Custom watchface face from
nightscout#5123 replaced the Watch Face Studio face (AAPS V4). Both are now built and
embedded, and the wearer picks one on the phone.

Phone: the Wear plugin's main page gets a "Watchface installed on watch"
card with two choices, Custom watchface (default) and Complications
watchface. Changing it asks for confirmation, because the watch replaces
its face at once and the choices made in the watch face editor are reset.
With the complications face selected, the CWF buttons are hidden and the
face preview is shown instead. The choice travels with the preferences.

Watch: WatchFacePushHelper keeps the selected face and updates its slot
with the other APK when the choice changes. Measured on a Galaxy Watch 5,
the updated slot stays the active face, so the wrist follows the phone
without any activation permission. "Open settings on wear" opens the main
settings menu when the complications face is selected, since the Display
screen only holds settings of the code-based faces.

Build: :wear:watchfacepush gets a "face" flavor dimension (wfs, cwf) with
per-face templates, previews and strings; the wear app embeds both APKs
with their validation tokens. Package suffixes differ on purpose: the
runtime never re-applies DefaultProviderPolicy to a slot id it has bound,
and the two documents use overlapping slot ids with different providers.

Two faults found while testing the swap on a Galaxy Watch 5:

- Installs could overlap. The startup sync and the preferences arriving
  from the phone both saw an empty slot table and both called add; the
  first won with the face the phone had just switched away from, the
  second failed with "limit of watch faces reached". Installs now run one
  at a time, and each reads the selected face under the lock, so the
  phone's last choice always wins. An update that hits a slot left stale
  by an uninstall from the watch settings falls back to add.
- The picker listed the same face twice after such an uninstall and a
  reinstall: one slot, one package, two entries with the same picture.
  MultipleInstancesAllowed, which Watch Face Studio writes as true, is
  now false for both faces.

The face id aapsv4 becomes wfs. Watches that already hold the old face
get one config reset on the first sync, as the package name changes.
CwfComplicationUpdater ran from app start on every watch: a frame a
second while awake and one a minute always, plus three update requests
a second, whether or not any face showed the picture. On a Wear OS 5
watch the code-based Custom watchface draws itself and none of that was
ever seen; on a Wear OS 6 watch showing any other face, the same.

The system asks a data source only for a bound complication, so a
request or an activation is the proof that somebody is looking.
CwfFaceComplication records both, and the updater renders and requests
only while one arrived in the last ten minutes. Demand renews itself
while the face is bound, because every tick makes the runtime ask.

The runtime's onComplicationDeactivated ends demand at once when the
last bound slot lets go, so the loops stop the moment another face is
selected; the ten minute timeout stays as the safety net. Measured on a
Galaxy Watch 5: a request queued by our own last tick still lands after
the deactivation, and the runtime asks before it activates, so once the
slot table is known to be empty only an activation counts again. App
start knocks once so an already shown face answers.
… chooser

Three near-identical "Custom watchface" entries looked like a mistake, and the chooser is the wrong place for them anyway: AAPS ships the Watch Face Format face that shows the picture, and its slots are not customizable. A hidden source can still be named as a default provider,
which is how that face binds them, and a slot that already holds one keeps it.
@Philoul
Philoul merged commit 7a1e515 into Philoul:wear/cwf_wff Sep 13, 2026
Philoul pushed a commit that referenced this pull request Sep 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants