Skip to content

Commit

Permalink
Decouple GuestViewContainer from Extensions
Browse files Browse the repository at this point in the history
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}
  • Loading branch information
fsamuel authored and Commit bot committed May 8, 2015
1 parent 5d8094a commit 7427a2f
Show file tree
Hide file tree
Showing 13 changed files with 389 additions and 327 deletions.
10 changes: 7 additions & 3 deletions chrome/renderer/chrome_content_renderer_client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1322,12 +1322,16 @@ bool ChromeContentRendererClient::ShouldFork(blink::WebFrame* frame,
return false;
}

#if defined(ENABLE_EXTENSIONS)
bool ChromeContentRendererClient::ShouldForwardToGuestContainer(
const IPC::Message& msg) {
return extensions::GuestViewContainer::HandlesMessage(msg);
}
if (IPC_MESSAGE_CLASS(msg) == GuestViewMsgStart)
return true;
#if defined(ENABLE_EXTENSIONS)
return IPC_MESSAGE_CLASS(msg) == ExtensionsGuestViewMsgStart;
#else
return false;
#endif
}

bool ChromeContentRendererClient::WillSendRequest(
blink::WebFrame* frame,
Expand Down
2 changes: 0 additions & 2 deletions chrome/renderer/chrome_content_renderer_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,7 @@ class ChromeContentRendererClient : public content::ContentRendererClient {
bool is_initial_navigation,
bool is_server_redirect,
bool* send_referrer) override;
#if defined(ENABLE_EXTENSIONS)
bool ShouldForwardToGuestContainer(const IPC::Message& msg) override;
#endif
bool WillSendRequest(blink::WebFrame* frame,
ui::PageTransition transition_type,
const GURL& url,
Expand Down
2 changes: 2 additions & 0 deletions extensions/extensions.gypi
Original file line number Diff line number Diff line change
Expand Up @@ -867,6 +867,8 @@
'renderer/guest_view/extensions_guest_view_container.h',
'renderer/guest_view/guest_view_container.cc',
'renderer/guest_view/guest_view_container.h',
'renderer/guest_view/guest_view_request.cc',
'renderer/guest_view/guest_view_request.h',
'renderer/guest_view/guest_view_internal_custom_bindings.cc',
'renderer/guest_view/guest_view_internal_custom_bindings.h',
'renderer/guest_view/mime_handler_view/mime_handler_view_container.cc',
Expand Down
202 changes: 1 addition & 201 deletions extensions/renderer/guest_view/extensions_guest_view_container.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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_);
Expand All @@ -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) {
Expand All @@ -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) {
Expand All @@ -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
79 changes: 0 additions & 79 deletions extensions/renderer/guest_view/extensions_guest_view_container.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand All @@ -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_;
Expand Down
Loading

0 comments on commit 7427a2f

Please sign in to comment.