summaryrefslogtreecommitdiffstats
path: root/components/guest_view
diff options
context:
space:
mode:
Diffstat (limited to 'components/guest_view')
-rw-r--r--components/guest_view/browser/guest_view_base.cc9
-rw-r--r--components/guest_view/browser/guest_view_base.h4
-rw-r--r--components/guest_view/browser/guest_view_manager.cc89
-rw-r--r--components/guest_view/browser/guest_view_manager.h27
-rw-r--r--components/guest_view/browser/test_guest_view_manager.cc4
-rw-r--r--components/guest_view/browser/test_guest_view_manager.h2
6 files changed, 105 insertions, 30 deletions
diff --git a/components/guest_view/browser/guest_view_base.cc b/components/guest_view/browser/guest_view_base.cc
index 599f8c0..ef65c87 100644
--- a/components/guest_view/browser/guest_view_base.cc
+++ b/components/guest_view/browser/guest_view_base.cc
@@ -76,11 +76,6 @@ class GuestViewBase::OwnerContentsObserver : public WebContentsObserver {
void RenderProcessGone(base::TerminationStatus status) override {
if (destroyed_)
return;
-
- GuestViewManager::FromBrowserContext(web_contents()->GetBrowserContext())
- ->EmbedderWillBeDestroyed(
- web_contents()->GetRenderProcessHost()->GetID());
-
// If the embedder process is destroyed, then destroy the guest.
Destroy();
}
@@ -322,7 +317,9 @@ void GuestViewBase::SetSize(const SetSizeParams& params) {
}
// static
-void GuestViewBase::CleanUp(int embedder_process_id, int view_instance_id) {
+void GuestViewBase::CleanUp(content::BrowserContext* browser_context,
+ int embedder_process_id,
+ int view_instance_id) {
// TODO(paulmeyer): Add in any general GuestView cleanup work here.
}
diff --git a/components/guest_view/browser/guest_view_base.h b/components/guest_view/browser/guest_view_base.h
index 6a52980..2e7862d 100644
--- a/components/guest_view/browser/guest_view_base.h
+++ b/components/guest_view/browser/guest_view_base.h
@@ -65,7 +65,9 @@ class GuestViewBase : public content::BrowserPluginGuestDelegate,
// potentially be created and destroyed in JavaScript before getting a
// GuestViewBase instance. This method can be hidden by a CleanUp() method in
// a derived class, in which case the derived method should call this one.
- static void CleanUp(int embedder_process_id, int view_instance_id);
+ static void CleanUp(content::BrowserContext* browser_context,
+ int embedder_process_id,
+ int view_instance_id);
static GuestViewBase* FromWebContents(
const content::WebContents* web_contents);
diff --git a/components/guest_view/browser/guest_view_manager.cc b/components/guest_view/browser/guest_view_manager.cc
index 07da1ad..fa40a76 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);
}
diff --git a/components/guest_view/browser/guest_view_manager.h b/components/guest_view/browser/guest_view_manager.h
index 5364ede..87b1831 100644
--- a/components/guest_view/browser/guest_view_manager.h
+++ b/components/guest_view/browser/guest_view_manager.h
@@ -6,12 +6,14 @@
#define COMPONENTS_GUEST_VIEW_BROWSER_GUEST_VIEW_MANAGER_H_
#include <map>
+#include <set>
#include <vector>
#include "base/bind.h"
#include "base/gtest_prod_util.h"
#include "base/lazy_instance.h"
#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
#include "content/public/browser/browser_plugin_guest_manager.h"
#include "content/public/browser/site_instance.h"
#include "content/public/browser/web_contents.h"
@@ -132,6 +134,8 @@ class GuestViewManager : public content::BrowserPluginGuestManager,
friend class GuestViewEvent;
friend class GuestViewMessageFilter;
+ class EmbedderRenderProcessHostObserver;
+
// These methods are virtual so that they can be overriden in tests.
virtual void AddGuest(int guest_instance_id,
@@ -139,8 +143,8 @@ class GuestViewManager : public content::BrowserPluginGuestManager,
virtual void RemoveGuest(int guest_instance_id);
// This method is called when the embedder process with ID
- // |embedder_process_id| is about to be destroyed.
- virtual void EmbedderWillBeDestroyed(int embedder_process_id);
+ // |embedder_process_id| has been destroyed.
+ virtual void EmbedderProcessDestroyed(int embedder_process_id);
// Called when a GuestView has been created in JavaScript.
virtual void ViewCreated(int embedder_process_id,
@@ -151,6 +155,15 @@ class GuestViewManager : public content::BrowserPluginGuestManager,
virtual void ViewGarbageCollected(int embedder_process_id,
int view_instance_id);
+ // Calls all destruction callbacks registered for the GuestView identified by
+ // |embedder_process_id| and |view_instance_id|.
+ void CallViewDestructionCallbacks(int embedder_process_id,
+ int view_instance_id);
+
+ // Calls all destruction callbacks registered for GuestViews in the embedder
+ // with ID |embedder_process_id|.
+ void CallViewDestructionCallbacks(int embedder_process_id);
+
// Creates a guest of the provided |view_type|.
GuestViewBase* CreateGuestInternal(content::WebContents* owner_web_contents,
const std::string& view_type);
@@ -215,7 +228,8 @@ class GuestViewManager : public content::BrowserPluginGuestManager,
using GuestViewCreateFunction =
base::Callback<GuestViewBase*(content::WebContents*)>;
- using GuestViewCleanUpFunction = base::Callback<void(int, int)>;
+ using GuestViewCleanUpFunction =
+ base::Callback<void(content::BrowserContext*, int, int)>;
struct GuestViewData {
GuestViewData(const GuestViewCreateFunction& create_function,
const GuestViewCleanUpFunction& cleanup_function);
@@ -241,6 +255,9 @@ class GuestViewManager : public content::BrowserPluginGuestManager,
scoped_ptr<GuestViewManagerDelegate> delegate_;
+ // This tracks which GuestView embedders are currently being observed.
+ std::set<int> embedders_observed_;
+
// |view_destruction_callback_map_| maps from embedder process ID to view ID
// to a vector of callback functions to be called when that view is destroyed.
using Callbacks = std::vector<base::Closure> ;
@@ -248,6 +265,10 @@ class GuestViewManager : public content::BrowserPluginGuestManager,
using CallbacksForEachEmbedderID = std::map<int, CallbacksForEachViewID> ;
CallbacksForEachEmbedderID view_destruction_callback_map_;
+ // This is used to ensure that an EmbedderRenderProcessHostObserver will not
+ // call into this GuestViewManager after it has been destroyed.
+ base::WeakPtrFactory<GuestViewManager> weak_ptr_factory_;
+
DISALLOW_COPY_AND_ASSIGN(GuestViewManager);
};
diff --git a/components/guest_view/browser/test_guest_view_manager.cc b/components/guest_view/browser/test_guest_view_manager.cc
index c23399a..210e74f 100644
--- a/components/guest_view/browser/test_guest_view_manager.cc
+++ b/components/guest_view/browser/test_guest_view_manager.cc
@@ -113,9 +113,9 @@ void TestGuestViewManager::RemoveGuest(int guest_instance_id) {
GuestViewManager::RemoveGuest(guest_instance_id);
}
-void TestGuestViewManager::EmbedderWillBeDestroyed(int embedder_process_id) {
+void TestGuestViewManager::EmbedderProcessDestroyed(int embedder_process_id) {
++num_embedder_processes_destroyed_;
- GuestViewManager::EmbedderWillBeDestroyed(embedder_process_id);
+ GuestViewManager::EmbedderProcessDestroyed(embedder_process_id);
}
void TestGuestViewManager::ViewGarbageCollected(int embedder_process_id,
diff --git a/components/guest_view/browser/test_guest_view_manager.h b/components/guest_view/browser/test_guest_view_manager.h
index 5367737..4f6d201 100644
--- a/components/guest_view/browser/test_guest_view_manager.h
+++ b/components/guest_view/browser/test_guest_view_manager.h
@@ -80,7 +80,7 @@ class TestGuestViewManager : public GuestViewManager {
void AddGuest(int guest_instance_id,
content::WebContents* guest_web_contents) override;
void RemoveGuest(int guest_instance_id) override;
- void EmbedderWillBeDestroyed(int embedder_process_id) override;
+ void EmbedderProcessDestroyed(int embedder_process_id) override;
void ViewGarbageCollected(int embedder_process_id,
int view_instance_id) override;