Chromium Code Reviews| 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 |