summaryrefslogtreecommitdiffstats
path: root/extensions/renderer/guest_view
diff options
context:
space:
mode:
authorfsamuel <fsamuel@chromium.org>2015-05-08 10:27:17 -0700
committerCommit bot <commit-bot@chromium.org>2015-05-08 17:27:37 +0000
commit7427a2fea91dcd0331628297cc08a33eb1765ad2 (patch)
treefc7d42eacd945ef071d3cf52ccfe05e3250c0d13 /extensions/renderer/guest_view
parent5d8094a323492b3cb1439e6c69fc0851f330757a (diff)
downloadchromium_src-7427a2fea91dcd0331628297cc08a33eb1765ad2.zip
chromium_src-7427a2fea91dcd0331628297cc08a33eb1765ad2.tar.gz
chromium_src-7427a2fea91dcd0331628297cc08a33eb1765ad2.tar.bz2
Decouple GuestViewContainer from Extensions
This CL does the following: 1. It moves ExtensionsGuestViewContainer::Request/AttachRequest/DetachRequest to guest_view_request.* 2. It moves the queuing functionality for attach/detach to guest_view_container.* 3. It removes extensions dependencies in guest_view_container A subsequent patch will move extensions/this to components. BUG=444869 Review URL: https://codereview.chromium.org/1118243003 Cr-Commit-Position: refs/heads/master@{#328974}
Diffstat (limited to 'extensions/renderer/guest_view')
-rw-r--r--extensions/renderer/guest_view/extensions_guest_view_container.cc202
-rw-r--r--extensions/renderer/guest_view/extensions_guest_view_container.h79
-rw-r--r--extensions/renderer/guest_view/guest_view_container.cc94
-rw-r--r--extensions/renderer/guest_view/guest_view_container.h41
-rw-r--r--extensions/renderer/guest_view/guest_view_internal_custom_bindings.cc27
-rw-r--r--extensions/renderer/guest_view/guest_view_request.cc123
-rw-r--r--extensions/renderer/guest_view/guest_view_request.h97
-rw-r--r--extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container.cc29
-rw-r--r--extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container.h6
9 files changed, 377 insertions, 321 deletions
diff --git a/extensions/renderer/guest_view/extensions_guest_view_container.cc b/extensions/renderer/guest_view/extensions_guest_view_container.cc
index 5b43598..358f800 100644
--- a/extensions/renderer/guest_view/extensions_guest_view_container.cc
+++ b/extensions/renderer/guest_view/extensions_guest_view_container.cc
@@ -4,157 +4,21 @@
#include "extensions/renderer/guest_view/extensions_guest_view_container.h"
-#include "components/guest_view/common/guest_view_constants.h"
-#include "components/guest_view/common/guest_view_messages.h"
#include "content/public/renderer/render_frame.h"
-#include "content/public/renderer/render_view.h"
-#include "third_party/WebKit/public/web/WebLocalFrame.h"
#include "third_party/WebKit/public/web/WebScopedMicrotaskSuppression.h"
-#include "third_party/WebKit/public/web/WebView.h"
-
-namespace {
-typedef std::map<int, extensions::ExtensionsGuestViewContainer*>
- ExtensionsGuestViewContainerMap;
-static base::LazyInstance<ExtensionsGuestViewContainerMap>
- g_guest_view_container_map = LAZY_INSTANCE_INITIALIZER;
-} // namespace
+#include "ui/gfx/geometry/size.h"
namespace extensions {
-ExtensionsGuestViewContainer::Request::Request(GuestViewContainer* container,
- v8::Local<v8::Function> callback,
- v8::Isolate* isolate)
- : container_(container), callback_(isolate, callback), isolate_(isolate) {
-}
-
-ExtensionsGuestViewContainer::Request::~Request() {
-}
-
-bool ExtensionsGuestViewContainer::Request::HasCallback() const {
- return !callback_.IsEmpty();
-}
-
-v8::Local<v8::Function> ExtensionsGuestViewContainer::Request::GetCallback()
- const {
- return v8::Local<v8::Function>::New(isolate_, callback_);
-}
-
-void ExtensionsGuestViewContainer::Request::ExecuteCallbackIfAvailable(
- int argc,
- scoped_ptr<v8::Local<v8::Value>[]> argv) {
- if (!HasCallback())
- return;
-
- v8::HandleScope handle_scope(isolate());
- v8::Local<v8::Function> callback = GetCallback();
- v8::Local<v8::Context> context = callback->CreationContext();
- if (context.IsEmpty())
- return;
-
- v8::Context::Scope context_scope(context);
- blink::WebScopedMicrotaskSuppression suppression;
-
- // Call the AttachGuest API's callback with the guest proxy as the first
- // parameter.
- callback->Call(context->Global(), argc, argv.get());
-}
-
-ExtensionsGuestViewContainer::AttachRequest::AttachRequest(
- GuestViewContainer* container,
- int guest_instance_id,
- scoped_ptr<base::DictionaryValue> params,
- v8::Local<v8::Function> callback,
- v8::Isolate* isolate)
- : Request(container, callback, isolate),
- guest_instance_id_(guest_instance_id),
- params_(params.Pass()) {
-}
-
-ExtensionsGuestViewContainer::AttachRequest::~AttachRequest() {
-}
-
-void ExtensionsGuestViewContainer::AttachRequest::PerformRequest() {
- if (!container()->render_frame())
- return;
-
- // Step 1, send the attach params to extensions/.
- container()->render_frame()->Send(
- new GuestViewHostMsg_AttachGuest(container()->element_instance_id(),
- guest_instance_id_,
- *params_));
-
- // Step 2, attach plugin through content/.
- container()->render_frame()->AttachGuest(container()->element_instance_id());
-}
-
-void ExtensionsGuestViewContainer::AttachRequest::HandleResponse(
- const IPC::Message& message) {
- GuestViewMsg_GuestAttached::Param param;
- if (!GuestViewMsg_GuestAttached::Read(&message, &param))
- return;
-
- content::RenderView* guest_proxy_render_view =
- content::RenderView::FromRoutingID(get<1>(param));
- // TODO(fsamuel): Should we be reporting an error to JavaScript or DCHECKing?
- if (!guest_proxy_render_view)
- return;
-
- v8::HandleScope handle_scope(isolate());
- blink::WebFrame* frame = guest_proxy_render_view->GetWebView()->mainFrame();
- v8::Local<v8::Value> window = frame->mainWorldScriptContext()->Global();
-
- const int argc = 1;
- scoped_ptr<v8::Local<v8::Value>[]> argv(new v8::Local<v8::Value>[argc]);
- argv[0] = window;
-
- ExecuteCallbackIfAvailable(argc, argv.Pass());
-}
-
-ExtensionsGuestViewContainer::DetachRequest::DetachRequest(
- GuestViewContainer* container,
- v8::Local<v8::Function> callback,
- v8::Isolate* isolate)
- : Request(container, callback, isolate) {
-}
-
-ExtensionsGuestViewContainer::DetachRequest::~DetachRequest() {
-}
-
-void ExtensionsGuestViewContainer::DetachRequest::PerformRequest() {
- if (!container()->render_frame())
- return;
-
- container()->render_frame()->DetachGuest(container()->element_instance_id());
-}
-
-void ExtensionsGuestViewContainer::DetachRequest::HandleResponse(
- const IPC::Message& message) {
- ExecuteCallbackIfAvailable(0 /* argc */, nullptr);
-}
-
ExtensionsGuestViewContainer::ExtensionsGuestViewContainer(
content::RenderFrame* render_frame)
: GuestViewContainer(render_frame),
- ready_(false),
destruction_isolate_(nullptr),
element_resize_isolate_(nullptr),
weak_ptr_factory_(this) {
}
ExtensionsGuestViewContainer::~ExtensionsGuestViewContainer() {
- if (element_instance_id() != guest_view::kInstanceIDNone)
- g_guest_view_container_map.Get().erase(element_instance_id());
-
- if (pending_response_.get())
- pending_response_->ExecuteCallbackIfAvailable(0 /* argc */, nullptr);
-
- while (pending_requests_.size() > 0) {
- linked_ptr<Request> pending_request = pending_requests_.front();
- pending_requests_.pop_front();
- // Call the JavaScript callbacks with no arguments which implies an error.
- pending_request->ExecuteCallbackIfAvailable(0 /* argc */, nullptr);
- }
-
// Call the destruction callback, if one is registered.
if (!destruction_callback_.IsEmpty()) {
v8::HandleScope handle_scope(destruction_isolate_);
@@ -171,19 +35,6 @@ ExtensionsGuestViewContainer::~ExtensionsGuestViewContainer() {
}
}
-ExtensionsGuestViewContainer* ExtensionsGuestViewContainer::FromID(
- int element_instance_id) {
- ExtensionsGuestViewContainerMap* guest_view_containers =
- g_guest_view_container_map.Pointer();
- auto it = guest_view_containers->find(element_instance_id);
- return it == guest_view_containers->end() ? nullptr : it->second;
-}
-
-void ExtensionsGuestViewContainer::IssueRequest(linked_ptr<Request> request) {
- EnqueueRequest(request);
- PerformPendingRequest();
-}
-
void ExtensionsGuestViewContainer::RegisterDestructionCallback(
v8::Local<v8::Function> callback,
v8::Isolate* isolate) {
@@ -210,36 +61,6 @@ void ExtensionsGuestViewContainer::DidResizeElement(const gfx::Size& old_size,
weak_ptr_factory_.GetWeakPtr(), old_size, new_size));
}
-bool ExtensionsGuestViewContainer::OnMessageReceived(
- const IPC::Message& message) {
- OnHandleCallback(message);
- return true;
-}
-
-void ExtensionsGuestViewContainer::SetElementInstanceID(
- int element_instance_id) {
- GuestViewContainer::SetElementInstanceID(element_instance_id);
-
- DCHECK(g_guest_view_container_map.Get().find(element_instance_id) ==
- g_guest_view_container_map.Get().end());
- g_guest_view_container_map.Get().insert(
- std::make_pair(element_instance_id, this));
-}
-
-void ExtensionsGuestViewContainer::Ready() {
- ready_ = true;
- CHECK(!pending_response_.get());
- PerformPendingRequest();
-}
-
-void ExtensionsGuestViewContainer::OnHandleCallback(
- const IPC::Message& message) {
- // Handle the callback for the current request with a pending response.
- HandlePendingResponseCallback(message);
- // Perform the subsequent attach request if one exists.
- PerformPendingRequest();
-}
-
void ExtensionsGuestViewContainer::CallElementResizeCallback(
const gfx::Size& old_size,
const gfx::Size& new_size) {
@@ -263,25 +84,4 @@ void ExtensionsGuestViewContainer::CallElementResizeCallback(
callback->Call(context->Global(), argc, argv);
}
-void ExtensionsGuestViewContainer::EnqueueRequest(linked_ptr<Request> request) {
- pending_requests_.push_back(request);
-}
-
-void ExtensionsGuestViewContainer::PerformPendingRequest() {
- if (!ready_ || pending_requests_.empty() || pending_response_.get())
- return;
-
- linked_ptr<Request> pending_request = pending_requests_.front();
- pending_requests_.pop_front();
- pending_request->PerformRequest();
- pending_response_ = pending_request;
-}
-
-void ExtensionsGuestViewContainer::HandlePendingResponseCallback(
- const IPC::Message& message) {
- CHECK(pending_response_.get());
- linked_ptr<Request> pending_response(pending_response_.release());
- pending_response->HandleResponse(message);
-}
-
} // namespace extensions
diff --git a/extensions/renderer/guest_view/extensions_guest_view_container.h b/extensions/renderer/guest_view/extensions_guest_view_container.h
index f1a6622..0a29daf 100644
--- a/extensions/renderer/guest_view/extensions_guest_view_container.h
+++ b/extensions/renderer/guest_view/extensions_guest_view_container.h
@@ -7,9 +7,6 @@
#include <queue>
-#include "base/memory/linked_ptr.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/values.h"
#include "extensions/renderer/guest_view/guest_view_container.h"
#include "v8/include/v8.h"
@@ -21,97 +18,21 @@ namespace extensions {
class ExtensionsGuestViewContainer : public GuestViewContainer {
public:
-
- class Request {
- public:
- Request(GuestViewContainer* container,
- v8::Local<v8::Function> callback,
- v8::Isolate* isolate);
- virtual ~Request();
-
- virtual void PerformRequest() = 0;
- virtual void HandleResponse(const IPC::Message& message) = 0;
-
- void ExecuteCallbackIfAvailable(int argc,
- scoped_ptr<v8::Local<v8::Value>[]> argv);
-
- GuestViewContainer* container() const { return container_; }
-
- bool HasCallback() const;
-
- v8::Local<v8::Function> GetCallback() const;
-
- v8::Isolate* isolate() const { return isolate_; }
-
- private:
- GuestViewContainer* container_;
- v8::Global<v8::Function> callback_;
- v8::Isolate* const isolate_;
- };
-
- // This class represents an AttachGuest request from Javascript. It includes
- // the input parameters and the callback function. The Attach operation may
- // not execute immediately, if the container is not ready or if there are
- // other attach operations in flight.
- class AttachRequest : public Request {
- public:
- AttachRequest(GuestViewContainer* container,
- int guest_instance_id,
- scoped_ptr<base::DictionaryValue> params,
- v8::Local<v8::Function> callback,
- v8::Isolate* isolate);
- ~AttachRequest() override;
-
- void PerformRequest() override;
- void HandleResponse(const IPC::Message& message) override;
-
- private:
- const int guest_instance_id_;
- scoped_ptr<base::DictionaryValue> params_;
- };
-
- class DetachRequest : public Request {
- public:
- DetachRequest(GuestViewContainer* container,
- v8::Local<v8::Function> callback,
- v8::Isolate* isolate);
- ~DetachRequest() override;
-
- void PerformRequest() override;
- void HandleResponse(const IPC::Message& message) override;
- };
-
explicit ExtensionsGuestViewContainer(content::RenderFrame* render_frame);
~ExtensionsGuestViewContainer() override;
- static ExtensionsGuestViewContainer* FromID(int element_instance_id);
-
- void IssueRequest(linked_ptr<Request> request);
void RegisterDestructionCallback(v8::Local<v8::Function> callback,
v8::Isolate* isolate);
void RegisterElementResizeCallback(v8::Local<v8::Function> callback,
v8::Isolate* isolate);
// BrowserPluginDelegate implementation.
- bool OnMessageReceived(const IPC::Message& message) override;
- void SetElementInstanceID(int element_instance_id) override;
- void Ready() override;
void DidResizeElement(const gfx::Size& old_size,
const gfx::Size& new_size) override;
private:
- void OnHandleCallback(const IPC::Message& message);
-
void CallElementResizeCallback(const gfx::Size& old_size,
const gfx::Size& new_size);
- void EnqueueRequest(linked_ptr<Request> request);
- void PerformPendingRequest();
- void HandlePendingResponseCallback(const IPC::Message& message);
-
- bool ready_;
-
- std::deque<linked_ptr<Request> > pending_requests_;
- linked_ptr<Request> pending_response_;
v8::Global<v8::Function> destruction_callback_;
v8::Isolate* destruction_isolate_;
diff --git a/extensions/renderer/guest_view/guest_view_container.cc b/extensions/renderer/guest_view/guest_view_container.cc
index be6316d..d09fa00 100644
--- a/extensions/renderer/guest_view/guest_view_container.cc
+++ b/extensions/renderer/guest_view/guest_view_container.cc
@@ -10,6 +10,15 @@
#include "content/public/renderer/render_frame_observer.h"
#include "content/public/renderer/render_view.h"
#include "extensions/common/guest_view/extensions_guest_view_messages.h"
+#include "extensions/renderer/guest_view/guest_view_request.h"
+
+namespace {
+
+using GuestViewContainerMap = std::map<int, extensions::GuestViewContainer*>;
+static base::LazyInstance<GuestViewContainerMap> g_guest_view_container_map =
+ LAZY_INSTANCE_INITIALIZER;
+
+} // namespace
namespace extensions {
@@ -40,17 +49,33 @@ void GuestViewContainer::RenderFrameLifetimeObserver::OnDestruct() {
GuestViewContainer::GuestViewContainer(content::RenderFrame* render_frame)
: element_instance_id_(guest_view::kInstanceIDNone),
- render_frame_(render_frame) {
+ render_frame_(render_frame),
+ ready_(false) {
render_frame_lifetime_observer_.reset(
new RenderFrameLifetimeObserver(this, render_frame_));
}
-GuestViewContainer::~GuestViewContainer() {}
+GuestViewContainer::~GuestViewContainer() {
+ if (element_instance_id() != guest_view::kInstanceIDNone)
+ g_guest_view_container_map.Get().erase(element_instance_id());
+
+ if (pending_response_.get())
+ pending_response_->ExecuteCallbackIfAvailable(0 /* argc */, nullptr);
+
+ while (pending_requests_.size() > 0) {
+ linked_ptr<GuestViewRequest> pending_request = pending_requests_.front();
+ pending_requests_.pop_front();
+ // Call the JavaScript callbacks with no arguments which implies an error.
+ pending_request->ExecuteCallbackIfAvailable(0 /* argc */, nullptr);
+ }
+}
// static.
-bool GuestViewContainer::HandlesMessage(const IPC::Message& msg) {
- return (IPC_MESSAGE_CLASS(msg) == GuestViewMsgStart) ||
- (IPC_MESSAGE_CLASS(msg) == ExtensionsGuestViewMsgStart);
+GuestViewContainer* GuestViewContainer::FromID(int element_instance_id) {
+ GuestViewContainerMap* guest_view_containers =
+ g_guest_view_container_map.Pointer();
+ auto it = guest_view_containers->find(element_instance_id);
+ return it == guest_view_containers->end() ? nullptr : it->second;
}
void GuestViewContainer::RenderFrameDestroyed() {
@@ -58,9 +83,68 @@ void GuestViewContainer::RenderFrameDestroyed() {
render_frame_ = nullptr;
}
+void GuestViewContainer::IssueRequest(linked_ptr<GuestViewRequest> request) {
+ EnqueueRequest(request);
+ PerformPendingRequest();
+}
+
+void GuestViewContainer::EnqueueRequest(linked_ptr<GuestViewRequest> request) {
+ pending_requests_.push_back(request);
+}
+
+void GuestViewContainer::PerformPendingRequest() {
+ if (!ready_ || pending_requests_.empty() || pending_response_.get())
+ return;
+
+ linked_ptr<GuestViewRequest> pending_request = pending_requests_.front();
+ pending_requests_.pop_front();
+ pending_request->PerformRequest();
+ pending_response_ = pending_request;
+}
+
+void GuestViewContainer::HandlePendingResponseCallback(
+ const IPC::Message& message) {
+ CHECK(pending_response_.get());
+ linked_ptr<GuestViewRequest> pending_response(pending_response_.release());
+ pending_response->HandleResponse(message);
+}
+
+void GuestViewContainer::OnHandleCallback(const IPC::Message& message) {
+ // Handle the callback for the current request with a pending response.
+ HandlePendingResponseCallback(message);
+ // Perform the subsequent request if one exists.
+ PerformPendingRequest();
+}
+
+bool GuestViewContainer::OnMessage(const IPC::Message& message) {
+ return false;
+}
+
+bool GuestViewContainer::OnMessageReceived(const IPC::Message& message) {
+ if (OnMessage(message))
+ return true;
+
+ OnHandleCallback(message);
+ return true;
+}
+
+void GuestViewContainer::Ready() {
+ ready_ = true;
+ CHECK(!pending_response_.get());
+ PerformPendingRequest();
+
+ // Give the derived type an opportunity to perform some actions when the
+ // container acquires a geometry.
+ OnReady();
+}
+
void GuestViewContainer::SetElementInstanceID(int element_instance_id) {
DCHECK_EQ(element_instance_id_, guest_view::kInstanceIDNone);
element_instance_id_ = element_instance_id;
+
+ DCHECK(!g_guest_view_container_map.Get().count(element_instance_id));
+ g_guest_view_container_map.Get().insert(
+ std::make_pair(element_instance_id, this));
}
} // namespace extensions
diff --git a/extensions/renderer/guest_view/guest_view_container.h b/extensions/renderer/guest_view/guest_view_container.h
index 42ec6e14..8855dd7 100644
--- a/extensions/renderer/guest_view/guest_view_container.h
+++ b/extensions/renderer/guest_view/guest_view_container.h
@@ -5,37 +5,66 @@
#ifndef EXTENSIONS_RENDERER_GUEST_VIEW_GUEST_VIEW_CONTAINER_H_
#define EXTENSIONS_RENDERER_GUEST_VIEW_GUEST_VIEW_CONTAINER_H_
+#include "base/memory/linked_ptr.h"
#include "base/memory/scoped_ptr.h"
#include "content/public/renderer/browser_plugin_delegate.h"
#include "ipc/ipc_message.h"
namespace extensions {
+class GuestViewRequest;
+
class GuestViewContainer : public content::BrowserPluginDelegate {
public:
explicit GuestViewContainer(content::RenderFrame* render_frame);
~GuestViewContainer() override;
- // Queries whether GuestViewContainer is interested in the |message|.
- static bool HandlesMessage(const IPC::Message& message);
-
- void RenderFrameDestroyed();
+ static GuestViewContainer* FromID(int element_instance_id);
- // BrowserPluginDelegate implementation.
- void SetElementInstanceID(int element_instance_id) override;
+ // IssueRequest queues up a |request| until the container is ready and
+ // the browser process has responded to the last request if it's still
+ // pending.
+ void IssueRequest(linked_ptr<GuestViewRequest> request);
int element_instance_id() const { return element_instance_id_; }
content::RenderFrame* render_frame() const { return render_frame_; }
+ // Called when the embedding RenderFrame is destroyed.
virtual void OnRenderFrameDestroyed() {}
+ // Called to respond to IPCs from the browser process that have not been
+ // handled by GuestViewContainer.
+ virtual bool OnMessage(const IPC::Message& message);
+
+ // Called to perform actions when a GuestViewContainer gets a geometry.
+ virtual void OnReady() {}
+
private:
class RenderFrameLifetimeObserver;
+ friend class RenderFrameLifetimeObserver;
+
+ void RenderFrameDestroyed();
+
+ void EnqueueRequest(linked_ptr<GuestViewRequest> request);
+ void PerformPendingRequest();
+ void HandlePendingResponseCallback(const IPC::Message& message);
+
+ void OnHandleCallback(const IPC::Message& message);
+
+ // BrowserPluginDelegate implementation.
+ bool OnMessageReceived(const IPC::Message& message) final;
+ void Ready() final;
+ void SetElementInstanceID(int element_instance_id) final;
int element_instance_id_;
content::RenderFrame* render_frame_;
scoped_ptr<RenderFrameLifetimeObserver> render_frame_lifetime_observer_;
+ bool ready_;
+
+ std::deque<linked_ptr<GuestViewRequest> > pending_requests_;
+ linked_ptr<GuestViewRequest> pending_response_;
+
DISALLOW_COPY_AND_ASSIGN(GuestViewContainer);
};
diff --git a/extensions/renderer/guest_view/guest_view_internal_custom_bindings.cc b/extensions/renderer/guest_view/guest_view_internal_custom_bindings.cc
index 9f8d952..902465f 100644
--- a/extensions/renderer/guest_view/guest_view_internal_custom_bindings.cc
+++ b/extensions/renderer/guest_view/guest_view_internal_custom_bindings.cc
@@ -13,6 +13,7 @@
#include "extensions/common/extension.h"
#include "extensions/common/extension_messages.h"
#include "extensions/renderer/guest_view/extensions_guest_view_container.h"
+#include "extensions/renderer/guest_view/guest_view_request.h"
#include "extensions/renderer/script_context.h"
#include "third_party/WebKit/public/web/WebFrame.h"
#include "third_party/WebKit/public/web/WebScopedUserGesture.h"
@@ -64,9 +65,8 @@ void GuestViewInternalCustomBindings::AttachGuest(
CHECK(args.Length() < 4 || args[3]->IsFunction());
int element_instance_id = args[0]->Int32Value();
- // An element instance ID uniquely identifies a ExtensionsGuestViewContainer.
- ExtensionsGuestViewContainer* guest_view_container =
- ExtensionsGuestViewContainer::FromID(element_instance_id);
+ // An element instance ID uniquely identifies a GuestViewContainer.
+ auto guest_view_container = GuestViewContainer::FromID(element_instance_id);
// TODO(fsamuel): Should we be reporting an error if the element instance ID
// is invalid?
@@ -89,8 +89,8 @@ void GuestViewInternalCustomBindings::AttachGuest(
// logical units.
params->SetBoolean(guest_view::kElementSizeIsLogical, true);
- linked_ptr<ExtensionsGuestViewContainer::Request> request(
- new ExtensionsGuestViewContainer::AttachRequest(
+ linked_ptr<GuestViewRequest> request(
+ new GuestViewAttachRequest(
guest_view_container, guest_instance_id, params.Pass(),
args.Length() == 4 ? args[3].As<v8::Function>()
: v8::Local<v8::Function>(),
@@ -110,17 +110,16 @@ void GuestViewInternalCustomBindings::DetachGuest(
CHECK(args.Length() < 2 || args[1]->IsFunction());
int element_instance_id = args[0]->Int32Value();
- // An element instance ID uniquely identifies a ExtensionsGuestViewContainer.
- ExtensionsGuestViewContainer* guest_view_container =
- ExtensionsGuestViewContainer::FromID(element_instance_id);
+ // An element instance ID uniquely identifies a GuestViewContainer.
+ auto guest_view_container = GuestViewContainer::FromID(element_instance_id);
// TODO(fsamuel): Should we be reporting an error if the element instance ID
// is invalid?
if (!guest_view_container)
return;
- linked_ptr<ExtensionsGuestViewContainer::Request> request(
- new ExtensionsGuestViewContainer::DetachRequest(
+ linked_ptr<GuestViewRequest> request(
+ new GuestViewDetachRequest(
guest_view_container, args.Length() == 2 ? args[1].As<v8::Function>()
: v8::Local<v8::Function>(),
args.GetIsolate()));
@@ -166,8 +165,8 @@ void GuestViewInternalCustomBindings::RegisterDestructionCallback(
int element_instance_id = args[0]->Int32Value();
// An element instance ID uniquely identifies a ExtensionsGuestViewContainer
// within a RenderView.
- ExtensionsGuestViewContainer* guest_view_container =
- ExtensionsGuestViewContainer::FromID(element_instance_id);
+ auto guest_view_container = static_cast<ExtensionsGuestViewContainer*>(
+ GuestViewContainer::FromID(element_instance_id));
if (!guest_view_container)
return;
@@ -189,8 +188,8 @@ void GuestViewInternalCustomBindings::RegisterElementResizeCallback(
int element_instance_id = args[0]->Int32Value();
// An element instance ID uniquely identifies a ExtensionsGuestViewContainer
// within a RenderView.
- ExtensionsGuestViewContainer* guest_view_container =
- ExtensionsGuestViewContainer::FromID(element_instance_id);
+ auto guest_view_container = static_cast<ExtensionsGuestViewContainer*>(
+ GuestViewContainer::FromID(element_instance_id));
if (!guest_view_container)
return;
diff --git a/extensions/renderer/guest_view/guest_view_request.cc b/extensions/renderer/guest_view/guest_view_request.cc
new file mode 100644
index 0000000..78251d9
--- /dev/null
+++ b/extensions/renderer/guest_view/guest_view_request.cc
@@ -0,0 +1,123 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "extensions/renderer/guest_view/guest_view_request.h"
+
+#include "components/guest_view/common/guest_view_messages.h"
+#include "content/public/renderer/render_frame.h"
+#include "content/public/renderer/render_view.h"
+#include "extensions/renderer/guest_view/guest_view_container.h"
+#include "third_party/WebKit/public/web/WebLocalFrame.h"
+#include "third_party/WebKit/public/web/WebScopedMicrotaskSuppression.h"
+#include "third_party/WebKit/public/web/WebView.h"
+
+namespace extensions {
+
+GuestViewRequest::GuestViewRequest(GuestViewContainer* container,
+ v8::Local<v8::Function> callback,
+ v8::Isolate* isolate)
+ : container_(container),
+ callback_(isolate, callback),
+ isolate_(isolate) {
+}
+
+GuestViewRequest::~GuestViewRequest() {
+}
+
+void GuestViewRequest::ExecuteCallbackIfAvailable(
+ int argc,
+ scoped_ptr<v8::Local<v8::Value>[]> argv) {
+ if (callback_.IsEmpty())
+ return;
+
+ v8::HandleScope handle_scope(isolate());
+ v8::Local<v8::Function> callback =
+ v8::Local<v8::Function>::New(isolate_, callback_);
+ v8::Local<v8::Context> context = callback->CreationContext();
+ if (context.IsEmpty())
+ return;
+
+ v8::Context::Scope context_scope(context);
+ blink::WebScopedMicrotaskSuppression suppression;
+
+ callback->Call(context->Global(), argc, argv.get());
+}
+
+GuestViewAttachRequest::GuestViewAttachRequest(
+ GuestViewContainer* container,
+ int guest_instance_id,
+ scoped_ptr<base::DictionaryValue> params,
+ v8::Local<v8::Function> callback,
+ v8::Isolate* isolate)
+ : GuestViewRequest(container, callback, isolate),
+ guest_instance_id_(guest_instance_id),
+ params_(params.Pass()) {
+}
+
+GuestViewAttachRequest::~GuestViewAttachRequest() {
+}
+
+void GuestViewAttachRequest::PerformRequest() {
+ if (!container()->render_frame())
+ return;
+
+ // Step 1, send the attach params to extensions/.
+ container()->render_frame()->Send(
+ new GuestViewHostMsg_AttachGuest(container()->element_instance_id(),
+ guest_instance_id_,
+ *params_));
+
+ // Step 2, attach plugin through content/.
+ container()->render_frame()->AttachGuest(container()->element_instance_id());
+}
+
+void GuestViewAttachRequest::HandleResponse(const IPC::Message& message) {
+ // TODO(fsamuel): Rename this message so that it's apparent that this is a
+ // response to GuestViewHostMsg_AttachGuest. Perhaps
+ // GuestViewMsg_AttachGuest_ACK?
+ GuestViewMsg_GuestAttached::Param param;
+ if (!GuestViewMsg_GuestAttached::Read(&message, &param))
+ return;
+
+ content::RenderView* guest_proxy_render_view =
+ content::RenderView::FromRoutingID(get<1>(param));
+ // TODO(fsamuel): Should we be reporting an error to JavaScript or DCHECKing?
+ if (!guest_proxy_render_view)
+ return;
+
+ v8::HandleScope handle_scope(isolate());
+ blink::WebFrame* frame = guest_proxy_render_view->GetWebView()->mainFrame();
+ v8::Local<v8::Value> window = frame->mainWorldScriptContext()->Global();
+
+ const int argc = 1;
+ scoped_ptr<v8::Local<v8::Value>[]> argv(new v8::Local<v8::Value>[argc]);
+ argv[0] = window;
+
+ // Call the AttachGuest API's callback with the guest proxy as the first
+ // parameter.
+ ExecuteCallbackIfAvailable(argc, argv.Pass());
+}
+
+GuestViewDetachRequest::GuestViewDetachRequest(
+ GuestViewContainer* container,
+ v8::Local<v8::Function> callback,
+ v8::Isolate* isolate)
+ : GuestViewRequest(container, callback, isolate) {
+}
+
+GuestViewDetachRequest::~GuestViewDetachRequest() {
+}
+
+void GuestViewDetachRequest::PerformRequest() {
+ if (!container()->render_frame())
+ return;
+
+ container()->render_frame()->DetachGuest(container()->element_instance_id());
+}
+
+void GuestViewDetachRequest::HandleResponse(const IPC::Message& message) {
+ ExecuteCallbackIfAvailable(0 /* argc */, nullptr);
+}
+
+} // namespace extensions
diff --git a/extensions/renderer/guest_view/guest_view_request.h b/extensions/renderer/guest_view/guest_view_request.h
new file mode 100644
index 0000000..dbb7343
--- /dev/null
+++ b/extensions/renderer/guest_view/guest_view_request.h
@@ -0,0 +1,97 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef EXTENSIONS_RENDERER_GUEST_VIEW_EXTENSIONS_GUEST_VIEW_REQUEST_H_
+#define EXTENSIONS_RENDERER_GUEST_VIEW_EXTENSIONS_GUEST_VIEW_REQUEST_H_
+
+#include "ipc/ipc_message.h"
+#include "v8/include/v8.h"
+
+namespace extensions {
+
+class GuestViewContainer;
+
+// A GuestViewRequest is the base class for an asynchronous operation performed
+// on a GuestView or GuestViewContainer from JavaScript. This operation may be
+// queued until the container is ready to be operated upon (it has geometry).
+// A GuestViewRequest may or may not have a callback back into JavaScript.
+// Typically, performing a request involves sending an IPC to the browser
+// process in PerformRequest. Handling a response involves receiving a related
+// IPC from the browser process in HandleResponse.
+class GuestViewRequest {
+ public:
+ GuestViewRequest(GuestViewContainer* container,
+ v8::Local<v8::Function> callback,
+ v8::Isolate* isolate);
+ virtual ~GuestViewRequest();
+
+ // Performs the associated request.
+ virtual void PerformRequest() = 0;
+
+ // Called by GuestViewContainer when the browser process has responded to the
+ // request initiated by PerformRequest.
+ virtual void HandleResponse(const IPC::Message& message) = 0;
+
+ // Called to call the callback associated with this request if one is
+ // available.
+ // Note: the callback may be called even if a response has not been heard from
+ // the browser process if the GuestViewContainer is being torn down.
+ void ExecuteCallbackIfAvailable(int argc,
+ scoped_ptr<v8::Local<v8::Value>[]> argv);
+
+ GuestViewContainer* container() const { return container_; }
+
+ v8::Isolate* isolate() const { return isolate_; }
+
+ private:
+ GuestViewContainer* const container_;
+ v8::Global<v8::Function> callback_;
+ v8::Isolate* const isolate_;
+
+ DISALLOW_COPY_AND_ASSIGN(GuestViewRequest);
+};
+
+// This class represents an AttachGuest request from Javascript. It includes
+// the input parameters and the callback function. The Attach operation may
+// not execute immediately, if the container is not ready or if there are
+// other GuestViewRequests in flight.
+class GuestViewAttachRequest : public GuestViewRequest {
+ public:
+ GuestViewAttachRequest(GuestViewContainer* container,
+ int guest_instance_id,
+ scoped_ptr<base::DictionaryValue> params,
+ v8::Local<v8::Function> callback,
+ v8::Isolate* isolate);
+ ~GuestViewAttachRequest() override;
+
+ void PerformRequest() override;
+ void HandleResponse(const IPC::Message& message) override;
+
+ private:
+ const int guest_instance_id_;
+ scoped_ptr<base::DictionaryValue> params_;
+
+ DISALLOW_COPY_AND_ASSIGN(GuestViewAttachRequest);
+};
+
+// This class represents a DetachGuest request from Javascript. The Detach
+// operation may not execute immediately, if the container is not ready or if
+// there are other GuestViewRequests in flight.
+class GuestViewDetachRequest : public GuestViewRequest {
+ public:
+ GuestViewDetachRequest(GuestViewContainer* container,
+ v8::Local<v8::Function> callback,
+ v8::Isolate* isolate);
+ ~GuestViewDetachRequest() override;
+
+ void PerformRequest() override;
+ void HandleResponse(const IPC::Message& message) override;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(GuestViewDetachRequest);
+};
+
+} // namespace extensions
+
+#endif // EXTENSIONS_RENDERER_GUEST_VIEW_EXTENSIONS_GUEST_VIEW_CONTAINER_H_
diff --git a/extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container.cc b/extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container.cc
index 67add24..812f381 100644
--- a/extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container.cc
+++ b/extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container.cc
@@ -129,7 +129,7 @@ MimeHandlerViewContainer::FromRenderFrame(content::RenderFrame* render_frame) {
it->second.end());
}
-void MimeHandlerViewContainer::Ready() {
+void MimeHandlerViewContainer::OnReady() {
if (!render_frame())
return;
@@ -148,6 +148,20 @@ void MimeHandlerViewContainer::Ready() {
loader_->loadAsynchronously(request, this);
}
+bool MimeHandlerViewContainer::OnMessage(const IPC::Message& message) {
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(MimeHandlerViewContainer, message)
+ IPC_MESSAGE_HANDLER(ExtensionsGuestViewMsg_CreateMimeHandlerViewGuestACK,
+ OnCreateMimeHandlerViewGuestACK)
+ IPC_MESSAGE_HANDLER(
+ ExtensionsGuestViewMsg_MimeHandlerViewGuestOnLoadCompleted,
+ OnMimeHandlerViewGuestOnLoadCompleted)
+ IPC_MESSAGE_HANDLER(GuestViewMsg_GuestAttached, OnGuestAttached)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ return handled;
+}
+
void MimeHandlerViewContainer::DidFinishLoading() {
DCHECK(!is_embedded_);
CreateMimeHandlerViewGuest();
@@ -162,19 +176,6 @@ void MimeHandlerViewContainer::DidReceiveData(const char* data,
view_id_ += std::string(data, data_length);
}
-bool MimeHandlerViewContainer::OnMessageReceived(const IPC::Message& message) {
- bool handled = true;
- IPC_BEGIN_MESSAGE_MAP(MimeHandlerViewContainer, message)
- IPC_MESSAGE_HANDLER(ExtensionsGuestViewMsg_CreateMimeHandlerViewGuestACK,
- OnCreateMimeHandlerViewGuestACK)
- IPC_MESSAGE_HANDLER(
- ExtensionsGuestViewMsg_MimeHandlerViewGuestOnLoadCompleted,
- OnMimeHandlerViewGuestOnLoadCompleted)
- IPC_MESSAGE_HANDLER(GuestViewMsg_GuestAttached, OnGuestAttached)
- IPC_MESSAGE_UNHANDLED(handled = false)
- IPC_END_MESSAGE_MAP()
- return handled;
-}
void MimeHandlerViewContainer::DidResizeElement(const gfx::Size& old_size,
const gfx::Size& new_size) {
diff --git a/extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container.h b/extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container.h
index b08f1c9..00f0211 100644
--- a/extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container.h
+++ b/extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container.h
@@ -46,13 +46,15 @@ class MimeHandlerViewContainer : public GuestViewContainer,
static std::vector<MimeHandlerViewContainer*> FromRenderFrame(
content::RenderFrame* render_frame);
+ // GuestViewContainer implementation.
+ bool OnMessage(const IPC::Message& message) override;
+ void OnReady() override;
+
// BrowserPluginDelegate implementation.
- void Ready() override;
void DidFinishLoading() override;
void DidReceiveData(const char* data, int data_length) override;
void DidResizeElement(const gfx::Size& old_size,
const gfx::Size& new_size) override;
- bool OnMessageReceived(const IPC::Message& message) override;
v8::Local<v8::Object> V8ScriptableObject(v8::Isolate*) override;
// WebURLLoaderClient overrides.