Skip to content

Updater: add configurable update check frequency and update behavior#126

Open
misakazip wants to merge 1 commit into
GrapheneOS:16-qpr2from
misakazip:16-qpr2
Open

Updater: add configurable update check frequency and update behavior#126
misakazip wants to merge 1 commit into
GrapheneOS:16-qpr2from
misakazip:16-qpr2

Conversation

@misakazip

Copy link
Copy Markdown

Fixes GrapheneOS/os-issue-tracker#7596

(I don't have an environment where I can fully test the behavior, so please check it before merging.)

Copilot AI review requested due to automatic review settings May 16, 2026 06:31

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Adds two new user-configurable settings to the Updater app — update check frequency (Daily / Weekly / Monthly / Manual only) and update behavior (auto-install / auto-download + notify / notify-only) — and wires the supporting flow so that pre-install notifications can trigger an install via a new InstallReceiver. The previously hardcoded 6-hour periodic check interval is replaced by the user-selected frequency, with 0 meaning "manual only" (the periodic job is cancelled).

Changes:

  • Replace the hardcoded INTERVAL_MILLIS in PeriodicJob with Settings.getCheckFrequency(...), including a "manual only" path that cancels the periodic job.
  • Plumb a new update_behavior setting and a USER_REQUESTED_INSTALL intent extra through Service/Service.onDownloadFinished so the service can stop after the metadata fetch (notify only) or after verification (auto-download), with a new InstallReceiver triggered by notification actions.
  • Add NOTIFICATION_ID_AVAILABLE / NOTIFICATION_ID_DOWNLOADED notifications and the associated available notification channel, plus all new strings and array resources for the two ListPreference entries in settings.xml.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/app/seamlessupdate/client/Settings.java Adds KEY_CHECK_FREQUENCY / KEY_UPDATE_BEHAVIOR, getter helpers, behavior constants, and rescheduling on frequency change.
src/app/seamlessupdate/client/PeriodicJob.java Replaces fixed 6-hour interval with Settings.getCheckFrequency; cancels job when value is 0.
src/app/seamlessupdate/client/Service.java Branches on update behavior to either skip download, skip install after verify, or proceed; threads installAfterVerify into onDownloadFinished.
src/app/seamlessupdate/client/NotificationHandler.java Adds new IDs, an available channel, and showUpdateAvailableNotification / showUpdateDownloadedNotification with an install action.
src/app/seamlessupdate/client/InstallReceiver.java New broadcast receiver invoked from notification action; starts Service with USER_REQUESTED_INSTALL=true.
AndroidManifest.xml Registers the new InstallReceiver.
res/xml/settings.xml Adds the two new ListPreference entries.
res/values/strings.xml Adds titles, entries, notification text, and action labels.
res/values/arrays.xml Adds entries/values arrays for frequency and behavior.
res/values/config.xml Adds default values for check_frequency (24h) and update_behavior (auto-install).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +214 to +246
void showUpdateAvailableNotification() {
final Notification.Action action = new Notification.Action.Builder(
Icon.createWithResource(service.getApplication(), R.drawable.system_update_fill0_wght400_grad0_opsz48),
service.getString(R.string.notification_available_action),
getPendingInstallIntent()).build();

notificationManager.notify(NOTIFICATION_ID_AVAILABLE, new Notification.Builder(service, NOTIFICATION_CHANNEL_ID_AVAILABLE)
.addAction(action)
.setContentIntent(getPendingInstallIntent())
.setContentTitle(service.getString(R.string.notification_available_title))
.setContentText(service.getString(R.string.notification_available_text))
.setShowWhen(true)
.setTimeoutAfter(-1)
.setSmallIcon(R.drawable.system_update_fill0_wght400_grad0_opsz48)
.build());
}

void showUpdateDownloadedNotification() {
final Notification.Action action = new Notification.Action.Builder(
Icon.createWithResource(service.getApplication(), R.drawable.system_update_fill0_wght400_grad0_opsz48),
service.getString(R.string.notification_downloaded_action),
getPendingInstallIntent()).build();

notificationManager.notify(NOTIFICATION_ID_DOWNLOADED, new Notification.Builder(service, NOTIFICATION_CHANNEL_ID_AVAILABLE)
.addAction(action)
.setContentIntent(getPendingInstallIntent())
.setContentTitle(service.getString(R.string.notification_downloaded_title))
.setContentText(service.getString(R.string.notification_downloaded_text))
.setShowWhen(true)
.setTimeoutAfter(-1)
.setSmallIcon(R.drawable.system_update_fill0_wght400_grad0_opsz48)
.build());
}
final Network network = connectivityManager.getActiveNetwork();
final Intent service = new Intent(context, Service.class);
service.putExtra(Service.INTENT_EXTRA_NETWORK, network);
service.putExtra(Service.INTENT_EXTRA_USER_REQUESTED_INSTALL, true);
service.getString(R.string.notification_downloaded_action),
getPendingInstallIntent()).build();

notificationManager.notify(NOTIFICATION_ID_DOWNLOADED, new Notification.Builder(service, NOTIFICATION_CHANNEL_ID_AVAILABLE)
}
if (!installAfterVerify) {
Log.d(TAG, "update downloaded and verified; notifying user to install manually");
notificationHandler.showUpdateDownloadedNotification();
Comment thread res/values/arrays.xml
Change-Id: I187f3d409ac3b283b942aa7c5fa6194c8a5c5f3f
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.

More control over system updates

2 participants