component_updater_service.h revision 1320f92c476a1ad9d19dba2a48c72b75566198e9
1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com// Copyright 2014 The Chromium Authors. All rights reserved. 28a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// Use of this source code is governed by a BSD-style license that can be 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com// found in the LICENSE file. 48a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com#ifndef COMPONENTS_COMPONENT_UPDATER_COMPONENT_UPDATER_SERVICE_H_ 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com#define COMPONENTS_COMPONENT_UPDATER_COMPONENT_UPDATER_SERVICE_H_ 78a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include <stdint.h> 9ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com#include <string> 108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include <vector> 118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "base/callback_forward.h" 138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "base/gtest_prod_util.h" 14629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com#include "base/memory/ref_counted.h" 15629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com#include "base/version.h" 16629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com#include "url/gurl.h" 175f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com 18629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.comclass ComponentsUI; 198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comnamespace base { 218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass DictionaryValue; 228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass FilePath; 238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SequencedTaskRunner; 248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comnamespace net { 278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass URLRequestContextGetter; 288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass URLRequest; 298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 307ffb1b21abcc7bbed5a0fc711f6dd7b9dbb4f577ctguil@chromium.org 318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comnamespace content { 320456e0b7b85060e9b9597ce414c4c2b19aff4f58robertphillips@google.comclass ResourceThrottle; 330456e0b7b85060e9b9597ce414c4c2b19aff4f58robertphillips@google.com} 348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comnamespace component_updater { 36fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com 37fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.comclass Configurator; 38fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.comclass OnDemandUpdater; 39fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com 40fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com// Component specific installers must derive from this class and implement 41fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com// OnUpdateError() and Install(). A valid instance of this class must be 42fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com// given to ComponentUpdateService::RegisterComponent(). 43fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.comclass ComponentInstaller { 44fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com public: 45fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com // Called by the component updater on the main thread when there was a 46fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com // problem unpacking or verifying the component. |error| is a non-zero 47fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com // value which is only meaningful to the component updater. 48fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com virtual void OnUpdateError(int error) = 0; 49fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com 50fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com // Called by the component updater when a component has been unpacked 51548a1f321011292359ef163f78c8a1d4871b3b7freed@google.com // and is ready to be installed. |manifest| contains the CRX manifest 52548a1f321011292359ef163f78c8a1d4871b3b7freed@google.com // json dictionary and |unpack_path| contains the temporary directory 538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // with all the unpacked CRX files. This method may be called from 54e4f10a70807166484e5a6303a5cd0034e5e87abareed@google.com // a thread other than the main thread. 55e4f10a70807166484e5a6303a5cd0034e5e87abareed@google.com virtual bool Install(const base::DictionaryValue& manifest, 56e4f10a70807166484e5a6303a5cd0034e5e87abareed@google.com const base::FilePath& unpack_path) = 0; 57e4f10a70807166484e5a6303a5cd0034e5e87abareed@google.com 58548a1f321011292359ef163f78c8a1d4871b3b7freed@google.com // Set |installed_file| to the full path to the installed |file|. |file| is 59e4f10a70807166484e5a6303a5cd0034e5e87abareed@google.com // the filename of the file in this component's CRX. Returns false if this is 60629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com // not possible (the file has been removed or modified, or its current 61629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com // location is unknown). Otherwise, returns true. 62629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com virtual bool GetInstalledFile(const std::string& file, 63687c57c7d5a17549f63e0b15208db18b220e2a91skia.committer@gmail.com base::FilePath* installed_file) = 0; 64629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com 65629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com virtual ~ComponentInstaller() {} 66629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com}; 67629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com 68935ad026826fb7d31d562ff7326b84ec3a827456robertphillips@google.com// Describes a particular component that can be installed or updated. This 69935ad026826fb7d31d562ff7326b84ec3a827456robertphillips@google.com// structure is required to register a component with the component updater. 70935ad026826fb7d31d562ff7326b84ec3a827456robertphillips@google.com// |pk_hash| is the SHA256 hash of the component's public key. If the component 71629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com// is to be installed then version should be "0" or "0.0", else it should be 72687c57c7d5a17549f63e0b15208db18b220e2a91skia.committer@gmail.com// the current version. |fingerprint|, and |name| are optional. 73629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com// |allow_background_download| specifies that the component can be background 74629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com// downloaded in some cases. The default for this value is |true| and the value 75935ad026826fb7d31d562ff7326b84ec3a827456robertphillips@google.com// can be overriden at the registration time. This is a temporary change until 76935ad026826fb7d31d562ff7326b84ec3a827456robertphillips@google.com// the issue 340448 is resolved. 77935ad026826fb7d31d562ff7326b84ec3a827456robertphillips@google.comstruct CrxComponent { 78629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com std::vector<uint8_t> pk_hash; 79629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com ComponentInstaller* installer; 80629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com Version version; 81629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com std::string fingerprint; 82629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com std::string name; 83629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com bool allow_background_download; 84629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com CrxComponent(); 85629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com ~CrxComponent(); 86629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com}; 87629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com 88629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.comstruct CrxUpdateItem; 89629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com 90629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com// The component update service is in charge of installing or upgrading 91935ad026826fb7d31d562ff7326b84ec3a827456robertphillips@google.com// select parts of chrome. Each part is called a component and managed by 92935ad026826fb7d31d562ff7326b84ec3a827456robertphillips@google.com// instances of CrxComponent registered using RegisterComponent(). On the 93629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com// server, each component is packaged as a CRX which is the same format used 94629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com// to package extensions. To the update service each component is identified 95629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com// by its public key hash (CrxComponent::pk_hash). If there is an update 966d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com// available and its version is bigger than (CrxComponent::version), it will 976d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com// be downloaded, verified and unpacked. Then component-specific installer 986d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com// ComponentInstaller::Install (of CrxComponent::installer) will be called. 99629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com// 100629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com// During the normal operation of the component updater some specific 101629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com// notifications are fired, like COMPONENT_UPDATER_STARTED and 102629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com// COMPONENT_UPDATE_FOUND. See notification_type.h for more details. 103629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com// 104629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com// All methods are safe to call ONLY from the browser's main thread. 105687c57c7d5a17549f63e0b15208db18b220e2a91skia.committer@gmail.comclass ComponentUpdateService { 106629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com public: 107629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com enum Status { kOk, kReplaced, kInProgress, kError }; 108ba28d03e94dc221d6a803bf2a84a420b9159255cdjsollen@google.com 109ba28d03e94dc221d6a803bf2a84a420b9159255cdjsollen@google.com // Defines an interface to observe ComponentUpdateService. It provides 110ba28d03e94dc221d6a803bf2a84a420b9159255cdjsollen@google.com // notifications when state changes occur for the service or for the 1118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // registered components. 1128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com class Observer { 1138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com public: 1148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com enum Events { 115ba28d03e94dc221d6a803bf2a84a420b9159255cdjsollen@google.com // Sent when the component updater starts doing update checks. 116ba28d03e94dc221d6a803bf2a84a420b9159255cdjsollen@google.com COMPONENT_UPDATER_STARTED, 1178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // Sent when the component updater is going to take a long nap. 1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com COMPONENT_UPDATER_SLEEPING, 1208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // Sent when there is a new version of a registered component. After 1228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // the notification is sent the component will be downloaded. 1238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com COMPONENT_UPDATE_FOUND, 1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // Sent when the new component has been downloaded and an installation 1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // or upgrade is about to be attempted. 1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com COMPONENT_UPDATE_READY, 1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // Sent when a component has been successfully updated. 1308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com COMPONENT_UPDATED, 1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13254924243c1b65b3ee6d8fa064b50a9b1bb2a19a5djsollen@google.com // Sent when a component has not been updated following an update check: 13354924243c1b65b3ee6d8fa064b50a9b1bb2a19a5djsollen@google.com // either there was no update available, or an update failed. 1348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com COMPONENT_NOT_UPDATED, 1358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 136fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com // Sent when component bytes are being downloaded. 1378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com COMPONENT_UPDATE_DOWNLOADING, 1388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com }; 1398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com virtual ~Observer() {} 1418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // The component updater service will call this function when an interesting 1438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // state change happens. If the |id| is specified, then the event is fired 1448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // on behalf of a specific component. The implementors of this interface are 1458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // expected to filter the relevant events based on the component id. 1468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com virtual void OnEvent(Events event, const std::string& id) = 0; 1478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com }; 1488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // Adds an observer for this class. An observer should not be added more 1508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // than once. The caller retains the ownership of the observer object. 1518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com virtual void AddObserver(Observer* observer) = 0; 1528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // Removes an observer. It is safe for an observer to be removed while 1548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // the observers are being notified. 1558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com virtual void RemoveObserver(Observer* observer) = 0; 156548a1f321011292359ef163f78c8a1d4871b3b7freed@google.com 157548a1f321011292359ef163f78c8a1d4871b3b7freed@google.com // Start doing update checks and installing new versions of registered 1588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // components after Configurator::InitialDelay() seconds. 159ba28d03e94dc221d6a803bf2a84a420b9159255cdjsollen@google.com virtual Status Start() = 0; 1608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 16154924243c1b65b3ee6d8fa064b50a9b1bb2a19a5djsollen@google.com // Stop doing update checks. In-flight requests and pending installations 1628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // will not be canceled. 1638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com virtual Status Stop() = 0; 16454924243c1b65b3ee6d8fa064b50a9b1bb2a19a5djsollen@google.com 1658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // Add component to be checked for updates. You can call this method 1668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // before calling Start(). 1678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com virtual Status RegisterComponent(const CrxComponent& component) = 0; 168fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // Returns a list of registered components. 1708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com virtual std::vector<std::string> GetComponentIDs() const = 0; 1718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // Returns an interface for on-demand updates. On-demand updates are 1738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // proactively triggered outside the normal component update service schedule. 1748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com virtual OnDemandUpdater& GetOnDemandUpdater() = 0; 1758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // This method is used to trigger an on-demand update for component |crx_id|. 1778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // This can be used when loading a resource that depends on this component. 1788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // 1798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // |callback| is called on the main thread once the on-demand update is 1808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // complete, regardless of success. |callback| may be called immediately 1818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // within the method body. 1828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // 1838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // Additionally, this function implements an embedder-defined cooldown 1848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // interval between on demand update attempts. This behavior is intended 1858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // to be defensive against programming bugs, usually triggered by web fetches, 1868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // where the on-demand functionality is invoked too often. If this function 187548a1f321011292359ef163f78c8a1d4871b3b7freed@google.com // is called while still on cooldown, |callback| will be called immediately. 188548a1f321011292359ef163f78c8a1d4871b3b7freed@google.com virtual void MaybeThrottle(const std::string& crx_id, 1898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const base::Closure& callback) = 0; 190ba28d03e94dc221d6a803bf2a84a420b9159255cdjsollen@google.com 1918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // Returns a task runner suitable for use by component installers. 19254924243c1b65b3ee6d8fa064b50a9b1bb2a19a5djsollen@google.com virtual scoped_refptr<base::SequencedTaskRunner> GetSequencedTaskRunner() = 0; 1938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com virtual ~ComponentUpdateService() {} 19554924243c1b65b3ee6d8fa064b50a9b1bb2a19a5djsollen@google.com 1968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com private: 1978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // Returns details about registered component in the |item| parameter. The 1988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // function returns true in case of success and false in case of errors. 1998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com virtual bool GetComponentDetails(const std::string& component_id, 2008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com CrxUpdateItem* item) const = 0; 2018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com friend class ::ComponentsUI; 2038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 2048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 205typedef ComponentUpdateService::Observer ServiceObserver; 206 207class OnDemandUpdater { 208 public: 209 virtual ~OnDemandUpdater() {} 210 211 private: 212 friend class OnDemandTester; 213 friend class ::ComponentsUI; 214 215 // Triggers an update check for a component. |component_id| is a value 216 // returned by GetCrxComponentID(). If an update for this component is already 217 // in progress, the function returns |kInProgress|. If an update is available, 218 // the update will be applied. The caller can subscribe to component update 219 // service notifications to get an indication about the outcome of the 220 // on-demand update. The function does not implement any cooldown interval. 221 virtual ComponentUpdateService::Status OnDemandUpdate( 222 const std::string& component_id) = 0; 223}; 224 225// Creates the component updater. You must pass a valid |config| allocated on 226// the heap which the component updater will own. 227ComponentUpdateService* ComponentUpdateServiceFactory(Configurator* config); 228 229} // namespace component_updater 230 231#endif // COMPONENTS_COMPONENT_UPDATER_COMPONENT_UPDATER_SERVICE_H_ 232