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/guest_view/guest_view_base.h" | 5 #include "extensions/browser/guest_view/guest_view_base.h" |
6 | 6 |
7 #include "base/lazy_instance.h" | 7 #include "base/lazy_instance.h" |
8 #include "base/strings/utf_string_conversions.h" | 8 #include "base/strings/utf_string_conversions.h" |
9 #include "content/public/browser/render_frame_host.h" | 9 #include "content/public/browser/render_frame_host.h" |
10 #include "content/public/browser/render_process_host.h" | 10 #include "content/public/browser/render_process_host.h" |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
50 | 50 |
51 GuestViewBase::Event::~Event() { | 51 GuestViewBase::Event::~Event() { |
52 } | 52 } |
53 | 53 |
54 scoped_ptr<base::DictionaryValue> GuestViewBase::Event::GetArguments() { | 54 scoped_ptr<base::DictionaryValue> GuestViewBase::Event::GetArguments() { |
55 return args_.Pass(); | 55 return args_.Pass(); |
56 } | 56 } |
57 | 57 |
58 // This observer ensures that the GuestViewBase destroys itself when its | 58 // This observer ensures that the GuestViewBase destroys itself when its |
59 // embedder goes away. | 59 // embedder goes away. |
60 class GuestViewBase::EmbedderWebContentsObserver : public WebContentsObserver { | 60 class GuestViewBase::EmbedderLifetimeObserver : public WebContentsObserver { |
61 public: | 61 public: |
62 explicit EmbedderWebContentsObserver(GuestViewBase* guest) | 62 EmbedderLifetimeObserver(GuestViewBase* guest, |
63 : WebContentsObserver(guest->embedder_web_contents()), | 63 content::WebContents* embedder_web_contents) |
64 : WebContentsObserver(embedder_web_contents), | |
64 destroyed_(false), | 65 destroyed_(false), |
65 guest_(guest) { | 66 guest_(guest) {} |
66 } | |
67 | 67 |
68 virtual ~EmbedderWebContentsObserver() { | 68 virtual ~EmbedderLifetimeObserver() {} |
69 } | |
70 | 69 |
71 // WebContentsObserver implementation. | 70 // WebContentsObserver implementation. |
72 virtual void WebContentsDestroyed() override { | 71 virtual void WebContentsDestroyed() override { |
73 // If the embedder is destroyed then destroy the guest. | 72 // If the embedder is destroyed then destroy the guest. |
74 Destroy(); | 73 Destroy(); |
75 } | 74 } |
76 | 75 |
77 virtual void AboutToNavigateRenderView( | 76 virtual void AboutToNavigateRenderView( |
78 content::RenderViewHost* render_view_host) override { | 77 content::RenderViewHost* render_view_host) override { |
79 // If the embedder navigates then destroy the guest. | 78 // If the embedder navigates then destroy the guest. |
(...skipping 11 matching lines...) Expand all Loading... | |
91 | 90 |
92 void Destroy() { | 91 void Destroy() { |
93 if (destroyed_) | 92 if (destroyed_) |
94 return; | 93 return; |
95 destroyed_ = true; | 94 destroyed_ = true; |
96 guest_->embedder_web_contents_ = NULL; | 95 guest_->embedder_web_contents_ = NULL; |
97 guest_->EmbedderDestroyed(); | 96 guest_->EmbedderDestroyed(); |
98 guest_->Destroy(); | 97 guest_->Destroy(); |
99 } | 98 } |
100 | 99 |
101 DISALLOW_COPY_AND_ASSIGN(EmbedderWebContentsObserver); | 100 DISALLOW_COPY_AND_ASSIGN(EmbedderLifetimeObserver); |
102 }; | 101 }; |
103 | 102 |
104 GuestViewBase::GuestViewBase(content::BrowserContext* browser_context, | 103 GuestViewBase::GuestViewBase(content::BrowserContext* browser_context, |
105 int guest_instance_id) | 104 int guest_instance_id) |
106 : embedder_web_contents_(NULL), | 105 : embedder_web_contents_(NULL), |
107 embedder_render_process_id_(0), | 106 embedder_render_process_id_(0), |
108 browser_context_(browser_context), | 107 browser_context_(browser_context), |
109 guest_instance_id_(guest_instance_id), | 108 guest_instance_id_(guest_instance_id), |
110 view_instance_id_(guestview::kInstanceIDNone), | 109 view_instance_id_(guestview::kInstanceIDNone), |
111 element_instance_id_(guestview::kInstanceIDNone), | 110 element_instance_id_(guestview::kInstanceIDNone), |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
152 return; | 151 return; |
153 } | 152 } |
154 | 153 |
155 CreateWebContents(embedder_extension_id, | 154 CreateWebContents(embedder_extension_id, |
156 embedder_process_id, | 155 embedder_process_id, |
157 embedder_site_url, | 156 embedder_site_url, |
158 create_params, | 157 create_params, |
159 base::Bind(&GuestViewBase::CompleteInit, | 158 base::Bind(&GuestViewBase::CompleteInit, |
160 weak_ptr_factory_.GetWeakPtr(), | 159 weak_ptr_factory_.GetWeakPtr(), |
161 embedder_extension_id, | 160 embedder_extension_id, |
162 embedder_process_id, | 161 embedder_web_contents, |
163 callback)); | 162 callback)); |
164 } | 163 } |
165 | 164 |
166 void GuestViewBase::InitWithWebContents( | 165 void GuestViewBase::InitWithWebContents( |
167 const std::string& embedder_extension_id, | 166 const std::string& embedder_extension_id, |
168 int embedder_render_process_id, | 167 content::WebContents* embedder_web_contents, |
169 content::WebContents* guest_web_contents) { | 168 content::WebContents* guest_web_contents) { |
170 DCHECK(guest_web_contents); | 169 DCHECK(guest_web_contents); |
170 DCHECK(embedder_web_contents); | |
171 int embedder_render_process_id = | |
172 embedder_web_contents->GetRenderProcessHost()->GetID(); | |
171 content::RenderProcessHost* embedder_render_process_host = | 173 content::RenderProcessHost* embedder_render_process_host = |
172 content::RenderProcessHost::FromID(embedder_render_process_id); | 174 content::RenderProcessHost::FromID(embedder_render_process_id); |
173 | 175 |
174 embedder_extension_id_ = embedder_extension_id; | 176 embedder_extension_id_ = embedder_extension_id; |
175 embedder_render_process_id_ = embedder_render_process_host->GetID(); | 177 embedder_render_process_id_ = embedder_render_process_host->GetID(); |
176 embedder_render_process_host->AddObserver(this); | 178 |
179 // At this point, we have just created the guest WebContents, we need to add | |
180 // an observer to the embedder WebContents. This observer will be responsible | |
181 // for destroying the guest WebContents if the embedder goes away. | |
182 embedder_web_contents_observer_.reset( | |
183 new EmbedderLifetimeObserver(this, embedder_web_contents)); | |
177 | 184 |
178 WebContentsObserver::Observe(guest_web_contents); | 185 WebContentsObserver::Observe(guest_web_contents); |
179 guest_web_contents->SetDelegate(this); | 186 guest_web_contents->SetDelegate(this); |
180 webcontents_guestview_map.Get().insert( | 187 webcontents_guestview_map.Get().insert( |
181 std::make_pair(guest_web_contents, this)); | 188 std::make_pair(guest_web_contents, this)); |
182 GuestViewManager::FromBrowserContext(browser_context_)-> | 189 GuestViewManager::FromBrowserContext(browser_context_)-> |
183 AddGuest(guest_instance_id_, guest_web_contents); | 190 AddGuest(guest_instance_id_, guest_web_contents); |
184 | 191 |
185 // Give the derived class an opportunity to perform additional initialization. | 192 // Give the derived class an opportunity to perform additional initialization. |
186 DidInitialize(); | 193 DidInitialize(); |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
271 } | 278 } |
272 | 279 |
273 bool GuestViewBase::IsAutoSizeSupported() const { | 280 bool GuestViewBase::IsAutoSizeSupported() const { |
274 return false; | 281 return false; |
275 } | 282 } |
276 | 283 |
277 bool GuestViewBase::IsDragAndDropEnabled() const { | 284 bool GuestViewBase::IsDragAndDropEnabled() const { |
278 return false; | 285 return false; |
279 } | 286 } |
280 | 287 |
281 void GuestViewBase::RenderProcessExited(content::RenderProcessHost* host, | |
282 base::ProcessHandle handle, | |
283 base::TerminationStatus status, | |
284 int exit_code) { | |
285 // GuestViewBase tracks the lifetime of its embedder render process until it | |
286 // is attached to a particular embedder WebContents. At that point, its | |
287 // lifetime is restricted in scope to the lifetime of its embedder | |
288 // WebContents. | |
289 CHECK(!attached()); | |
290 CHECK_EQ(host->GetID(), embedder_render_process_id()); | |
291 | |
292 // This code path may be reached if the embedder WebContents is killed for | |
293 // whatever reason immediately after a called to GuestViewInternal.createGuest | |
294 // and before attaching the new guest to a frame. | |
295 Destroy(); | |
296 } | |
297 | |
298 void GuestViewBase::DidAttach(int guest_proxy_routing_id) { | 288 void GuestViewBase::DidAttach(int guest_proxy_routing_id) { |
299 // Give the derived class an opportunity to perform some actions. | 289 // Give the derived class an opportunity to perform some actions. |
300 DidAttachToEmbedder(); | 290 DidAttachToEmbedder(); |
301 | 291 |
302 // Inform the associated GuestViewContainer that the contentWindow is ready. | 292 // Inform the associated GuestViewContainer that the contentWindow is ready. |
303 embedder_web_contents()->Send(new ExtensionMsg_GuestAttached( | 293 embedder_web_contents()->Send(new ExtensionMsg_GuestAttached( |
304 embedder_web_contents()->GetMainFrame()->GetRoutingID(), | 294 embedder_web_contents()->GetMainFrame()->GetRoutingID(), |
305 element_instance_id_, | 295 element_instance_id_, |
306 guest_proxy_routing_id)); | 296 guest_proxy_routing_id)); |
307 | 297 |
308 SendQueuedEvents(); | 298 SendQueuedEvents(); |
309 } | 299 } |
310 | 300 |
311 void GuestViewBase::ElementSizeChanged(const gfx::Size& old_size, | 301 void GuestViewBase::ElementSizeChanged(const gfx::Size& old_size, |
312 const gfx::Size& new_size) { | 302 const gfx::Size& new_size) { |
313 element_size_ = new_size; | 303 element_size_ = new_size; |
314 } | 304 } |
315 | 305 |
316 void GuestViewBase::GuestSizeChanged(const gfx::Size& old_size, | 306 void GuestViewBase::GuestSizeChanged(const gfx::Size& old_size, |
317 const gfx::Size& new_size) { | 307 const gfx::Size& new_size) { |
318 if (!auto_size_enabled_) | 308 if (!auto_size_enabled_) |
319 return; | 309 return; |
320 guest_size_ = new_size; | 310 guest_size_ = new_size; |
321 GuestSizeChangedDueToAutoSize(old_size, new_size); | 311 GuestSizeChangedDueToAutoSize(old_size, new_size); |
322 } | 312 } |
323 | 313 |
324 void GuestViewBase::Destroy() { | 314 void GuestViewBase::Destroy() { |
325 DCHECK(web_contents()); | 315 DCHECK(web_contents()); |
326 | 316 |
327 content::RenderProcessHost* host = | |
328 content::RenderProcessHost::FromID(embedder_render_process_id()); | |
329 if (host) | |
330 host->RemoveObserver(this); | |
331 | |
332 // Give the derived class an opportunity to perform some cleanup. | 317 // Give the derived class an opportunity to perform some cleanup. |
333 WillDestroy(); | 318 WillDestroy(); |
334 | 319 |
335 // Invalidate weak pointers now so that bound callbacks cannot be called late | 320 // Invalidate weak pointers now so that bound callbacks cannot be called late |
336 // into destruction. We must call this after WillDestroy because derived types | 321 // into destruction. We must call this after WillDestroy because derived types |
337 // may wish to access their openers. | 322 // may wish to access their openers. |
338 weak_ptr_factory_.InvalidateWeakPtrs(); | 323 weak_ptr_factory_.InvalidateWeakPtrs(); |
339 | 324 |
340 // Give the content module an opportunity to perform some cleanup. | 325 // Give the content module an opportunity to perform some cleanup. |
341 if (!destruction_callback_.is_null()) | 326 if (!destruction_callback_.is_null()) |
(...skipping 21 matching lines...) Expand all Loading... | |
363 opener_ = base::WeakPtr<GuestViewBase>(); | 348 opener_ = base::WeakPtr<GuestViewBase>(); |
364 } | 349 } |
365 | 350 |
366 void GuestViewBase::RegisterDestructionCallback( | 351 void GuestViewBase::RegisterDestructionCallback( |
367 const DestructionCallback& callback) { | 352 const DestructionCallback& callback) { |
368 destruction_callback_ = callback; | 353 destruction_callback_ = callback; |
369 } | 354 } |
370 | 355 |
371 void GuestViewBase::WillAttach(content::WebContents* embedder_web_contents, | 356 void GuestViewBase::WillAttach(content::WebContents* embedder_web_contents, |
372 int element_instance_id) { | 357 int element_instance_id) { |
373 // After attachment, this GuestViewBase's lifetime is restricted to the | |
374 // lifetime of its embedder WebContents. Observing the RenderProcessHost | |
375 // of the embedder is no longer necessary. | |
376 embedder_web_contents->GetRenderProcessHost()->RemoveObserver(this); | |
377 embedder_web_contents_ = embedder_web_contents; | 358 embedder_web_contents_ = embedder_web_contents; |
378 embedder_web_contents_observer_.reset( | 359 |
379 new EmbedderWebContentsObserver(this)); | 360 // If we are attaching to a different WebContents than the one that created |
361 // the guest, we need to create a new LifetimeObserver. | |
362 if (embedder_web_contents != embedder_web_contents_observer_->web_contents()) | |
363 embedder_web_contents_observer_.reset( | |
Fady Samuel
2014/10/09 15:58:49
nit: since this statement occupies multiple lines,
lfg
2014/10/09 17:56:02
Done.
| |
364 new EmbedderLifetimeObserver(this, embedder_web_contents)); | |
365 | |
380 element_instance_id_ = element_instance_id; | 366 element_instance_id_ = element_instance_id; |
381 | 367 |
382 WillAttachToEmbedder(); | 368 WillAttachToEmbedder(); |
383 } | 369 } |
384 | 370 |
385 void GuestViewBase::DidStopLoading(content::RenderViewHost* render_view_host) { | 371 void GuestViewBase::DidStopLoading(content::RenderViewHost* render_view_host) { |
386 if (!IsDragAndDropEnabled()) { | 372 if (!IsDragAndDropEnabled()) { |
387 const char script[] = "window.addEventListener('dragstart', function() { " | 373 const char script[] = "window.addEventListener('dragstart', function() { " |
388 " window.event.preventDefault(); " | 374 " window.event.preventDefault(); " |
389 "});"; | 375 "});"; |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
481 if (!attached()) | 467 if (!attached()) |
482 return; | 468 return; |
483 while (!pending_events_.empty()) { | 469 while (!pending_events_.empty()) { |
484 linked_ptr<Event> event_ptr = pending_events_.front(); | 470 linked_ptr<Event> event_ptr = pending_events_.front(); |
485 pending_events_.pop_front(); | 471 pending_events_.pop_front(); |
486 DispatchEventToEmbedder(event_ptr.release()); | 472 DispatchEventToEmbedder(event_ptr.release()); |
487 } | 473 } |
488 } | 474 } |
489 | 475 |
490 void GuestViewBase::CompleteInit(const std::string& embedder_extension_id, | 476 void GuestViewBase::CompleteInit(const std::string& embedder_extension_id, |
491 int embedder_render_process_id, | 477 content::WebContents* embedder_web_contents, |
492 const WebContentsCreatedCallback& callback, | 478 const WebContentsCreatedCallback& callback, |
493 content::WebContents* guest_web_contents) { | 479 content::WebContents* guest_web_contents) { |
494 if (!guest_web_contents) { | 480 if (!guest_web_contents) { |
495 // The derived class did not create a WebContents so this class serves no | 481 // The derived class did not create a WebContents so this class serves no |
496 // purpose. Let's self-destruct. | 482 // purpose. Let's self-destruct. |
497 delete this; | 483 delete this; |
498 callback.Run(NULL); | 484 callback.Run(NULL); |
499 return; | 485 return; |
500 } | 486 } |
501 InitWithWebContents(embedder_extension_id, | 487 InitWithWebContents( |
502 embedder_render_process_id, | 488 embedder_extension_id, embedder_web_contents, guest_web_contents); |
503 guest_web_contents); | |
504 callback.Run(guest_web_contents); | 489 callback.Run(guest_web_contents); |
505 } | 490 } |
506 | 491 |
507 // static | 492 // static |
508 void GuestViewBase::RegisterGuestViewTypes() { | 493 void GuestViewBase::RegisterGuestViewTypes() { |
509 AppViewGuest::Register(); | 494 AppViewGuest::Register(); |
510 ExtensionOptionsGuest::Register(); | 495 ExtensionOptionsGuest::Register(); |
511 MimeHandlerViewGuest::Register(); | 496 MimeHandlerViewGuest::Register(); |
512 WebViewGuest::Register(); | 497 WebViewGuest::Register(); |
513 } | 498 } |
514 | 499 |
515 } // namespace extensions | 500 } // namespace extensions |
OLD | NEW |