|  | // Copyright 2015 The Chromium Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | #ifndef COMPONENTS_UPDATE_CLIENT_UPDATE_CLIENT_H_ | 
|  | #define COMPONENTS_UPDATE_CLIENT_UPDATE_CLIENT_H_ | 
|  |  | 
|  | #include <stdint.h> | 
|  |  | 
|  | #include <map> | 
|  | #include <memory> | 
|  | #include <string> | 
|  | #include <vector> | 
|  |  | 
|  | #include "base/callback_forward.h" | 
|  | #include "base/memory/ref_counted.h" | 
|  | #include "base/version.h" | 
|  |  | 
|  | // The UpdateClient class is a facade with a simple interface. The interface | 
|  | // exposes a few APIs to install a CRX or update a group of CRXs. | 
|  | // | 
|  | // The difference between a CRX install and a CRX update is relatively minor. | 
|  | // The terminology going forward will use the word "update" to cover both | 
|  | // install and update scenarios, except where details regarding the install | 
|  | // case are relevant. | 
|  | // | 
|  | // Handling an update consists of a series of actions such as sending an update | 
|  | // check to the server, followed by parsing the server response, identifying | 
|  | // the CRXs that require an update, downloading the differential update if | 
|  | // it is available, unpacking and patching the differential update, then | 
|  | // falling back to trying a similar set of actions using the full update. | 
|  | // At the end of this process, completion pings are sent to the server, | 
|  | // as needed, for the CRXs which had updates. | 
|  | // | 
|  | // As a general idea, this code handles the action steps needed to update | 
|  | // a group of components serially, one step at a time. However, concurrent | 
|  | // execution of calls to UpdateClient::Update is possible, therefore, | 
|  | // queuing of updates could happen in some cases. More below. | 
|  | // | 
|  | // The UpdateClient class features a subject-observer interface to observe | 
|  | // the CRX state changes during an update. | 
|  | // | 
|  | // The threading model for this code assumes that most of the code in the | 
|  | // public interface runs on a SingleThreadTaskRunner. | 
|  | // This task runner corresponds to the browser UI thread in many cases. There | 
|  | // are parts of the installer interface that run on blocking task runners, which | 
|  | // are usually threads in a thread pool. | 
|  | // | 
|  | // Using the UpdateClient is relatively easy. This assumes that the client | 
|  | // of this code has already implemented the observer interface as needed, and | 
|  | // can provide an installer, as described below. | 
|  | // | 
|  | //    std::unique_ptr<UpdateClient> update_client(UpdateClientFactory(...)); | 
|  | //    update_client->AddObserver(&observer); | 
|  | //    std::vector<std::string> ids; | 
|  | //    ids.push_back(...)); | 
|  | //    update_client->Update(ids, base::Bind(...), base::Bind(...)); | 
|  | // | 
|  | // UpdateClient::Update takes two callbacks as parameters. First callback | 
|  | // allows the client of this code to provide an instance of CrxComponent | 
|  | // data structure that specifies additional parameters of the update. | 
|  | // CrxComponent has a CrxInstaller data member, which must be provided by the | 
|  | // callers of this class. The second callback indicates that this non-blocking | 
|  | // call has completed. | 
|  | // | 
|  | // There could be several ways of triggering updates for a CRX, user-initiated, | 
|  | // or timer-based. Since the execution of updates is concurrent, the parameters | 
|  | // for the update must be provided right before the update is handled. | 
|  | // Otherwise, the version of the CRX set in the CrxComponent may not be correct. | 
|  | // | 
|  | // The UpdateClient public interface includes two functions: Install and | 
|  | // Update. These functions correspond to installing one CRX immediately as a | 
|  | // foreground activity (Install), and updating a group of CRXs silently in the | 
|  | // background (Update). This distinction is important. Background updates are | 
|  | // queued up and their actions run serially, one at a time, for the purpose of | 
|  | // conserving local resources such as CPU, network, and I/O. | 
|  | // On the other hand, installs are never queued up but run concurrently, as | 
|  | // requested by the user. | 
|  | // | 
|  | // The update client introduces a runtime constraint regarding interleaving | 
|  | // updates and installs. If installs or updates for a given CRX are in progress, | 
|  | // then installs for the same CRX will fail with a specific error. | 
|  | // | 
|  | // Implementation details. | 
|  | // | 
|  | // The implementation details below are not relevant to callers of this | 
|  | // code. However, these design notes are relevant to the owners and maintainers | 
|  | // of this module. | 
|  | // | 
|  | // The design for the update client consists of a number of abstractions | 
|  | // such as: task, update engine, update context, and action. | 
|  | // The execution model for these abstractions is simple. They usually expose | 
|  | // a public, non-blocking Run function, and they invoke a callback when | 
|  | // the Run function has completed. | 
|  | // | 
|  | // A task is the unit of work for the UpdateClient. A task is associated | 
|  | // with a single call of the Update function. A task represents a group | 
|  | // of CRXs that are updated together. | 
|  | // | 
|  | // The UpdateClient is responsible for the queuing of tasks, if queuing is | 
|  | // needed. | 
|  | // | 
|  | // When the task runs, it calls the update engine to handle the updates for | 
|  | // the CRXs associated with the task. The UpdateEngine is the abstraction | 
|  | // responsible for breaking down the update in a set of discrete steps, which | 
|  | // are implemented as actions, and running the actions. | 
|  | // | 
|  | // The UpdateEngine maintains a set of UpdateContext instances. Each of | 
|  | // these instances maintains the update state for all the CRXs belonging to | 
|  | // a given task. The UpdateContext contains a queue of CRX ids. | 
|  | // The UpdateEngine will handle updates for the CRXs in the order they appear | 
|  | // in the queue, until the queue is empty. | 
|  | // | 
|  | // The update state for each CRX is maintained in a container of CrxUpdateItem*. | 
|  | // As actions run, each action updates the CRX state, represented by one of | 
|  | // these CrxUpdateItem* instances. | 
|  | // | 
|  | // Although the UpdateEngine can and will run update tasks concurrently, the | 
|  | // actions of a task are run sequentially. | 
|  | // | 
|  | // The Action is a polymorphic type. There is some code reuse for convenience, | 
|  | // implemented as a mixin. The polymorphic behavior of some of the actions | 
|  | // is achieved using a template method. | 
|  | // | 
|  | // State changes of a CRX could generate events, which are observed using a | 
|  | // subject-observer interface. | 
|  | // | 
|  | // The actions chain up. In some sense, the actions implement a state machine, | 
|  | // as the CRX undergoes a series of state transitions in the process of | 
|  | // being checked for updates and applying the update. | 
|  |  | 
|  | class ComponentsUI; | 
|  | class PrefRegistrySimple; | 
|  |  | 
|  | namespace base { | 
|  | class DictionaryValue; | 
|  | class FilePath; | 
|  | } | 
|  |  | 
|  | namespace update_client { | 
|  |  | 
|  | class Configurator; | 
|  | struct CrxUpdateItem; | 
|  |  | 
|  | enum Error { | 
|  | ERROR_UPDATE_INVALID_ARGUMENT = -1, | 
|  | ERROR_UPDATE_IN_PROGRESS = 1, | 
|  | ERROR_UPDATE_CANCELED = 2, | 
|  | ERROR_UPDATE_RETRY_LATER = 3, | 
|  | }; | 
|  |  | 
|  | // Defines an interface for a generic CRX installer. | 
|  | class CrxInstaller : public base::RefCountedThreadSafe<CrxInstaller> { | 
|  | public: | 
|  | // Called on the main thread when there was a problem unpacking or | 
|  | // verifying the CRX. |error| is a non-zero value which is only meaningful | 
|  | // to the caller. | 
|  | virtual void OnUpdateError(int error) = 0; | 
|  |  | 
|  | // Called by the update service when a CRX has been unpacked | 
|  | // and it is ready to be installed. |manifest| contains the CRX manifest | 
|  | // as a json dictionary.|unpack_path| contains the temporary directory | 
|  | // with all the unpacked CRX files. | 
|  | // This method may be called from a thread other than the main thread. | 
|  | virtual bool Install(const base::DictionaryValue& manifest, | 
|  | const base::FilePath& unpack_path) = 0; | 
|  |  | 
|  | // Sets |installed_file| to the full path to the installed |file|. |file| is | 
|  | // the filename of the file in this CRX. Returns false if this is | 
|  | // not possible (the file has been removed or modified, or its current | 
|  | // location is unknown). Otherwise, it returns true. | 
|  | virtual bool GetInstalledFile(const std::string& file, | 
|  | base::FilePath* installed_file) = 0; | 
|  |  | 
|  | // Called when a CRX has been unregistered and all versions should | 
|  | // be uninstalled from disk. Returns true if uninstallation is supported, | 
|  | // and false otherwise. | 
|  | virtual bool Uninstall() = 0; | 
|  |  | 
|  | protected: | 
|  | friend class base::RefCountedThreadSafe<CrxInstaller>; | 
|  |  | 
|  | virtual ~CrxInstaller() {} | 
|  | }; | 
|  |  | 
|  | // A dictionary of installer-specific, arbitrary name-value pairs, which | 
|  | // may be used in the update checks requests. | 
|  | using InstallerAttributes = std::map<std::string, std::string>; | 
|  |  | 
|  | // TODO(sorin): this structure will be refactored soon. | 
|  | struct CrxComponent { | 
|  | CrxComponent(); | 
|  | CrxComponent(const CrxComponent& other); | 
|  | ~CrxComponent(); | 
|  |  | 
|  | // SHA256 hash of the CRX's public key. | 
|  | std::vector<uint8_t> pk_hash; | 
|  | scoped_refptr<CrxInstaller> installer; | 
|  |  | 
|  | // The current version if the CRX is updated. Otherwise, "0" or "0.0" if | 
|  | // the CRX is installed. | 
|  | Version version; | 
|  |  | 
|  | std::string fingerprint;  // Optional. | 
|  | std::string name;         // Optional. | 
|  |  | 
|  | // Optional. | 
|  | // Valid values for the name part of an attribute match | 
|  | // ^[-_a-zA-Z0-9]{1,256}$ and valid values the value part of an attribute | 
|  | // match ^[-.,;+_=a-zA-Z0-9]{0,256}$ . | 
|  | InstallerAttributes installer_attributes; | 
|  |  | 
|  | // Specifies that the CRX can be background-downloaded in some cases. | 
|  | // The default for this value is |true|. | 
|  | bool allows_background_download; | 
|  |  | 
|  | // Specifies that the update checks and pings associated with this component | 
|  | // require confidentiality. The default for this value is |true|. As a side | 
|  | // note, the confidentiality of the downloads is enforced by the server, | 
|  | // which only returns secure download URLs in this case. | 
|  | bool requires_network_encryption; | 
|  | }; | 
|  |  | 
|  | // All methods are safe to call only from the browser's main thread. Once an | 
|  | // instance of this class is created, the reference to it must be released | 
|  | // only after the thread pools of the browser process have been destroyed and | 
|  | // the browser process has gone single-threaded. | 
|  | class UpdateClient : public base::RefCounted<UpdateClient> { | 
|  | public: | 
|  | using CrxDataCallback = | 
|  | base::Callback<void(const std::vector<std::string>& ids, | 
|  | std::vector<CrxComponent>* components)>; | 
|  | using CompletionCallback = base::Callback<void(int error)>; | 
|  |  | 
|  | // Defines an interface to observe the UpdateClient. It provides | 
|  | // notifications when state changes occur for the service itself or for the | 
|  | // registered CRXs. | 
|  | class Observer { | 
|  | public: | 
|  | enum class Events { | 
|  | // Sent before the update client does an update check. | 
|  | COMPONENT_CHECKING_FOR_UPDATES, | 
|  |  | 
|  | // Sent when there is a new version of a registered CRX. After | 
|  | // the notification is sent the CRX will be downloaded unless the | 
|  | // update client inserts a | 
|  | COMPONENT_UPDATE_FOUND, | 
|  |  | 
|  | // Sent when a CRX is in the update queue but it can't be acted on | 
|  | // right away, because the update client spaces out CRX updates due to a | 
|  | // throttling policy. | 
|  | COMPONENT_WAIT, | 
|  |  | 
|  | // Sent after the new CRX has been downloaded but before the install | 
|  | // or the upgrade is attempted. | 
|  | COMPONENT_UPDATE_READY, | 
|  |  | 
|  | // Sent when a CRX has been successfully updated. | 
|  | COMPONENT_UPDATED, | 
|  |  | 
|  | // Sent when a CRX has not been updated following an update check: | 
|  | // either there was no update available, or the update failed. | 
|  | COMPONENT_NOT_UPDATED, | 
|  |  | 
|  | // Sent when CRX bytes are being downloaded. | 
|  | COMPONENT_UPDATE_DOWNLOADING, | 
|  | }; | 
|  |  | 
|  | virtual ~Observer() {} | 
|  |  | 
|  | // Called by the update client when a state change happens. | 
|  | // If an |id| is specified, then the event is fired on behalf of the | 
|  | // specific CRX. The implementors of this interface are | 
|  | // expected to filter the relevant events based on the id of the CRX. | 
|  | virtual void OnEvent(Events event, const std::string& id) = 0; | 
|  | }; | 
|  |  | 
|  | // Adds an observer for this class. An observer should not be added more | 
|  | // than once. The caller retains the ownership of the observer object. | 
|  | virtual void AddObserver(Observer* observer) = 0; | 
|  |  | 
|  | // Removes an observer. It is safe for an observer to be removed while | 
|  | // the observers are being notified. | 
|  | virtual void RemoveObserver(Observer* observer) = 0; | 
|  |  | 
|  | // Installs the specified CRX. Calls back on |completion_callback| after the | 
|  | // update has been handled. The |error| parameter of the |completion_callback| | 
|  | // contains an error code in the case of a run-time error, or 0 if the | 
|  | // install has been handled successfully. Overlapping calls of this function | 
|  | // are executed concurrently, as long as the id parameter is different, | 
|  | // meaning that installs of different components are parallelized. | 
|  | // The |Install| function is intended to be used for foreground installs of | 
|  | // one CRX. These cases are usually associated with on-demand install | 
|  | // scenarios, which are triggered by user actions. Installs are never | 
|  | // queued up. | 
|  | virtual void Install(const std::string& id, | 
|  | const CrxDataCallback& crx_data_callback, | 
|  | const CompletionCallback& completion_callback) = 0; | 
|  |  | 
|  | // Updates the specified CRXs. Calls back on |crx_data_callback| before the | 
|  | // update is attempted to give the caller the opportunity to provide the | 
|  | // instances of CrxComponent to be used for this update. The |Update| function | 
|  | // is intended to be used for background updates of several CRXs. Overlapping | 
|  | // calls to this function result in a queuing behavior, and the execution | 
|  | // of each call is serialized. In addition, updates are always queued up when | 
|  | // installs are running. | 
|  | virtual void Update(const std::vector<std::string>& ids, | 
|  | const CrxDataCallback& crx_data_callback, | 
|  | const CompletionCallback& completion_callback) = 0; | 
|  |  | 
|  | // Sends an uninstall ping for the CRX identified by |id| and |version|. The | 
|  | // |reason| parameter is defined by the caller. The current implementation of | 
|  | // this function only sends a best-effort, fire-and-forget ping. It has no | 
|  | // other side effects regarding installs or updates done through an instance | 
|  | // of this class. | 
|  | virtual void SendUninstallPing(const std::string& id, | 
|  | const Version& version, | 
|  | int reason) = 0; | 
|  |  | 
|  | // Returns status details about a CRX update. The function returns true in | 
|  | // case of success and false in case of errors, such as |id| was | 
|  | // invalid or not known. | 
|  | virtual bool GetCrxUpdateState(const std::string& id, | 
|  | CrxUpdateItem* update_item) const = 0; | 
|  |  | 
|  | // Returns true if the |id| is found in any running task. | 
|  | virtual bool IsUpdating(const std::string& id) const = 0; | 
|  |  | 
|  | // Cancels the queued updates and makes a best effort to stop updates in | 
|  | // progress as soon as possible. Some updates may not be stopped, in which | 
|  | // case, the updates will run to completion. Calling this function has no | 
|  | // effect if updates are not currently executed or queued up. | 
|  | virtual void Stop() = 0; | 
|  |  | 
|  | protected: | 
|  | friend class base::RefCounted<UpdateClient>; | 
|  |  | 
|  | virtual ~UpdateClient() {} | 
|  | }; | 
|  |  | 
|  | // Creates an instance of the update client. | 
|  | scoped_refptr<UpdateClient> UpdateClientFactory( | 
|  | const scoped_refptr<Configurator>& config); | 
|  |  | 
|  | // This must be called prior to the construction of any Configurator that | 
|  | // contains a PrefService. | 
|  | void RegisterPrefs(PrefRegistrySimple* registry); | 
|  |  | 
|  | }  // namespace update_client | 
|  |  | 
|  | #endif  // COMPONENTS_UPDATE_CLIENT_UPDATE_CLIENT_H_ |