Skip to content

Drive Always-on-display wakeup events using a timerfd - #285

Open
FlorentRevest wants to merge 1 commit into
masterfrom
aod-timerfd
Open

FlorentRevest wants to merge 1 commit into
masterfrom
aod-timerfd

Conversation

@FlorentRevest

Copy link
Copy Markdown
Member

No description provided.

@FlorentRevest

Copy link
Copy Markdown
Member Author

This goes hand in hand with AsteroidOS/meta-asteroid#296

Comment thread lipstick/src/compositor/lipstickcompositor.cpp Outdated
return;
}

// The CLOCK_REALTIME_ALARM RTC wakeup keeps the AP awake long enough to

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we actually know how long it stays awake? Iirc in the previous approach MCE held a wakelock.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hopefully the new explanation is clearer. The kernel's alarmtimer mechanism seems to hold a wakeup source when an alarm-class timer fires, until the fd is serviced. As far as I could test on my aurora, the frame rendering seems to happen within that time frame so. Maybe there are some oddities left, we should keep an eye on it but that seems to work for me. At least better than the timed case which was broken on aurora for some reason

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mh well, I've been arguing with my slopbot and it's actually unsure at this point. My personal take is: it seems to work without a wake lock at the moment and introducing so I'm tempted to go ahead with this and see what happens. If it turns out to be an issue, we can consider introducing a wakelock but that will require CAP_BLOCK_SUSPEND too and maybe exposing some sysfs files too so I'm not too keen right unless that's proven necessary.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this ends up needing a wakelock, can we please avoid using the wakelock kernel API directly, and instead talk to MCE over DBUS? Obviously this would be another dependency on MCE, but we have plenty of those.
The kernel wakelock API is just not very good (it relies on writing a string into a lock and unlock files). It feels a lot safer if we just have one daemon that does all the wakelocking.

Comment thread lipstick/src/compositor/lipstickcompositor.h Outdated
// Alarm-class timer for the ambient (AOD) minute tick. CLOCK_REALTIME_ALARM
// wakes the AP out of autosleep, so the watchface still updates off-charger,
// and it tracks wall-clock so ticks stay aligned to :00 across NTP/timezone
// changes. Requires CAP_WAKE_ALARM, granted to the launcher unit.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you checked that this is set in the systems service?

We have the service file also in the meta-smartwatch layer (should probably merge with meta-asteroid someday)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yeah, it's a little confusing because that's done in yet another pull request uh https://github.com/AsteroidOS/meta-asteroid/pull/290/commits

The whole timerfd conversion is to untangle both dsme, iphb and timed so currently it's a bit of a soup but eventually things will be more straightforward to understand hopefully!

@MagneFire

Copy link
Copy Markdown
Member

Forgot to mention but this is great! Keep it up 💪

@FlorentRevest
FlorentRevest force-pushed the aod-timerfd branch 2 times, most recently from 9789cf4 to e00d802 Compare July 28, 2026 12:16
…imerfd

The always-on-display clock was repainted once a minute by scheduling a
'wakeup' event in timed, which timed re-broadcast over D-Bus and mce relayed
back to the compositor as setAmbientUpdatesEnabled(true). That round-trip
through two other daemons was fragile, and because timed's event did not wake
the AP the clock froze whenever the device autosleeps (e.g. off-charger).

Arm a CLOCK_REALTIME_ALARM timerfd for the next wall-clock minute instead,
watched with a QSocketNotifier; on expiry re-enable ambient updates and let the
existing re-arm path schedule the following minute. The RTC delivers the alarm
through suspend, so the ambient watchface keeps ticking off-charger, and the
mechanism is self-contained in the compositor. The launcher already holds
CAP_WAKE_ALARM, and the kernel keeps the AP awake long enough after an RTC
alarm to composite the frame, so no wakelock is required.
@dodoradio

Copy link
Copy Markdown
Contributor

I feel a bit mixed on this. As I mentioned in a comment above, the timerfd and wakelock APIs are a bit austere, and they're not something that applications would want to use.
The current model, where timed does the wakeups, is not ideal. However, overall, I think there is value in having something like timed which abstracts wakeups.
I'm not sure it's good that this functionality is being brought directly into asteroid-launcher, as it would imply that every other application that wants to do anything in the background should also be talking to timerfds directly.

Of course, the AOD usecase is a little bit special, as it needs to happen exactly once a minute and it happens more frequently than most other background tasks would. So maybe this solution is appropriate here, but some thought does need to be given to background tasks would work elsewhere.

@FlorentRevest

Copy link
Copy Markdown
Member Author

I feel a bit mixed on this. As I mentioned in a comment above, the timerfd and wakelock APIs are a bit austere, and they're not something that applications would want to use.
The current model, where timed does the wakeups, is not ideal. However, overall, I think there is value in having something like timed which abstracts wakeups.
I'm not sure it's good that this functionality is being brought directly into asteroid-launcher, as it would imply that every other application that wants to do anything in the background should also be talking to timerfds directly.

If your concern is API complexity, we could trivially have a C++ library that wraps timerfd's low level file descriptor APIs and what not with a higher level API (like QTimer). The part that matters to me is that we no longer need complex IPCs and a privileged daemon to do such simple things. I don't care what abstraction level we use to communicate with timerfd, what matters to me is that architecturally it's a lot simpler to have each process be able to directly ask the kernel for wake up events using a mainline API rather than have this crazy iphb custom socket protocol communicate with dsme which itself has crazy abstractions for legacy wakeup mechanisms that none of our watches have.

@MagneFire

Copy link
Copy Markdown
Member

@dodoradio Are you ok with the latest comments?

@dodoradio

dodoradio commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

I think AOD can be a good reason to talk to the kernel directly, since we can almost see it as a hardware feature. So yeah, I think this is good to merge!

Regarding other usecases however, a response to kido's comment:

If your concern is API complexity, we could trivially have a C++ library that wraps timerfd's low level file descriptor APIs and what not with a higher level API (like QTimer). The part that matters to me is that we no longer need complex IPCs and a privileged daemon to do such simple things. I don't care what abstraction level we use to communicate with timerfd, what matters to me is that architecturally it's a lot simpler to have each process be able to directly ask the kernel for wake up events using a mainline API rather than have this crazy iphb custom socket protocol communicate with dsme which itself has crazy abstractions for legacy wakeup mechanisms that none of our watches have.

I think some level of abstraction is actually desirable. Not just an API wrapper, but something that abstracts some of the design decisions from application developers.
I think part of the concept of timed, a daemon that schedules wakeups based on requests from applications over DBUS, is desirable. broadly because:

  • Only one daemon needs to talk to the kernel
  • Talking to it over DBUS means that applications could continue to work within, eg., flatpak
  • That daemon can make smart decisions, eg. about grouping wakeups. The API could be a bit more abstract than 'when' or 'how often'. Instead, wakeups could be scheduled as 'frequent', 'regular' or 'occasional', and then the daemon could schedule actual wakeups based on user activity and system resources, such as battery or network state. Wakeups could also depend on the availability of things like the network state (eg. not attempting to sync online data when the system is offline).

Obviously timed doesn't do all of this, and it has accumulated issues in both design and implementation, like the dependency on DSME, or the very rigid and tangled alarmclock system. But I don't think it's worth completely throwing out the idea of wakeup middleware, as it seems kinda necessary for more complex background usecases, and it's something that seems to be missing on other mobile linuxes. (Apparently systemd.timer hits some of these usecases, but I've not seen any well-developed implementations of power-aware background sync with it, so I'm not sure)

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.

3 participants