OLD | NEW |
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 Loading... |
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 has_loaded_once_(false), | 61 did_stop_loading_(false), |
62 document_element_available_(false), | 62 document_element_available_(false), |
63 initial_url_(url), | 63 initial_url_(url), |
64 extension_function_dispatcher_(browser_context_, this), | 64 extension_function_dispatcher_(browser_context_, this), |
65 extension_host_type_(host_type) { | 65 extension_host_type_(host_type) { |
66 // Not used for panels, see PanelHost. | 66 // Not used for panels, see PanelHost. |
67 DCHECK(host_type == VIEW_TYPE_EXTENSION_BACKGROUND_PAGE || | 67 DCHECK(host_type == VIEW_TYPE_EXTENSION_BACKGROUND_PAGE || |
68 host_type == VIEW_TYPE_EXTENSION_DIALOG || | 68 host_type == VIEW_TYPE_EXTENSION_DIALOG || |
69 host_type == VIEW_TYPE_EXTENSION_POPUP); | 69 host_type == VIEW_TYPE_EXTENSION_POPUP); |
70 host_contents_.reset(WebContents::Create( | 70 host_contents_.reset(WebContents::Create( |
71 WebContents::CreateParams(browser_context_, site_instance))), | 71 WebContents::CreateParams(browser_context_, site_instance))), |
(...skipping 13 matching lines...) Expand all Loading... |
85 | 85 |
86 ExtensionHost::~ExtensionHost() { | 86 ExtensionHost::~ExtensionHost() { |
87 ExtensionRegistry::Get(browser_context_)->RemoveObserver(this); | 87 ExtensionRegistry::Get(browser_context_)->RemoveObserver(this); |
88 | 88 |
89 if (extension_host_type_ == VIEW_TYPE_EXTENSION_BACKGROUND_PAGE && | 89 if (extension_host_type_ == VIEW_TYPE_EXTENSION_BACKGROUND_PAGE && |
90 extension_ && BackgroundInfo::HasLazyBackgroundPage(extension_) && | 90 extension_ && BackgroundInfo::HasLazyBackgroundPage(extension_) && |
91 load_start_.get()) { | 91 load_start_.get()) { |
92 UMA_HISTOGRAM_LONG_TIMES("Extensions.EventPageActiveTime2", | 92 UMA_HISTOGRAM_LONG_TIMES("Extensions.EventPageActiveTime2", |
93 load_start_->Elapsed()); | 93 load_start_->Elapsed()); |
94 } | 94 } |
95 | |
96 content::NotificationService::current()->Notify( | 95 content::NotificationService::current()->Notify( |
97 extensions::NOTIFICATION_EXTENSION_HOST_DESTROYED, | 96 extensions::NOTIFICATION_EXTENSION_HOST_DESTROYED, |
98 content::Source<BrowserContext>(browser_context_), | 97 content::Source<BrowserContext>(browser_context_), |
99 content::Details<ExtensionHost>(this)); | 98 content::Details<ExtensionHost>(this)); |
100 FOR_EACH_OBSERVER(ExtensionHostObserver, observer_list_, | 99 FOR_EACH_OBSERVER(ExtensionHostObserver, observer_list_, |
101 OnExtensionHostDestroyed(this)); | 100 OnExtensionHostDestroyed(this)); |
102 FOR_EACH_OBSERVER(DeferredStartRenderHostObserver, | 101 FOR_EACH_OBSERVER(DeferredStartRenderHostObserver, |
103 deferred_start_render_host_observer_list_, | 102 deferred_start_render_host_observer_list_, |
104 OnDeferredStartRenderHostDestroyed(this)); | 103 OnDeferredStartRenderHostDestroyed(this)); |
105 | |
106 // Remove ourselves from the queue as late as possible (before effectively | |
107 // destroying self, but after everything else) so that queues that are | |
108 // monitoring lifetime get a chance to see stop-loading events. | |
109 delegate_->GetExtensionHostQueue()->Remove(this); | 104 delegate_->GetExtensionHostQueue()->Remove(this); |
110 | 105 // Immediately stop observing |host_contents_| because its destruction events |
111 // Deliberately stop observing |host_contents_| because its destruction | 106 // (like DidStopLoading, it turns out) can call back into ExtensionHost |
112 // events (like DidStopLoading, it turns out) can call back into | 107 // re-entrantly, when anything declared after |host_contents_| has already |
113 // ExtensionHost re-entrantly, when anything declared after |host_contents_| | 108 // been destroyed. |
114 // has already been destroyed. | |
115 content::WebContentsObserver::Observe(nullptr); | 109 content::WebContentsObserver::Observe(nullptr); |
116 } | 110 } |
117 | 111 |
118 content::RenderProcessHost* ExtensionHost::render_process_host() const { | 112 content::RenderProcessHost* ExtensionHost::render_process_host() const { |
119 return render_view_host()->GetProcess(); | 113 return render_view_host()->GetProcess(); |
120 } | 114 } |
121 | 115 |
122 RenderViewHost* ExtensionHost::render_view_host() const { | 116 RenderViewHost* ExtensionHost::render_view_host() const { |
123 // TODO(mpcomplete): This can be null. How do we handle that? | 117 // TODO(mpcomplete): This can be null. How do we handle that? |
124 return render_view_host_; | 118 return render_view_host_; |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
218 } | 212 } |
219 | 213 |
220 void ExtensionHost::LoadInitialURL() { | 214 void ExtensionHost::LoadInitialURL() { |
221 load_start_.reset(new base::ElapsedTimer()); | 215 load_start_.reset(new base::ElapsedTimer()); |
222 host_contents_->GetController().LoadURL( | 216 host_contents_->GetController().LoadURL( |
223 initial_url_, content::Referrer(), ui::PAGE_TRANSITION_LINK, | 217 initial_url_, content::Referrer(), ui::PAGE_TRANSITION_LINK, |
224 std::string()); | 218 std::string()); |
225 } | 219 } |
226 | 220 |
227 bool ExtensionHost::IsBackgroundPage() const { | 221 bool ExtensionHost::IsBackgroundPage() const { |
228 DCHECK_EQ(extension_host_type_, VIEW_TYPE_EXTENSION_BACKGROUND_PAGE); | 222 DCHECK(extension_host_type_ == VIEW_TYPE_EXTENSION_BACKGROUND_PAGE); |
229 return true; | 223 return true; |
230 } | 224 } |
231 | 225 |
232 void ExtensionHost::OnExtensionUnloaded( | 226 void ExtensionHost::OnExtensionUnloaded( |
233 content::BrowserContext* browser_context, | 227 content::BrowserContext* browser_context, |
234 const Extension* extension, | 228 const Extension* extension, |
235 UnloadedExtensionInfo::Reason reason) { | 229 UnloadedExtensionInfo::Reason reason) { |
236 // The extension object will be deleted after this notification has been sent. | 230 // The extension object will be deleted after this notification has been sent. |
237 // Null it out so that dirty pointer issues don't arise in cases when multiple | 231 // Null it out so that dirty pointer issues don't arise in cases when multiple |
238 // ExtensionHost objects pointing to the same Extension are present. | 232 // ExtensionHost objects pointing to the same Extension are present. |
(...skipping 28 matching lines...) Expand all Loading... |
267 content::Details<ExtensionHost>(this)); | 261 content::Details<ExtensionHost>(this)); |
268 } | 262 } |
269 | 263 |
270 void ExtensionHost::DidStartLoading(content::RenderViewHost* render_view_host) { | 264 void ExtensionHost::DidStartLoading(content::RenderViewHost* render_view_host) { |
271 FOR_EACH_OBSERVER(DeferredStartRenderHostObserver, | 265 FOR_EACH_OBSERVER(DeferredStartRenderHostObserver, |
272 deferred_start_render_host_observer_list_, | 266 deferred_start_render_host_observer_list_, |
273 OnDeferredStartRenderHostDidStartLoading(this)); | 267 OnDeferredStartRenderHostDidStartLoading(this)); |
274 } | 268 } |
275 | 269 |
276 void ExtensionHost::DidStopLoading(content::RenderViewHost* render_view_host) { | 270 void ExtensionHost::DidStopLoading(content::RenderViewHost* render_view_host) { |
277 // Only record UMA for the first load. Subsequent loads will likely behave | 271 bool notify = !did_stop_loading_; |
278 // quite different, and it's first load we're most interested in. | 272 did_stop_loading_ = true; |
279 if (!has_loaded_once_) | |
280 RecordStopLoadingUMA(); | |
281 has_loaded_once_ = true; | |
282 OnDidStopLoading(); | 273 OnDidStopLoading(); |
283 content::NotificationService::current()->Notify( | 274 if (notify) { |
284 extensions::NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING, | 275 CHECK(load_start_.get()); |
285 content::Source<BrowserContext>(browser_context_), | 276 if (extension_host_type_ == VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) { |
286 content::Details<ExtensionHost>(this)); | 277 if (extension_ && BackgroundInfo::HasLazyBackgroundPage(extension_)) { |
287 FOR_EACH_OBSERVER(DeferredStartRenderHostObserver, | 278 UMA_HISTOGRAM_MEDIUM_TIMES("Extensions.EventPageLoadTime2", |
288 deferred_start_render_host_observer_list_, | 279 load_start_->Elapsed()); |
289 OnDeferredStartRenderHostDidStopLoading(this)); | 280 } else { |
| 281 UMA_HISTOGRAM_MEDIUM_TIMES("Extensions.BackgroundPageLoadTime2", |
| 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 } |
290 } | 296 } |
291 | 297 |
292 void ExtensionHost::OnDidStopLoading() { | 298 void ExtensionHost::OnDidStopLoading() { |
293 DCHECK_EQ(extension_host_type_, VIEW_TYPE_EXTENSION_BACKGROUND_PAGE); | 299 DCHECK(extension_host_type_ == VIEW_TYPE_EXTENSION_BACKGROUND_PAGE); |
294 // Nothing to do for background pages. | 300 // Nothing to do for background pages. |
295 } | 301 } |
296 | 302 |
297 void ExtensionHost::DocumentAvailableInMainFrame() { | 303 void ExtensionHost::DocumentAvailableInMainFrame() { |
298 // If the document has already been marked as available for this host, then | 304 // If the document has already been marked as available for this host, then |
299 // bail. No need for the redundant setup. http://crbug.com/31170 | 305 // bail. No need for the redundant setup. http://crbug.com/31170 |
300 if (document_element_available_) | 306 if (document_element_available_) |
301 return; | 307 return; |
302 document_element_available_ = true; | 308 document_element_available_ = true; |
303 | 309 |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
448 content::MediaStreamType type) { | 454 content::MediaStreamType type) { |
449 return delegate_->CheckMediaAccessPermission( | 455 return delegate_->CheckMediaAccessPermission( |
450 web_contents, security_origin, type, extension()); | 456 web_contents, security_origin, type, extension()); |
451 } | 457 } |
452 | 458 |
453 bool ExtensionHost::IsNeverVisible(content::WebContents* web_contents) { | 459 bool ExtensionHost::IsNeverVisible(content::WebContents* web_contents) { |
454 ViewType view_type = extensions::GetViewType(web_contents); | 460 ViewType view_type = extensions::GetViewType(web_contents); |
455 return view_type == extensions::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE; | 461 return view_type == extensions::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE; |
456 } | 462 } |
457 | 463 |
458 void ExtensionHost::RecordStopLoadingUMA() { | |
459 CHECK(load_start_.get()); | |
460 if (extension_host_type_ == VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) { | |
461 if (extension_ && BackgroundInfo::HasLazyBackgroundPage(extension_)) { | |
462 UMA_HISTOGRAM_MEDIUM_TIMES("Extensions.EventPageLoadTime2", | |
463 load_start_->Elapsed()); | |
464 } else { | |
465 UMA_HISTOGRAM_MEDIUM_TIMES("Extensions.BackgroundPageLoadTime2", | |
466 load_start_->Elapsed()); | |
467 } | |
468 } else if (extension_host_type_ == VIEW_TYPE_EXTENSION_POPUP) { | |
469 UMA_HISTOGRAM_MEDIUM_TIMES("Extensions.PopupLoadTime2", | |
470 load_start_->Elapsed()); | |
471 } | |
472 } | |
473 | |
474 } // namespace extensions | 464 } // namespace extensions |
OLD | NEW |