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