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

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 private:
264 enum State {
265 NEW,
266 BLOCKED,
267 UNBLOCKED
268 };
269
270 State state_;
271 };
272
273 void UnblockResourceThrottle(base::WeakPtr<CUResourceThrottle> rt) {
274 BrowserThread::PostTask(
275 BrowserThread::IO,
276 FROM_HERE,
277 base::Bind(&CUResourceThrottle::Unblock, rt));
278 }
279
280 void UnblockandReapAllThrottles(
281 std::vector<base::WeakPtr<CUResourceThrottle>>* throttles) {
282 std::vector<base::WeakPtr<CUResourceThrottle>>::iterator it;
283 for (it == throttles->begin(); it != throttles->end(); ++it)
284 UnblockResourceThrottle(*it);
Sorin Jianu 2013/10/31 18:43:58 I share your concern about loops without {}. That
cpu_(ooo_6.6-7.5) 2013/10/31 21:36:08 Most chromistas would object to that.
285 throttles->clear();
286 }
287
239 ////////////////////////////////////////////////////////////////////////////// 288 //////////////////////////////////////////////////////////////////////////////
240 // The one and only implementation of the ComponentUpdateService interface. In 289 // The one and only implementation of the ComponentUpdateService interface. In
241 // charge of running the show. The main method is ProcessPendingItems() which 290 // charge of running the show. The main method is ProcessPendingItems() which
242 // is called periodically to do the upgrades/installs or the update checks. 291 // 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 292 // 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 293 // 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 294 // 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_| 295 // the tasks. Also when we do network requests there is only one |url_fetcher_|
247 // in flight at a time. 296 // in flight at a time.
248 // There are no locks in this code, the main structure |work_items_| is mutated 297 // 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 298 // 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 299 // thread and the network requests are done in the IO thread and in the file
251 // thread. 300 // thread.
252 class CrxUpdateService : public ComponentUpdateService { 301 class CrxUpdateService : public ComponentUpdateService {
253 public: 302 public:
254 explicit CrxUpdateService(ComponentUpdateService::Configurator* config); 303 explicit CrxUpdateService(ComponentUpdateService::Configurator* config);
255 304
256 virtual ~CrxUpdateService(); 305 virtual ~CrxUpdateService();
257 306
258 // Overrides for ComponentUpdateService. 307 // Overrides for ComponentUpdateService.
259 virtual Status Start() OVERRIDE; 308 virtual Status Start() OVERRIDE;
260 virtual Status Stop() OVERRIDE; 309 virtual Status Stop() OVERRIDE;
261 virtual Status RegisterComponent(const CrxComponent& component) OVERRIDE; 310 virtual Status RegisterComponent(const CrxComponent& component) OVERRIDE;
262 virtual Status OnDemandUpdate(const std::string& component_id) OVERRIDE; 311 virtual Status OnDemandUpdate(const std::string& component_id) OVERRIDE;
263 virtual void GetComponents( 312 virtual void GetComponents(
264 std::vector<CrxComponentInfo>* components) OVERRIDE; 313 std::vector<CrxComponentInfo>* components) OVERRIDE;
314 virtual content::ResourceThrottle* GetOnDemandResourceThrottle(
315 net::URLRequest* request, const char* crx_id) OVERRIDE;
265 316
266 // The only purpose of this class is to forward the 317 // The only purpose of this class is to forward the
267 // UtilityProcessHostClient callbacks so CrxUpdateService does 318 // UtilityProcessHostClient callbacks so CrxUpdateService does
268 // not have to derive from it because that is refcounted. 319 // not have to derive from it because that is refcounted.
269 class ManifestParserBridge : public UtilityProcessHostClient { 320 class ManifestParserBridge : public UtilityProcessHostClient {
270 public: 321 public:
271 explicit ManifestParserBridge(CrxUpdateService* service) 322 explicit ManifestParserBridge(CrxUpdateService* service)
272 : service_(service) {} 323 : service_(service) {}
273 324
274 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE { 325 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE {
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
335 }; 386 };
336 387
337 // See ManifestParserBridge. 388 // See ManifestParserBridge.
338 void OnParseUpdateManifestSucceeded(const UpdateManifest::Results& results); 389 void OnParseUpdateManifestSucceeded(const UpdateManifest::Results& results);
339 390
340 // See ManifestParserBridge. 391 // See ManifestParserBridge.
341 void OnParseUpdateManifestFailed(const std::string& error_message); 392 void OnParseUpdateManifestFailed(const std::string& error_message);
342 393
343 bool AddItemToUpdateCheck(CrxUpdateItem* item, std::string* query); 394 bool AddItemToUpdateCheck(CrxUpdateItem* item, std::string* query);
344 395
396 Status OnDemandUpdateInternal(CrxUpdateItem* item);
397
345 void ProcessPendingItems(); 398 void ProcessPendingItems();
346 399
347 CrxUpdateItem* FindReadyComponent(); 400 CrxUpdateItem* FindReadyComponent();
348 401
349 void UpdateComponent(CrxUpdateItem* workitem); 402 void UpdateComponent(CrxUpdateItem* workitem);
350 403
351 void AddUpdateCheckItems(std::string* query); 404 void AddUpdateCheckItems(std::string* query);
352 405
353 void DoUpdateCheck(const std::string& query); 406 void DoUpdateCheck(const std::string& query);
354 407
(...skipping 12 matching lines...) Expand all
367 size_t ChangeItemStatus(CrxUpdateItem::Status from, 420 size_t ChangeItemStatus(CrxUpdateItem::Status from,
368 CrxUpdateItem::Status to); 421 CrxUpdateItem::Status to);
369 422
370 CrxUpdateItem* FindUpdateItemById(const std::string& id); 423 CrxUpdateItem* FindUpdateItemById(const std::string& id);
371 424
372 void NotifyComponentObservers(ComponentObserver::Events event, 425 void NotifyComponentObservers(ComponentObserver::Events event,
373 int extra) const; 426 int extra) const;
374 427
375 bool HasOnDemandItems() const; 428 bool HasOnDemandItems() const;
376 429
430 void OnNewResourceThrottle(base::WeakPtr<CUResourceThrottle> rt,
431 const std::string& crx_id);
432
377 scoped_ptr<ComponentUpdateService::Configurator> config_; 433 scoped_ptr<ComponentUpdateService::Configurator> config_;
378 434
379 scoped_ptr<ComponentPatcher> component_patcher_; 435 scoped_ptr<ComponentPatcher> component_patcher_;
380 436
381 scoped_ptr<net::URLFetcher> url_fetcher_; 437 scoped_ptr<net::URLFetcher> url_fetcher_;
382 438
383 scoped_ptr<component_updater::PingManager> ping_manager_; 439 scoped_ptr<component_updater::PingManager> ping_manager_;
384 440
385 // A collection of every work item. 441 // A collection of every work item.
386 typedef std::vector<CrxUpdateItem*> UpdateItems; 442 typedef std::vector<CrxUpdateItem*> UpdateItems;
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
545 break; 601 break;
546 case CrxUpdateItem::kNew: 602 case CrxUpdateItem::kNew:
547 case CrxUpdateItem::kChecking: 603 case CrxUpdateItem::kChecking:
548 case CrxUpdateItem::kDownloading: 604 case CrxUpdateItem::kDownloading:
549 case CrxUpdateItem::kDownloadingDiff: 605 case CrxUpdateItem::kDownloadingDiff:
550 case CrxUpdateItem::kLastStatus: 606 case CrxUpdateItem::kLastStatus:
551 // No notification for these states. 607 // No notification for these states.
552 break; 608 break;
553 } 609 }
554 } 610 }
611
612 // Free possible pending network requests.
613 if ((to == CrxUpdateItem::kUpdated) ||
614 (to == CrxUpdateItem::kUpToDate) ||
615 (to == CrxUpdateItem::kNoUpdate)) {
616 UnblockandReapAllThrottles(&item->throttles);
617 }
555 } 618 }
556 619
557 // Changes all the components in |work_items_| that have |from| status to 620 // Changes all the components in |work_items_| that have |from| status to
558 // |to| status and returns how many have been changed. 621 // |to| status and returns how many have been changed.
559 size_t CrxUpdateService::ChangeItemStatus(CrxUpdateItem::Status from, 622 size_t CrxUpdateService::ChangeItemStatus(CrxUpdateItem::Status from,
560 CrxUpdateItem::Status to) { 623 CrxUpdateItem::Status to) {
561 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 624 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
562 size_t count = 0; 625 size_t count = 0;
563 for (UpdateItems::iterator it = work_items_.begin(); 626 for (UpdateItems::iterator it = work_items_.begin();
564 it != work_items_.end(); ++it) { 627 it != work_items_.end(); ++it) {
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
634 item->diff_error_code = 0; 697 item->diff_error_code = 0;
635 item->diff_extra_code1 = 0; 698 item->diff_extra_code1 = 0;
636 return true; 699 return true;
637 } 700 }
638 701
639 // Start the process of checking for an update, for a particular component 702 // Start the process of checking for an update, for a particular component
640 // that was previously registered. 703 // that was previously registered.
641 // |component_id| is a value returned from GetCrxComponentID(). 704 // |component_id| is a value returned from GetCrxComponentID().
642 ComponentUpdateService::Status CrxUpdateService::OnDemandUpdate( 705 ComponentUpdateService::Status CrxUpdateService::OnDemandUpdate(
643 const std::string& component_id) { 706 const std::string& component_id) {
644 CrxUpdateItem* uit; 707 return OnDemandUpdateInternal(FindUpdateItemById(component_id));
645 uit = FindUpdateItemById(component_id); 708 }
709
710 ComponentUpdateService::Status CrxUpdateService::OnDemandUpdateInternal(
711 CrxUpdateItem* uit) {
646 if (!uit) 712 if (!uit)
647 return kError; 713 return kError;
648
649 // Check if the request is too soon. 714 // Check if the request is too soon.
650 base::TimeDelta delta = base::Time::Now() - uit->last_check; 715 base::TimeDelta delta = base::Time::Now() - uit->last_check;
651 if (delta < base::TimeDelta::FromSeconds(config_->OnDemandDelay())) 716 if (delta < base::TimeDelta::FromSeconds(config_->OnDemandDelay()))
652 return kError; 717 return kError;
653 718
654 switch (uit->status) { 719 switch (uit->status) {
655 // If the item is already in the process of being updated, there is 720 // If the item is already in the process of being updated, there is
656 // no point in this call, so return kInProgress. 721 // no point in this call, so return kInProgress.
657 case CrxUpdateItem::kChecking: 722 case CrxUpdateItem::kChecking:
658 case CrxUpdateItem::kCanUpdate: 723 case CrxUpdateItem::kCanUpdate:
(...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after
1062 void CrxUpdateService::NotifyComponentObservers( 1127 void CrxUpdateService::NotifyComponentObservers(
1063 ComponentObserver::Events event, int extra) const { 1128 ComponentObserver::Events event, int extra) const {
1064 for (UpdateItems::const_iterator it = work_items_.begin(); 1129 for (UpdateItems::const_iterator it = work_items_.begin();
1065 it != work_items_.end(); ++it) { 1130 it != work_items_.end(); ++it) {
1066 ComponentObserver* observer = (*it)->component.observer; 1131 ComponentObserver* observer = (*it)->component.observer;
1067 if (observer) 1132 if (observer)
1068 observer->OnEvent(event, 0); 1133 observer->OnEvent(event, 0);
1069 } 1134 }
1070 } 1135 }
1071 1136
1137 content::ResourceThrottle* CrxUpdateService::GetOnDemandResourceThrottle(
1138 net::URLRequest* request, const char* crx_id) {
1139 // We give the raw pointer to the caller, who will delete it at will
1140 // and we keep for ourselves a weak pointer to it so we can post tasks
1141 // from the UI thread without having to track lifetime directly.
1142 CUResourceThrottle* rt = new CUResourceThrottle(request);
1143 BrowserThread::PostTask(
1144 BrowserThread::UI,
1145 FROM_HERE,
1146 base::Bind(&CrxUpdateService::OnNewResourceThrottle,
1147 base::Unretained(this),
1148 rt->AsWeakPtr(),
1149 crx_id));
1150 return rt;
1151 }
1152
1153 void CrxUpdateService::OnNewResourceThrottle(
1154 base::WeakPtr<CUResourceThrottle> rt, const std::string& crx_id) {
1155 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1156 // Check if we can on-demand update, else unblock the request anyway.
1157 CrxUpdateItem* item = FindUpdateItemById(crx_id);
1158 Status status = OnDemandUpdateInternal(item);
1159 if (status == kOk || status == kInProgress) {
1160 item->throttles.push_back(rt);
1161 return;
1162 }
1163 UnblockResourceThrottle(rt);
1164 }
1165
1166 ///////////////////////////////////////////////////////////////////////////////
1167
1168 CUResourceThrottle::CUResourceThrottle(const net::URLRequest* request)
1169 : state_(NEW) {
1170 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1171 }
1172
1173 CUResourceThrottle::~CUResourceThrottle() {
1174 }
1175
1176 void CUResourceThrottle::WillStartRequest(bool* defer) {
1177 if (state_ != UNBLOCKED) {
1178 state_ = BLOCKED;
1179 *defer = true;
1180 } else {
1181 *defer = false;
1182 }
1183 }
1184
1185 void CUResourceThrottle::WillRedirectRequest(const GURL& new_url, bool* defer) {
1186 WillStartRequest(defer);
1187 }
1188
1189 void CUResourceThrottle::Unblock() {
1190 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1191 if (state_ == BLOCKED)
1192 controller()->Resume();
1193 state_ = UNBLOCKED;
1194 }
1195
1072 // The component update factory. Using the component updater as a singleton 1196 // The component update factory. Using the component updater as a singleton
1073 // is the job of the browser process. 1197 // is the job of the browser process.
1074 ComponentUpdateService* ComponentUpdateServiceFactory( 1198 ComponentUpdateService* ComponentUpdateServiceFactory(
1075 ComponentUpdateService::Configurator* config) { 1199 ComponentUpdateService::Configurator* config) {
1076 DCHECK(config); 1200 DCHECK(config);
1077 return new CrxUpdateService(config); 1201 return new CrxUpdateService(config);
1078 } 1202 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698