1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#ifndef CHROME_BROWSER_EXTENSIONS_UPDATER_EXTENSION_UPDATER_H_ 6#define CHROME_BROWSER_EXTENSIONS_UPDATER_EXTENSION_UPDATER_H_ 7 8#include <list> 9#include <map> 10#include <set> 11#include <stack> 12#include <string> 13 14#include "base/callback_forward.h" 15#include "base/compiler_specific.h" 16#include "base/files/file_path.h" 17#include "base/gtest_prod_util.h" 18#include "base/memory/scoped_ptr.h" 19#include "base/memory/weak_ptr.h" 20#include "base/scoped_observer.h" 21#include "base/time/time.h" 22#include "base/timer/timer.h" 23#include "chrome/browser/extensions/updater/extension_downloader.h" 24#include "chrome/browser/extensions/updater/extension_downloader_delegate.h" 25#include "content/public/browser/notification_observer.h" 26#include "content/public/browser/notification_registrar.h" 27#include "extensions/browser/extension_registry_observer.h" 28#include "extensions/browser/updater/manifest_fetch_data.h" 29#include "url/gurl.h" 30 31class ExtensionServiceInterface; 32class PrefService; 33class Profile; 34 35namespace content { 36class BrowserContext; 37} 38 39namespace extensions { 40 41class ExtensionCache; 42class ExtensionPrefs; 43class ExtensionRegistry; 44class ExtensionSet; 45class ExtensionUpdaterTest; 46 47// A class for doing auto-updates of installed Extensions. Used like this: 48// 49// ExtensionUpdater* updater = new ExtensionUpdater(my_extensions_service, 50// extension_prefs, 51// pref_service, 52// profile, 53// update_frequency_secs, 54// downloader_factory); 55// updater->Start(); 56// .... 57// updater->Stop(); 58class ExtensionUpdater : public ExtensionDownloaderDelegate, 59 public ExtensionRegistryObserver, 60 public content::NotificationObserver { 61 public: 62 typedef base::Closure FinishedCallback; 63 64 struct CheckParams { 65 // Creates a default CheckParams instance that checks for all extensions. 66 CheckParams(); 67 ~CheckParams(); 68 69 // The set of extensions that should be checked for updates. If empty 70 // all extensions will be included in the update check. 71 std::list<std::string> ids; 72 73 // Normally extension updates get installed only when the extension is idle. 74 // Setting this to true causes any updates that are found to be installed 75 // right away. 76 bool install_immediately; 77 78 // Callback to call when the update check is complete. Can be null, if 79 // you're not interested in when this happens. 80 FinishedCallback callback; 81 }; 82 83 // Holds a pointer to the passed |service|, using it for querying installed 84 // extensions and installing updated ones. The |frequency_seconds| parameter 85 // controls how often update checks are scheduled. 86 ExtensionUpdater(ExtensionServiceInterface* service, 87 ExtensionPrefs* extension_prefs, 88 PrefService* prefs, 89 Profile* profile, 90 int frequency_seconds, 91 ExtensionCache* cache, 92 const ExtensionDownloader::Factory& downloader_factory); 93 94 virtual ~ExtensionUpdater(); 95 96 // Starts the updater running. Should be called at most once. 97 void Start(); 98 99 // Stops the updater running, cancelling any outstanding update manifest and 100 // crx downloads. Does not cancel any in-progress installs. 101 void Stop(); 102 103 // Posts a task to do an update check. Does nothing if there is 104 // already a pending task that has not yet run. 105 void CheckSoon(); 106 107 // Starts an update check for the specified extension soon. If a check 108 // is already running, or finished too recently without an update being 109 // installed, this method returns false and the check won't be scheduled. 110 bool CheckExtensionSoon(const std::string& extension_id, 111 const FinishedCallback& callback); 112 113 // Starts an update check right now, instead of waiting for the next 114 // regularly scheduled check or a pending check from CheckSoon(). 115 void CheckNow(const CheckParams& params); 116 117 // Returns true iff CheckSoon() has been called but the update check 118 // hasn't been performed yet. This is used mostly by tests; calling 119 // code should just call CheckSoon(). 120 bool WillCheckSoon() const; 121 122 // Changes the params that are used for the automatic periodic update checks, 123 // as well as for explicit calls to CheckSoon. 124 void set_default_check_params(const CheckParams& params) { 125 default_params_ = params; 126 } 127 128 private: 129 friend class ExtensionUpdaterTest; 130 friend class ExtensionUpdaterFileHandler; 131 132 // FetchedCRXFile holds information about a CRX file we fetched to disk, 133 // but have not yet installed. 134 struct FetchedCRXFile { 135 FetchedCRXFile(); 136 FetchedCRXFile(const std::string& id, 137 const base::FilePath& path, 138 bool file_ownership_passed, 139 const std::set<int>& request_ids); 140 ~FetchedCRXFile(); 141 142 std::string extension_id; 143 base::FilePath path; 144 bool file_ownership_passed; 145 std::set<int> request_ids; 146 }; 147 148 struct InProgressCheck { 149 InProgressCheck(); 150 ~InProgressCheck(); 151 152 bool install_immediately; 153 FinishedCallback callback; 154 // The ids of extensions that have in-progress update checks. 155 std::list<std::string> in_progress_ids_; 156 }; 157 158 struct ThrottleInfo; 159 160 // Callback used to continue CheckNow after determining which extensions 161 // should be force-updated. 162 void OnForcedUpdatesDetermined(const CheckParams& params, 163 const std::set<std::string>& forced_updates); 164 165 // Ensure that we have a valid ExtensionDownloader instance referenced by 166 // |downloader|. 167 void EnsureDownloaderCreated(); 168 169 // Computes when to schedule the first update check. 170 base::TimeDelta DetermineFirstCheckDelay(); 171 172 // Sets the timer to call TimerFired after roughly |target_delay| from now. 173 // To help spread load evenly on servers, this method adds some random 174 // jitter. It also saves the scheduled time so it can be reloaded on 175 // browser restart. 176 void ScheduleNextCheck(const base::TimeDelta& target_delay); 177 178 // Add fetch records for extensions that are installed to the downloader, 179 // ignoring |pending_ids| so the extension isn't fetched again. 180 void AddToDownloader(const ExtensionSet* extensions, 181 const std::list<std::string>& pending_ids, 182 int request_id); 183 184 // BaseTimer::ReceiverMethod callback. 185 void TimerFired(); 186 187 // Posted by CheckSoon(). 188 void DoCheckSoon(); 189 190 // Implementation of ExtensionDownloaderDelegate. 191 virtual void OnExtensionDownloadFailed( 192 const std::string& id, 193 Error error, 194 const PingResult& ping, 195 const std::set<int>& request_ids) OVERRIDE; 196 virtual void OnExtensionDownloadFinished( 197 const std::string& id, 198 const base::FilePath& path, 199 bool file_ownership_passed, 200 const GURL& download_url, 201 const std::string& version, 202 const PingResult& ping, 203 const std::set<int>& request_id) OVERRIDE; 204 virtual bool GetPingDataForExtension( 205 const std::string& id, 206 ManifestFetchData::PingData* ping_data) OVERRIDE; 207 virtual std::string GetUpdateUrlData(const std::string& id) OVERRIDE; 208 virtual bool IsExtensionPending(const std::string& id) OVERRIDE; 209 virtual bool GetExtensionExistingVersion(const std::string& id, 210 std::string* version) OVERRIDE; 211 virtual bool ShouldForceUpdate(const std::string& extension_id, 212 std::string* source) OVERRIDE; 213 214 void UpdatePingData(const std::string& id, const PingResult& ping_result); 215 216 // Starts installing a crx file that has been fetched but not installed yet. 217 void MaybeInstallCRXFile(); 218 219 // content::NotificationObserver implementation. 220 virtual void Observe(int type, 221 const content::NotificationSource& source, 222 const content::NotificationDetails& details) OVERRIDE; 223 224 // Implementation of ExtensionRegistryObserver. 225 virtual void OnExtensionWillBeInstalled( 226 content::BrowserContext* browser_context, 227 const Extension* extension, 228 bool is_update, 229 bool from_ephemeral, 230 const std::string& old_name) OVERRIDE; 231 232 // Send a notification that update checks are starting. 233 void NotifyStarted(); 234 235 // Send a notification if we're finished updating. 236 void NotifyIfFinished(int request_id); 237 238 void ExtensionCheckFinished(const std::string& extension_id, 239 const FinishedCallback& callback); 240 241 // Whether Start() has been called but not Stop(). 242 bool alive_; 243 244 // Pointer back to the service that owns this ExtensionUpdater. 245 ExtensionServiceInterface* service_; 246 247 // A closure passed into the ExtensionUpdater to teach it how to construct 248 // new ExtensionDownloader instances. 249 const ExtensionDownloader::Factory downloader_factory_; 250 251 // Fetches the crx files for the extensions that have an available update. 252 scoped_ptr<ExtensionDownloader> downloader_; 253 254 base::OneShotTimer<ExtensionUpdater> timer_; 255 int frequency_seconds_; 256 bool will_check_soon_; 257 258 ExtensionPrefs* extension_prefs_; 259 PrefService* prefs_; 260 Profile* profile_; 261 262 std::map<int, InProgressCheck> requests_in_progress_; 263 int next_request_id_; 264 265 // Observes CRX installs we initiate. 266 content::NotificationRegistrar registrar_; 267 268 ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver> 269 extension_registry_observer_; 270 271 // True when a CrxInstaller is doing an install. Used in MaybeUpdateCrxFile() 272 // to keep more than one install from running at once. 273 bool crx_install_is_running_; 274 275 // Fetched CRX files waiting to be installed. 276 std::stack<FetchedCRXFile> fetched_crx_files_; 277 FetchedCRXFile current_crx_file_; 278 279 CheckParams default_params_; 280 281 ExtensionCache* extension_cache_; 282 283 // Keeps track of when an extension tried to update itself, so we can throttle 284 // checks to prevent too many requests from being made. 285 std::map<std::string, ThrottleInfo> throttle_info_; 286 287 // Keeps track of extensions (by ID) whose update should be forced during the 288 // next update check. 289 std::set<std::string> forced_updates_; 290 291 base::WeakPtrFactory<ExtensionUpdater> weak_ptr_factory_; 292 293 DISALLOW_COPY_AND_ASSIGN(ExtensionUpdater); 294}; 295 296} // namespace extensions 297 298#endif // CHROME_BROWSER_EXTENSIONS_UPDATER_EXTENSION_UPDATER_H_ 299