| 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 != |
| 363 embedder_web_contents_observer_->web_contents()) { |
| 364 embedder_web_contents_observer_.reset( |
| 365 new EmbedderLifetimeObserver(this, embedder_web_contents)); |
| 366 } |
| 367 |
| 380 element_instance_id_ = element_instance_id; | 368 element_instance_id_ = element_instance_id; |
| 381 | 369 |
| 382 WillAttachToEmbedder(); | 370 WillAttachToEmbedder(); |
| 383 } | 371 } |
| 384 | 372 |
| 385 void GuestViewBase::DidStopLoading(content::RenderViewHost* render_view_host) { | 373 void GuestViewBase::DidStopLoading(content::RenderViewHost* render_view_host) { |
| 386 if (!IsDragAndDropEnabled()) { | 374 if (!IsDragAndDropEnabled()) { |
| 387 const char script[] = "window.addEventListener('dragstart', function() { " | 375 const char script[] = "window.addEventListener('dragstart', function() { " |
| 388 " window.event.preventDefault(); " | 376 " window.event.preventDefault(); " |
| 389 "});"; | 377 "});"; |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 481 if (!attached()) | 469 if (!attached()) |
| 482 return; | 470 return; |
| 483 while (!pending_events_.empty()) { | 471 while (!pending_events_.empty()) { |
| 484 linked_ptr<Event> event_ptr = pending_events_.front(); | 472 linked_ptr<Event> event_ptr = pending_events_.front(); |
| 485 pending_events_.pop_front(); | 473 pending_events_.pop_front(); |
| 486 DispatchEventToEmbedder(event_ptr.release()); | 474 DispatchEventToEmbedder(event_ptr.release()); |
| 487 } | 475 } |
| 488 } | 476 } |
| 489 | 477 |
| 490 void GuestViewBase::CompleteInit(const std::string& embedder_extension_id, | 478 void GuestViewBase::CompleteInit(const std::string& embedder_extension_id, |
| 491 int embedder_render_process_id, | 479 content::WebContents* embedder_web_contents, |
| 492 const WebContentsCreatedCallback& callback, | 480 const WebContentsCreatedCallback& callback, |
| 493 content::WebContents* guest_web_contents) { | 481 content::WebContents* guest_web_contents) { |
| 494 if (!guest_web_contents) { | 482 if (!guest_web_contents) { |
| 495 // The derived class did not create a WebContents so this class serves no | 483 // The derived class did not create a WebContents so this class serves no |
| 496 // purpose. Let's self-destruct. | 484 // purpose. Let's self-destruct. |
| 497 delete this; | 485 delete this; |
| 498 callback.Run(NULL); | 486 callback.Run(NULL); |
| 499 return; | 487 return; |
| 500 } | 488 } |
| 501 InitWithWebContents(embedder_extension_id, | 489 InitWithWebContents( |
| 502 embedder_render_process_id, | 490 embedder_extension_id, embedder_web_contents, guest_web_contents); |
| 503 guest_web_contents); | |
| 504 callback.Run(guest_web_contents); | 491 callback.Run(guest_web_contents); |
| 505 } | 492 } |
| 506 | 493 |
| 507 // static | 494 // static |
| 508 void GuestViewBase::RegisterGuestViewTypes() { | 495 void GuestViewBase::RegisterGuestViewTypes() { |
| 509 AppViewGuest::Register(); | 496 AppViewGuest::Register(); |
| 510 ExtensionOptionsGuest::Register(); | 497 ExtensionOptionsGuest::Register(); |
| 511 MimeHandlerViewGuest::Register(); | 498 MimeHandlerViewGuest::Register(); |
| 512 WebViewGuest::Register(); | 499 WebViewGuest::Register(); |
| 513 } | 500 } |
| 514 | 501 |
| 515 } // namespace extensions | 502 } // namespace extensions |
| OLD | NEW |