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