| // Copyright (c) 2013 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 "chrome/renderer/pepper/pepper_extensions_common_host.h" |
| |
| #include "base/logging.h" |
| #include "base/memory/scoped_ptr.h" |
| #include "base/values.h" |
| #include "chrome/renderer/extensions/chrome_v8_context.h" |
| #include "chrome/renderer/extensions/dispatcher.h" |
| #include "chrome/renderer/extensions/extension_helper.h" |
| #include "content/public/renderer/render_view.h" |
| #include "content/public/renderer/renderer_ppapi_host.h" |
| #include "ppapi/c/pp_errors.h" |
| #include "ppapi/host/dispatch_host_message.h" |
| #include "ppapi/host/host_message_context.h" |
| #include "ppapi/host/ppapi_host.h" |
| #include "ppapi/proxy/ppapi_messages.h" |
| #include "third_party/WebKit/public/web/WebDocument.h" |
| #include "third_party/WebKit/public/web/WebElement.h" |
| #include "third_party/WebKit/public/web/WebFrame.h" |
| #include "third_party/WebKit/public/web/WebPluginContainer.h" |
| |
| PepperExtensionsCommonHost::PepperExtensionsCommonHost( |
| content::RendererPpapiHost* host, |
| PP_Instance instance, |
| PP_Resource resource, |
| extensions::Dispatcher* dispatcher) |
| : ResourceHost(host->GetPpapiHost(), instance, resource), |
| renderer_ppapi_host_(host), |
| dispatcher_(dispatcher) { |
| } |
| |
| PepperExtensionsCommonHost::~PepperExtensionsCommonHost() { |
| dispatcher_->request_sender()->InvalidateSource(this); |
| } |
| |
| // static |
| PepperExtensionsCommonHost* PepperExtensionsCommonHost::Create( |
| content::RendererPpapiHost* host, |
| PP_Instance instance, |
| PP_Resource resource) { |
| content::RenderView* render_view = host->GetRenderViewForInstance(instance); |
| if (!render_view) |
| return NULL; |
| extensions::ExtensionHelper* extension_helper = |
| extensions::ExtensionHelper::Get(render_view); |
| if (!extension_helper) |
| return NULL; |
| extensions::Dispatcher* dispatcher = extension_helper->dispatcher(); |
| if (!dispatcher) |
| return NULL; |
| |
| return new PepperExtensionsCommonHost(host, instance, resource, dispatcher); |
| } |
| |
| int32_t PepperExtensionsCommonHost::OnResourceMessageReceived( |
| const IPC::Message& msg, |
| ppapi::host::HostMessageContext* context) { |
| IPC_BEGIN_MESSAGE_MAP(PepperExtensionsCommonHost, msg) |
| PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_ExtensionsCommon_Post, |
| OnPost) |
| PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_ExtensionsCommon_Call, |
| OnCall) |
| IPC_END_MESSAGE_MAP() |
| return PP_ERROR_FAILED; |
| } |
| |
| extensions::ChromeV8Context* PepperExtensionsCommonHost::GetContext() { |
| WebKit::WebPluginContainer* container = |
| renderer_ppapi_host_->GetContainerForInstance(pp_instance()); |
| if (!container) |
| return NULL; |
| |
| WebKit::WebFrame* frame = container->element().document().frame(); |
| v8::HandleScope scope(v8::Isolate::GetCurrent()); |
| return dispatcher_->v8_context_set().GetByV8Context( |
| frame->mainWorldScriptContext()); |
| } |
| |
| void PepperExtensionsCommonHost::OnResponseReceived( |
| const std::string& /* name */, |
| int request_id, |
| bool success, |
| const base::ListValue& response, |
| const std::string& /* error */) { |
| PendingRequestMap::iterator iter = pending_request_map_.find(request_id); |
| |
| // Ignore responses resulted from calls to OnPost(). |
| if (iter == pending_request_map_.end()) { |
| DCHECK_EQ(0u, response.GetSize()); |
| return; |
| } |
| |
| linked_ptr<ppapi::host::ReplyMessageContext> context = iter->second; |
| pending_request_map_.erase(iter); |
| |
| context->params.set_result(success ? PP_OK : PP_ERROR_FAILED); |
| SendReply(*context, PpapiPluginMsg_ExtensionsCommon_CallReply(response)); |
| } |
| |
| int32_t PepperExtensionsCommonHost::OnPost( |
| ppapi::host::HostMessageContext* context, |
| const std::string& request_name, |
| base::ListValue& args) { |
| // TODO(yzshen): Add support for calling into JS for APIs that have custom |
| // bindings. |
| int request_id = dispatcher_->request_sender()->GetNextRequestId(); |
| dispatcher_->request_sender()->StartRequest(this, request_name, request_id, |
| false, false, &args); |
| return PP_OK; |
| } |
| |
| int32_t PepperExtensionsCommonHost::OnCall( |
| ppapi::host::HostMessageContext* context, |
| const std::string& request_name, |
| base::ListValue& args) { |
| // TODO(yzshen): Add support for calling into JS for APIs that have custom |
| // bindings. |
| int request_id = dispatcher_->request_sender()->GetNextRequestId(); |
| pending_request_map_[request_id] = |
| linked_ptr<ppapi::host::ReplyMessageContext>( |
| new ppapi::host::ReplyMessageContext( |
| context->MakeReplyMessageContext())); |
| |
| dispatcher_->request_sender()->StartRequest(this, request_name, request_id, |
| true, false, &args); |
| return PP_OK_COMPLETIONPENDING; |
| } |