summaryrefslogtreecommitdiffstats
path: root/components/guest_view
diff options
context:
space:
mode:
authorfsamuel <fsamuel@chromium.org>2015-05-28 09:29:54 -0700
committerCommit bot <commit-bot@chromium.org>2015-05-28 16:30:23 +0000
commitaf5bf6d16b1248654b940eb7337ef9734b384604 (patch)
treeb6836917479c80558eb90a97c80f43b068b8498a /components/guest_view
parentd5f30a32be8b582cb7dc8c2f918b7d0247df01ef (diff)
downloadchromium_src-af5bf6d16b1248654b940eb7337ef9734b384604.zip
chromium_src-af5bf6d16b1248654b940eb7337ef9734b384604.tar.gz
chromium_src-af5bf6d16b1248654b940eb7337ef9734b384604.tar.bz2
Move GuestViewContainer to components
BUG=444869 Review URL: https://codereview.chromium.org/1129173007 Cr-Commit-Position: refs/heads/master@{#331796}
Diffstat (limited to 'components/guest_view')
-rw-r--r--components/guest_view/browser/BUILD.gn (renamed from components/guest_view/BUILD.gn)12
-rw-r--r--components/guest_view/common/BUILD.gn15
-rw-r--r--components/guest_view/renderer/BUILD.gn17
-rw-r--r--components/guest_view/renderer/DEPS6
-rw-r--r--components/guest_view/renderer/OWNERS3
-rw-r--r--components/guest_view/renderer/guest_view_container.cc149
-rw-r--r--components/guest_view/renderer/guest_view_container.h73
-rw-r--r--components/guest_view/renderer/guest_view_request.cc123
-rw-r--r--components/guest_view/renderer/guest_view_request.h97
9 files changed, 487 insertions, 8 deletions
diff --git a/components/guest_view/BUILD.gn b/components/guest_view/browser/BUILD.gn
index 0beda18..7bc221f 100644
--- a/components/guest_view/BUILD.gn
+++ b/components/guest_view/browser/BUILD.gn
@@ -2,8 +2,8 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-static_library("guest_view") {
- output_name = "guest_view"
+static_library("browser") {
+ output_name = "guest_view_browser"
sources = [
"//components/guest_view/browser/guest_view.h",
"//components/guest_view/browser/guest_view_base.cc",
@@ -17,15 +17,11 @@ static_library("guest_view") {
"//components/guest_view/browser/guest_view_manager_factory.h",
"//components/guest_view/browser/guest_view_message_filter.cc",
"//components/guest_view/browser/guest_view_message_filter.h",
- "//components/guest_view/common/guest_view_constants.cc",
- "//components/guest_view/common/guest_view_constants.h",
- "//components/guest_view/common/guest_view_message_generator.cc",
- "//components/guest_view/common/guest_view_message_generator.h",
- "//components/guest_view/common/guest_view_messages.h",
]
deps = [
"//base",
+ "//components/guest_view/common",
"//content/public/browser",
"//content/public/common",
"//third_party/WebKit/public:blink",
@@ -40,7 +36,7 @@ static_library("test_support") {
]
deps = [
- ":guest_view",
+ ":browser",
"//content/test:test_support",
]
}
diff --git a/components/guest_view/common/BUILD.gn b/components/guest_view/common/BUILD.gn
new file mode 100644
index 0000000..9916d95a
--- /dev/null
+++ b/components/guest_view/common/BUILD.gn
@@ -0,0 +1,15 @@
+static_library("common") {
+ output_name = "guest_view_common"
+ sources = [
+ "guest_view_constants.cc",
+ "guest_view_constants.h",
+ "guest_view_message_generator.cc",
+ "guest_view_message_generator.h",
+ "guest_view_messages.h",
+ ]
+
+ deps = [
+ "//base",
+ "//ipc",
+ ]
+}
diff --git a/components/guest_view/renderer/BUILD.gn b/components/guest_view/renderer/BUILD.gn
new file mode 100644
index 0000000..200070b
--- /dev/null
+++ b/components/guest_view/renderer/BUILD.gn
@@ -0,0 +1,17 @@
+static_library("renderer") {
+ sources = [
+ "guest_view_container.cc",
+ "guest_view_container.h",
+ "guest_view_request.cc",
+ "guest_view_request.h"
+ ]
+
+ deps = [
+ "//base",
+ "//components/guest_view/common",
+ "//content/public/renderer",
+ "//ipc",
+ "//third_party/WebKit/public:blink",
+ "//v8",
+ ]
+}
diff --git a/components/guest_view/renderer/DEPS b/components/guest_view/renderer/DEPS
new file mode 100644
index 0000000..2f9ba27
--- /dev/null
+++ b/components/guest_view/renderer/DEPS
@@ -0,0 +1,6 @@
+include_rules = [
+ "+content/public/renderer",
+ "+ipc",
+ "+third_party/WebKit/public",
+ "+v8/include/v8.h",
+]
diff --git a/components/guest_view/renderer/OWNERS b/components/guest_view/renderer/OWNERS
new file mode 100644
index 0000000..f9575e8
--- /dev/null
+++ b/components/guest_view/renderer/OWNERS
@@ -0,0 +1,3 @@
+fsamuel@chromium.org
+lazyboy@chromium.org
+hanxi@chromium.org
diff --git a/components/guest_view/renderer/guest_view_container.cc b/components/guest_view/renderer/guest_view_container.cc
new file mode 100644
index 0000000..1c13456
--- /dev/null
+++ b/components/guest_view/renderer/guest_view_container.cc
@@ -0,0 +1,149 @@
+// Copyright 2014 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 "components/guest_view/renderer/guest_view_container.h"
+
+#include "components/guest_view/common/guest_view_constants.h"
+#include "components/guest_view/common/guest_view_messages.h"
+#include "components/guest_view/renderer/guest_view_request.h"
+#include "content/public/renderer/render_frame.h"
+#include "content/public/renderer/render_frame_observer.h"
+#include "content/public/renderer/render_view.h"
+
+namespace {
+
+using GuestViewContainerMap = std::map<int, guest_view::GuestViewContainer*>;
+static base::LazyInstance<GuestViewContainerMap> g_guest_view_container_map =
+ LAZY_INSTANCE_INITIALIZER;
+
+} // namespace
+
+namespace guest_view {
+
+class GuestViewContainer::RenderFrameLifetimeObserver
+ : public content::RenderFrameObserver {
+ public:
+ RenderFrameLifetimeObserver(GuestViewContainer* container,
+ content::RenderFrame* render_frame);
+
+ // content::RenderFrameObserver overrides.
+ void OnDestruct() override;
+
+ private:
+ GuestViewContainer* container_;
+
+ DISALLOW_COPY_AND_ASSIGN(RenderFrameLifetimeObserver);
+};
+
+GuestViewContainer::RenderFrameLifetimeObserver::RenderFrameLifetimeObserver(
+ GuestViewContainer* container,
+ content::RenderFrame* render_frame)
+ : content::RenderFrameObserver(render_frame),
+ container_(container) {}
+
+void GuestViewContainer::RenderFrameLifetimeObserver::OnDestruct() {
+ container_->RenderFrameDestroyed();
+}
+
+GuestViewContainer::GuestViewContainer(content::RenderFrame* render_frame)
+ : element_instance_id_(guest_view::kInstanceIDNone),
+ render_frame_(render_frame),
+ ready_(false) {
+ render_frame_lifetime_observer_.reset(
+ new RenderFrameLifetimeObserver(this, render_frame_));
+}
+
+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.
+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() {
+ OnRenderFrameDestroyed();
+ 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 guest_view
diff --git a/components/guest_view/renderer/guest_view_container.h b/components/guest_view/renderer/guest_view_container.h
new file mode 100644
index 0000000..19175b9c
--- /dev/null
+++ b/components/guest_view/renderer/guest_view_container.h
@@ -0,0 +1,73 @@
+// Copyright 2014 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 COMPONENTS_GUEST_VIEW_RENDERER_GUEST_VIEW_CONTAINER_H_
+#define COMPONENTS_GUEST_VIEW_RENDERER_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 guest_view {
+
+class GuestViewRequest;
+
+class GuestViewContainer : public content::BrowserPluginDelegate {
+ public:
+ explicit GuestViewContainer(content::RenderFrame* render_frame);
+ ~GuestViewContainer() override;
+
+ static GuestViewContainer* FromID(int element_instance_id);
+
+ // 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);
+};
+
+} // namespace guest_view
+
+#endif // COMPONENTS_GUEST_VIEW_RENDERER_GUEST_VIEW_CONTAINER_H_
diff --git a/components/guest_view/renderer/guest_view_request.cc b/components/guest_view/renderer/guest_view_request.cc
new file mode 100644
index 0000000..902429c
--- /dev/null
+++ b/components/guest_view/renderer/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 "components/guest_view/renderer/guest_view_request.h"
+
+#include "components/guest_view/common/guest_view_messages.h"
+#include "components/guest_view/renderer/guest_view_container.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 guest_view {
+
+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 guest_view/.
+ 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 guest_view
diff --git a/components/guest_view/renderer/guest_view_request.h b/components/guest_view/renderer/guest_view_request.h
new file mode 100644
index 0000000..222c7dd
--- /dev/null
+++ b/components/guest_view/renderer/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 COMPONENTS_GUEST_VIEW_RENDERER_GUEST_VIEW_REQUEST_H_
+#define COMPONENTS_GUEST_VIEW_RENDERER_GUEST_VIEW_REQUEST_H_
+
+#include "ipc/ipc_message.h"
+#include "v8/include/v8.h"
+
+namespace guest_view {
+
+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 guest_view
+
+#endif // COMPONENTS_GUEST_VIEW_RENDERER_GUEST_VIEW_CONTAINER_H_