| Index: components/guest_view/browser/guest_view_manager.cc
|
| diff --git a/components/guest_view/browser/guest_view_manager.cc b/components/guest_view/browser/guest_view_manager.cc
|
| index 07da1adf11f022be2079599f915fbe9e41e7c06c..fa40a7652b3fa6f9483763abedc6829a68921509 100644
|
| --- a/components/guest_view/browser/guest_view_manager.cc
|
| +++ b/components/guest_view/browser/guest_view_manager.cc
|
| @@ -22,11 +22,42 @@
|
| #include "url/gurl.h"
|
|
|
| using content::BrowserContext;
|
| +using content::RenderProcessHost;
|
| using content::SiteInstance;
|
| using content::WebContents;
|
|
|
| namespace guest_view {
|
|
|
| +// This observer observes the RenderProcessHosts of GuestView embedders, and
|
| +// notifies the GuestViewManager when they are destroyed.
|
| +class GuestViewManager::EmbedderRenderProcessHostObserver
|
| + : public content::RenderProcessHostObserver {
|
| + public:
|
| + EmbedderRenderProcessHostObserver(
|
| + base::WeakPtr<GuestViewManager> guest_view_manager,
|
| + int embedder_process_id)
|
| + : guest_view_manager_(guest_view_manager), id_(embedder_process_id) {
|
| + RenderProcessHost* rph = RenderProcessHost::FromID(id_);
|
| + rph->AddObserver(this);
|
| + }
|
| +
|
| + ~EmbedderRenderProcessHostObserver() override {
|
| + RenderProcessHost* rph = RenderProcessHost::FromID(id_);
|
| + if (rph)
|
| + rph->RemoveObserver(this);
|
| + }
|
| +
|
| + void RenderProcessHostDestroyed(RenderProcessHost* host) override {
|
| + if (guest_view_manager_.get())
|
| + guest_view_manager_->EmbedderProcessDestroyed(id_);
|
| + delete this;
|
| + }
|
| +
|
| + private:
|
| + base::WeakPtr<GuestViewManager> guest_view_manager_;
|
| + int id_;
|
| +};
|
| +
|
| // static
|
| GuestViewManagerFactory* GuestViewManager::factory_ = nullptr;
|
|
|
| @@ -36,7 +67,8 @@ GuestViewManager::GuestViewManager(
|
| : current_instance_id_(0),
|
| last_instance_id_removed_(0),
|
| context_(context),
|
| - delegate_(delegate.Pass()) {
|
| + delegate_(delegate.Pass()),
|
| + weak_ptr_factory_(this) {
|
| }
|
|
|
| GuestViewManager::~GuestViewManager() {}
|
| @@ -245,20 +277,9 @@ void GuestViewManager::RemoveGuest(int guest_instance_id) {
|
| }
|
| }
|
|
|
| -void GuestViewManager::EmbedderWillBeDestroyed(int embedder_process_id) {
|
| - // Find and call any callbacks associated with the embedder that is being
|
| - // destroyed.
|
| - auto embedder_it = view_destruction_callback_map_.find(embedder_process_id);
|
| - if (embedder_it == view_destruction_callback_map_.end())
|
| - return;
|
| - CallbacksForEachViewID& callbacks_for_embedder = embedder_it->second;
|
| - for (auto& view_pair : callbacks_for_embedder) {
|
| - Callbacks& callbacks_for_view = view_pair.second;
|
| - for (auto& callback : callbacks_for_view) {
|
| - callback.Run();
|
| - }
|
| - }
|
| - view_destruction_callback_map_.erase(embedder_it);
|
| +void GuestViewManager::EmbedderProcessDestroyed(int embedder_process_id) {
|
| + embedders_observed_.erase(embedder_process_id);
|
| + CallViewDestructionCallbacks(embedder_process_id);
|
| }
|
|
|
| void GuestViewManager::ViewCreated(int embedder_process_id,
|
| @@ -274,18 +295,39 @@ void GuestViewManager::ViewCreated(int embedder_process_id,
|
| RegisterViewDestructionCallback(embedder_process_id,
|
| view_instance_id,
|
| base::Bind(view_it->second.cleanup_function,
|
| + context_,
|
| embedder_process_id,
|
| view_instance_id));
|
| }
|
|
|
| void GuestViewManager::ViewGarbageCollected(int embedder_process_id,
|
| int view_instance_id) {
|
| - // Find and call any callbacks associated with the view that has been garbage
|
| - // collected.
|
| + CallViewDestructionCallbacks(embedder_process_id, view_instance_id);
|
| +}
|
| +
|
| +void GuestViewManager::CallViewDestructionCallbacks(int embedder_process_id,
|
| + int view_instance_id) {
|
| + // Find the callbacks for the embedder with ID |embedder_process_id|.
|
| auto embedder_it = view_destruction_callback_map_.find(embedder_process_id);
|
| if (embedder_it == view_destruction_callback_map_.end())
|
| return;
|
| CallbacksForEachViewID& callbacks_for_embedder = embedder_it->second;
|
| +
|
| + // If |view_instance_id| is guest_view::kInstanceIDNone, then all callbacks
|
| + // for this embedder should be called.
|
| + if (view_instance_id == guest_view::kInstanceIDNone) {
|
| + // Call all callbacks for the embedder with ID |embedder_process_id|.
|
| + for (auto& view_pair : callbacks_for_embedder) {
|
| + Callbacks& callbacks_for_view = view_pair.second;
|
| + for (auto& callback : callbacks_for_view)
|
| + callback.Run();
|
| + }
|
| + view_destruction_callback_map_.erase(embedder_it);
|
| + return;
|
| + }
|
| +
|
| + // Otherwise, call the callbacks only for the specific view with ID
|
| + // |view_instance_id|.
|
| auto view_it = callbacks_for_embedder.find(view_instance_id);
|
| if (view_it == callbacks_for_embedder.end())
|
| return;
|
| @@ -295,6 +337,11 @@ void GuestViewManager::ViewGarbageCollected(int embedder_process_id,
|
| callbacks_for_embedder.erase(view_it);
|
| }
|
|
|
| +void GuestViewManager::CallViewDestructionCallbacks(int embedder_process_id) {
|
| + CallViewDestructionCallbacks(embedder_process_id,
|
| + guest_view::kInstanceIDNone);
|
| +}
|
| +
|
| GuestViewBase* GuestViewManager::CreateGuestInternal(
|
| content::WebContents* owner_web_contents,
|
| const std::string& view_type) {
|
| @@ -318,6 +365,14 @@ void GuestViewManager::RegisterViewDestructionCallback(
|
| int embedder_process_id,
|
| int view_instance_id,
|
| const base::Closure& callback) {
|
| + // When an embedder is registered for the first time, create an observer to
|
| + // watch for its destruction.
|
| + if (!embedders_observed_.count(embedder_process_id)) {
|
| + embedders_observed_.insert(embedder_process_id);
|
| + /*new EmbedderRenderProcessHostObserver(weak_ptr_factory_.GetWeakPtr(),
|
| + embedder_process_id);*/
|
| + }
|
| +
|
| view_destruction_callback_map_[embedder_process_id][view_instance_id]
|
| .push_back(callback);
|
| }
|
|
|