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