103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "components/component_updater/component_updater_service.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <set> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/at_exit.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/bind_helpers.h" 146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "base/callback.h" 15eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/compiler_specific.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h" 171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/macros.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/message_loop/message_loop_proxy.h" 225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "base/observer_list.h" 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/sequenced_task_runner.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h" 250f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "base/threading/sequenced_worker_pool.h" 265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/threading/thread_checker.h" 27eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/timer/timer.h" 2803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "components/component_updater/component_patcher_operation.h" 2903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "components/component_updater/component_unpacker.h" 3003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "components/component_updater/component_updater_configurator.h" 3103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "components/component_updater/component_updater_ping_manager.h" 3203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "components/component_updater/component_updater_utils.h" 3303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "components/component_updater/crx_downloader.h" 3403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "components/component_updater/crx_update_item.h" 3503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "components/component_updater/update_checker.h" 3603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "components/component_updater/update_response.h" 37eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "url/gurl.h" 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace component_updater { 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The component updater is designed to live until process shutdown, so 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// base::Bind() calls are not refcounted. 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Returns true if the |proposed| version is newer than |current| version. 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsVersionNewer(const Version& current, const std::string& proposed) { 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Version proposed_ver(proposed); 49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return proposed_ver.IsValid() && current.CompareTo(proposed_ver) < 0; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 52eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Returns true if a differential update is available, it has not failed yet, 53eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// and the configuration allows it. 54eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool CanTryDiffUpdate(const CrxUpdateItem* update_item, 55116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const Configurator& config) { 56010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return HasDiffUpdate(update_item) && !update_item->diff_update_failed && 57eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch config.DeltasEnabled(); 58eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 59eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AppendDownloadMetrics( 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::vector<CrxDownloader::DownloadMetrics>& source, 625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::vector<CrxDownloader::DownloadMetrics>* destination) { 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) destination->insert(destination->end(), source.begin(), source.end()); 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 66ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} // namespace 67ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 68ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochCrxUpdateItem::CrxUpdateItem() 69ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch : status(kNew), 701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) on_demand(false), 71ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch diff_update_failed(false), 72ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch error_category(0), 73ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch error_code(0), 74ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch extra_code1(0), 75ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch diff_error_category(0), 76ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch diff_error_code(0), 77ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch diff_extra_code1(0) { 78ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 79ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 80ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochCrxUpdateItem::~CrxUpdateItem() { 81ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)CrxComponent::CrxComponent() 84010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) : installer(NULL), allow_background_download(true) { 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)CrxComponent::~CrxComponent() { 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////// 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The one and only implementation of the ComponentUpdateService interface. In 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// charge of running the show. The main method is ProcessPendingItems() which 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// is called periodically to do the upgrades/installs or the update checks. 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// An important consideration here is to be as "low impact" as we can to the 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// rest of the browser, so even if we have many components registered and 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// eligible for update, we only do one thing at a time with pauses in between 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the tasks. Also when we do network requests there is only one |url_fetcher_| 98eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// in flight at a time. 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// There are no locks in this code, the main structure |work_items_| is mutated 1005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// only from the main thread. The unpack and installation is done in a blocking 1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// pool thread. The network requests are done in the IO thread or in the file 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// thread. 103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class CrxUpdateService : public ComponentUpdateService, public OnDemandUpdater { 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 105116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch explicit CrxUpdateService(Configurator* config); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~CrxUpdateService(); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Overrides for ComponentUpdateService. 1095c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu virtual void AddObserver(Observer* observer) OVERRIDE; 1105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu virtual void RemoveObserver(Observer* observer) OVERRIDE; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual Status Start() OVERRIDE; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual Status Stop() OVERRIDE; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual Status RegisterComponent(const CrxComponent& component) OVERRIDE; 11446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) virtual std::vector<std::string> GetComponentIDs() const OVERRIDE; 115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) virtual OnDemandUpdater& GetOnDemandUpdater() OVERRIDE; 1166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) virtual void MaybeThrottle(const std::string& crx_id, 1176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const base::Closure& callback) OVERRIDE; 1185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) virtual scoped_refptr<base::SequencedTaskRunner> GetSequencedTaskRunner() 1195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) OVERRIDE; 120cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 121010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Context for a crx download url request. 122010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) struct CRXContext { 123010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ComponentInstaller* installer; 1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::vector<uint8_t> pk_hash; 125010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) std::string id; 126010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) std::string fingerprint; 127010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) CRXContext() : installer(NULL) {} 128010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) }; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 131ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch enum ErrorCategory { 132ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch kErrorNone = 0, 133ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch kNetworkError, 134ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch kUnpackError, 135ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch kInstallError, 136ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch }; 137ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 1383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) enum StepDelayInterval { 1393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) kStepDelayShort = 0, 1403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) kStepDelayMedium, 1413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) kStepDelayLong, 1423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) }; 1433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // Overrides for ComponentUpdateService. 1456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) virtual bool GetComponentDetails(const std::string& component_id, 1466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) CrxUpdateItem* item) const OVERRIDE; 1476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // Overrides for OnDemandUpdater. 1496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) virtual Status OnDemandUpdate(const std::string& component_id) OVERRIDE; 1506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void UpdateCheckComplete(const GURL& original_url, 1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int error, 1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& error_message, 1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const UpdateResponse::Results& results); 1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void OnUpdateCheckSucceeded(const UpdateResponse::Results& results); 1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void OnUpdateCheckFailed(int error, const std::string& error_message); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 158010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) void DownloadProgress(const std::string& component_id, 159010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const CrxDownloader::Result& download_result); 160010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 161010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) void DownloadComplete(scoped_ptr<CRXContext> crx_context, 162010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const CrxDownloader::Result& download_result); 163a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 1640f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) Status OnDemandUpdateInternal(CrxUpdateItem* item); 16546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) Status OnDemandUpdateWithCooldown(CrxUpdateItem* item); 1660f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ProcessPendingItems(); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Find a component that is ready to update. 1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CrxUpdateItem* FindReadyComponent() const; 1711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Prepares the components for an update check and initiates the request. 1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Returns true if an update check request has been made. Returns false if 1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // no update check was needed or an error occured. 1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool CheckForUpdates(); 1761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void UpdateComponent(CrxUpdateItem* workitem); 1781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) void ScheduleNextRun(StepDelayInterval step_delay); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 181f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void ParseResponse(const std::string& xml); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 183a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) void Install(scoped_ptr<CRXContext> context, const base::FilePath& crx_path); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void EndUnpacking(const std::string& component_id, 1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::FilePath& crx_path, 1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ComponentUnpacker::Error error, 1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int extended_error); 1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DoneInstalling(const std::string& component_id, 191eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ComponentUnpacker::Error error, 192eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int extended_error); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) void ChangeItemState(CrxUpdateItem* item, CrxUpdateItem::Status to); 1951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 196010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) size_t ChangeItemStatus(CrxUpdateItem::Status from, CrxUpdateItem::Status to); 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) CrxUpdateItem* FindUpdateItemById(const std::string& id) const; 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2005c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu void NotifyObservers(Observer::Events event, const std::string& id); 201a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 2021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) bool HasOnDemandItems() const; 2031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 20446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) Status GetServiceStatus(const CrxUpdateItem::Status status); 20546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 206116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_ptr<Configurator> config_; 207eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<UpdateChecker> update_checker_; 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<PingManager> ping_manager_; 211ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 212effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch scoped_refptr<ComponentUnpacker> unpacker_; 2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<CrxDownloader> crx_downloader_; 215a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // A collection of every work item. 217eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch typedef std::vector<CrxUpdateItem*> UpdateItems; 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateItems work_items_; 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::OneShotTimer<CrxUpdateService> timer_; 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::ThreadChecker thread_checker_; 2235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Used to post responses back to the main thread. 2255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; 2265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2270f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_; 2280f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool running_; 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ObserverList<Observer> observer_list_; 2325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(CrxUpdateService); 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////// 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 238116680a4aac90f2aa7413d9095a592090648e557Ben MurdochCrxUpdateService::CrxUpdateService(Configurator* config) 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : config_(config), 240116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ping_manager_(new PingManager(*config)), 2415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) main_task_runner_(base::MessageLoopProxy::current()), 2425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) blocking_task_runner_(config->GetSequencedTaskRunner()), 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) running_(false) { 24458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CrxUpdateService::~CrxUpdateService() { 2475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Because we are a singleton, at this point only the main thread should be 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // alive, this simplifies the management of the work that could be in 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // flight in other threads. 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Stop(); 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) STLDeleteElements(&work_items_); 25258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid CrxUpdateService::AddObserver(Observer* observer) { 2555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 2565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu observer_list_.AddObserver(observer); 2575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 2585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 2595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid CrxUpdateService::RemoveObserver(Observer* observer) { 2605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 2615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu observer_list_.RemoveObserver(observer); 2625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 2635c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ComponentUpdateService::Status CrxUpdateService::Start() { 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that RegisterComponent will call Start() when the first 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // component is registered, so it can be called twice. This way 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we avoid scheduling the timer if there is no work to do. 2685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu VLOG(1) << "CrxUpdateService starting up"; 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) running_ = true; 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (work_items_.empty()) 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return kOk; 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu NotifyObservers(Observer::COMPONENT_UPDATER_STARTED, ""); 274a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 2755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu VLOG(1) << "First update attempt will take place in " 2765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu << config_->InitialDelay() << " seconds"; 277010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) timer_.Start(FROM_HERE, 278010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::TimeDelta::FromSeconds(config_->InitialDelay()), 279010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) this, 280010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) &CrxUpdateService::ProcessPendingItems); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return kOk; 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Stop the main check + update loop. In flight operations will be 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// completed. 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ComponentUpdateService::Status CrxUpdateService::Stop() { 2875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu VLOG(1) << "CrxUpdateService stopping"; 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) running_ = false; 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) timer_.Stop(); 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return kOk; 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)bool CrxUpdateService::HasOnDemandItems() const { 2941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) class Helper { 2951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) public: 296010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) static bool IsOnDemand(CrxUpdateItem* item) { return item->on_demand; } 2971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) }; 2981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return std::find_if(work_items_.begin(), 2991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) work_items_.end(), 3001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) Helper::IsOnDemand) != work_items_.end(); 3011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 3021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// This function sets the timer which will call ProcessPendingItems() or 3041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// ProcessRequestedItem() if there is an on_demand item. There 3053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// are three kinds of waits: 3063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// - a short delay, when there is immediate work to be done. 3073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// - a medium delay, when there are updates to be applied within the current 3083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// update cycle, or there are components that are still unchecked. 3093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// - a long delay when a full check/update cycle has completed for all 3103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// components. 3113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void CrxUpdateService::ScheduleNextRun(StepDelayInterval step_delay) { 3125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 3135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(!update_checker_); 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(!timer_.IsRunning()); 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // It could be the case that Stop() had been called while a url request 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // or unpacking was in flight, if so we arrive here but |running_| is 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // false. In that case do not loop again. 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!running_) 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Keep the delay short if in the middle of an update (step_delay), 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // or there are new requested_work_items_ that have not been processed yet. 3231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int64_t delay_seconds = 0; 3241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (!HasOnDemandItems()) { 3253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) switch (step_delay) { 3263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case kStepDelayShort: 3273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) delay_seconds = config_->StepDelay(); 3283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) break; 3293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case kStepDelayMedium: 3303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) delay_seconds = config_->StepDelayMedium(); 3313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) break; 3323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case kStepDelayLong: 3333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) delay_seconds = config_->NextCheckDelay(); 3343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) break; 3353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 3363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else { 3373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) delay_seconds = config_->StepDelay(); 3383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (step_delay != kStepDelayShort) { 3415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu NotifyObservers(Observer::COMPONENT_UPDATER_SLEEPING, ""); 342a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Zero is only used for unit tests. 3443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (0 == delay_seconds) 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu VLOG(1) << "Scheduling next run to occur in " << delay_seconds << " seconds"; 349010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) timer_.Start(FROM_HERE, 350010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::TimeDelta::FromSeconds(delay_seconds), 351010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) this, 352010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) &CrxUpdateService::ProcessPendingItems); 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Given a extension-like component id, find the associated component. 35646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)CrxUpdateItem* CrxUpdateService::FindUpdateItemById( 35746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const std::string& id) const { 3585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CrxUpdateItem::FindById finder(id); 36046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) UpdateItems::const_iterator it = 361010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) std::find_if(work_items_.begin(), work_items_.end(), finder); 3625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return it != work_items_.end() ? *it : NULL; 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// Changes a component's status, clearing on_demand and firing notifications as 3661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// necessary. By convention, this is the only function that can change a 3671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// CrxUpdateItem's |status|. 3681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// TODO(waffles): Do we want to add DCHECKS for valid state transitions here? 3691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void CrxUpdateService::ChangeItemState(CrxUpdateItem* item, 3701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) CrxUpdateItem::Status to) { 3715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 372010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (to == CrxUpdateItem::kNoUpdate || to == CrxUpdateItem::kUpdated || 3731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) to == CrxUpdateItem::kUpToDate) { 3741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) item->on_demand = false; 3751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 3761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) item->status = to; 3781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu switch (to) { 3805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu case CrxUpdateItem::kCanUpdate: 3815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu NotifyObservers(Observer::COMPONENT_UPDATE_FOUND, item->id); 3825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu break; 3835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu case CrxUpdateItem::kUpdatingDiff: 3845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu case CrxUpdateItem::kUpdating: 3855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu NotifyObservers(Observer::COMPONENT_UPDATE_READY, item->id); 3865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu break; 3875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu case CrxUpdateItem::kUpdated: 3885c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu NotifyObservers(Observer::COMPONENT_UPDATED, item->id); 3895c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu break; 3905c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu case CrxUpdateItem::kUpToDate: 3915c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu case CrxUpdateItem::kNoUpdate: 3925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu NotifyObservers(Observer::COMPONENT_NOT_UPDATED, item->id); 3935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu break; 3945c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu case CrxUpdateItem::kNew: 3955c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu case CrxUpdateItem::kChecking: 3965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu case CrxUpdateItem::kDownloading: 3975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu case CrxUpdateItem::kDownloadingDiff: 3985c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu case CrxUpdateItem::kLastStatus: 3995c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // No notification for these states. 4005c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu break; 4011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 4020f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 4030f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // Free possible pending network requests. 404010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if ((to == CrxUpdateItem::kUpdated) || (to == CrxUpdateItem::kUpToDate) || 4050f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) (to == CrxUpdateItem::kNoUpdate)) { 4066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) for (std::vector<base::Closure>::iterator it = 4076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) item->ready_callbacks.begin(); 4086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) it != item->ready_callbacks.end(); 4096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) ++it) { 4106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) it->Run(); 4116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 4126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) item->ready_callbacks.clear(); 4130f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) } 4141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 4151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Changes all the components in |work_items_| that have |from| status to 417eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// |to| status and returns how many have been changed. 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)size_t CrxUpdateService::ChangeItemStatus(CrxUpdateItem::Status from, 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CrxUpdateItem::Status to) { 4205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t count = 0; 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (UpdateItems::iterator it = work_items_.begin(); 423010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) it != work_items_.end(); 424010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ++it) { 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CrxUpdateItem* item = *it; 4265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (item->status == from) { 4275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ChangeItemState(item, to); 4285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ++count; 4295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return count; 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Adds a component to be checked for upgrades. If the component exists it 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// it will be replaced and the return code is kReplaced. 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ComponentUpdateService::Status CrxUpdateService::RegisterComponent( 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const CrxComponent& component) { 4385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 439010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (component.pk_hash.empty() || !component.version.IsValid() || 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !component.installer) 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return kError; 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string id(GetCrxComponentID(component)); 4445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CrxUpdateItem* uit = FindUpdateItemById(id); 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (uit) { 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uit->component = component; 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return kReplaced; 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uit = new CrxUpdateItem; 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uit->id.swap(id); 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uit->component = component; 453eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) work_items_.push_back(uit); 455f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If this is the first component registered we call Start to 457f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // schedule the first timer. Otherwise, reset the timer to trigger another 458f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // pass over the work items, if the component updater is sleeping, fact 459f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // indicated by a running timer. If the timer is not running, it means that 460f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // the service is busy updating something, and in that case, this component 461f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // will be picked up at the next pass. 462f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (running_) { 463f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (work_items_.size() == 1) { 464f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) Start(); 465f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } else if (timer_.IsRunning()) { 466f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) timer_.Start(FROM_HERE, 467f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::TimeDelta::FromSeconds(config_->InitialDelay()), 468f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) this, 469f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) &CrxUpdateService::ProcessPendingItems); 470f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 471f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return kOk; 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 47646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)std::vector<std::string> CrxUpdateService::GetComponentIDs() const { 4775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 47846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) std::vector<std::string> component_ids; 4793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) for (UpdateItems::const_iterator it = work_items_.begin(); 480010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) it != work_items_.end(); 481010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ++it) { 4823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const CrxUpdateItem* item = *it; 48346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) component_ids.push_back(item->id); 4843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 48546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return component_ids; 48646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 48746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 4886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)OnDemandUpdater& CrxUpdateService::GetOnDemandUpdater() { 4896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return *this; 4906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 4916e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 4926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void CrxUpdateService::MaybeThrottle(const std::string& crx_id, 4936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const base::Closure& callback) { 4946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 4956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // Check if we can on-demand update, else unblock the request anyway. 4966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) CrxUpdateItem* item = FindUpdateItemById(crx_id); 4976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) Status status = OnDemandUpdateWithCooldown(item); 4986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (status == kOk || status == kInProgress) { 4996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) item->ready_callbacks.push_back(callback); 5006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return; 5016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 5026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) callback.Run(); 5036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 5046e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 5056e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)scoped_refptr<base::SequencedTaskRunner> 5066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)CrxUpdateService::GetSequencedTaskRunner() { 5076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return config_->GetSequencedTaskRunner(); 5086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 5096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 510f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool CrxUpdateService::GetComponentDetails(const std::string& component_id, 511f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) CrxUpdateItem* item) const { 5125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 513f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const CrxUpdateItem* crx_update_item(FindUpdateItemById(component_id)); 514f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (crx_update_item) 515f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) *item = *crx_update_item; 516f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return crx_update_item != NULL; 5173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 5183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 5196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// Start the process of checking for an update, for a particular component 5206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// that was previously registered. 5216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// |component_id| is a value returned from GetCrxComponentID(). 5226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)ComponentUpdateService::Status CrxUpdateService::OnDemandUpdate( 5236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const std::string& component_id) { 5246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return OnDemandUpdateInternal(FindUpdateItemById(component_id)); 5255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 5265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 5275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// This is the main loop of the component updater. It updates one component 5285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// at a time if updates are available. Otherwise, it does an update check or 5295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// takes a long sleep until the loop runs again. 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CrxUpdateService::ProcessPendingItems() { 5315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 5325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) CrxUpdateItem* ready_upgrade = FindReadyComponent(); 5341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (ready_upgrade) { 5351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) UpdateComponent(ready_upgrade); 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!CheckForUpdates()) 5405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScheduleNextRun(kStepDelayLong); 5411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 5421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 5435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)CrxUpdateItem* CrxUpdateService::FindReadyComponent() const { 5441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) class Helper { 5451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) public: 5461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) static bool IsReadyOnDemand(CrxUpdateItem* item) { 5471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return item->on_demand && IsReady(item); 5481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 5491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) static bool IsReady(CrxUpdateItem* item) { 5501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return item->status == CrxUpdateItem::kCanUpdate; 5511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 5521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) }; 5531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 5545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::vector<CrxUpdateItem*>::const_iterator it = std::find_if( 5551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) work_items_.begin(), work_items_.end(), Helper::IsReadyOnDemand); 5561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (it != work_items_.end()) 5571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return *it; 5581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) it = std::find_if(work_items_.begin(), work_items_.end(), Helper::IsReady); 5591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (it != work_items_.end()) 5601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return *it; 5611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return NULL; 5621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 5631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 5645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Prepares the components for an update check and initiates the request. 565a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// On demand components are always included in the update check request. 566a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Otherwise, only include components that have not been checked recently. 5675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool CrxUpdateService::CheckForUpdates() { 568a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const base::TimeDelta minimum_recheck_wait_time = 569a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::TimeDelta::FromSeconds(config_->MinimumReCheckWait()); 570a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const base::Time now(base::Time::Now()); 571a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 5725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::vector<CrxUpdateItem*> items_to_check; 5735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (size_t i = 0; i != work_items_.size(); ++i) { 5745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CrxUpdateItem* item = work_items_[i]; 5755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(item->status == CrxUpdateItem::kNew || 5765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) item->status == CrxUpdateItem::kNoUpdate || 5775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) item->status == CrxUpdateItem::kUpToDate || 5785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) item->status == CrxUpdateItem::kUpdated); 5795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 580a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const base::TimeDelta time_since_last_checked(now - item->last_check); 581a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 582a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!item->on_demand && 583a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) time_since_last_checked < minimum_recheck_wait_time) { 5845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu VLOG(1) << "Skipping check for component update: id=" << item->id 5855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu << ", time_since_last_checked=" 5865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu << time_since_last_checked.InSeconds() 5875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu << " seconds: too soon to check for an update"; 588a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) continue; 589a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 590a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 5915c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu VLOG(1) << "Scheduling update check for component id=" << item->id 5925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu << ", time_since_last_checked=" 593010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) << time_since_last_checked.InSeconds() << " seconds"; 5945c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 595a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) item->last_check = now; 5965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) item->crx_urls.clear(); 5975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) item->crx_diffurls.clear(); 5985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) item->previous_version = item->component.version; 5995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) item->next_version = Version(); 6005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) item->previous_fp = item->component.fingerprint; 6015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) item->next_fp.clear(); 6025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) item->diff_update_failed = false; 6035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) item->error_category = 0; 6045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) item->error_code = 0; 6055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) item->extra_code1 = 0; 6065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) item->diff_error_category = 0; 6075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) item->diff_error_code = 0; 6085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) item->diff_extra_code1 = 0; 6095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) item->download_metrics.clear(); 6105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 6115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) items_to_check.push_back(item); 612116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 613116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ChangeItemState(item, CrxUpdateItem::kChecking); 6145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 6155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 6165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (items_to_check.empty()) 6175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 6185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 6191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci update_checker_ = UpdateChecker::Create(*config_).Pass(); 6201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return update_checker_->CheckForUpdates( 6211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci items_to_check, 6221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci config_->ExtraRequestParams(), 6231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(&CrxUpdateService::UpdateCheckComplete, 6241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Unretained(this))); 6255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 6265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 6271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void CrxUpdateService::UpdateComponent(CrxUpdateItem* workitem) { 628a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_ptr<CRXContext> crx_context(new CRXContext); 629a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) crx_context->pk_hash = workitem->component.pk_hash; 630a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) crx_context->id = workitem->id; 631a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) crx_context->installer = workitem->component.installer; 632a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) crx_context->fingerprint = workitem->next_fp; 6335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::vector<GURL>* urls = NULL; 6345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool allow_background_download = false; 6351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (CanTryDiffUpdate(workitem, *config_)) { 6365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) urls = &workitem->crx_diffurls; 6371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) ChangeItemState(workitem, CrxUpdateItem::kDownloadingDiff); 6381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } else { 6395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Background downloads are enabled only for selected components and 6405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // only for full downloads (see issue 340448). 6415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) allow_background_download = workitem->component.allow_background_download; 6425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) urls = &workitem->crx_urls; 6431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) ChangeItemState(workitem, CrxUpdateItem::kDownloading); 6441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 645a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 646a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // On demand component updates are always downloaded in foreground. 647010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const bool is_background_download = !workitem->on_demand && 648010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) allow_background_download && 649010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) config_->UseBackgroundDownloader(); 650a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 6515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) crx_downloader_.reset( 6525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) CrxDownloader::Create(is_background_download, 6535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) config_->RequestContext(), 6545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) blocking_task_runner_, 6555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) config_->GetSingleThreadTaskRunner())); 656010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) crx_downloader_->set_progress_callback( 657010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Bind(&CrxUpdateService::DownloadProgress, 658010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Unretained(this), 659010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) crx_context->id)); 6605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu crx_downloader_->StartDownload(*urls, 6615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Bind(&CrxUpdateService::DownloadComplete, 6625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Unretained(this), 6635c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Passed(&crx_context))); 664f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 665f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 6665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void CrxUpdateService::UpdateCheckComplete( 6671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const GURL& original_url, 6685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int error, 6695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& error_message, 6705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const UpdateResponse::Results& results) { 6715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 6721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci VLOG(1) << "Update check completed from: " << original_url.spec(); 6735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) update_checker_.reset(); 6745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!error) 6755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) OnUpdateCheckSucceeded(results); 676f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) else 6775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) OnUpdateCheckFailed(error, error_message); 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Handles a valid Omaha update check response by matching the results with 6815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// the registered components which were checked for updates. 6825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// If updates are found, prepare the components for the actual version upgrade. 6835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// One of these components will be drafted for the upgrade next time 6845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// ProcessPendingItems is called. 6855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void CrxUpdateService::OnUpdateCheckSucceeded( 6865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const UpdateResponse::Results& results) { 687f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) size_t num_updates_pending = 0; 6885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 6895c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu VLOG(1) << "Update check succeeded."; 6905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::vector<UpdateResponse::Result>::const_iterator it; 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (it = results.list.begin(); it != results.list.end(); ++it) { 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CrxUpdateItem* crx = FindUpdateItemById(it->extension_id); 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!crx) 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 696f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (crx->status != CrxUpdateItem::kChecking) { 697f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) NOTREACHED(); 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; // Not updating this component now. 699f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 701f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (it->manifest.version.empty()) { 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No version means no update available. 7031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) ChangeItemState(crx, CrxUpdateItem::kNoUpdate); 7045c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu VLOG(1) << "No update available for component: " << crx->id; 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 707f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 708f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!IsVersionNewer(crx->component.version, it->manifest.version)) { 709f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // The component is up to date. 7101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) ChangeItemState(crx, CrxUpdateItem::kUpToDate); 7115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu VLOG(1) << "Component already up-to-date: " << crx->id; 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 714f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 715f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!it->manifest.browser_min_version.empty()) { 716116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (IsVersionNewer(config_->GetBrowserVersion(), 717116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch it->manifest.browser_min_version)) { 718f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // The component is not compatible with this Chrome version. 7195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu VLOG(1) << "Ignoring incompatible component: " << crx->id; 7201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) ChangeItemState(crx, CrxUpdateItem::kNoUpdate); 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 724f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 725f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (it->manifest.packages.size() != 1) { 726f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Assume one and only one package per component. 7275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu VLOG(1) << "Ignoring multiple packages for component: " << crx->id; 728f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ChangeItemState(crx, CrxUpdateItem::kNoUpdate); 729f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) continue; 730f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 731f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 732f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Parse the members of the result and queue an upgrade for this component. 733f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) crx->next_version = Version(it->manifest.version); 734f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 7355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu VLOG(1) << "Update found for component: " << crx->id; 7365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 7375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) typedef UpdateResponse::Result::Manifest::Package Package; 738f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const Package& package(it->manifest.packages[0]); 739f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) crx->next_fp = package.fingerprint; 740f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 7415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Resolve the urls by combining the base urls with the package names. 7425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (size_t i = 0; i != it->crx_urls.size(); ++i) { 7435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const GURL url(it->crx_urls[i].Resolve(package.name)); 7445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (url.is_valid()) 745010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) crx->crx_urls.push_back(url); 7465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 7475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (size_t i = 0; i != it->crx_diffurls.size(); ++i) { 7485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const GURL url(it->crx_diffurls[i].Resolve(package.namediff)); 7495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (url.is_valid()) 750010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) crx->crx_diffurls.push_back(url); 7515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 752f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 7531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) ChangeItemState(crx, CrxUpdateItem::kCanUpdate); 754f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ++num_updates_pending; 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 757f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // All components that are not included in the update response are 758f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // considered up to date. 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChangeItemStatus(CrxUpdateItem::kChecking, CrxUpdateItem::kUpToDate); 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // If there are updates pending we do a short wait, otherwise we take 7623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // a longer delay until we check the components again. 763a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ScheduleNextRun(num_updates_pending > 0 ? kStepDelayShort : kStepDelayLong); 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void CrxUpdateService::OnUpdateCheckFailed(int error, 7675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& error_message) { 7685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 7695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(error); 770010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) size_t count = 771010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ChangeItemStatus(CrxUpdateItem::kChecking, CrxUpdateItem::kNoUpdate); 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GT(count, 0ul); 7735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu VLOG(1) << "Update check failed."; 7743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ScheduleNextRun(kStepDelayLong); 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 777010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Called when progress is being made downloading a CRX. The progress may 778010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// not monotonically increase due to how the CRX downloader switches between 779010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// different downloaders and fallback urls. 780010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void CrxUpdateService::DownloadProgress( 781010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const std::string& component_id, 782010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const CrxDownloader::Result& download_result) { 7835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 784010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) NotifyObservers(Observer::COMPONENT_UPDATE_DOWNLOADING, component_id); 785010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 786010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Called when the CRX package has been downloaded to a temporary location. 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Here we fire the notifications and schedule the component-specific installer 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to be called in the file thread. 790a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void CrxUpdateService::DownloadComplete( 791a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_ptr<CRXContext> crx_context, 7925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const CrxDownloader::Result& download_result) { 7935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 79458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 79558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) CrxUpdateItem* crx = FindUpdateItemById(crx_context->id); 796eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(crx->status == CrxUpdateItem::kDownloadingDiff || 797eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch crx->status == CrxUpdateItem::kDownloading); 798eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 7995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AppendDownloadMetrics(crx_downloader_->download_metrics(), 8005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &crx->download_metrics); 8015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 802010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) crx_downloader_.reset(); 803010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 804a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (download_result.error) { 805eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (crx->status == CrxUpdateItem::kDownloadingDiff) { 806ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch crx->diff_error_category = kNetworkError; 807a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) crx->diff_error_code = download_result.error; 808eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch crx->diff_update_failed = true; 809eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch size_t count = ChangeItemStatus(CrxUpdateItem::kDownloadingDiff, 810eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CrxUpdateItem::kCanUpdate); 811eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK_EQ(count, 1ul); 812ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 8133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ScheduleNextRun(kStepDelayShort); 814eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return; 815eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 816ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch crx->error_category = kNetworkError; 817a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) crx->error_code = download_result.error; 818010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) size_t count = 819010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ChangeItemStatus(CrxUpdateItem::kDownloading, CrxUpdateItem::kNoUpdate); 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(count, 1ul); 821eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 822ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // At this point, since both the differential and the full downloads failed, 823ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // the update for this component has finished with an error. 824ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch ping_manager_->OnUpdateComplete(crx); 825ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 8263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Move on to the next update, if there is one available. 8273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ScheduleNextRun(kStepDelayMedium); 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 829eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch size_t count = 0; 830eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (crx->status == CrxUpdateItem::kDownloadingDiff) { 831eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch count = ChangeItemStatus(CrxUpdateItem::kDownloadingDiff, 832eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CrxUpdateItem::kUpdatingDiff); 833eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } else { 834eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch count = ChangeItemStatus(CrxUpdateItem::kDownloading, 835eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CrxUpdateItem::kUpdating); 836eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(count, 1ul); 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Why unretained? See comment at top of file. 8400f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) blocking_task_runner_->PostDelayedTask( 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&CrxUpdateService::Install, 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this), 844a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::Passed(&crx_context), 845a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) download_result.response), 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromMilliseconds(config_->StepDelay())); 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Install consists of digital signature verification, unpacking and then 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// calling the component specific installer. All that is handled by the 8525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// |unpacker_|. If there is an error this function is in charge of deleting 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the files created. 854a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void CrxUpdateService::Install(scoped_ptr<CRXContext> context, 8552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& crx_path) { 8560f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // This function owns the file at |crx_path| and the |context| object. 857effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch unpacker_ = new ComponentUnpacker(context->pk_hash, 858effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch crx_path, 859effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch context->fingerprint, 860effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch context->installer, 8615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) config_->CreateOutOfProcessPatcher(), 862effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch blocking_task_runner_); 8635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) unpacker_->Unpack(base::Bind(&CrxUpdateService::EndUnpacking, 8645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Unretained(this), 8655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) context->id, 8665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) crx_path)); 8675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 8685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 8695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void CrxUpdateService::EndUnpacking(const std::string& component_id, 8705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::FilePath& crx_path, 8715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ComponentUnpacker::Error error, 8725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int extended_error) { 8735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!DeleteFileAndEmptyParentDirectory(crx_path)) 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << crx_path.value(); 8755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) main_task_runner_->PostDelayedTask( 8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 877010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Bind(&CrxUpdateService::DoneInstalling, 878010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Unretained(this), 879010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) component_id, 880010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) error, 881010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) extended_error), 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromMilliseconds(config_->StepDelay())); 883effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // Reset the unpacker last, otherwise we free our own arguments. 884effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch unpacker_ = NULL; 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Installation has been completed. Adjust the component status and 888ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// schedule the next check. Schedule a short delay before trying the full 889ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// update when the differential update failed. 8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CrxUpdateService::DoneInstalling(const std::string& component_id, 891eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ComponentUnpacker::Error error, 892eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int extra_code) { 8935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch ErrorCategory error_category = kErrorNone; 896ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch switch (error) { 897ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch case ComponentUnpacker::kNone: 898ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch break; 899ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch case ComponentUnpacker::kInstallerError: 900ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch error_category = kInstallError; 901ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch break; 902ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch default: 903ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch error_category = kUnpackError; 904ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch break; 905ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 906ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 907ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const bool is_success = error == ComponentUnpacker::kNone; 908ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CrxUpdateItem* item = FindUpdateItemById(component_id); 910ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (item->status == CrxUpdateItem::kUpdatingDiff && !is_success) { 911ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch item->diff_error_category = error_category; 912ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch item->diff_error_code = error; 913ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch item->diff_extra_code1 = extra_code; 91458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) item->diff_update_failed = true; 91558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) size_t count = ChangeItemStatus(CrxUpdateItem::kUpdatingDiff, 91658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) CrxUpdateItem::kCanUpdate); 91758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK_EQ(count, 1ul); 91858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ScheduleNextRun(kStepDelayShort); 91958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return; 920010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 921eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 922ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (is_success) { 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item->component.version = item->next_version; 924eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch item->component.fingerprint = item->next_fp; 925116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ChangeItemState(item, CrxUpdateItem::kUpdated); 926ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } else { 927ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch item->error_category = error_category; 928ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch item->error_code = error; 929ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch item->extra_code1 = extra_code; 930116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ChangeItemState(item, CrxUpdateItem::kNoUpdate); 931eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 933ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch ping_manager_->OnUpdateComplete(item); 9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Move on to the next update, if there is one available. 9363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ScheduleNextRun(kStepDelayMedium); 9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid CrxUpdateService::NotifyObservers(Observer::Events event, 9405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const std::string& id) { 9415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 9425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu FOR_EACH_OBSERVER(Observer, observer_list_, OnEvent(event, id)); 943a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 944a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 94546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)ComponentUpdateService::Status CrxUpdateService::OnDemandUpdateWithCooldown( 946cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CrxUpdateItem* uit) { 947cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!uit) 948cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return kError; 949cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 950cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Check if the request is too soon. 951cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::TimeDelta delta = base::Time::Now() - uit->last_check; 952cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (delta < base::TimeDelta::FromSeconds(config_->OnDemandDelay())) 953cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return kError; 954cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 95546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return OnDemandUpdateInternal(uit); 95646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 95746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 95846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)ComponentUpdateService::Status CrxUpdateService::OnDemandUpdateInternal( 95946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) CrxUpdateItem* uit) { 96046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (!uit) 96146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return kError; 96246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 96346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) uit->on_demand = true; 96446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 965116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // If there is an update available for this item, then continue processing 966116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // the update. This is an artifact of how update checks are done: in addition 967116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // to the on-demand item, the update check may include other items as well. 968116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (uit->status != CrxUpdateItem::kCanUpdate) { 969116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch Status service_status = GetServiceStatus(uit->status); 970116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // If the item is already in the process of being updated, there is 971116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // no point in this call, so return kInProgress. 972116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (service_status == kInProgress) 973116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return service_status; 974116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 975116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Otherwise the item was already checked a while back (or it is new), 976116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // set its status to kNew to give it a slightly higher priority. 977116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ChangeItemState(uit, CrxUpdateItem::kNew); 978116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 979116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 98046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // In case the current delay is long, set the timer to a shorter value 98146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // to get the ball rolling. 98246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (timer_.IsRunning()) { 98346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) timer_.Stop(); 98446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) timer_.Start(FROM_HERE, 98546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::TimeDelta::FromSeconds(config_->StepDelay()), 98646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) this, 98746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) &CrxUpdateService::ProcessPendingItems); 98846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 98946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 99046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return kOk; 99146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 99246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 99346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)ComponentUpdateService::Status CrxUpdateService::GetServiceStatus( 99446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) CrxUpdateItem::Status status) { 99546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) switch (status) { 996cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case CrxUpdateItem::kChecking: 997cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case CrxUpdateItem::kCanUpdate: 998cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case CrxUpdateItem::kDownloadingDiff: 999cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case CrxUpdateItem::kDownloading: 1000cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case CrxUpdateItem::kUpdatingDiff: 1001cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case CrxUpdateItem::kUpdating: 1002cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return kInProgress; 1003cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case CrxUpdateItem::kNew: 1004cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case CrxUpdateItem::kUpdated: 1005cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case CrxUpdateItem::kUpToDate: 1006cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case CrxUpdateItem::kNoUpdate: 100746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return kOk; 1008cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case CrxUpdateItem::kLastStatus: 100946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) NOTREACHED() << status; 1010cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 101146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return kError; 1012cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 1013cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 10140f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)/////////////////////////////////////////////////////////////////////////////// 10150f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The component update factory. Using the component updater as a singleton 10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// is the job of the browser process. 1018116680a4aac90f2aa7413d9095a592090648e557Ben MurdochComponentUpdateService* ComponentUpdateServiceFactory(Configurator* config) { 10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(config); 10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new CrxUpdateService(config); 10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1022f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 10235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace component_updater 1024