1// Copyright (c) 2013 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "chrome/renderer/pepper/pepper_extensions_common_host.h" 6 7#include "base/logging.h" 8#include "base/memory/scoped_ptr.h" 9#include "base/values.h" 10#include "chrome/renderer/extensions/chrome_v8_context.h" 11#include "chrome/renderer/extensions/dispatcher.h" 12#include "chrome/renderer/extensions/extension_helper.h" 13#include "content/public/renderer/render_view.h" 14#include "content/public/renderer/renderer_ppapi_host.h" 15#include "ppapi/c/pp_errors.h" 16#include "ppapi/host/dispatch_host_message.h" 17#include "ppapi/host/host_message_context.h" 18#include "ppapi/host/ppapi_host.h" 19#include "ppapi/proxy/ppapi_messages.h" 20#include "third_party/WebKit/public/web/WebDocument.h" 21#include "third_party/WebKit/public/web/WebElement.h" 22#include "third_party/WebKit/public/web/WebFrame.h" 23#include "third_party/WebKit/public/web/WebPluginContainer.h" 24 25namespace chrome { 26 27PepperExtensionsCommonHost::PepperExtensionsCommonHost( 28 content::RendererPpapiHost* host, 29 PP_Instance instance, 30 PP_Resource resource, 31 extensions::Dispatcher* dispatcher) 32 : ResourceHost(host->GetPpapiHost(), instance, resource), 33 renderer_ppapi_host_(host), 34 dispatcher_(dispatcher) { 35} 36 37PepperExtensionsCommonHost::~PepperExtensionsCommonHost() { 38 dispatcher_->request_sender()->InvalidateSource(this); 39} 40 41// static 42PepperExtensionsCommonHost* PepperExtensionsCommonHost::Create( 43 content::RendererPpapiHost* host, 44 PP_Instance instance, 45 PP_Resource resource) { 46 content::RenderView* render_view = host->GetRenderViewForInstance(instance); 47 if (!render_view) 48 return NULL; 49 extensions::ExtensionHelper* extension_helper = 50 extensions::ExtensionHelper::Get(render_view); 51 if (!extension_helper) 52 return NULL; 53 extensions::Dispatcher* dispatcher = extension_helper->dispatcher(); 54 if (!dispatcher) 55 return NULL; 56 57 return new PepperExtensionsCommonHost(host, instance, resource, dispatcher); 58} 59 60int32_t PepperExtensionsCommonHost::OnResourceMessageReceived( 61 const IPC::Message& msg, 62 ppapi::host::HostMessageContext* context) { 63 IPC_BEGIN_MESSAGE_MAP(PepperExtensionsCommonHost, msg) 64 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_ExtensionsCommon_Post, 65 OnPost) 66 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_ExtensionsCommon_Call, 67 OnCall) 68 IPC_END_MESSAGE_MAP() 69 return PP_ERROR_FAILED; 70} 71 72extensions::ChromeV8Context* PepperExtensionsCommonHost::GetContext() { 73 WebKit::WebPluginContainer* container = 74 renderer_ppapi_host_->GetContainerForInstance(pp_instance()); 75 if (!container) 76 return NULL; 77 78 WebKit::WebFrame* frame = container->element().document().frame(); 79 v8::HandleScope scope; 80 return dispatcher_->v8_context_set().GetByV8Context( 81 frame->mainWorldScriptContext()); 82} 83 84void PepperExtensionsCommonHost::OnResponseReceived( 85 const std::string& /* name */, 86 int request_id, 87 bool success, 88 const base::ListValue& response, 89 const std::string& /* error */) { 90 PendingRequestMap::iterator iter = pending_request_map_.find(request_id); 91 92 // Ignore responses resulted from calls to OnPost(). 93 if (iter == pending_request_map_.end()) { 94 DCHECK_EQ(0u, response.GetSize()); 95 return; 96 } 97 98 linked_ptr<ppapi::host::ReplyMessageContext> context = iter->second; 99 pending_request_map_.erase(iter); 100 101 context->params.set_result(success ? PP_OK : PP_ERROR_FAILED); 102 SendReply(*context, PpapiPluginMsg_ExtensionsCommon_CallReply(response)); 103} 104 105int32_t PepperExtensionsCommonHost::OnPost( 106 ppapi::host::HostMessageContext* context, 107 const std::string& request_name, 108 base::ListValue& args) { 109 // TODO(yzshen): Add support for calling into JS for APIs that have custom 110 // bindings. 111 int request_id = dispatcher_->request_sender()->GetNextRequestId(); 112 dispatcher_->request_sender()->StartRequest(this, request_name, request_id, 113 false, false, &args); 114 return PP_OK; 115} 116 117int32_t PepperExtensionsCommonHost::OnCall( 118 ppapi::host::HostMessageContext* context, 119 const std::string& request_name, 120 base::ListValue& args) { 121 // TODO(yzshen): Add support for calling into JS for APIs that have custom 122 // bindings. 123 int request_id = dispatcher_->request_sender()->GetNextRequestId(); 124 pending_request_map_[request_id] = 125 linked_ptr<ppapi::host::ReplyMessageContext>( 126 new ppapi::host::ReplyMessageContext( 127 context->MakeReplyMessageContext())); 128 129 dispatcher_->request_sender()->StartRequest(this, request_name, request_id, 130 true, false, &args); 131 return PP_OK_COMPLETIONPENDING; 132} 133 134} // namespace chrome 135 136