OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/component_updater/component_updater_service.h" | 5 #include "chrome/browser/component_updater/component_updater_service.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <set> | 8 #include <set> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
11 #include "base/at_exit.h" | 11 #include "base/at_exit.h" |
12 #include "base/bind.h" | 12 #include "base/bind.h" |
13 #include "base/compiler_specific.h" | 13 #include "base/compiler_specific.h" |
14 #include "base/file_util.h" | 14 #include "base/file_util.h" |
15 #include "base/files/file_path.h" | 15 #include "base/files/file_path.h" |
16 #include "base/logging.h" | 16 #include "base/logging.h" |
17 #include "base/memory/scoped_ptr.h" | 17 #include "base/memory/scoped_ptr.h" |
18 #include "base/memory/weak_ptr.h" | |
18 #include "base/stl_util.h" | 19 #include "base/stl_util.h" |
19 #include "base/strings/string_number_conversions.h" | 20 #include "base/strings/string_number_conversions.h" |
20 #include "base/strings/string_piece.h" | 21 #include "base/strings/string_piece.h" |
21 #include "base/strings/string_util.h" | 22 #include "base/strings/string_util.h" |
22 #include "base/strings/stringprintf.h" | 23 #include "base/strings/stringprintf.h" |
23 #include "base/timer/timer.h" | 24 #include "base/timer/timer.h" |
24 #include "chrome/browser/browser_process.h" | 25 #include "chrome/browser/browser_process.h" |
25 #include "chrome/browser/component_updater/component_patcher.h" | 26 #include "chrome/browser/component_updater/component_patcher.h" |
26 #include "chrome/browser/component_updater/component_unpacker.h" | 27 #include "chrome/browser/component_updater/component_unpacker.h" |
27 #include "chrome/browser/component_updater/component_updater_ping_manager.h" | 28 #include "chrome/browser/component_updater/component_updater_ping_manager.h" |
28 #include "chrome/browser/component_updater/crx_update_item.h" | 29 #include "chrome/browser/component_updater/crx_update_item.h" |
29 #include "chrome/common/chrome_utility_messages.h" | 30 #include "chrome/common/chrome_utility_messages.h" |
30 #include "chrome/common/chrome_version_info.h" | 31 #include "chrome/common/chrome_version_info.h" |
31 #include "chrome/common/extensions/extension.h" | 32 #include "chrome/common/extensions/extension.h" |
32 #include "content/public/browser/browser_thread.h" | 33 #include "content/public/browser/browser_thread.h" |
34 #include "content/public/browser/resource_controller.h" | |
35 #include "content/public/browser/resource_throttle.h" | |
33 #include "content/public/browser/utility_process_host.h" | 36 #include "content/public/browser/utility_process_host.h" |
34 #include "content/public/browser/utility_process_host_client.h" | 37 #include "content/public/browser/utility_process_host_client.h" |
35 #include "net/base/escape.h" | 38 #include "net/base/escape.h" |
36 #include "net/base/load_flags.h" | 39 #include "net/base/load_flags.h" |
37 #include "net/base/net_errors.h" | 40 #include "net/base/net_errors.h" |
38 #include "net/url_request/url_fetcher.h" | 41 #include "net/url_request/url_fetcher.h" |
39 #include "net/url_request/url_fetcher_delegate.h" | 42 #include "net/url_request/url_fetcher_delegate.h" |
43 #include "net/url_request/url_request.h" | |
40 #include "net/url_request/url_request_status.h" | 44 #include "net/url_request/url_request_status.h" |
41 #include "url/gurl.h" | 45 #include "url/gurl.h" |
42 | 46 |
43 using content::BrowserThread; | 47 using content::BrowserThread; |
44 using content::UtilityProcessHost; | 48 using content::UtilityProcessHost; |
45 using content::UtilityProcessHostClient; | 49 using content::UtilityProcessHostClient; |
46 using extensions::Extension; | 50 using extensions::Extension; |
47 | 51 |
48 // The component updater is designed to live until process shutdown, so | 52 // The component updater is designed to live until process shutdown, so |
49 // base::Bind() calls are not refcounted. | 53 // base::Bind() calls are not refcounted. |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
229 return HexStringToID(StringToLowerASCII(base::HexEncode(&component.pk_hash[0], | 233 return HexStringToID(StringToLowerASCII(base::HexEncode(&component.pk_hash[0], |
230 component.pk_hash.size()/2))); | 234 component.pk_hash.size()/2))); |
231 } | 235 } |
232 | 236 |
233 CrxComponentInfo::CrxComponentInfo() { | 237 CrxComponentInfo::CrxComponentInfo() { |
234 } | 238 } |
235 | 239 |
236 CrxComponentInfo::~CrxComponentInfo() { | 240 CrxComponentInfo::~CrxComponentInfo() { |
237 } | 241 } |
238 | 242 |
243 /////////////////////////////////////////////////////////////////////////////// | |
244 // In charge of blocking url requests until the |crx_id| component has been | |
245 // updated. This class is touched solely from the IO thread. The UI thread | |
246 // can post tasks to it via weak pointers. By default the request is blocked | |
247 // unless the CrxUpdateService calls Unblock(). | |
248 // The lifetime is controlled by Chrome's resource loader so the component | |
249 // updater cannot touch objects from this class except via weak pointers. | |
250 class CUResourceThrottle | |
251 : public content::ResourceThrottle, | |
252 public base::SupportsWeakPtr<CUResourceThrottle> { | |
253 public: | |
254 explicit CUResourceThrottle(const net::URLRequest* request); | |
255 virtual ~CUResourceThrottle(); | |
256 // Overriden from ResourceThrottle. | |
257 virtual void WillStartRequest(bool* defer) OVERRIDE; | |
258 virtual void WillRedirectRequest(const GURL& new_url, bool* defer) OVERRIDE; | |
259 | |
260 // Component updater calls this function via PostTask to unblock the request. | |
261 void Unblock(); | |
262 | |
263 typedef std::vector<base::WeakPtr<CUResourceThrottle> > WeakPtrVector; | |
264 | |
265 private: | |
266 enum State { | |
waffles
2013/11/01 19:16:56
I think this is indented by 3 spaces.
| |
267 NEW, | |
268 BLOCKED, | |
269 UNBLOCKED | |
270 }; | |
271 | |
272 State state_; | |
273 }; | |
274 | |
275 void UnblockResourceThrottle(base::WeakPtr<CUResourceThrottle> rt) { | |
276 BrowserThread::PostTask( | |
277 BrowserThread::IO, | |
278 FROM_HERE, | |
279 base::Bind(&CUResourceThrottle::Unblock, rt)); | |
280 } | |
281 | |
282 void UnblockandReapAllThrottles(CUResourceThrottle::WeakPtrVector* throttles) { | |
283 CUResourceThrottle::WeakPtrVector::iterator it; | |
284 for (it = throttles->begin(); it != throttles->end(); ++it) | |
285 UnblockResourceThrottle(*it); | |
286 throttles->clear(); | |
287 } | |
288 | |
239 ////////////////////////////////////////////////////////////////////////////// | 289 ////////////////////////////////////////////////////////////////////////////// |
240 // The one and only implementation of the ComponentUpdateService interface. In | 290 // The one and only implementation of the ComponentUpdateService interface. In |
241 // charge of running the show. The main method is ProcessPendingItems() which | 291 // charge of running the show. The main method is ProcessPendingItems() which |
242 // is called periodically to do the upgrades/installs or the update checks. | 292 // is called periodically to do the upgrades/installs or the update checks. |
243 // An important consideration here is to be as "low impact" as we can to the | 293 // An important consideration here is to be as "low impact" as we can to the |
244 // rest of the browser, so even if we have many components registered and | 294 // rest of the browser, so even if we have many components registered and |
245 // eligible for update, we only do one thing at a time with pauses in between | 295 // eligible for update, we only do one thing at a time with pauses in between |
246 // the tasks. Also when we do network requests there is only one |url_fetcher_| | 296 // the tasks. Also when we do network requests there is only one |url_fetcher_| |
247 // in flight at a time. | 297 // in flight at a time. |
248 // There are no locks in this code, the main structure |work_items_| is mutated | 298 // There are no locks in this code, the main structure |work_items_| is mutated |
249 // only from the UI thread. The unpack and installation is done in the file | 299 // only from the UI thread. The unpack and installation is done in the file |
250 // thread and the network requests are done in the IO thread and in the file | 300 // thread and the network requests are done in the IO thread and in the file |
251 // thread. | 301 // thread. |
252 class CrxUpdateService : public ComponentUpdateService { | 302 class CrxUpdateService : public ComponentUpdateService { |
253 public: | 303 public: |
254 explicit CrxUpdateService(ComponentUpdateService::Configurator* config); | 304 explicit CrxUpdateService(ComponentUpdateService::Configurator* config); |
255 | 305 |
256 virtual ~CrxUpdateService(); | 306 virtual ~CrxUpdateService(); |
257 | 307 |
258 // Overrides for ComponentUpdateService. | 308 // Overrides for ComponentUpdateService. |
259 virtual Status Start() OVERRIDE; | 309 virtual Status Start() OVERRIDE; |
260 virtual Status Stop() OVERRIDE; | 310 virtual Status Stop() OVERRIDE; |
261 virtual Status RegisterComponent(const CrxComponent& component) OVERRIDE; | 311 virtual Status RegisterComponent(const CrxComponent& component) OVERRIDE; |
262 virtual Status OnDemandUpdate(const std::string& component_id) OVERRIDE; | 312 virtual Status OnDemandUpdate(const std::string& component_id) OVERRIDE; |
263 virtual void GetComponents( | 313 virtual void GetComponents( |
264 std::vector<CrxComponentInfo>* components) OVERRIDE; | 314 std::vector<CrxComponentInfo>* components) OVERRIDE; |
315 virtual content::ResourceThrottle* GetOnDemandResourceThrottle( | |
316 net::URLRequest* request, const std::string& crx_id) OVERRIDE; | |
265 | 317 |
266 // The only purpose of this class is to forward the | 318 // The only purpose of this class is to forward the |
267 // UtilityProcessHostClient callbacks so CrxUpdateService does | 319 // UtilityProcessHostClient callbacks so CrxUpdateService does |
268 // not have to derive from it because that is refcounted. | 320 // not have to derive from it because that is refcounted. |
269 class ManifestParserBridge : public UtilityProcessHostClient { | 321 class ManifestParserBridge : public UtilityProcessHostClient { |
270 public: | 322 public: |
271 explicit ManifestParserBridge(CrxUpdateService* service) | 323 explicit ManifestParserBridge(CrxUpdateService* service) |
272 : service_(service) {} | 324 : service_(service) {} |
273 | 325 |
274 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE { | 326 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE { |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
335 }; | 387 }; |
336 | 388 |
337 // See ManifestParserBridge. | 389 // See ManifestParserBridge. |
338 void OnParseUpdateManifestSucceeded(const UpdateManifest::Results& results); | 390 void OnParseUpdateManifestSucceeded(const UpdateManifest::Results& results); |
339 | 391 |
340 // See ManifestParserBridge. | 392 // See ManifestParserBridge. |
341 void OnParseUpdateManifestFailed(const std::string& error_message); | 393 void OnParseUpdateManifestFailed(const std::string& error_message); |
342 | 394 |
343 bool AddItemToUpdateCheck(CrxUpdateItem* item, std::string* query); | 395 bool AddItemToUpdateCheck(CrxUpdateItem* item, std::string* query); |
344 | 396 |
397 Status OnDemandUpdateInternal(CrxUpdateItem* item); | |
398 | |
345 void ProcessPendingItems(); | 399 void ProcessPendingItems(); |
346 | 400 |
347 CrxUpdateItem* FindReadyComponent(); | 401 CrxUpdateItem* FindReadyComponent(); |
348 | 402 |
349 void UpdateComponent(CrxUpdateItem* workitem); | 403 void UpdateComponent(CrxUpdateItem* workitem); |
350 | 404 |
351 void AddUpdateCheckItems(std::string* query); | 405 void AddUpdateCheckItems(std::string* query); |
352 | 406 |
353 void DoUpdateCheck(const std::string& query); | 407 void DoUpdateCheck(const std::string& query); |
354 | 408 |
(...skipping 12 matching lines...) Expand all Loading... | |
367 size_t ChangeItemStatus(CrxUpdateItem::Status from, | 421 size_t ChangeItemStatus(CrxUpdateItem::Status from, |
368 CrxUpdateItem::Status to); | 422 CrxUpdateItem::Status to); |
369 | 423 |
370 CrxUpdateItem* FindUpdateItemById(const std::string& id); | 424 CrxUpdateItem* FindUpdateItemById(const std::string& id); |
371 | 425 |
372 void NotifyComponentObservers(ComponentObserver::Events event, | 426 void NotifyComponentObservers(ComponentObserver::Events event, |
373 int extra) const; | 427 int extra) const; |
374 | 428 |
375 bool HasOnDemandItems() const; | 429 bool HasOnDemandItems() const; |
376 | 430 |
431 void OnNewResourceThrottle(base::WeakPtr<CUResourceThrottle> rt, | |
432 const std::string& crx_id); | |
433 | |
377 scoped_ptr<ComponentUpdateService::Configurator> config_; | 434 scoped_ptr<ComponentUpdateService::Configurator> config_; |
378 | 435 |
379 scoped_ptr<ComponentPatcher> component_patcher_; | 436 scoped_ptr<ComponentPatcher> component_patcher_; |
380 | 437 |
381 scoped_ptr<net::URLFetcher> url_fetcher_; | 438 scoped_ptr<net::URLFetcher> url_fetcher_; |
382 | 439 |
383 scoped_ptr<component_updater::PingManager> ping_manager_; | 440 scoped_ptr<component_updater::PingManager> ping_manager_; |
384 | 441 |
385 // A collection of every work item. | 442 // A collection of every work item. |
386 typedef std::vector<CrxUpdateItem*> UpdateItems; | 443 typedef std::vector<CrxUpdateItem*> UpdateItems; |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
545 break; | 602 break; |
546 case CrxUpdateItem::kNew: | 603 case CrxUpdateItem::kNew: |
547 case CrxUpdateItem::kChecking: | 604 case CrxUpdateItem::kChecking: |
548 case CrxUpdateItem::kDownloading: | 605 case CrxUpdateItem::kDownloading: |
549 case CrxUpdateItem::kDownloadingDiff: | 606 case CrxUpdateItem::kDownloadingDiff: |
550 case CrxUpdateItem::kLastStatus: | 607 case CrxUpdateItem::kLastStatus: |
551 // No notification for these states. | 608 // No notification for these states. |
552 break; | 609 break; |
553 } | 610 } |
554 } | 611 } |
612 | |
613 // Free possible pending network requests. | |
614 if ((to == CrxUpdateItem::kUpdated) || | |
615 (to == CrxUpdateItem::kUpToDate) || | |
616 (to == CrxUpdateItem::kNoUpdate)) { | |
617 UnblockandReapAllThrottles(&item->throttles); | |
618 } | |
555 } | 619 } |
556 | 620 |
557 // Changes all the components in |work_items_| that have |from| status to | 621 // Changes all the components in |work_items_| that have |from| status to |
558 // |to| status and returns how many have been changed. | 622 // |to| status and returns how many have been changed. |
559 size_t CrxUpdateService::ChangeItemStatus(CrxUpdateItem::Status from, | 623 size_t CrxUpdateService::ChangeItemStatus(CrxUpdateItem::Status from, |
560 CrxUpdateItem::Status to) { | 624 CrxUpdateItem::Status to) { |
561 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 625 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
562 size_t count = 0; | 626 size_t count = 0; |
563 for (UpdateItems::iterator it = work_items_.begin(); | 627 for (UpdateItems::iterator it = work_items_.begin(); |
564 it != work_items_.end(); ++it) { | 628 it != work_items_.end(); ++it) { |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
634 item->diff_error_code = 0; | 698 item->diff_error_code = 0; |
635 item->diff_extra_code1 = 0; | 699 item->diff_extra_code1 = 0; |
636 return true; | 700 return true; |
637 } | 701 } |
638 | 702 |
639 // Start the process of checking for an update, for a particular component | 703 // Start the process of checking for an update, for a particular component |
640 // that was previously registered. | 704 // that was previously registered. |
641 // |component_id| is a value returned from GetCrxComponentID(). | 705 // |component_id| is a value returned from GetCrxComponentID(). |
642 ComponentUpdateService::Status CrxUpdateService::OnDemandUpdate( | 706 ComponentUpdateService::Status CrxUpdateService::OnDemandUpdate( |
643 const std::string& component_id) { | 707 const std::string& component_id) { |
644 CrxUpdateItem* uit; | 708 return OnDemandUpdateInternal(FindUpdateItemById(component_id)); |
645 uit = FindUpdateItemById(component_id); | 709 } |
710 | |
711 ComponentUpdateService::Status CrxUpdateService::OnDemandUpdateInternal( | |
712 CrxUpdateItem* uit) { | |
646 if (!uit) | 713 if (!uit) |
647 return kError; | 714 return kError; |
648 | |
649 // Check if the request is too soon. | 715 // Check if the request is too soon. |
650 base::TimeDelta delta = base::Time::Now() - uit->last_check; | 716 base::TimeDelta delta = base::Time::Now() - uit->last_check; |
651 if (delta < base::TimeDelta::FromSeconds(config_->OnDemandDelay())) | 717 if (delta < base::TimeDelta::FromSeconds(config_->OnDemandDelay())) |
652 return kError; | 718 return kError; |
653 | 719 |
654 switch (uit->status) { | 720 switch (uit->status) { |
655 // If the item is already in the process of being updated, there is | 721 // If the item is already in the process of being updated, there is |
656 // no point in this call, so return kInProgress. | 722 // no point in this call, so return kInProgress. |
657 case CrxUpdateItem::kChecking: | 723 case CrxUpdateItem::kChecking: |
658 case CrxUpdateItem::kCanUpdate: | 724 case CrxUpdateItem::kCanUpdate: |
(...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1062 void CrxUpdateService::NotifyComponentObservers( | 1128 void CrxUpdateService::NotifyComponentObservers( |
1063 ComponentObserver::Events event, int extra) const { | 1129 ComponentObserver::Events event, int extra) const { |
1064 for (UpdateItems::const_iterator it = work_items_.begin(); | 1130 for (UpdateItems::const_iterator it = work_items_.begin(); |
1065 it != work_items_.end(); ++it) { | 1131 it != work_items_.end(); ++it) { |
1066 ComponentObserver* observer = (*it)->component.observer; | 1132 ComponentObserver* observer = (*it)->component.observer; |
1067 if (observer) | 1133 if (observer) |
1068 observer->OnEvent(event, 0); | 1134 observer->OnEvent(event, 0); |
1069 } | 1135 } |
1070 } | 1136 } |
1071 | 1137 |
1138 content::ResourceThrottle* CrxUpdateService::GetOnDemandResourceThrottle( | |
1139 net::URLRequest* request, const std::string& crx_id) { | |
1140 // We give the raw pointer to the caller, who will delete it at will | |
1141 // and we keep for ourselves a weak pointer to it so we can post tasks | |
1142 // from the UI thread without having to track lifetime directly. | |
1143 CUResourceThrottle* rt = new CUResourceThrottle(request); | |
1144 BrowserThread::PostTask( | |
1145 BrowserThread::UI, | |
1146 FROM_HERE, | |
1147 base::Bind(&CrxUpdateService::OnNewResourceThrottle, | |
1148 base::Unretained(this), | |
1149 rt->AsWeakPtr(), | |
1150 crx_id)); | |
1151 return rt; | |
1152 } | |
1153 | |
1154 void CrxUpdateService::OnNewResourceThrottle( | |
1155 base::WeakPtr<CUResourceThrottle> rt, const std::string& crx_id) { | |
1156 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
1157 // Check if we can on-demand update, else unblock the request anyway. | |
1158 CrxUpdateItem* item = FindUpdateItemById(crx_id); | |
1159 Status status = OnDemandUpdateInternal(item); | |
1160 if (status == kOk || status == kInProgress) { | |
1161 item->throttles.push_back(rt); | |
1162 return; | |
1163 } | |
1164 UnblockResourceThrottle(rt); | |
1165 } | |
1166 | |
1167 /////////////////////////////////////////////////////////////////////////////// | |
1168 | |
1169 CUResourceThrottle::CUResourceThrottle(const net::URLRequest* request) | |
1170 : state_(NEW) { | |
1171 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
1172 } | |
1173 | |
1174 CUResourceThrottle::~CUResourceThrottle() { | |
1175 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
1176 } | |
1177 | |
1178 void CUResourceThrottle::WillStartRequest(bool* defer) { | |
1179 if (state_ != UNBLOCKED) { | |
1180 state_ = BLOCKED; | |
1181 *defer = true; | |
1182 } else { | |
1183 *defer = false; | |
1184 } | |
1185 } | |
1186 | |
1187 void CUResourceThrottle::WillRedirectRequest(const GURL& new_url, bool* defer) { | |
1188 WillStartRequest(defer); | |
1189 } | |
1190 | |
1191 void CUResourceThrottle::Unblock() { | |
1192 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
1193 if (state_ == BLOCKED) | |
1194 controller()->Resume(); | |
1195 state_ = UNBLOCKED; | |
1196 } | |
1197 | |
1072 // The component update factory. Using the component updater as a singleton | 1198 // The component update factory. Using the component updater as a singleton |
1073 // is the job of the browser process. | 1199 // is the job of the browser process. |
1074 ComponentUpdateService* ComponentUpdateServiceFactory( | 1200 ComponentUpdateService* ComponentUpdateServiceFactory( |
1075 ComponentUpdateService::Configurator* config) { | 1201 ComponentUpdateService::Configurator* config) { |
1076 DCHECK(config); | 1202 DCHECK(config); |
1077 return new CrxUpdateService(config); | 1203 return new CrxUpdateService(config); |
1078 } | 1204 } |
OLD | NEW |