Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / updater / extension_downloader.h
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_DOWNLOADER_H_
6 #define CHROME_BROWSER_EXTENSIONS_UPDATER_EXTENSION_DOWNLOADER_H_
7
8 #include <deque>
9 #include <map>
10 #include <set>
11 #include <string>
12 #include <utility>
13 #include <vector>
14
15 #include "base/basictypes.h"
16 #include "base/compiler_specific.h"
17 #include "base/memory/linked_ptr.h"
18 #include "base/memory/scoped_ptr.h"
19 #include "base/memory/weak_ptr.h"
20 #include "base/version.h"
21 #include "chrome/browser/extensions/updater/extension_downloader_delegate.h"
22 #include "chrome/browser/extensions/updater/manifest_fetch_data.h"
23 #include "chrome/browser/extensions/updater/request_queue.h"
24 #include "chrome/common/extensions/update_manifest.h"
25 #include "extensions/common/extension.h"
26 #include "net/url_request/url_fetcher_delegate.h"
27 #include "url/gurl.h"
28
29 namespace net {
30 class URLFetcher;
31 class URLRequestContextGetter;
32 class URLRequestStatus;
33 }
34
35 namespace extensions {
36
37 struct UpdateDetails {
38   UpdateDetails(const std::string& id, const base::Version& version);
39   ~UpdateDetails();
40
41   std::string id;
42   base::Version version;
43 };
44
45 class ExtensionCache;
46 class ExtensionUpdaterTest;
47
48 // A class that checks for updates of a given list of extensions, and downloads
49 // the crx file when updates are found. It uses a |ExtensionDownloaderDelegate|
50 // that takes ownership of the downloaded crx files, and handles events during
51 // the update check.
52 class ExtensionDownloader : public net::URLFetcherDelegate {
53  public:
54   // |delegate| is stored as a raw pointer and must outlive the
55   // ExtensionDownloader.
56   ExtensionDownloader(ExtensionDownloaderDelegate* delegate,
57                       net::URLRequestContextGetter* request_context);
58   virtual ~ExtensionDownloader();
59
60   // Adds |extension| to the list of extensions to check for updates.
61   // Returns false if the |extension| can't be updated due to invalid details.
62   // In that case, no callbacks will be performed on the |delegate_|.
63   // The |request_id| is passed on as is to the various |delegate_| callbacks.
64   // This is used for example by ExtensionUpdater to keep track of when
65   // potentially concurrent update checks complete.
66   bool AddExtension(const Extension& extension, int request_id);
67
68   // Adds extension |id| to the list of extensions to check for updates.
69   // Returns false if the |id| can't be updated due to invalid details.
70   // In that case, no callbacks will be performed on the |delegate_|.
71   // The |request_id| is passed on as is to the various |delegate_| callbacks.
72   // This is used for example by ExtensionUpdater to keep track of when
73   // potentially concurrent update checks complete.
74   bool AddPendingExtension(const std::string& id,
75                            const GURL& update_url,
76                            int request_id);
77
78   // Schedules a fetch of the manifest of all the extensions added with
79   // AddExtension() and AddPendingExtension().
80   void StartAllPending(ExtensionCache* cache);
81
82   // Schedules an update check of the blacklist.
83   void StartBlacklistUpdate(const std::string& version,
84                             const ManifestFetchData::PingData& ping_data,
85                             int request_id);
86
87   // These are needed for unit testing, to help identify the correct mock
88   // URLFetcher objects.
89   static const int kManifestFetcherId = 1;
90   static const int kExtensionFetcherId = 2;
91
92   // Update AppID for extension blacklist.
93   static const char kBlacklistAppID[];
94
95   static const int kMaxRetries = 10;
96
97  private:
98   friend class ExtensionUpdaterTest;
99
100   // These counters are bumped as extensions are added to be fetched. They
101   // are then recorded as UMA metrics when all the extensions have been added.
102   struct URLStats {
103     URLStats()
104         : no_url_count(0),
105           google_url_count(0),
106           other_url_count(0),
107           extension_count(0),
108           theme_count(0),
109           app_count(0),
110           platform_app_count(0),
111           pending_count(0) {}
112
113     int no_url_count, google_url_count, other_url_count;
114     int extension_count, theme_count, app_count, platform_app_count,
115         pending_count;
116   };
117
118   // We need to keep track of some information associated with a url
119   // when doing a fetch.
120   struct ExtensionFetch {
121     ExtensionFetch();
122     ExtensionFetch(const std::string& id, const GURL& url,
123                    const std::string& package_hash, const std::string& version,
124                    const std::set<int>& request_ids);
125     ~ExtensionFetch();
126
127     std::string id;
128     GURL url;
129     std::string package_hash;
130     std::string version;
131     std::set<int> request_ids;
132
133     // Indicates whether or not the fetch is known to require credentials.
134     bool is_protected;
135   };
136
137   // Helper for AddExtension() and AddPendingExtension().
138   bool AddExtensionData(const std::string& id,
139                         const base::Version& version,
140                         Manifest::Type extension_type,
141                         const GURL& extension_update_url,
142                         const std::string& update_url_data,
143                         int request_id);
144
145   // Adds all recorded stats taken so far to histogram counts.
146   void ReportStats() const;
147
148   // Begins an update check.
149   void StartUpdateCheck(scoped_ptr<ManifestFetchData> fetch_data);
150
151   // Called by RequestQueue when a new manifest fetch request is started.
152   void CreateManifestFetcher();
153
154   // net::URLFetcherDelegate implementation.
155   virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE;
156
157   // Handles the result of a manifest fetch.
158   void OnManifestFetchComplete(const GURL& url,
159                                const net::URLRequestStatus& status,
160                                int response_code,
161                                const base::TimeDelta& backoff_delay,
162                                const std::string& data);
163
164   // Once a manifest is parsed, this starts fetches of any relevant crx files.
165   // If |results| is null, it means something went wrong when parsing it.
166   void HandleManifestResults(const ManifestFetchData& fetch_data,
167                              const UpdateManifest::Results* results);
168
169   // Given a list of potential updates, returns the indices of the ones that are
170   // applicable (are actually a new version, etc.) in |result|.
171   void DetermineUpdates(const ManifestFetchData& fetch_data,
172                         const UpdateManifest::Results& possible_updates,
173                         std::vector<int>* result);
174
175   // Begins (or queues up) download of an updated extension.
176   void FetchUpdatedExtension(scoped_ptr<ExtensionFetch> fetch_data);
177
178   // Called by RequestQueue when a new extension fetch request is started.
179   void CreateExtensionFetcher();
180
181   // Handles the result of a crx fetch.
182   void OnCRXFetchComplete(const net::URLFetcher* source,
183                           const GURL& url,
184                           const net::URLRequestStatus& status,
185                           int response_code,
186                           const base::TimeDelta& backoff_delay);
187
188   // Invokes OnExtensionDownloadFailed() on the |delegate_| for each extension
189   // in the set, with |error| as the reason for failure.
190   void NotifyExtensionsDownloadFailed(const std::set<std::string>& id_set,
191                                       const std::set<int>& request_ids,
192                                       ExtensionDownloaderDelegate::Error error);
193
194   // Send a notification that an update was found for |id| that we'll
195   // attempt to download.
196   void NotifyUpdateFound(const std::string& id, const std::string& version);
197
198   // Do real work of StartAllPending. If .crx cache is used, this function
199   // is called when cache is ready.
200   void DoStartAllPending();
201
202   // Notify delegate and remove ping results.
203   void NotifyDelegateDownloadFinished(scoped_ptr<ExtensionFetch> fetch_data,
204                                       const base::FilePath& crx_path,
205                                       bool file_ownership_passed);
206
207   // The delegate that receives the crx files downloaded by the
208   // ExtensionDownloader, and that fills in optional ping and update url data.
209   ExtensionDownloaderDelegate* delegate_;
210
211   // The request context to use for the URLFetchers.
212   scoped_refptr<net::URLRequestContextGetter> request_context_;
213
214   // Used to create WeakPtrs to |this|.
215   base::WeakPtrFactory<ExtensionDownloader> weak_ptr_factory_;
216
217   // Collects UMA samples that are reported when ReportStats() is called.
218   URLStats url_stats_;
219
220   // List of data on fetches we're going to do. We limit the number of
221   // extensions grouped together in one batch to avoid running into the limits
222   // on the length of http GET requests, so there might be multiple
223   // ManifestFetchData* objects with the same base_url.
224   typedef std::map<std::pair<int, GURL>,
225                    std::vector<linked_ptr<ManifestFetchData> > > FetchMap;
226   FetchMap fetches_preparing_;
227
228   // Outstanding url fetch requests for manifests and updates.
229   scoped_ptr<net::URLFetcher> manifest_fetcher_;
230   scoped_ptr<net::URLFetcher> extension_fetcher_;
231
232   // Pending manifests and extensions to be fetched when the appropriate fetcher
233   // is available.
234   RequestQueue<ManifestFetchData> manifests_queue_;
235   RequestQueue<ExtensionFetch> extensions_queue_;
236
237   // Maps an extension-id to its PingResult data.
238   std::map<std::string, ExtensionDownloaderDelegate::PingResult> ping_results_;
239
240   // Cache for .crx files.
241   ExtensionCache* extension_cache_;
242
243   DISALLOW_COPY_AND_ASSIGN(ExtensionDownloader);
244 };
245
246 }  // namespace extensions
247
248 #endif  // CHROME_BROWSER_EXTENSIONS_UPDATER_EXTENSION_DOWNLOADER_H_