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 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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |