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