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::EmbedderWebContentsObserver : public WebContentsObserver { |
Fady Samuel
2014/10/08 21:45:32
Maybe if we rename this to EmbedderLifetimeObserve
lfg
2014/10/08 23:25:36
Done.
| |
61 public: | 61 public: |
62 explicit EmbedderWebContentsObserver(GuestViewBase* guest) | 62 explicit EmbedderWebContentsObserver( |
Fady Samuel
2014/10/08 21:45:32
remove explicit
lfg
2014/10/08 23:25:36
Done.
| |
63 : WebContentsObserver(guest->embedder_web_contents()), | 63 GuestViewBase* guest, |
64 content::WebContents* embedder_web_contents) | |
65 : WebContentsObserver(embedder_web_contents), | |
64 destroyed_(false), | 66 destroyed_(false), |
65 guest_(guest) { | 67 guest_(guest) {} |
66 } | |
67 | 68 |
68 virtual ~EmbedderWebContentsObserver() { | 69 virtual ~EmbedderWebContentsObserver() { |
69 } | 70 } |
70 | 71 |
71 // WebContentsObserver implementation. | 72 // WebContentsObserver implementation. |
72 virtual void WebContentsDestroyed() override { | 73 virtual void WebContentsDestroyed() override { |
73 // If the embedder is destroyed then destroy the guest. | 74 // If the embedder is destroyed then destroy the guest. |
74 Destroy(); | 75 Destroy(); |
75 } | 76 } |
76 | 77 |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
153 } | 154 } |
154 | 155 |
155 CreateWebContents(embedder_extension_id, | 156 CreateWebContents(embedder_extension_id, |
156 embedder_process_id, | 157 embedder_process_id, |
157 embedder_site_url, | 158 embedder_site_url, |
158 create_params, | 159 create_params, |
159 base::Bind(&GuestViewBase::CompleteInit, | 160 base::Bind(&GuestViewBase::CompleteInit, |
160 weak_ptr_factory_.GetWeakPtr(), | 161 weak_ptr_factory_.GetWeakPtr(), |
161 embedder_extension_id, | 162 embedder_extension_id, |
162 embedder_process_id, | 163 embedder_process_id, |
164 embedder_web_contents, | |
163 callback)); | 165 callback)); |
164 } | 166 } |
165 | 167 |
166 void GuestViewBase::InitWithWebContents( | 168 void GuestViewBase::InitWithWebContents( |
167 const std::string& embedder_extension_id, | 169 const std::string& embedder_extension_id, |
168 int embedder_render_process_id, | 170 int embedder_render_process_id, |
Fady Samuel
2014/10/08 21:45:32
Looks like we can get rid of this. You can instea
lfg
2014/10/08 23:25:36
Done.
| |
171 content::WebContents* embedder_web_contents, | |
169 content::WebContents* guest_web_contents) { | 172 content::WebContents* guest_web_contents) { |
170 DCHECK(guest_web_contents); | 173 DCHECK(guest_web_contents); |
171 content::RenderProcessHost* embedder_render_process_host = | 174 content::RenderProcessHost* embedder_render_process_host = |
172 content::RenderProcessHost::FromID(embedder_render_process_id); | 175 content::RenderProcessHost::FromID(embedder_render_process_id); |
173 | 176 |
174 embedder_extension_id_ = embedder_extension_id; | 177 embedder_extension_id_ = embedder_extension_id; |
175 embedder_render_process_id_ = embedder_render_process_host->GetID(); | 178 embedder_render_process_id_ = embedder_render_process_host->GetID(); |
176 embedder_render_process_host->AddObserver(this); | 179 |
180 // At this point, we have just created the guest WebContents, we need to add | |
181 // an observer to the embedder WebContents. This observer will be responsible | |
182 // for destroying the guest WebContents if the embedder goes away. | |
183 embedder_web_contents_observer_.reset( | |
184 new EmbedderWebContentsObserver(this, embedder_web_contents)); | |
177 | 185 |
178 WebContentsObserver::Observe(guest_web_contents); | 186 WebContentsObserver::Observe(guest_web_contents); |
179 guest_web_contents->SetDelegate(this); | 187 guest_web_contents->SetDelegate(this); |
180 webcontents_guestview_map.Get().insert( | 188 webcontents_guestview_map.Get().insert( |
181 std::make_pair(guest_web_contents, this)); | 189 std::make_pair(guest_web_contents, this)); |
182 GuestViewManager::FromBrowserContext(browser_context_)-> | 190 GuestViewManager::FromBrowserContext(browser_context_)-> |
183 AddGuest(guest_instance_id_, guest_web_contents); | 191 AddGuest(guest_instance_id_, guest_web_contents); |
184 | 192 |
185 // Give the derived class an opportunity to perform additional initialization. | 193 // Give the derived class an opportunity to perform additional initialization. |
186 DidInitialize(); | 194 DidInitialize(); |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
271 } | 279 } |
272 | 280 |
273 bool GuestViewBase::IsAutoSizeSupported() const { | 281 bool GuestViewBase::IsAutoSizeSupported() const { |
274 return false; | 282 return false; |
275 } | 283 } |
276 | 284 |
277 bool GuestViewBase::IsDragAndDropEnabled() const { | 285 bool GuestViewBase::IsDragAndDropEnabled() const { |
278 return false; | 286 return false; |
279 } | 287 } |
280 | 288 |
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) { | 289 void GuestViewBase::DidAttach(int guest_proxy_routing_id) { |
299 // Give the derived class an opportunity to perform some actions. | 290 // Give the derived class an opportunity to perform some actions. |
300 DidAttachToEmbedder(); | 291 DidAttachToEmbedder(); |
301 | 292 |
302 // Inform the associated GuestViewContainer that the contentWindow is ready. | 293 // Inform the associated GuestViewContainer that the contentWindow is ready. |
303 embedder_web_contents()->Send(new ExtensionMsg_GuestAttached( | 294 embedder_web_contents()->Send(new ExtensionMsg_GuestAttached( |
304 embedder_web_contents()->GetMainFrame()->GetRoutingID(), | 295 embedder_web_contents()->GetMainFrame()->GetRoutingID(), |
305 element_instance_id_, | 296 element_instance_id_, |
306 guest_proxy_routing_id)); | 297 guest_proxy_routing_id)); |
307 | 298 |
308 SendQueuedEvents(); | 299 SendQueuedEvents(); |
309 } | 300 } |
310 | 301 |
311 void GuestViewBase::ElementSizeChanged(const gfx::Size& old_size, | 302 void GuestViewBase::ElementSizeChanged(const gfx::Size& old_size, |
312 const gfx::Size& new_size) { | 303 const gfx::Size& new_size) { |
313 element_size_ = new_size; | 304 element_size_ = new_size; |
314 } | 305 } |
315 | 306 |
316 void GuestViewBase::GuestSizeChanged(const gfx::Size& old_size, | 307 void GuestViewBase::GuestSizeChanged(const gfx::Size& old_size, |
317 const gfx::Size& new_size) { | 308 const gfx::Size& new_size) { |
318 if (!auto_size_enabled_) | 309 if (!auto_size_enabled_) |
319 return; | 310 return; |
320 guest_size_ = new_size; | 311 guest_size_ = new_size; |
321 GuestSizeChangedDueToAutoSize(old_size, new_size); | 312 GuestSizeChangedDueToAutoSize(old_size, new_size); |
322 } | 313 } |
323 | 314 |
324 void GuestViewBase::Destroy() { | 315 void GuestViewBase::Destroy() { |
325 DCHECK(web_contents()); | 316 DCHECK(web_contents()); |
326 | 317 |
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. | 318 // Give the derived class an opportunity to perform some cleanup. |
333 WillDestroy(); | 319 WillDestroy(); |
334 | 320 |
335 // Invalidate weak pointers now so that bound callbacks cannot be called late | 321 // Invalidate weak pointers now so that bound callbacks cannot be called late |
336 // into destruction. We must call this after WillDestroy because derived types | 322 // into destruction. We must call this after WillDestroy because derived types |
337 // may wish to access their openers. | 323 // may wish to access their openers. |
338 weak_ptr_factory_.InvalidateWeakPtrs(); | 324 weak_ptr_factory_.InvalidateWeakPtrs(); |
339 | 325 |
340 // Give the content module an opportunity to perform some cleanup. | 326 // Give the content module an opportunity to perform some cleanup. |
341 if (!destruction_callback_.is_null()) | 327 if (!destruction_callback_.is_null()) |
(...skipping 21 matching lines...) Expand all Loading... | |
363 opener_ = base::WeakPtr<GuestViewBase>(); | 349 opener_ = base::WeakPtr<GuestViewBase>(); |
364 } | 350 } |
365 | 351 |
366 void GuestViewBase::RegisterDestructionCallback( | 352 void GuestViewBase::RegisterDestructionCallback( |
367 const DestructionCallback& callback) { | 353 const DestructionCallback& callback) { |
368 destruction_callback_ = callback; | 354 destruction_callback_ = callback; |
369 } | 355 } |
370 | 356 |
371 void GuestViewBase::WillAttach(content::WebContents* embedder_web_contents, | 357 void GuestViewBase::WillAttach(content::WebContents* embedder_web_contents, |
372 int element_instance_id) { | 358 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; | 359 embedder_web_contents_ = embedder_web_contents; |
378 embedder_web_contents_observer_.reset( | |
379 new EmbedderWebContentsObserver(this)); | |
380 element_instance_id_ = element_instance_id; | 360 element_instance_id_ = element_instance_id; |
381 | 361 |
382 WillAttachToEmbedder(); | 362 WillAttachToEmbedder(); |
383 } | 363 } |
384 | 364 |
385 void GuestViewBase::DidStopLoading(content::RenderViewHost* render_view_host) { | 365 void GuestViewBase::DidStopLoading(content::RenderViewHost* render_view_host) { |
386 if (!IsDragAndDropEnabled()) { | 366 if (!IsDragAndDropEnabled()) { |
387 const char script[] = "window.addEventListener('dragstart', function() { " | 367 const char script[] = "window.addEventListener('dragstart', function() { " |
388 " window.event.preventDefault(); " | 368 " window.event.preventDefault(); " |
389 "});"; | 369 "});"; |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
481 if (!attached()) | 461 if (!attached()) |
482 return; | 462 return; |
483 while (!pending_events_.empty()) { | 463 while (!pending_events_.empty()) { |
484 linked_ptr<Event> event_ptr = pending_events_.front(); | 464 linked_ptr<Event> event_ptr = pending_events_.front(); |
485 pending_events_.pop_front(); | 465 pending_events_.pop_front(); |
486 DispatchEventToEmbedder(event_ptr.release()); | 466 DispatchEventToEmbedder(event_ptr.release()); |
487 } | 467 } |
488 } | 468 } |
489 | 469 |
490 void GuestViewBase::CompleteInit(const std::string& embedder_extension_id, | 470 void GuestViewBase::CompleteInit(const std::string& embedder_extension_id, |
491 int embedder_render_process_id, | 471 int embedder_render_process_id, |
Fady Samuel
2014/10/08 21:45:32
Do we need to pass in this field as well? It seems
lfg
2014/10/08 23:25:36
Done.
| |
472 content::WebContents* embedder_web_contents, | |
492 const WebContentsCreatedCallback& callback, | 473 const WebContentsCreatedCallback& callback, |
493 content::WebContents* guest_web_contents) { | 474 content::WebContents* guest_web_contents) { |
494 if (!guest_web_contents) { | 475 if (!guest_web_contents) { |
495 // The derived class did not create a WebContents so this class serves no | 476 // The derived class did not create a WebContents so this class serves no |
496 // purpose. Let's self-destruct. | 477 // purpose. Let's self-destruct. |
497 delete this; | 478 delete this; |
498 callback.Run(NULL); | 479 callback.Run(NULL); |
499 return; | 480 return; |
500 } | 481 } |
501 InitWithWebContents(embedder_extension_id, | 482 InitWithWebContents(embedder_extension_id, |
502 embedder_render_process_id, | 483 embedder_render_process_id, |
Fady Samuel
2014/10/08 21:45:32
Remove this.
lfg
2014/10/08 23:25:36
Done.
| |
484 embedder_web_contents, | |
503 guest_web_contents); | 485 guest_web_contents); |
504 callback.Run(guest_web_contents); | 486 callback.Run(guest_web_contents); |
505 } | 487 } |
506 | 488 |
507 // static | 489 // static |
508 void GuestViewBase::RegisterGuestViewTypes() { | 490 void GuestViewBase::RegisterGuestViewTypes() { |
509 AppViewGuest::Register(); | 491 AppViewGuest::Register(); |
510 ExtensionOptionsGuest::Register(); | 492 ExtensionOptionsGuest::Register(); |
511 MimeHandlerViewGuest::Register(); | 493 MimeHandlerViewGuest::Register(); |
512 WebViewGuest::Register(); | 494 WebViewGuest::Register(); |
513 } | 495 } |
514 | 496 |
515 } // namespace extensions | 497 } // namespace extensions |
OLD | NEW |