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

Unified Diff: chrome/browser/extensions/network_delay_listener.cc

Issue 8205001: (Owner approval for) Delay network requests on startup if any webRequest ... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 2 months 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/extensions/network_delay_listener.cc
===================================================================
--- chrome/browser/extensions/network_delay_listener.cc (revision 0)
+++ chrome/browser/extensions/network_delay_listener.cc (revision 0)
@@ -0,0 +1,161 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/extensions/network_delay_listener.h"
+
+#include "base/metrics/histogram.h"
+#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/common/chrome_notification_types.h"
+#include "chrome/common/extensions/extension.h"
+#include "chrome/common/url_constants.h"
+#include "chrome/browser/extensions/extension_host.h"
+#include "content/browser/browser_thread.h"
+#include "content/common/notification_service.h"
+#include "net/url_request/url_request.h"
+
+NetworkDelayListener::NetworkDelayListener()
+ : resource_queue_(NULL),
+ extensions_ready_(false),
+ recorded_startup_delay_(false) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED,
+ NotificationService::AllSources());
+ registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED,
+ NotificationService::AllSources());
+ registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING,
+ NotificationService::AllSources());
+ AddRef(); // Will be balanced in Cleanup().
+}
+
+void NetworkDelayListener::Initialize(ResourceQueue* resource_queue) {
+ resource_queue_ = resource_queue;
+}
+
+bool NetworkDelayListener::ShouldDelayRequest(
+ net::URLRequest* request,
+ const ResourceDispatcherHostRequestInfo& request_info,
+ const GlobalRequestID& request_id) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+ // Don't block internal URLs.
+ if (request->url().SchemeIs(chrome::kChromeUIScheme) ||
+ request->url().SchemeIs(chrome::kExtensionScheme)) {
+ return false;
+ }
+
+ return extensions_ready_;
+}
+
+NetworkDelayListener::~NetworkDelayListener() {
+}
+
+void NetworkDelayListener::WillShutdownResourceQueue() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ resource_queue_ = NULL;
+
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ NewRunnableMethod(this, &NetworkDelayListener::Cleanup));
+}
+
+void NetworkDelayListener::OnExtensionPending(const Extension* extension) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+ DCHECK(pending_extensions_.count(extension->id()) == 0);
+
+ // We only wait for background pages to load. If the extension has no
+ // background page, ignore it.
+ if (!extension->background_url().is_empty()) {
+ extensions_ready_ = false;
+ pending_extensions_.insert(extension->id());
+ delay_start_times_[extension->id()] = base::TimeTicks::Now();
+ }
+}
+
+void NetworkDelayListener::OnExtensionReady(const Extension* extension) {
+ // This may be called multiple times, if an extension finishes loading and is
+ // then disabled or uninstalled.
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+ // Quick escape to save work in the common case.
+ if (pending_extensions_.count(extension->id()) == 0)
+ return;
+
+ UMA_HISTOGRAM_TIMES("Extensions.StartupDelay",
+ base::TimeTicks::Now() - delay_start_times_[extension->id()]);
+ delay_start_times_.erase(extension->id());
+ pending_extensions_.erase(extension->id());
+
+ if (pending_extensions_.empty()) {
+ extensions_ready_ = true;
+ if (!recorded_startup_delay_) {
+ UMA_HISTOGRAM_TIMES("Extensions.StartupDelay_Total",
+ overall_start_time_.Elapsed());
+ recorded_startup_delay_ = true;
+ }
+ if (resource_queue_)
+ resource_queue_->StartDelayedRequests(this);
+ }
+}
+
+void NetworkDelayListener::Cleanup() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
Aaron Boodman 2011/10/10 22:59:29 I think these should be CHECK. Being on the wrong
+ registrar_.RemoveAll();
+ Release();
+}
+
+void NetworkDelayListener::Observe(int type,
+ const NotificationSource& source,
+ const NotificationDetails& details) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ switch (type) {
+ case chrome::NOTIFICATION_EXTENSION_LOADED: {
+ const Extension* extension = Details<const Extension>(details).ptr();
+ ExtensionService* service =
+ Source<Profile>(source).ptr()->GetExtensionService();
+ if (service->DelaysNetworkRequests(extension)) {
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ NewRunnableMethod(
battre 2011/10/10 15:33:29 This is old-school ;-) Check Albert J Wong's emai
+ this, &NetworkDelayListener::OnExtensionPending, extension));
+ }
+ break;
+ }
+ case chrome::NOTIFICATION_EXTENSION_UNLOADED: {
+ const Extension* extension =
+ Details<UnloadedExtensionInfo>(details)->extension;
+ ExtensionService* service =
+ Source<Profile>(source).ptr()->GetExtensionService();
+ if (service->DelaysNetworkRequests(extension)) {
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ NewRunnableMethod(
+ this, &NetworkDelayListener::OnExtensionReady, extension));
+ }
+ break;
+ }
+ case chrome::NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING: {
+ const ExtensionHost* eh = Details<ExtensionHost>(details).ptr();
+ if (eh->extension_host_type() != ViewType::EXTENSION_BACKGROUND_PAGE)
+ return;
+
+ const Extension* extension = eh ->extension();
battre 2011/10/10 15:33:29 nit: space before ->
+ ExtensionService* service =
+ Source<Profile>(source).ptr()->GetExtensionService();
+ if (service->DelaysNetworkRequests(extension)) {
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ NewRunnableMethod(
+ this, &NetworkDelayListener::OnExtensionReady, extension));
+ }
+ break;
+ }
+
+ default:
+ NOTREACHED();
+ }
+}
Property changes on: chrome\browser\extensions\network_delay_listener.cc
___________________________________________________________________
Added: svn:eol-style
+ LF

Powered by Google App Engine
This is Rietveld 408576698