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

Side by Side Diff: extensions/browser/extension_host.cc

Issue 995983002: Make LoadMonitoringExtensionHostQueue remove itself as an ExtensionHost observer at the correct tim… (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: aha Created 5 years, 9 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 unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "extensions/browser/extension_host.h" 5 #include "extensions/browser/extension_host.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/metrics/field_trial.h" 8 #include "base/metrics/field_trial.h"
9 #include "base/metrics/histogram_macros.h" 9 #include "base/metrics/histogram_macros.h"
10 #include "base/profiler/scoped_tracker.h" 10 #include "base/profiler/scoped_tracker.h"
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 51
52 ExtensionHost::ExtensionHost(const Extension* extension, 52 ExtensionHost::ExtensionHost(const Extension* extension,
53 SiteInstance* site_instance, 53 SiteInstance* site_instance,
54 const GURL& url, 54 const GURL& url,
55 ViewType host_type) 55 ViewType host_type)
56 : delegate_(ExtensionsBrowserClient::Get()->CreateExtensionHostDelegate()), 56 : delegate_(ExtensionsBrowserClient::Get()->CreateExtensionHostDelegate()),
57 extension_(extension), 57 extension_(extension),
58 extension_id_(extension->id()), 58 extension_id_(extension->id()),
59 browser_context_(site_instance->GetBrowserContext()), 59 browser_context_(site_instance->GetBrowserContext()),
60 render_view_host_(nullptr), 60 render_view_host_(nullptr),
61 did_stop_loading_(false), 61 is_loading_(false),
62 has_loaded_once_(false),
62 document_element_available_(false), 63 document_element_available_(false),
63 initial_url_(url), 64 initial_url_(url),
64 extension_function_dispatcher_(browser_context_, this), 65 extension_function_dispatcher_(browser_context_, this),
65 extension_host_type_(host_type) { 66 extension_host_type_(host_type) {
66 // Not used for panels, see PanelHost. 67 // Not used for panels, see PanelHost.
67 DCHECK(host_type == VIEW_TYPE_EXTENSION_BACKGROUND_PAGE || 68 DCHECK(host_type == VIEW_TYPE_EXTENSION_BACKGROUND_PAGE ||
68 host_type == VIEW_TYPE_EXTENSION_DIALOG || 69 host_type == VIEW_TYPE_EXTENSION_DIALOG ||
69 host_type == VIEW_TYPE_EXTENSION_POPUP); 70 host_type == VIEW_TYPE_EXTENSION_POPUP);
70 host_contents_.reset(WebContents::Create( 71 host_contents_.reset(WebContents::Create(
71 WebContents::CreateParams(browser_context_, site_instance))), 72 WebContents::CreateParams(browser_context_, site_instance))),
(...skipping 13 matching lines...) Expand all
85 86
86 ExtensionHost::~ExtensionHost() { 87 ExtensionHost::~ExtensionHost() {
87 ExtensionRegistry::Get(browser_context_)->RemoveObserver(this); 88 ExtensionRegistry::Get(browser_context_)->RemoveObserver(this);
88 89
89 if (extension_host_type_ == VIEW_TYPE_EXTENSION_BACKGROUND_PAGE && 90 if (extension_host_type_ == VIEW_TYPE_EXTENSION_BACKGROUND_PAGE &&
90 extension_ && BackgroundInfo::HasLazyBackgroundPage(extension_) && 91 extension_ && BackgroundInfo::HasLazyBackgroundPage(extension_) &&
91 load_start_.get()) { 92 load_start_.get()) {
92 UMA_HISTOGRAM_LONG_TIMES("Extensions.EventPageActiveTime2", 93 UMA_HISTOGRAM_LONG_TIMES("Extensions.EventPageActiveTime2",
93 load_start_->Elapsed()); 94 load_start_->Elapsed());
94 } 95 }
96
97 // Record UMA now because we're about to stop observing our WebContents.
Yoyo Zhou 2015/03/12 22:57:29 We'll be recording incomplete loads? Hope that's o
not at google - send to devlin 2015/03/12 23:29:22 Yeah I couldn't decide whether or not this was a g
98 if (is_loading_)
99 RecordStopLoadingUMA();
100
95 content::NotificationService::current()->Notify( 101 content::NotificationService::current()->Notify(
96 extensions::NOTIFICATION_EXTENSION_HOST_DESTROYED, 102 extensions::NOTIFICATION_EXTENSION_HOST_DESTROYED,
97 content::Source<BrowserContext>(browser_context_), 103 content::Source<BrowserContext>(browser_context_),
98 content::Details<ExtensionHost>(this)); 104 content::Details<ExtensionHost>(this));
99 FOR_EACH_OBSERVER(ExtensionHostObserver, observer_list_, 105 FOR_EACH_OBSERVER(ExtensionHostObserver, observer_list_,
100 OnExtensionHostDestroyed(this)); 106 OnExtensionHostDestroyed(this));
101 FOR_EACH_OBSERVER(DeferredStartRenderHostObserver, 107 FOR_EACH_OBSERVER(DeferredStartRenderHostObserver,
102 deferred_start_render_host_observer_list_, 108 deferred_start_render_host_observer_list_,
103 OnDeferredStartRenderHostDestroyed(this)); 109 OnDeferredStartRenderHostDestroyed(this));
110
111 // Remove ourselves from the queue as late as possible (before effectively
112 // destroying self, but after everything else) so that queues that are
113 // monitoring lifetime get a chance to see stop-loading events.
104 delegate_->GetExtensionHostQueue()->Remove(this); 114 delegate_->GetExtensionHostQueue()->Remove(this);
105 // Immediately stop observing |host_contents_| because its destruction events 115
106 // (like DidStopLoading, it turns out) can call back into ExtensionHost 116 // Deliberately stop observing |host_contents_| because its destruction
107 // re-entrantly, when anything declared after |host_contents_| has already 117 // events (like DidStopLoading, it turns out) can call back into
108 // been destroyed. 118 // ExtensionHost re-entrantly, when anything declared after |host_contents_|
119 // has already been destroyed.
109 content::WebContentsObserver::Observe(nullptr); 120 content::WebContentsObserver::Observe(nullptr);
110 } 121 }
111 122
112 content::RenderProcessHost* ExtensionHost::render_process_host() const { 123 content::RenderProcessHost* ExtensionHost::render_process_host() const {
113 return render_view_host()->GetProcess(); 124 return render_view_host()->GetProcess();
114 } 125 }
115 126
116 RenderViewHost* ExtensionHost::render_view_host() const { 127 RenderViewHost* ExtensionHost::render_view_host() const {
117 // TODO(mpcomplete): This can be null. How do we handle that? 128 // TODO(mpcomplete): This can be null. How do we handle that?
118 return render_view_host_; 129 return render_view_host_;
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
212 } 223 }
213 224
214 void ExtensionHost::LoadInitialURL() { 225 void ExtensionHost::LoadInitialURL() {
215 load_start_.reset(new base::ElapsedTimer()); 226 load_start_.reset(new base::ElapsedTimer());
216 host_contents_->GetController().LoadURL( 227 host_contents_->GetController().LoadURL(
217 initial_url_, content::Referrer(), ui::PAGE_TRANSITION_LINK, 228 initial_url_, content::Referrer(), ui::PAGE_TRANSITION_LINK,
218 std::string()); 229 std::string());
219 } 230 }
220 231
221 bool ExtensionHost::IsBackgroundPage() const { 232 bool ExtensionHost::IsBackgroundPage() const {
222 DCHECK(extension_host_type_ == VIEW_TYPE_EXTENSION_BACKGROUND_PAGE); 233 DCHECK_EQ(extension_host_type_, VIEW_TYPE_EXTENSION_BACKGROUND_PAGE);
223 return true; 234 return true;
224 } 235 }
225 236
226 void ExtensionHost::OnExtensionUnloaded( 237 void ExtensionHost::OnExtensionUnloaded(
227 content::BrowserContext* browser_context, 238 content::BrowserContext* browser_context,
228 const Extension* extension, 239 const Extension* extension,
229 UnloadedExtensionInfo::Reason reason) { 240 UnloadedExtensionInfo::Reason reason) {
230 // The extension object will be deleted after this notification has been sent. 241 // The extension object will be deleted after this notification has been sent.
231 // Null it out so that dirty pointer issues don't arise in cases when multiple 242 // Null it out so that dirty pointer issues don't arise in cases when multiple
232 // ExtensionHost objects pointing to the same Extension are present. 243 // ExtensionHost objects pointing to the same Extension are present.
(...skipping 22 matching lines...) Expand all
255 // TODO(aa): This is suspicious. There can be multiple views in an extension, 266 // TODO(aa): This is suspicious. There can be multiple views in an extension,
256 // and they aren't all going to use ExtensionHost. This should be in someplace 267 // and they aren't all going to use ExtensionHost. This should be in someplace
257 // more central, like EPM maybe. 268 // more central, like EPM maybe.
258 content::NotificationService::current()->Notify( 269 content::NotificationService::current()->Notify(
259 extensions::NOTIFICATION_EXTENSION_PROCESS_TERMINATED, 270 extensions::NOTIFICATION_EXTENSION_PROCESS_TERMINATED,
260 content::Source<BrowserContext>(browser_context_), 271 content::Source<BrowserContext>(browser_context_),
261 content::Details<ExtensionHost>(this)); 272 content::Details<ExtensionHost>(this));
262 } 273 }
263 274
264 void ExtensionHost::DidStartLoading(content::RenderViewHost* render_view_host) { 275 void ExtensionHost::DidStartLoading(content::RenderViewHost* render_view_host) {
276 CHECK(!is_loading_);
277 is_loading_ = true;
265 FOR_EACH_OBSERVER(DeferredStartRenderHostObserver, 278 FOR_EACH_OBSERVER(DeferredStartRenderHostObserver,
266 deferred_start_render_host_observer_list_, 279 deferred_start_render_host_observer_list_,
267 OnDeferredStartRenderHostDidStartLoading(this)); 280 OnDeferredStartRenderHostDidStartLoading(this));
268 } 281 }
269 282
270 void ExtensionHost::DidStopLoading(content::RenderViewHost* render_view_host) { 283 void ExtensionHost::DidStopLoading(content::RenderViewHost* render_view_host) {
271 bool notify = !did_stop_loading_; 284 CHECK(is_loading_);
272 did_stop_loading_ = true; 285 is_loading_ = false;
273 OnDidStopLoading(); 286 has_loaded_once_ = true;
274 if (notify) { 287 RecordStopLoadingUMA();
275 CHECK(load_start_.get()); 288 content::NotificationService::current()->Notify(
276 if (extension_host_type_ == VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) { 289 extensions::NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING,
277 if (extension_ && BackgroundInfo::HasLazyBackgroundPage(extension_)) { 290 content::Source<BrowserContext>(browser_context_),
278 UMA_HISTOGRAM_MEDIUM_TIMES("Extensions.EventPageLoadTime2", 291 content::Details<ExtensionHost>(this));
279 load_start_->Elapsed()); 292 FOR_EACH_OBSERVER(DeferredStartRenderHostObserver,
280 } else { 293 deferred_start_render_host_observer_list_,
281 UMA_HISTOGRAM_MEDIUM_TIMES("Extensions.BackgroundPageLoadTime2", 294 OnDeferredStartRenderHostDidStopLoading(this));
282 load_start_->Elapsed());
283 }
284 } else if (extension_host_type_ == VIEW_TYPE_EXTENSION_POPUP) {
285 UMA_HISTOGRAM_MEDIUM_TIMES("Extensions.PopupLoadTime2",
286 load_start_->Elapsed());
287 }
288 content::NotificationService::current()->Notify(
289 extensions::NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING,
290 content::Source<BrowserContext>(browser_context_),
291 content::Details<ExtensionHost>(this));
292 FOR_EACH_OBSERVER(DeferredStartRenderHostObserver,
293 deferred_start_render_host_observer_list_,
294 OnDeferredStartRenderHostDidStopLoading(this));
295 }
296 } 295 }
297 296
298 void ExtensionHost::OnDidStopLoading() { 297 void ExtensionHost::OnDidStopLoading() {
299 DCHECK(extension_host_type_ == VIEW_TYPE_EXTENSION_BACKGROUND_PAGE); 298 DCHECK_EQ(extension_host_type_, VIEW_TYPE_EXTENSION_BACKGROUND_PAGE);
300 // Nothing to do for background pages. 299 // Nothing to do for background pages.
301 } 300 }
302 301
303 void ExtensionHost::DocumentAvailableInMainFrame() { 302 void ExtensionHost::DocumentAvailableInMainFrame() {
304 // If the document has already been marked as available for this host, then 303 // If the document has already been marked as available for this host, then
305 // bail. No need for the redundant setup. http://crbug.com/31170 304 // bail. No need for the redundant setup. http://crbug.com/31170
306 if (document_element_available_) 305 if (document_element_available_)
307 return; 306 return;
308 document_element_available_ = true; 307 document_element_available_ = true;
309 308
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
454 content::MediaStreamType type) { 453 content::MediaStreamType type) {
455 return delegate_->CheckMediaAccessPermission( 454 return delegate_->CheckMediaAccessPermission(
456 web_contents, security_origin, type, extension()); 455 web_contents, security_origin, type, extension());
457 } 456 }
458 457
459 bool ExtensionHost::IsNeverVisible(content::WebContents* web_contents) { 458 bool ExtensionHost::IsNeverVisible(content::WebContents* web_contents) {
460 ViewType view_type = extensions::GetViewType(web_contents); 459 ViewType view_type = extensions::GetViewType(web_contents);
461 return view_type == extensions::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE; 460 return view_type == extensions::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE;
462 } 461 }
463 462
463 void ExtensionHost::RecordStopLoadingUMA() {
464 CHECK(load_start_.get());
465 if (extension_host_type_ == VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) {
466 if (extension_ && BackgroundInfo::HasLazyBackgroundPage(extension_)) {
467 UMA_HISTOGRAM_MEDIUM_TIMES("Extensions.EventPageLoadTime2",
468 load_start_->Elapsed());
469 } else {
470 UMA_HISTOGRAM_MEDIUM_TIMES("Extensions.BackgroundPageLoadTime2",
471 load_start_->Elapsed());
472 }
473 } else if (extension_host_type_ == VIEW_TYPE_EXTENSION_POPUP) {
474 UMA_HISTOGRAM_MEDIUM_TIMES("Extensions.PopupLoadTime2",
475 load_start_->Elapsed());
476 }
477 }
478
464 } // namespace extensions 479 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698