component_updater_service.cc revision 03b57e008b61dfcb1fbad3aea950ae0e001748b0
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" 136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "base/callback.h" 14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/compiler_specific.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/file_util.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/message_loop/message_loop_proxy.h" 205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "base/observer_list.h" 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/sequenced_task_runner.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h" 230f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "base/threading/sequenced_worker_pool.h" 245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/threading/thread_checker.h" 25eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/timer/timer.h" 2603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "components/component_updater/component_patcher_operation.h" 2703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "components/component_updater/component_unpacker.h" 2803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "components/component_updater/component_updater_configurator.h" 2903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "components/component_updater/component_updater_ping_manager.h" 3003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "components/component_updater/component_updater_utils.h" 3103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "components/component_updater/crx_downloader.h" 3203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "components/component_updater/crx_update_item.h" 3303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "components/component_updater/update_checker.h" 3403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "components/component_updater/update_response.h" 35eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "url/gurl.h" 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace component_updater { 385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The component updater is designed to live until process shutdown, so 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// base::Bind() calls are not refcounted. 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Returns true if the |proposed| version is newer than |current| version. 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsVersionNewer(const Version& current, const std::string& proposed) { 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Version proposed_ver(proposed); 47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return proposed_ver.IsValid() && current.CompareTo(proposed_ver) < 0; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 50eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Returns true if a differential update is available, it has not failed yet, 51eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// and the configuration allows it. 52eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool CanTryDiffUpdate(const CrxUpdateItem* update_item, 53116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const Configurator& config) { 54010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return HasDiffUpdate(update_item) && !update_item->diff_update_failed && 55eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch config.DeltasEnabled(); 56eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 57eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AppendDownloadMetrics( 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::vector<CrxDownloader::DownloadMetrics>& source, 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::vector<CrxDownloader::DownloadMetrics>* destination) { 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) destination->insert(destination->end(), source.begin(), source.end()); 625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 64ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} // namespace 65ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 66ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochCrxUpdateItem::CrxUpdateItem() 67ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch : status(kNew), 681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) on_demand(false), 69ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch diff_update_failed(false), 70ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch error_category(0), 71ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch error_code(0), 72ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch extra_code1(0), 73ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch diff_error_category(0), 74ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch diff_error_code(0), 75ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch diff_extra_code1(0) { 76ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 77ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 78ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochCrxUpdateItem::~CrxUpdateItem() { 79ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)CrxComponent::CrxComponent() 82010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) : installer(NULL), allow_background_download(true) { 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)CrxComponent::~CrxComponent() { 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////// 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The one and only implementation of the ComponentUpdateService interface. In 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// charge of running the show. The main method is ProcessPendingItems() which 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// is called periodically to do the upgrades/installs or the update checks. 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// An important consideration here is to be as "low impact" as we can to the 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// rest of the browser, so even if we have many components registered and 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// eligible for update, we only do one thing at a time with pauses in between 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the tasks. Also when we do network requests there is only one |url_fetcher_| 96eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// in flight at a time. 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// There are no locks in this code, the main structure |work_items_| is mutated 985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// only from the main thread. The unpack and installation is done in a blocking 995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// pool thread. The network requests are done in the IO thread or in the file 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// thread. 101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class CrxUpdateService : public ComponentUpdateService, public OnDemandUpdater { 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 103116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch explicit CrxUpdateService(Configurator* config); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~CrxUpdateService(); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Overrides for ComponentUpdateService. 1075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu virtual void AddObserver(Observer* observer) OVERRIDE; 1085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu virtual void RemoveObserver(Observer* observer) OVERRIDE; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual Status Start() OVERRIDE; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual Status Stop() OVERRIDE; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual Status RegisterComponent(const CrxComponent& component) OVERRIDE; 11246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) virtual std::vector<std::string> GetComponentIDs() const OVERRIDE; 113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) virtual OnDemandUpdater& GetOnDemandUpdater() OVERRIDE; 1146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) virtual void MaybeThrottle(const std::string& crx_id, 1156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const base::Closure& callback) OVERRIDE; 1165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) virtual scoped_refptr<base::SequencedTaskRunner> GetSequencedTaskRunner() 1175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) OVERRIDE; 118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 119010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Context for a crx download url request. 120010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) struct CRXContext { 121010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ComponentInstaller* installer; 122010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) std::vector<uint8> pk_hash; 123010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) std::string id; 124010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) std::string fingerprint; 125010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) CRXContext() : installer(NULL) {} 126010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) }; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 129ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch enum ErrorCategory { 130ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch kErrorNone = 0, 131ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch kNetworkError, 132ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch kUnpackError, 133ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch kInstallError, 134ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch }; 135ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 1363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) enum StepDelayInterval { 1373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) kStepDelayShort = 0, 1383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) kStepDelayMedium, 1393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) kStepDelayLong, 1403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) }; 1413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // Overrides for ComponentUpdateService. 1436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) virtual bool GetComponentDetails(const std::string& component_id, 1446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) CrxUpdateItem* item) const OVERRIDE; 1456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // Overrides for OnDemandUpdater. 1476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) virtual Status OnDemandUpdate(const std::string& component_id) OVERRIDE; 1486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void UpdateCheckComplete(int error, 1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& error_message, 1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const UpdateResponse::Results& results); 1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void OnUpdateCheckSucceeded(const UpdateResponse::Results& results); 1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void OnUpdateCheckFailed(int error, const std::string& error_message); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) void DownloadProgress(const std::string& component_id, 156010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const CrxDownloader::Result& download_result); 157010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 158010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) void DownloadComplete(scoped_ptr<CRXContext> crx_context, 159010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const CrxDownloader::Result& download_result); 160a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 1610f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) Status OnDemandUpdateInternal(CrxUpdateItem* item); 16246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) Status OnDemandUpdateWithCooldown(CrxUpdateItem* item); 1630f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ProcessPendingItems(); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Find a component that is ready to update. 1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CrxUpdateItem* FindReadyComponent() const; 1681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Prepares the components for an update check and initiates the request. 1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Returns true if an update check request has been made. Returns false if 1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // no update check was needed or an error occured. 1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool CheckForUpdates(); 1731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void UpdateComponent(CrxUpdateItem* workitem); 1751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) void ScheduleNextRun(StepDelayInterval step_delay); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 178f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void ParseResponse(const std::string& xml); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 180a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) void Install(scoped_ptr<CRXContext> context, const base::FilePath& crx_path); 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void EndUnpacking(const std::string& component_id, 1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::FilePath& crx_path, 1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ComponentUnpacker::Error error, 1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int extended_error); 1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DoneInstalling(const std::string& component_id, 188eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ComponentUnpacker::Error error, 189eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int extended_error); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) void ChangeItemState(CrxUpdateItem* item, CrxUpdateItem::Status to); 1921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 193010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) size_t ChangeItemStatus(CrxUpdateItem::Status from, CrxUpdateItem::Status to); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) CrxUpdateItem* FindUpdateItemById(const std::string& id) const; 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu void NotifyObservers(Observer::Events event, const std::string& id); 198a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) bool HasOnDemandItems() const; 2001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 20146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) Status GetServiceStatus(const CrxUpdateItem::Status status); 20246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 203116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_ptr<Configurator> config_; 204eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<UpdateChecker> update_checker_; 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<PingManager> ping_manager_; 208ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 209effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch scoped_refptr<ComponentUnpacker> unpacker_; 2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<CrxDownloader> crx_downloader_; 212a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // A collection of every work item. 214eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch typedef std::vector<CrxUpdateItem*> UpdateItems; 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateItems work_items_; 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::OneShotTimer<CrxUpdateService> timer_; 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::ThreadChecker thread_checker_; 2205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Used to post responses back to the main thread. 2225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; 2235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2240f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_; 2250f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool running_; 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ObserverList<Observer> observer_list_; 2295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(CrxUpdateService); 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////// 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235116680a4aac90f2aa7413d9095a592090648e557Ben MurdochCrxUpdateService::CrxUpdateService(Configurator* config) 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : config_(config), 237116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ping_manager_(new PingManager(*config)), 2385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) main_task_runner_(base::MessageLoopProxy::current()), 2395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) blocking_task_runner_(config->GetSequencedTaskRunner()), 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) running_(false) { 24158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CrxUpdateService::~CrxUpdateService() { 2445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Because we are a singleton, at this point only the main thread should be 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // alive, this simplifies the management of the work that could be in 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // flight in other threads. 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Stop(); 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) STLDeleteElements(&work_items_); 24958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid CrxUpdateService::AddObserver(Observer* observer) { 2525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 2535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu observer_list_.AddObserver(observer); 2545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 2555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 2565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid CrxUpdateService::RemoveObserver(Observer* observer) { 2575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 2585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu observer_list_.RemoveObserver(observer); 2595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 2605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ComponentUpdateService::Status CrxUpdateService::Start() { 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that RegisterComponent will call Start() when the first 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // component is registered, so it can be called twice. This way 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we avoid scheduling the timer if there is no work to do. 2655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu VLOG(1) << "CrxUpdateService starting up"; 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) running_ = true; 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (work_items_.empty()) 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return kOk; 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu NotifyObservers(Observer::COMPONENT_UPDATER_STARTED, ""); 271a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 2725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu VLOG(1) << "First update attempt will take place in " 2735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu << config_->InitialDelay() << " seconds"; 274010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) timer_.Start(FROM_HERE, 275010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::TimeDelta::FromSeconds(config_->InitialDelay()), 276010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) this, 277010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) &CrxUpdateService::ProcessPendingItems); 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return kOk; 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Stop the main check + update loop. In flight operations will be 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// completed. 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ComponentUpdateService::Status CrxUpdateService::Stop() { 2845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu VLOG(1) << "CrxUpdateService stopping"; 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) running_ = false; 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) timer_.Stop(); 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return kOk; 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)bool CrxUpdateService::HasOnDemandItems() const { 2911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) class Helper { 2921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) public: 293010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) static bool IsOnDemand(CrxUpdateItem* item) { return item->on_demand; } 2941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) }; 2951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return std::find_if(work_items_.begin(), 2961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) work_items_.end(), 2971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) Helper::IsOnDemand) != work_items_.end(); 2981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 2991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// This function sets the timer which will call ProcessPendingItems() or 3011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// ProcessRequestedItem() if there is an on_demand item. There 3023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// are three kinds of waits: 3033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// - a short delay, when there is immediate work to be done. 3043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// - a medium delay, when there are updates to be applied within the current 3053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// update cycle, or there are components that are still unchecked. 3063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// - a long delay when a full check/update cycle has completed for all 3073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// components. 3083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void CrxUpdateService::ScheduleNextRun(StepDelayInterval step_delay) { 3095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 3105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(!update_checker_); 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(!timer_.IsRunning()); 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // It could be the case that Stop() had been called while a url request 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // or unpacking was in flight, if so we arrive here but |running_| is 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // false. In that case do not loop again. 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!running_) 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Keep the delay short if in the middle of an update (step_delay), 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // or there are new requested_work_items_ that have not been processed yet. 3203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int64 delay_seconds = 0; 3211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (!HasOnDemandItems()) { 3223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) switch (step_delay) { 3233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case kStepDelayShort: 3243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) delay_seconds = config_->StepDelay(); 3253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) break; 3263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case kStepDelayMedium: 3273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) delay_seconds = config_->StepDelayMedium(); 3283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) break; 3293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case kStepDelayLong: 3303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) delay_seconds = config_->NextCheckDelay(); 3313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) break; 3323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 3333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else { 3343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) delay_seconds = config_->StepDelay(); 3353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (step_delay != kStepDelayShort) { 3385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu NotifyObservers(Observer::COMPONENT_UPDATER_SLEEPING, ""); 339a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Zero is only used for unit tests. 3413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (0 == delay_seconds) 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu VLOG(1) << "Scheduling next run to occur in " << delay_seconds << " seconds"; 346010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) timer_.Start(FROM_HERE, 347010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::TimeDelta::FromSeconds(delay_seconds), 348010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) this, 349010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) &CrxUpdateService::ProcessPendingItems); 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Given a extension-like component id, find the associated component. 35346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)CrxUpdateItem* CrxUpdateService::FindUpdateItemById( 35446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const std::string& id) const { 3555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CrxUpdateItem::FindById finder(id); 35746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) UpdateItems::const_iterator it = 358010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) std::find_if(work_items_.begin(), work_items_.end(), finder); 3595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return it != work_items_.end() ? *it : NULL; 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// Changes a component's status, clearing on_demand and firing notifications as 3631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// necessary. By convention, this is the only function that can change a 3641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// CrxUpdateItem's |status|. 3651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// TODO(waffles): Do we want to add DCHECKS for valid state transitions here? 3661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void CrxUpdateService::ChangeItemState(CrxUpdateItem* item, 3671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) CrxUpdateItem::Status to) { 3685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 369010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (to == CrxUpdateItem::kNoUpdate || to == CrxUpdateItem::kUpdated || 3701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) to == CrxUpdateItem::kUpToDate) { 3711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) item->on_demand = false; 3721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 3731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) item->status = to; 3751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu switch (to) { 3775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu case CrxUpdateItem::kCanUpdate: 3785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu NotifyObservers(Observer::COMPONENT_UPDATE_FOUND, item->id); 3795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu break; 3805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu case CrxUpdateItem::kUpdatingDiff: 3815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu case CrxUpdateItem::kUpdating: 3825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu NotifyObservers(Observer::COMPONENT_UPDATE_READY, item->id); 3835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu break; 3845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu case CrxUpdateItem::kUpdated: 3855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu NotifyObservers(Observer::COMPONENT_UPDATED, item->id); 3865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu break; 3875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu case CrxUpdateItem::kUpToDate: 3885c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu case CrxUpdateItem::kNoUpdate: 3895c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu NotifyObservers(Observer::COMPONENT_NOT_UPDATED, item->id); 3905c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu break; 3915c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu case CrxUpdateItem::kNew: 3925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu case CrxUpdateItem::kChecking: 3935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu case CrxUpdateItem::kDownloading: 3945c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu case CrxUpdateItem::kDownloadingDiff: 3955c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu case CrxUpdateItem::kLastStatus: 3965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // No notification for these states. 3975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu break; 3981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 3990f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 4000f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // Free possible pending network requests. 401010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if ((to == CrxUpdateItem::kUpdated) || (to == CrxUpdateItem::kUpToDate) || 4020f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) (to == CrxUpdateItem::kNoUpdate)) { 4036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) for (std::vector<base::Closure>::iterator it = 4046e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) item->ready_callbacks.begin(); 4056e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) it != item->ready_callbacks.end(); 4066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) ++it) { 4076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) it->Run(); 4086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 4096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) item->ready_callbacks.clear(); 4100f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) } 4111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 4121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Changes all the components in |work_items_| that have |from| status to 414eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// |to| status and returns how many have been changed. 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)size_t CrxUpdateService::ChangeItemStatus(CrxUpdateItem::Status from, 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CrxUpdateItem::Status to) { 4175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t count = 0; 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (UpdateItems::iterator it = work_items_.begin(); 420010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) it != work_items_.end(); 421010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ++it) { 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CrxUpdateItem* item = *it; 4235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (item->status == from) { 4245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ChangeItemState(item, to); 4255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ++count; 4265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return count; 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Adds a component to be checked for upgrades. If the component exists it 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// it will be replaced and the return code is kReplaced. 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ComponentUpdateService::Status CrxUpdateService::RegisterComponent( 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const CrxComponent& component) { 4355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 436010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (component.pk_hash.empty() || !component.version.IsValid() || 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !component.installer) 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return kError; 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string id(GetCrxComponentID(component)); 4415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CrxUpdateItem* uit = FindUpdateItemById(id); 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (uit) { 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uit->component = component; 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return kReplaced; 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uit = new CrxUpdateItem; 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uit->id.swap(id); 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uit->component = component; 450eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) work_items_.push_back(uit); 452f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If this is the first component registered we call Start to 454f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // schedule the first timer. Otherwise, reset the timer to trigger another 455f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // pass over the work items, if the component updater is sleeping, fact 456f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // indicated by a running timer. If the timer is not running, it means that 457f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // the service is busy updating something, and in that case, this component 458f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // will be picked up at the next pass. 459f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (running_) { 460f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (work_items_.size() == 1) { 461f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) Start(); 462f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } else if (timer_.IsRunning()) { 463f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) timer_.Start(FROM_HERE, 464f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::TimeDelta::FromSeconds(config_->InitialDelay()), 465f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) this, 466f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) &CrxUpdateService::ProcessPendingItems); 467f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 468f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return kOk; 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 47346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)std::vector<std::string> CrxUpdateService::GetComponentIDs() const { 4745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 47546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) std::vector<std::string> component_ids; 4763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) for (UpdateItems::const_iterator it = work_items_.begin(); 477010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) it != work_items_.end(); 478010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ++it) { 4793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const CrxUpdateItem* item = *it; 48046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) component_ids.push_back(item->id); 4813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 48246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return component_ids; 48346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 48446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 4856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)OnDemandUpdater& CrxUpdateService::GetOnDemandUpdater() { 4866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return *this; 4876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 4886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 4896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void CrxUpdateService::MaybeThrottle(const std::string& crx_id, 4906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const base::Closure& callback) { 4916e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 4926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // Check if we can on-demand update, else unblock the request anyway. 4936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) CrxUpdateItem* item = FindUpdateItemById(crx_id); 4946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) Status status = OnDemandUpdateWithCooldown(item); 4956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (status == kOk || status == kInProgress) { 4966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) item->ready_callbacks.push_back(callback); 4976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return; 4986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 4996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) callback.Run(); 5006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 5016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 5026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)scoped_refptr<base::SequencedTaskRunner> 5036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)CrxUpdateService::GetSequencedTaskRunner() { 5046e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return config_->GetSequencedTaskRunner(); 5056e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 5066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 507f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool CrxUpdateService::GetComponentDetails(const std::string& component_id, 508f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) CrxUpdateItem* item) const { 5095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 510f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const CrxUpdateItem* crx_update_item(FindUpdateItemById(component_id)); 511f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (crx_update_item) 512f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) *item = *crx_update_item; 513f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return crx_update_item != NULL; 5143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 5153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 5166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// Start the process of checking for an update, for a particular component 5176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// that was previously registered. 5186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// |component_id| is a value returned from GetCrxComponentID(). 5196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)ComponentUpdateService::Status CrxUpdateService::OnDemandUpdate( 5206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const std::string& component_id) { 5216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return OnDemandUpdateInternal(FindUpdateItemById(component_id)); 5225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 5235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 5245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// This is the main loop of the component updater. It updates one component 5255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// at a time if updates are available. Otherwise, it does an update check or 5265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// takes a long sleep until the loop runs again. 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CrxUpdateService::ProcessPendingItems() { 5285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 5295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) CrxUpdateItem* ready_upgrade = FindReadyComponent(); 5311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (ready_upgrade) { 5321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) UpdateComponent(ready_upgrade); 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!CheckForUpdates()) 5375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScheduleNextRun(kStepDelayLong); 5381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 5391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 5405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)CrxUpdateItem* CrxUpdateService::FindReadyComponent() const { 5411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) class Helper { 5421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) public: 5431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) static bool IsReadyOnDemand(CrxUpdateItem* item) { 5441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return item->on_demand && IsReady(item); 5451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 5461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) static bool IsReady(CrxUpdateItem* item) { 5471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return item->status == CrxUpdateItem::kCanUpdate; 5481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 5491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) }; 5501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 5515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::vector<CrxUpdateItem*>::const_iterator it = std::find_if( 5521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) work_items_.begin(), work_items_.end(), Helper::IsReadyOnDemand); 5531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (it != work_items_.end()) 5541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return *it; 5551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) it = std::find_if(work_items_.begin(), work_items_.end(), Helper::IsReady); 5561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (it != work_items_.end()) 5571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return *it; 5581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return NULL; 5591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 5601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 5615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Prepares the components for an update check and initiates the request. 562a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// On demand components are always included in the update check request. 563a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Otherwise, only include components that have not been checked recently. 5645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool CrxUpdateService::CheckForUpdates() { 565a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const base::TimeDelta minimum_recheck_wait_time = 566a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::TimeDelta::FromSeconds(config_->MinimumReCheckWait()); 567a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const base::Time now(base::Time::Now()); 568a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 5695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::vector<CrxUpdateItem*> items_to_check; 5705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (size_t i = 0; i != work_items_.size(); ++i) { 5715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CrxUpdateItem* item = work_items_[i]; 5725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(item->status == CrxUpdateItem::kNew || 5735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) item->status == CrxUpdateItem::kNoUpdate || 5745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) item->status == CrxUpdateItem::kUpToDate || 5755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) item->status == CrxUpdateItem::kUpdated); 5765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 577a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const base::TimeDelta time_since_last_checked(now - item->last_check); 578a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 579a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!item->on_demand && 580a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) time_since_last_checked < minimum_recheck_wait_time) { 5815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu VLOG(1) << "Skipping check for component update: id=" << item->id 5825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu << ", time_since_last_checked=" 5835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu << time_since_last_checked.InSeconds() 5845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu << " seconds: too soon to check for an update"; 585a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) continue; 586a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 587a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 5885c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu VLOG(1) << "Scheduling update check for component id=" << item->id 5895c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu << ", time_since_last_checked=" 590010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) << time_since_last_checked.InSeconds() << " seconds"; 5915c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 592a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) item->last_check = now; 5935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) item->crx_urls.clear(); 5945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) item->crx_diffurls.clear(); 5955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) item->previous_version = item->component.version; 5965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) item->next_version = Version(); 5975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) item->previous_fp = item->component.fingerprint; 5985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) item->next_fp.clear(); 5995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) item->diff_update_failed = false; 6005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) item->error_category = 0; 6015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) item->error_code = 0; 6025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) item->extra_code1 = 0; 6035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) item->diff_error_category = 0; 6045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) item->diff_error_code = 0; 6055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) item->diff_extra_code1 = 0; 6065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) item->download_metrics.clear(); 6075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 6085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) items_to_check.push_back(item); 609116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 610116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ChangeItemState(item, CrxUpdateItem::kChecking); 6115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 6125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 6135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (items_to_check.empty()) 6145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 6155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 616010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) update_checker_ = 617116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch UpdateChecker::Create(*config_, 618010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Bind(&CrxUpdateService::UpdateCheckComplete, 619010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Unretained(this))).Pass(); 6205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return update_checker_->CheckForUpdates(items_to_check, 6215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) config_->ExtraRequestParams()); 6225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 6235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 6241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void CrxUpdateService::UpdateComponent(CrxUpdateItem* workitem) { 625a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_ptr<CRXContext> crx_context(new CRXContext); 626a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) crx_context->pk_hash = workitem->component.pk_hash; 627a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) crx_context->id = workitem->id; 628a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) crx_context->installer = workitem->component.installer; 629a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) crx_context->fingerprint = workitem->next_fp; 6305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::vector<GURL>* urls = NULL; 6315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool allow_background_download = false; 6321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (CanTryDiffUpdate(workitem, *config_)) { 6335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) urls = &workitem->crx_diffurls; 6341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) ChangeItemState(workitem, CrxUpdateItem::kDownloadingDiff); 6351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } else { 6365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Background downloads are enabled only for selected components and 6375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // only for full downloads (see issue 340448). 6385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) allow_background_download = workitem->component.allow_background_download; 6395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) urls = &workitem->crx_urls; 6401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) ChangeItemState(workitem, CrxUpdateItem::kDownloading); 6411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 642a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 643a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // On demand component updates are always downloaded in foreground. 644010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const bool is_background_download = !workitem->on_demand && 645010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) allow_background_download && 646010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) config_->UseBackgroundDownloader(); 647a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 6485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) crx_downloader_.reset( 6495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) CrxDownloader::Create(is_background_download, 6505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) config_->RequestContext(), 6515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) blocking_task_runner_, 6525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) config_->GetSingleThreadTaskRunner())); 653010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) crx_downloader_->set_progress_callback( 654010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Bind(&CrxUpdateService::DownloadProgress, 655010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Unretained(this), 656010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) crx_context->id)); 6575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu crx_downloader_->StartDownload(*urls, 6585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Bind(&CrxUpdateService::DownloadComplete, 6595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Unretained(this), 6605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Passed(&crx_context))); 661f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 662f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 6635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void CrxUpdateService::UpdateCheckComplete( 6645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int error, 6655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& error_message, 6665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const UpdateResponse::Results& results) { 6675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 6685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) update_checker_.reset(); 6695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!error) 6705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) OnUpdateCheckSucceeded(results); 671f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) else 6725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) OnUpdateCheckFailed(error, error_message); 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Handles a valid Omaha update check response by matching the results with 6765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// the registered components which were checked for updates. 6775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// If updates are found, prepare the components for the actual version upgrade. 6785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// One of these components will be drafted for the upgrade next time 6795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// ProcessPendingItems is called. 6805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void CrxUpdateService::OnUpdateCheckSucceeded( 6815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const UpdateResponse::Results& results) { 682f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) size_t num_updates_pending = 0; 6835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 6845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu VLOG(1) << "Update check succeeded."; 6855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::vector<UpdateResponse::Result>::const_iterator it; 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (it = results.list.begin(); it != results.list.end(); ++it) { 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CrxUpdateItem* crx = FindUpdateItemById(it->extension_id); 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!crx) 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 691f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (crx->status != CrxUpdateItem::kChecking) { 692f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) NOTREACHED(); 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; // Not updating this component now. 694f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 696f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (it->manifest.version.empty()) { 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No version means no update available. 6981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) ChangeItemState(crx, CrxUpdateItem::kNoUpdate); 6995c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu VLOG(1) << "No update available for component: " << crx->id; 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 702f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 703f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!IsVersionNewer(crx->component.version, it->manifest.version)) { 704f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // The component is up to date. 7051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) ChangeItemState(crx, CrxUpdateItem::kUpToDate); 7065c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu VLOG(1) << "Component already up-to-date: " << crx->id; 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 709f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 710f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!it->manifest.browser_min_version.empty()) { 711116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (IsVersionNewer(config_->GetBrowserVersion(), 712116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch it->manifest.browser_min_version)) { 713f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // The component is not compatible with this Chrome version. 7145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu VLOG(1) << "Ignoring incompatible component: " << crx->id; 7151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) ChangeItemState(crx, CrxUpdateItem::kNoUpdate); 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 719f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 720f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (it->manifest.packages.size() != 1) { 721f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Assume one and only one package per component. 7225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu VLOG(1) << "Ignoring multiple packages for component: " << crx->id; 723f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ChangeItemState(crx, CrxUpdateItem::kNoUpdate); 724f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) continue; 725f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 726f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 727f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Parse the members of the result and queue an upgrade for this component. 728f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) crx->next_version = Version(it->manifest.version); 729f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 7305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu VLOG(1) << "Update found for component: " << crx->id; 7315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 7325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) typedef UpdateResponse::Result::Manifest::Package Package; 733f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const Package& package(it->manifest.packages[0]); 734f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) crx->next_fp = package.fingerprint; 735f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 7365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Resolve the urls by combining the base urls with the package names. 7375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (size_t i = 0; i != it->crx_urls.size(); ++i) { 7385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const GURL url(it->crx_urls[i].Resolve(package.name)); 7395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (url.is_valid()) 740010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) crx->crx_urls.push_back(url); 7415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 7425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (size_t i = 0; i != it->crx_diffurls.size(); ++i) { 7435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const GURL url(it->crx_diffurls[i].Resolve(package.namediff)); 7445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (url.is_valid()) 745010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) crx->crx_diffurls.push_back(url); 7465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 747f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 7481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) ChangeItemState(crx, CrxUpdateItem::kCanUpdate); 749f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ++num_updates_pending; 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 752f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // All components that are not included in the update response are 753f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // considered up to date. 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChangeItemStatus(CrxUpdateItem::kChecking, CrxUpdateItem::kUpToDate); 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // If there are updates pending we do a short wait, otherwise we take 7573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // a longer delay until we check the components again. 758a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ScheduleNextRun(num_updates_pending > 0 ? kStepDelayShort : kStepDelayLong); 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void CrxUpdateService::OnUpdateCheckFailed(int error, 7625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& error_message) { 7635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 7645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(error); 765010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) size_t count = 766010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ChangeItemStatus(CrxUpdateItem::kChecking, CrxUpdateItem::kNoUpdate); 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GT(count, 0ul); 7685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu VLOG(1) << "Update check failed."; 7693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ScheduleNextRun(kStepDelayLong); 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 772010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Called when progress is being made downloading a CRX. The progress may 773010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// not monotonically increase due to how the CRX downloader switches between 774010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// different downloaders and fallback urls. 775010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void CrxUpdateService::DownloadProgress( 776010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const std::string& component_id, 777010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const CrxDownloader::Result& download_result) { 7785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 779010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) NotifyObservers(Observer::COMPONENT_UPDATE_DOWNLOADING, component_id); 780010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 781010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Called when the CRX package has been downloaded to a temporary location. 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Here we fire the notifications and schedule the component-specific installer 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to be called in the file thread. 785a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void CrxUpdateService::DownloadComplete( 786a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_ptr<CRXContext> crx_context, 7875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const CrxDownloader::Result& download_result) { 7885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 78958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 79058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) CrxUpdateItem* crx = FindUpdateItemById(crx_context->id); 791eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(crx->status == CrxUpdateItem::kDownloadingDiff || 792eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch crx->status == CrxUpdateItem::kDownloading); 793eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 7945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AppendDownloadMetrics(crx_downloader_->download_metrics(), 7955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &crx->download_metrics); 7965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 797010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) crx_downloader_.reset(); 798010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 799a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (download_result.error) { 800eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (crx->status == CrxUpdateItem::kDownloadingDiff) { 801ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch crx->diff_error_category = kNetworkError; 802a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) crx->diff_error_code = download_result.error; 803eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch crx->diff_update_failed = true; 804eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch size_t count = ChangeItemStatus(CrxUpdateItem::kDownloadingDiff, 805eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CrxUpdateItem::kCanUpdate); 806eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK_EQ(count, 1ul); 807ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 8083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ScheduleNextRun(kStepDelayShort); 809eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return; 810eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 811ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch crx->error_category = kNetworkError; 812a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) crx->error_code = download_result.error; 813010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) size_t count = 814010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ChangeItemStatus(CrxUpdateItem::kDownloading, CrxUpdateItem::kNoUpdate); 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(count, 1ul); 816eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 817ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // At this point, since both the differential and the full downloads failed, 818ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // the update for this component has finished with an error. 819ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch ping_manager_->OnUpdateComplete(crx); 820ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 8213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Move on to the next update, if there is one available. 8223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ScheduleNextRun(kStepDelayMedium); 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 824eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch size_t count = 0; 825eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (crx->status == CrxUpdateItem::kDownloadingDiff) { 826eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch count = ChangeItemStatus(CrxUpdateItem::kDownloadingDiff, 827eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CrxUpdateItem::kUpdatingDiff); 828eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } else { 829eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch count = ChangeItemStatus(CrxUpdateItem::kDownloading, 830eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CrxUpdateItem::kUpdating); 831eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(count, 1ul); 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Why unretained? See comment at top of file. 8350f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) blocking_task_runner_->PostDelayedTask( 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&CrxUpdateService::Install, 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this), 839a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::Passed(&crx_context), 840a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) download_result.response), 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromMilliseconds(config_->StepDelay())); 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Install consists of digital signature verification, unpacking and then 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// calling the component specific installer. All that is handled by the 8475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// |unpacker_|. If there is an error this function is in charge of deleting 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the files created. 849a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void CrxUpdateService::Install(scoped_ptr<CRXContext> context, 8502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& crx_path) { 8510f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // This function owns the file at |crx_path| and the |context| object. 852effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch unpacker_ = new ComponentUnpacker(context->pk_hash, 853effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch crx_path, 854effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch context->fingerprint, 855effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch context->installer, 8565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) config_->CreateOutOfProcessPatcher(), 857effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch blocking_task_runner_); 8585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) unpacker_->Unpack(base::Bind(&CrxUpdateService::EndUnpacking, 8595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Unretained(this), 8605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) context->id, 8615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) crx_path)); 8625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 8635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 8645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void CrxUpdateService::EndUnpacking(const std::string& component_id, 8655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::FilePath& crx_path, 8665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ComponentUnpacker::Error error, 8675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int extended_error) { 8685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!DeleteFileAndEmptyParentDirectory(crx_path)) 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << crx_path.value(); 8705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) main_task_runner_->PostDelayedTask( 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 872010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Bind(&CrxUpdateService::DoneInstalling, 873010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Unretained(this), 874010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) component_id, 875010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) error, 876010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) extended_error), 8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromMilliseconds(config_->StepDelay())); 878effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // Reset the unpacker last, otherwise we free our own arguments. 879effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch unpacker_ = NULL; 8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Installation has been completed. Adjust the component status and 883ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// schedule the next check. Schedule a short delay before trying the full 884ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// update when the differential update failed. 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CrxUpdateService::DoneInstalling(const std::string& component_id, 886eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ComponentUnpacker::Error error, 887eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int extra_code) { 8885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 890ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch ErrorCategory error_category = kErrorNone; 891ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch switch (error) { 892ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch case ComponentUnpacker::kNone: 893ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch break; 894ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch case ComponentUnpacker::kInstallerError: 895ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch error_category = kInstallError; 896ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch break; 897ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch default: 898ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch error_category = kUnpackError; 899ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch break; 900ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 901ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 902ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const bool is_success = error == ComponentUnpacker::kNone; 903ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CrxUpdateItem* item = FindUpdateItemById(component_id); 905ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (item->status == CrxUpdateItem::kUpdatingDiff && !is_success) { 906ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch item->diff_error_category = error_category; 907ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch item->diff_error_code = error; 908ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch item->diff_extra_code1 = extra_code; 90958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) item->diff_update_failed = true; 91058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) size_t count = ChangeItemStatus(CrxUpdateItem::kUpdatingDiff, 91158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) CrxUpdateItem::kCanUpdate); 91258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK_EQ(count, 1ul); 91358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ScheduleNextRun(kStepDelayShort); 91458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return; 915010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 916eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 917ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (is_success) { 9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item->component.version = item->next_version; 919eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch item->component.fingerprint = item->next_fp; 920116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ChangeItemState(item, CrxUpdateItem::kUpdated); 921ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } else { 922ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch item->error_category = error_category; 923ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch item->error_code = error; 924ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch item->extra_code1 = extra_code; 925116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ChangeItemState(item, CrxUpdateItem::kNoUpdate); 926eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 928ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch ping_manager_->OnUpdateComplete(item); 9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Move on to the next update, if there is one available. 9313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ScheduleNextRun(kStepDelayMedium); 9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid CrxUpdateService::NotifyObservers(Observer::Events event, 9355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const std::string& id) { 9365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 9375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu FOR_EACH_OBSERVER(Observer, observer_list_, OnEvent(event, id)); 938a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 939a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 94046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)ComponentUpdateService::Status CrxUpdateService::OnDemandUpdateWithCooldown( 941cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CrxUpdateItem* uit) { 942cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!uit) 943cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return kError; 944cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 945cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Check if the request is too soon. 946cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::TimeDelta delta = base::Time::Now() - uit->last_check; 947cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (delta < base::TimeDelta::FromSeconds(config_->OnDemandDelay())) 948cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return kError; 949cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 95046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return OnDemandUpdateInternal(uit); 95146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 95246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 95346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)ComponentUpdateService::Status CrxUpdateService::OnDemandUpdateInternal( 95446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) CrxUpdateItem* uit) { 95546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (!uit) 95646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return kError; 95746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 95846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) uit->on_demand = true; 95946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 960116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // If there is an update available for this item, then continue processing 961116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // the update. This is an artifact of how update checks are done: in addition 962116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // to the on-demand item, the update check may include other items as well. 963116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (uit->status != CrxUpdateItem::kCanUpdate) { 964116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch Status service_status = GetServiceStatus(uit->status); 965116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // If the item is already in the process of being updated, there is 966116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // no point in this call, so return kInProgress. 967116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (service_status == kInProgress) 968116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return service_status; 969116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 970116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Otherwise the item was already checked a while back (or it is new), 971116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // set its status to kNew to give it a slightly higher priority. 972116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ChangeItemState(uit, CrxUpdateItem::kNew); 973116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 974116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 97546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // In case the current delay is long, set the timer to a shorter value 97646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // to get the ball rolling. 97746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (timer_.IsRunning()) { 97846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) timer_.Stop(); 97946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) timer_.Start(FROM_HERE, 98046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::TimeDelta::FromSeconds(config_->StepDelay()), 98146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) this, 98246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) &CrxUpdateService::ProcessPendingItems); 98346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 98446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 98546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return kOk; 98646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 98746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 98846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)ComponentUpdateService::Status CrxUpdateService::GetServiceStatus( 98946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) CrxUpdateItem::Status status) { 99046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) switch (status) { 991cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case CrxUpdateItem::kChecking: 992cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case CrxUpdateItem::kCanUpdate: 993cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case CrxUpdateItem::kDownloadingDiff: 994cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case CrxUpdateItem::kDownloading: 995cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case CrxUpdateItem::kUpdatingDiff: 996cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case CrxUpdateItem::kUpdating: 997cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return kInProgress; 998cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case CrxUpdateItem::kNew: 999cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case CrxUpdateItem::kUpdated: 1000cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case CrxUpdateItem::kUpToDate: 1001cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case CrxUpdateItem::kNoUpdate: 100246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return kOk; 1003cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case CrxUpdateItem::kLastStatus: 100446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) NOTREACHED() << status; 1005cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 100646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return kError; 1007cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 1008cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 10090f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)/////////////////////////////////////////////////////////////////////////////// 10100f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The component update factory. Using the component updater as a singleton 10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// is the job of the browser process. 1013116680a4aac90f2aa7413d9095a592090648e557Ben MurdochComponentUpdateService* ComponentUpdateServiceFactory(Configurator* config) { 10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(config); 10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new CrxUpdateService(config); 10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1017f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 10185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace component_updater 1019