Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(414)

Side by Side Diff: chrome/browser/component_updater/component_updater_service.cc

Issue 25713007: Component updater on-demand logic with ResourceThrottle (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698