| // Copyright 2020 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| library fuchsia.update; |
| |
| /// The Manager protocol is used by a client that wishes to either check for an |
| /// update, or follow the status of ongoing updates. |
| /// |
| /// The Manager provides a mechanism for checking for updates via the |
| /// [`Manager.CheckNow`] message. |
| [Discoverable] |
| protocol Manager { |
| /// Immediately check for an update, and optionally track the state and |
| /// progress of that update check. |
| /// |
| /// + request `options` Options for how this request should be performed. |
| /// E.g. What kind of entity initiated this request? |
| /// E.g. Is monitoring an existing update check that |
| /// is already in process an acceptable |
| /// alternative? |
| /// |
| /// + request `monitor` An interface on which to receive the status events |
| /// for this update check. The monitor is only valid |
| /// for this single update check, after that it will |
| /// not receive any more notifications and will be |
| /// closed. |
| /// |
| /// * error If an update check cannot be started, an error will be returned. |
| /// The [`Monitor`], if provided, will not receive any notifications. |
| CheckNow(CheckOptions options, Monitor? monitor) |
| -> () error CheckNotStartedReason; |
| |
| /// Performs any pending reboot of the system into an updated OS, if an |
| /// update has been staged for the next system startup. |
| /// |
| /// Should be used when the platform is configured to let the product drive |
| /// reboot scheduling. If this method is called when the platform is not |
| /// configured to let the product drive reboot scheduling, no reboot will |
| /// occur, and the system will reboot on its own after an update. |
| /// |
| /// In product-driven reboot configurations, the platform still contains a |
| /// backstop for post-update reboots. This means that if an update |
| /// is installed but the system has not rebooted before the backstop |
| /// duration occurs, the update system will automatically reboot the |
| /// system as a security measure. To avoid hitting this backstop, |
| /// products which desire control over reboot timing should call this |
| /// method roughly daily. |
| /// |
| /// - response `rebooting` true if the system is rebooting, false if no |
| /// update was pending reboot. |
| PerformPendingReboot() -> (bool rebooting); |
| }; |
| |
| /// Configuration options for an update check. |
| table CheckOptions { |
| /// Who or what initiated this update attempt. This is taken as input to |
| /// Policy, and may influence how the update check is performed. |
| /// |
| /// **This is a required field.** |
| 1: Initiator initiator; |
| |
| /// If an update check is already in progress, it's acceptable to instead |
| /// attach a Monitor to that in-progress update instead of failing this |
| /// request to check for updates. This may convert situations that would |
| /// have resulted in the ALREADY_IN_PROGRESS to be treated as non-error |
| /// cases. |
| 2: bool allow_attaching_to_existing_update_check; |
| }; |
| |
| /// Who or what initiated the update check. |
| enum Initiator { |
| /// The update check was initiated by an interactive user, or the user is |
| /// otherwise blocked and waiting for the result of this update check. This |
| /// SHOULD only be used when there is a UI element or flow that a user has |
| /// interacted with which has initiated this update check. |
| USER = 1; |
| |
| /// The update check was initiated by a service, not a user-facing aspect |
| /// of the system. |
| SERVICE = 2; |
| }; |
| |
| /// Monitors a single update check. |
| /// |
| /// Clients interested in receiving progress information for an update check |
| /// should implement this protocol and provide the client end to |
| /// [`Manager.CheckNow`]. |
| protocol Monitor { |
| /// Receives a status update for this update check. |
| /// |
| /// This request will be called for all state changes, skipping none. |
| /// However, message delivery is throttled by the rate at which the |
| /// implementation acknowledges the messages. |
| /// |
| /// The throttled delivery doesn't impact the underlying state of the |
| /// [`Manager`]. It does not wait for any acknowledgements before it moves |
| /// on to the next state in its state machine. The [`Manager`] will simply |
| /// queue up the states for the [`Monitor`] implementation to receive. |
| /// |
| /// During the installing_update state, the [`Manager`] may, at its |
| /// discretion, collapse redundant information like the fraction completed, |
| /// in the event that the [`Monitor`] implementation is not responding to |
| /// the `OnState()` requests in a timely manner. |
| /// |
| /// + request `state` The new state of the update check. |
| /// - response The implementation is ready to receive the next |
| /// [`State`] from the [`Manager`]. |
| OnState(State state) -> (); |
| }; |
| |
| /// The set of states that a [`Monitor`] can receive during an update check. |
| /// |
| /// An update check ends when it enters a terminal state, denoted below as the |
| /// states on the right-hand side of the diagram with no arrows leading out of |
| /// them. |
| /// |
| /// # State Machine Diagram |
| /// |
| /// ``` |
| /// +----------------------+ +---------------------------------+ |
| /// | checking_for_updates |---->| error_checking_for_update | |
| /// +----------------------+ +---------------------------------+ |
| /// | |
| /// | +---------------------------------+ |
| /// +---------------->| no_update_available | |
| /// | +---------------------------------+ |
| /// | |
| /// | +---------------------------------+ |
| /// +---------------->| installation_deferred_by_policy | |
| /// | +---------------------------------+ |
| /// v |
| /// +----------------------+ +---------------------------------+ |
| /// | installing_update |---->| installation_error | |
| /// +----------------------+ +---------------------------------+ |
| /// | |
| /// | +---------------------------------+ |
| /// +---------------->| waiting_for_reboot | |
| /// +---------------------------------+ |
| /// ``` |
| union State { |
| |
| /// The Manager is currently checking for an update. |
| /// |
| /// Next states: |
| /// * `installing_update` update is available and allowed by policy |
| /// * `error_checking_for_update` on error |
| /// * `update_deferred_by_policy` update is available but deferred by policy |
| 1: CheckingForUpdatesData checking_for_updates; |
| |
| /// The Manager encountered an error while checking for the existence of a |
| /// a new update. |
| /// |
| /// **This is a terminal state** |
| /// |
| 2: ErrorCheckingForUpdateData error_checking_for_update; |
| |
| /// There is not update available at this time. |
| /// |
| /// **This is a terminal state** |
| /// |
| 3: NoUpdateAvailableData no_update_available; |
| |
| /// The Manager has found an available update but is not acting on it at |
| /// this time due to policy restrictions. |
| /// |
| /// **This is a terminal state** |
| /// |
| 4: InstallationDeferredData installation_deferred_by_policy; |
| |
| /// The Manager is installing the available update. |
| /// |
| /// Next states: |
| /// * `waiting_for_reboot` on success |
| /// * `installation_error` on error |
| 5: InstallingData installing_update; |
| |
| /// The update has been installed, and the device is waiting to be rebooted. |
| /// |
| /// Next states: |
| /// * (none, the device reboots) |
| /// |
| /// **This is a terminal state** |
| /// |
| 6: InstallingData waiting_for_reboot; |
| |
| /// The Manager encountered an update in the installation of the update. |
| /// |
| /// **This is a terminal state** |
| /// |
| 7: InstallationErrorData installation_error; |
| }; |
| |
| /// This is the set of data associated with `checking_for_updates`. |
| /// (currently none) |
| table CheckingForUpdatesData { |
| }; |
| |
| /// This is the set of data associated with the `error_checking_for_update` |
| /// state. |
| /// (currently none) |
| table ErrorCheckingForUpdateData { |
| }; |
| |
| /// This is the set of data associated with the `no_update_available` state. |
| /// (currently none) |
| table NoUpdateAvailableData { |
| }; |
| |
| /// This is the set of data associated with the |
| /// `installation_deferred_by_policy` state. |
| table InstallationDeferredData { |
| 1: UpdateInfo update; |
| 2: InstallationDeferralReason deferral_reason; |
| }; |
| |
| /// This is the set of data associated with the states involved with installing |
| /// an update: |
| /// * `installing_update` |
| /// * `waiting_for_reboot` |
| table InstallingData { |
| 1: UpdateInfo update; |
| 2: InstallationProgress installation_progress; |
| }; |
| |
| /// This is the set of data associated with the `installation_error` state. |
| /// (currently none) |
| table InstallationErrorData { |
| 1: UpdateInfo update; |
| 2: InstallationProgress installation_progress; |
| }; |
| |
| /// This describes the update that is available to be installed. |
| table UpdateInfo { |
| /// A string that describes the version that is available. This may be |
| /// either a semantic version (A.B.C.D) or an opaque hash. Clients MUST |
| /// not attempt to inspect this value, it is for display purposes only. |
| 1: string:MAX_VERSION_STRING_SIZE version_available; |
| |
| /// The total number of bytes that may be downloaded to apply this update. |
| 2: uint64 download_size; |
| }; |
| |
| /// This is the maximum length of a version string that will be returned by the |
| /// protocol |
| const uint32 MAX_VERSION_STRING_SIZE = 128; |
| |
| /// This describes the progress installing the update that has been made so far. |
| table InstallationProgress { |
| /// The fraction [0-1.0f] of the installation that has been completed. |
| 1: float32 fraction_completed; |
| }; |
| |
| /// This is the set of values that are returned by an request to immediately |
| /// check for an update. |
| enum CheckNotStartedReason { |
| |
| /// There was an internal error in starting the update check. The client |
| /// is not expected to be able to do something meaningful about this error, |
| /// except to try again later (after an appropriate delay and back-off in |
| /// the event of multiple errors. |
| INTERNAL = 1; |
| |
| /// If there are required arguments or options (or option values in |
| /// conflict), provided via the CheckOptions table to CheckNow, this error |
| /// will be returned. |
| INVALID_OPTIONS = 2; |
| |
| /// There was already another update check in progress when this request was |
| /// made. A new update check will not be started. |
| ALREADY_IN_PROGRESS = 3; |
| |
| /// The update check was not started, because too many requests to check for |
| /// updates have been made by clients in a short period of time. |
| /// |
| /// **NOTE:** Clients MUST NOT attempt to cause background update checks to |
| /// happen at a more frequent rate than the fuchsia.update.Manager will do |
| /// them. |
| /// |
| /// If a client attempts to abuse this, it will be throttled. |
| THROTTLED = 4; |
| }; |
| |
| /// This is the set of values that are provided when an update installation |
| /// is deferred. |
| flexible enum InstallationDeferralReason { |
| |
| /// The update was not installed because the currently booted system is not |
| /// committed. Consumers are encouraged to use the [`CommitStatusProvider`] |
| /// to determine when to retry the update check such that the update will |
| /// be installed. |
| CURRENT_SYSTEM_NOT_COMMITTED = 1; |
| }; |