15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "content/renderer/pepper/ppb_broker_impl.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
83240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "content/common/view_messages.h"
92385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "content/renderer/pepper/host_globals.h"
10558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "content/renderer/pepper/pepper_broker.h"
1158e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch#include "content/renderer/pepper/pepper_plugin_instance_impl.h"
12bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "content/renderer/pepper/plugin_module.h"
133240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "content/renderer/render_thread_impl.h"
143240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "content/renderer/render_view_impl.h"
15d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "ppapi/c/pp_errors.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/shared_impl/platform_file.h"
177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebDocument.h"
187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebElement.h"
197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebPluginContainer.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ppapi::PlatformFileToInt;
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ppapi::thunk::PPB_Broker_API;
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ppapi::TrackedCallback;
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2558e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdochnamespace content {
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// PPB_Broker_Impl ------------------------------------------------------
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PPB_Broker_Impl::PPB_Broker_Impl(PP_Instance instance)
30ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    : Resource(ppapi::OBJECT_IS_IMPL, instance),
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      broker_(NULL),
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      connect_callback_(),
3346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      pipe_handle_(PlatformFileToInt(base::SyncSocket::kInvalidHandle)),
343240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      routing_id_(RenderThreadImpl::current()->GenerateRoutingID()) {
35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ChildThread::current()->GetRouter()->AddRoute(routing_id_, this);
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PPB_Broker_Impl::~PPB_Broker_Impl() {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (broker_) {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    broker_->Disconnect(this);
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    broker_ = NULL;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The plugin owns the handle.
4546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  pipe_handle_ = PlatformFileToInt(base::SyncSocket::kInvalidHandle);
46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ChildThread::current()->GetRouter()->RemoveRoute(routing_id_);
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochPPB_Broker_API* PPB_Broker_Impl::AsPPB_Broker_API() { return this; }
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int32_t PPB_Broker_Impl::Connect(
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<TrackedCallback> connect_callback) {
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(ddorwin): Return PP_ERROR_FAILED if plugin is in-process.
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (broker_) {
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // May only be called once.
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return PP_ERROR_FAILED;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6058e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch  PepperPluginInstanceImpl* plugin_instance =
612385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      HostGlobals::Get()->GetInstance(pp_instance());
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!plugin_instance)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return PP_ERROR_FAILED;
643240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  PluginModule* module = plugin_instance->module();
653240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  const base::FilePath& broker_path = module->path();
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The callback must be populated now in case we are connected to the broker
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and BrokerConnected is called before ConnectToBroker returns.
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Because it must be created now, it must be aborted and cleared if
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ConnectToBroker fails.
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  connect_callback_ = connect_callback;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
733240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  broker_ = module->GetBroker();
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!broker_) {
753240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    broker_ = new PepperBroker(module);
763240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
773240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    // Have the browser start the broker process for us.
78a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    RenderThreadImpl::current()->Send(
79a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        new ViewHostMsg_OpenChannelToPpapiBroker(routing_id_, broker_path));
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
823240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  RenderThreadImpl::current()->Send(
833240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      new ViewHostMsg_RequestPpapiBrokerPermission(
84a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          plugin_instance->render_frame()->render_view()->GetRoutingID(),
853240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch          routing_id_,
863240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch          GetDocumentUrl(),
873240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch          broker_path));
883240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
893240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Adds a reference, ensuring that the broker is not deleted when
903240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // |broker| goes out of scope.
913240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  broker_->AddPendingConnect(this);
923240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return PP_OK_COMPLETIONPENDING;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int32_t PPB_Broker_Impl::GetHandle(int32_t* handle) {
9746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (pipe_handle_ == PlatformFileToInt(base::SyncSocket::kInvalidHandle))
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return PP_ERROR_FAILED;  // Handle not set yet.
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *handle = pipe_handle_;
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return PP_OK;
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GURL PPB_Broker_Impl::GetDocumentUrl() {
10458e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch  PepperPluginInstanceImpl* plugin_instance =
1052385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      HostGlobals::Get()->GetInstance(pp_instance());
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return plugin_instance->container()->element().document().url();
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Transfers ownership of the handle to the plugin.
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PPB_Broker_Impl::BrokerConnected(int32_t handle, int32_t result) {
11146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(pipe_handle_ == PlatformFileToInt(base::SyncSocket::kInvalidHandle));
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(result == PP_OK ||
11346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)         handle == PlatformFileToInt(base::SyncSocket::kInvalidHandle));
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pipe_handle_ = handle;
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Synchronous calls are not supported.
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(TrackedCallback::IsPending(connect_callback_));
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  connect_callback_->Run(result);
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1233240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochbool PPB_Broker_Impl::OnMessageReceived(const IPC::Message& message) {
1243240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  bool handled = true;
1253240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  IPC_BEGIN_MESSAGE_MAP(PPB_Broker_Impl, message)
126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    IPC_MESSAGE_HANDLER(ViewMsg_PpapiBrokerChannelCreated,
127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                        OnPpapiBrokerChannelCreated)
128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    IPC_MESSAGE_HANDLER(ViewMsg_PpapiBrokerPermissionResult,
129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                        OnPpapiBrokerPermissionResult)
130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    IPC_MESSAGE_UNHANDLED(handled = false)
1313240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  IPC_END_MESSAGE_MAP()
1323240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  return handled;
1333240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}
1343240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
1353240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochvoid PPB_Broker_Impl::OnPpapiBrokerChannelCreated(
1363240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    base::ProcessId broker_pid,
1373240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    const IPC::ChannelHandle& handle) {
1383240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  broker_->OnBrokerChannelConnected(broker_pid, handle);
1393240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}
1403240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
1413240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochvoid PPB_Broker_Impl::OnPpapiBrokerPermissionResult(bool result) {
1423240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  broker_->OnBrokerPermissionResult(this, result);
1433240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}
1443240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
14558e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch}  // namespace content
146