Show an ongoing notification while the app is working

Everything this app asks for is minutes of the build machine's time
followed by a download, and all of it runs in the list screen's own
coroutines -- so with the app in the background the process is an
ordinary cached one, and Android is free to take it away halfway
through a build. A foreground service is the only way to say otherwise,
and its notification is both what that costs and what it is for: the
work is visible from the shade while it runs, and one tap comes back to
the card that started it.

The work itself stays where it is. WorkNoticeService runs nothing --
it collects a list of what is happening and reposts one notification,
stopping as soon as the list is empty -- and that list is *derived* by
workItems from the same projectStates/componentStates the cards are
drawn from, so there is nothing to forget to post and nothing to forget
to take back. The words are shared rather than written twice:
componentWorkLine and buildLine are now read by the card's own bars and
by the notification alike.

Measured on API 36 rather than assumed: the collapsed row drops the
content text the moment there is a progress bar, so one thing running
puts both the component and what is happening to it in the title
("Test Tablet / tablet: building  14/30"); several get a line each in
the expanded view and an indeterminate bar, there being no honest
single number for two builds at once. With the app at the home screen
the process sits at fg-service-act rather than cached, and the builds
it started landed while it was there.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
iris-aiandClaude Opus 5 committed 2026-09-19 19:36:03 -04:00
1 parent 4d00fe1b60
commit bb65526230
9 files changed
+583 -48

No files matched your search

+5
View File
@@ -119,6 +119,11 @@ dependencies {
implementation(libs.compose.material3)
implementation(libs.compose.ui)
implementation(libs.androidx.activity.compose)
// NotificationCompat and ServiceCompat, which are how the
// version-specific parts of a foreground service get written once
// rather than behind a check per call. Declared rather than inherited
// transitively, since this module calls it directly.
implementation(libs.androidx.core.ktx)
implementation(libs.zxing.embedded)
// The half of this app that is the same as ai-app's: pinned TLS, the
// enrollment store, and the scanner.