172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_UPDATER_H_ 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define CHROME_BROWSER_EXTENSIONS_EXTENSION_UPDATER_H_ 73345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma once 8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <deque> 10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <map> 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <set> 12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <string> 13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <vector> 14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 154a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "base/gtest_prod_util.h" 16ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/ref_counted.h" 17ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_ptr.h" 18ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_temp_dir.h" 19ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/weak_ptr.h" 20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/task.h" 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/time.h" 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/timer.h" 2321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/extensions/extension_service.h" 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/extensions/update_manifest.h" 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/net/url_fetcher.h" 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "googleurl/src/gurl.h" 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass Extension; 29ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenclass ExtensionPrefs; 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass ExtensionUpdaterTest; 31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass ExtensionUpdaterFileHandler; 32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass PrefService; 33ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenclass Profile; 34ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenclass SafeManifestParser; 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// To save on server resources we can request updates for multiple extensions 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// in one manifest check. This class helps us keep track of the id's for a 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// given fetch, building up the actual URL, and what if anything to include 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// in the ping parameter. 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass ManifestFetchData { 41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static const int kNeverPinged = -1; 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 44ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Each ping type is sent at most once per day. 45ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen enum PingType { 46ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Used for counting total installs of an extension/app/theme. 47ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ROLLCALL, 48ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 49ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Used for counting number of active users of an app, where "active" means 50ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // the app was launched at least once since the last active ping. 51ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ACTIVE 52ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen }; 53ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 54ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen struct PingData { 55ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // The number of days it's been since our last rollcall or active ping, 56ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // respectively. These are calculated based on the start of day from the 57ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // server's perspective. 58ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int rollcall_days; 59ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int active_days; 60ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 61ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen PingData() : rollcall_days(0), active_days(0) {} 62ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen PingData(int rollcall, int active) 63ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen : rollcall_days(rollcall), active_days(active) {} 64ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen }; 65ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 66513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch explicit ManifestFetchData(const GURL& update_url); 67731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ~ManifestFetchData(); 68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Returns true if this extension information was successfully added. If the 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // return value is false it means the full_url would have become too long, and 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // this ManifestFetchData object remains unchanged. 72ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen bool AddExtension(std::string id, std::string version, 73ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const PingData& ping_data, 744a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch const std::string& update_url_data); 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL& base_url() const { return base_url_; } 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL& full_url() const { return full_url_; } 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int extension_count() { return extension_ids_.size(); } 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::set<std::string>& extension_ids() const { return extension_ids_; } 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Returns true if the given id is included in this manifest fetch. 82ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen bool Includes(const std::string& extension_id) const; 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 84ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Returns true if a ping parameter for |type| was added to full_url for this 85ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // extension id. 86ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen bool DidPing(std::string extension_id, PingType type) const; 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 89ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // The set of extension id's for this ManifestFetchData. 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::set<std::string> extension_ids_; 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 92ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // The set of ping data we actually sent. 93ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::map<std::string, PingData> pings_; 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The base update url without any arguments added. 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL base_url_; 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The base update url plus arguments indicating the id, version, etc. 99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // information about each extension. 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL full_url_; 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DISALLOW_COPY_AND_ASSIGN(ManifestFetchData); 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// A class for building a set of ManifestFetchData objects from 106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// extensions and pending extensions. 107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass ManifestFetchesBuilder { 108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 109ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ManifestFetchesBuilder(ExtensionServiceInterface* service, 110ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ExtensionPrefs* prefs); 111731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ~ManifestFetchesBuilder(); 112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void AddExtension(const Extension& extension); 114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void AddPendingExtension(const std::string& id, 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const PendingExtensionInfo& info); 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Adds all recorded stats taken so far to histogram counts. 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void ReportStats() const; 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Caller takes ownership of the returned ManifestFetchData 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // objects. Clears all recorded stats. 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<ManifestFetchData*> GetFetches(); 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch struct URLStats { 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch URLStats() 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : no_url_count(0), 129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch google_url_count(0), 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch other_url_count(0), 13121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen extension_count(0), 13221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen theme_count(0), 13321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen app_count(0), 13421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen pending_count(0) {} 135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 13621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen int no_url_count, google_url_count, other_url_count; 13721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen int extension_count, theme_count, app_count, pending_count; 138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void AddExtensionData(Extension::Location location, 141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::string& id, 142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const Version& version, 14321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen Extension::Type extension_type, 1444a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch GURL update_url, 1454a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch const std::string& update_url_data); 146ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ExtensionServiceInterface* const service_; 147ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ExtensionPrefs* const prefs_; 148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // List of data on fetches we're going to do. We limit the number of 150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // extensions grouped together in one batch to avoid running into the limits 151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // on the length of http GET requests, so there might be multiple 152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // ManifestFetchData* objects with the same base_url. 153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::multimap<GURL, ManifestFetchData*> fetches_; 154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch URLStats url_stats_; 156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DISALLOW_COPY_AND_ASSIGN(ManifestFetchesBuilder); 158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// A class for doing auto-updates of installed Extensions. Used like this: 161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// ExtensionUpdater* updater = new ExtensionUpdater(my_extensions_service, 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// pref_service, 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// update_frequency_secs); 165ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// updater->Start(); 166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// .... 167ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// updater->Stop(); 168ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenclass ExtensionUpdater : public URLFetcher::Delegate { 169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Holds a pointer to the passed |service|, using it for querying installed 171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // extensions and installing updated ones. The |frequency_seconds| parameter 172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // controls how often update checks are scheduled. 173ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ExtensionUpdater(ExtensionServiceInterface* service, 174ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ExtensionPrefs* extension_prefs, 175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PrefService* prefs, 176ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Profile* profile, 177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int frequency_seconds); 178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 179ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen virtual ~ExtensionUpdater(); 180ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1814a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // Starts the updater running. Should be called at most once. 182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void Start(); 183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Stops the updater running, cancelling any outstanding update manifest and 185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // crx downloads. Does not cancel any in-progress installs. 186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void Stop(); 187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 188ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Posts a task to do an update check. Does nothing if there is 189ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // already a pending task that has not yet run. 190ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen void CheckSoon(); 191ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 192ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Starts an update check right now, instead of waiting for the next 193ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // regularly scheduled check or a pending check from CheckSoon(). 194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void CheckNow(); 195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Set blacklist checks on or off. 197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void set_blacklist_checks_enabled(bool enabled) { 198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch blacklist_checks_enabled_ = enabled; 199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 201ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Returns true iff CheckSoon() has been called but the update check 202ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // hasn't been performed yet. This is used mostly by tests; calling 203ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // code should just call CheckSoon(). 204ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen bool WillCheckSoon() const; 205ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch friend class ExtensionUpdaterTest; 208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch friend class ExtensionUpdaterFileHandler; 209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch friend class SafeManifestParser; 210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We need to keep track of some information associated with a url 212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // when doing a fetch. 213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch struct ExtensionFetch { 21472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ExtensionFetch(); 21572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ExtensionFetch(const std::string& i, const GURL& u, 21672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const std::string& h, const std::string& v); 21772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ~ExtensionFetch(); 21872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string id; 220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL url; 221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string package_hash; 222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string version; 223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // These are needed for unit testing, to help identify the correct mock 226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // URLFetcher objects. 227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static const int kManifestFetcherId = 1; 228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static const int kExtensionFetcherId = 2; 229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static const char* kBlacklistAppID; 231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Does common work from constructors. 233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void Init(); 234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Computes when to schedule the first update check. 236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::TimeDelta DetermineFirstCheckDelay(); 237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // URLFetcher::Delegate interface. 239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void OnURLFetchComplete(const URLFetcher* source, 240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL& url, 2413f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen const net::URLRequestStatus& status, 242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int response_code, 243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const ResponseCookies& cookies, 244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::string& data); 245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // These do the actual work when a URL fetch completes. 247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void OnManifestFetchComplete(const GURL& url, 2483f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen const net::URLRequestStatus& status, 249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int response_code, 250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::string& data); 251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void OnCRXFetchComplete(const GURL& url, 2523f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen const net::URLRequestStatus& status, 253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int response_code, 254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::string& data); 255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Called when a crx file has been written into a temp file, and is ready 257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // to be installed. 258ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen void OnCRXFileWritten(const std::string& id, 259ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const FilePath& path, 260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL& download_url); 261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 262ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Called when we encountered an error writing a crx file to a temp file. 263ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen void OnCRXFileWriteError(const std::string& id); 264ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Verifies downloaded blacklist. Based on the blacklist, calls extension 266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // service to unload blacklisted extensions and update pref. 267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void ProcessBlacklist(const std::string& data); 268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Sets the timer to call TimerFired after roughly |target_delay| from now. 270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // To help spread load evenly on servers, this method adds some random 271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // jitter. It also saves the scheduled time so it can be reloaded on 272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // browser restart. 273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void ScheduleNextCheck(const base::TimeDelta& target_delay); 274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // BaseTimer::ReceiverMethod callback. 276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void TimerFired(); 277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 278ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Posted by CheckSoon(). 279ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen void DoCheckSoon(); 280ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Begins an update check. Takes ownership of |fetch_data|. 282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void StartUpdateCheck(ManifestFetchData* fetch_data); 283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Begins (or queues up) download of an updated extension. 285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void FetchUpdatedExtension(const std::string& id, const GURL& url, 286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::string& hash, const std::string& version); 287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Once a manifest is parsed, this starts fetches of any relevant crx files. 289ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // If |results| is null, it means something went wrong when parsing it. 290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void HandleManifestResults(const ManifestFetchData& fetch_data, 291ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const UpdateManifest::Results* results); 292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Determines the version of an existing extension. 294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Returns true on success and false on failures. 295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool GetExistingVersion(const std::string& id, std::string* version); 296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Given a list of potential updates, returns the indices of the ones that are 298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // applicable (are actually a new version, etc.) in |result|. 299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<int> DetermineUpdates(const ManifestFetchData& fetch_data, 300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const UpdateManifest::Results& possible_updates); 301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 302ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Send a notification that update checks are starting. 303ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen void NotifyStarted(); 304ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 305ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Send a notification that an update was found for extension_id that we'll 306ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // attempt to download and install. 307ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen void NotifyUpdateFound(const std::string& extension_id); 308ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 309ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Send a notification if we're finished updating. 310ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen void NotifyIfFinished(); 311ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 312ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Adds a set of ids to in_progress_ids_. 313ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen void AddToInProgress(const std::set<std::string>& ids); 314ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 315ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Removes a set of ids from in_progress_ids_. 316ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen void RemoveFromInProgress(const std::set<std::string>& ids); 317ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 3184a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // Whether Start() has been called but not Stop(). 3194a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch bool alive_; 3204a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 321ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::WeakPtrFactory<ExtensionUpdater> weak_ptr_factory_; 322ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Outstanding url fetch requests for manifests and updates. 324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<URLFetcher> manifest_fetcher_; 325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<URLFetcher> extension_fetcher_; 326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Pending manifests and extensions to be fetched when the appropriate fetcher 328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // is available. 329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::deque<ManifestFetchData*> manifests_pending_; 330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::deque<ExtensionFetch> extensions_pending_; 331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The manifest currently being fetched (if any). 333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<ManifestFetchData> current_manifest_fetch_; 334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The extension currently being fetched (if any). 336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ExtensionFetch current_extension_fetch_; 337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Pointer back to the service that owns this ExtensionUpdater. 339ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ExtensionServiceInterface* service_; 340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::OneShotTimer<ExtensionUpdater> timer_; 342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int frequency_seconds_; 343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 344ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ScopedRunnableMethodFactory<ExtensionUpdater> method_factory_; 345ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 346ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen bool will_check_soon_; 347ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 348ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ExtensionPrefs* extension_prefs_; 349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PrefService* prefs_; 350ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Profile* profile_; 351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<ExtensionUpdaterFileHandler> file_handler_; 353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool blacklist_checks_enabled_; 354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 355ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // The ids of extensions that have in-progress update checks. 356ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::set<std::string> in_progress_ids_; 357ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 3584a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch FRIEND_TEST(ExtensionUpdaterTest, TestStartUpdateCheckMemory); 3594a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch FRIEND_TEST(ExtensionUpdaterTest, TestAfterStopBehavior); 3604a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DISALLOW_COPY_AND_ASSIGN(ExtensionUpdater); 362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_UPDATER_H_ 365