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)
5558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "content/renderer/pepper/pepper_broker.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "build/build_config.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/renderer/pepper/pepper_proxy_channel_delegate_impl.h"
9bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "content/renderer/pepper/plugin_module.h"
10bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "content/renderer/pepper/ppb_broker_impl.h"
11558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "content/renderer/pepper/renderer_restrict_dispatch_group.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_channel_handle.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/proxy/broker_dispatcher.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/proxy/ppapi_messages.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/shared_impl/platform_file.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <windows.h>
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::SyncSocket::Handle DuplicateHandle(base::SyncSocket::Handle handle) {
2646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  base::SyncSocket::Handle out_handle = base::SyncSocket::kInvalidHandle;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DWORD options = DUPLICATE_SAME_ACCESS;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!::DuplicateHandle(::GetCurrentProcess(),
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         handle,
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         ::GetCurrentProcess(),
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         &out_handle,
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         0,
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         FALSE,
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         options)) {
3646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    out_handle = base::SyncSocket::kInvalidHandle;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_POSIX)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If asked to close the source, we can simply re-use the source fd instead of
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // dup()ing and close()ing.
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out_handle = ::dup(handle);
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
43a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#error Not implemented.
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return out_handle;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochPepperBrokerDispatcherWrapper::PepperBrokerDispatcherWrapper() {}
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochPepperBrokerDispatcherWrapper::~PepperBrokerDispatcherWrapper() {}
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PepperBrokerDispatcherWrapper::Init(
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::ProcessId broker_pid,
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const IPC::ChannelHandle& channel_handle) {
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (channel_handle.name.empty())
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_NE(-1, channel_handle.socket.fd);
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (channel_handle.socket.fd == -1)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dispatcher_delegate_.reset(new PepperProxyChannelDelegateImpl);
67a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  dispatcher_.reset(new ppapi::proxy::BrokerHostDispatcher());
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!dispatcher_->InitBrokerWithChannel(dispatcher_delegate_.get(),
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                          broker_pid,
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          channel_handle,
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          true)) {  // Client.
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dispatcher_.reset();
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dispatcher_delegate_.reset();
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dispatcher_->channel()->SetRestrictDispatchChannelGroup(
7858e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch      kRendererRestrictDispatchGroup_Pepper);
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Does not take ownership of the local pipe.
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int32_t PepperBrokerDispatcherWrapper::SendHandleToBroker(
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PP_Instance instance,
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::SyncSocket::Handle handle) {
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC::PlatformFileForTransit foreign_socket_handle =
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dispatcher_->ShareHandleWithRemote(handle, false);
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (foreign_socket_handle == IPC::InvalidPlatformFileForTransit())
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return PP_ERROR_FAILED;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int32_t result;
92a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  if (!dispatcher_->Send(new PpapiMsg_ConnectToPlugin(
93a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch          instance, foreign_socket_handle, &result))) {
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The plugin did not receive the handle, so it must be closed.
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The easiest way to clean it up is to just put it in an object
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // and then close it. This failure case is not performance critical.
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The handle could still leak if Send succeeded but the IPC later failed.
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::SyncSocket temp_socket(
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        IPC::PlatformFileForTransitToPlatformFile(foreign_socket_handle));
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return PP_ERROR_FAILED;
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1063240926e260ce088908e02ac07a6cf7b0c0cbf44Ben MurdochPepperBroker::PepperBroker(PluginModule* plugin_module)
1073240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    : plugin_module_(plugin_module) {
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(plugin_module_);
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  plugin_module_->SetBroker(this);
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochPepperBroker::~PepperBroker() {
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ReportFailureToClients(PP_ERROR_ABORTED);
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  plugin_module_->SetBroker(NULL);
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  plugin_module_ = NULL;
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// If the channel is not ready, queue the connection.
120558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid PepperBroker::AddPendingConnect(PPB_Broker_Impl* client) {
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(pending_connects_.find(client) == pending_connects_.end())
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      << "Connect was already called for this client";
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure this object and the associated broker exist as long as the
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // client exists. There is a corresponding Release() call in Disconnect(),
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // which is called when the PPB_Broker_Impl is destroyed. The only other
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // possible reference is in pending_connect_broker_, which only holds a
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // transient reference. This ensures the broker is available as long as the
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // plugin needs it and allows the plugin to release the broker when it is no
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // longer using it.
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddRef();
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pending_connects_[client].client = client->AsWeakPtr();
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
136558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid PepperBroker::Disconnect(PPB_Broker_Impl* client) {
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Remove the pending connect if one exists. This class will not call client's
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // callback.
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pending_connects_.erase(client);
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(ddorwin): Send message disconnect message using dispatcher_.
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Release the reference added in Connect().
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This must be the last statement because it may delete this object.
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Release();
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
148558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid PepperBroker::OnBrokerChannelConnected(
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::ProcessId broker_pid,
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const IPC::ChannelHandle& channel_handle) {
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<PepperBrokerDispatcherWrapper> dispatcher(
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new PepperBrokerDispatcherWrapper);
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!dispatcher->Init(broker_pid, channel_handle)) {
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ReportFailureToClients(PP_ERROR_FAILED);
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dispatcher_.reset(dispatcher.release());
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Process all pending channel requests from the plugins.
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (ClientMap::iterator i = pending_connects_.begin();
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       i != pending_connects_.end();) {
16358e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch    base::WeakPtr<PPB_Broker_Impl>& weak_ptr = i->second.client;
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!i->second.is_authorized) {
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ++i;
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
169868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (weak_ptr.get())
170868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      ConnectPluginToBroker(weak_ptr.get());
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pending_connects_.erase(i++);
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
176558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid PepperBroker::OnBrokerPermissionResult(PPB_Broker_Impl* client,
177558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                            bool result) {
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClientMap::iterator entry = pending_connects_.find(client);
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (entry == pending_connects_.end())
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
182868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!entry->second.client.get()) {
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Client has gone away.
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pending_connects_.erase(entry);
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!result) {
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Report failure.
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    client->BrokerConnected(
19146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        ppapi::PlatformFileToInt(base::SyncSocket::kInvalidHandle),
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        PP_ERROR_NOACCESS);
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pending_connects_.erase(entry);
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (dispatcher_) {
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ConnectPluginToBroker(client);
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pending_connects_.erase(entry);
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Mark the request as authorized, continue waiting for the broker
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // connection.
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!entry->second.is_authorized);
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry->second.is_authorized = true;
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
209a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochPepperBroker::PendingConnection::PendingConnection() : is_authorized(false) {}
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
211a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochPepperBroker::PendingConnection::~PendingConnection() {}
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
213558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid PepperBroker::ReportFailureToClients(int error_code) {
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_NE(PP_OK, error_code);
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (ClientMap::iterator i = pending_connects_.begin();
216a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch       i != pending_connects_.end();
217a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch       ++i) {
21858e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch    base::WeakPtr<PPB_Broker_Impl>& weak_ptr = i->second.client;
219868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (weak_ptr.get()) {
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      weak_ptr->BrokerConnected(
22146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          ppapi::PlatformFileToInt(base::SyncSocket::kInvalidHandle),
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          error_code);
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pending_connects_.clear();
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
228558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid PepperBroker::ConnectPluginToBroker(PPB_Broker_Impl* client) {
22946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  base::SyncSocket::Handle plugin_handle = base::SyncSocket::kInvalidHandle;
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int32_t result = PP_OK;
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The socket objects will be deleted when this function exits, closing the
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // handles. Any uses of the socket must duplicate them.
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<base::SyncSocket> broker_socket(new base::SyncSocket());
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<base::SyncSocket> plugin_socket(new base::SyncSocket());
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (base::SyncSocket::CreatePair(broker_socket.get(), plugin_socket.get())) {
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result = dispatcher_->SendHandleToBroker(client->pp_instance(),
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             broker_socket->handle());
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // If the broker has its pipe handle, duplicate the plugin's handle.
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Otherwise, the plugin's handle will be automatically closed.
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (result == PP_OK)
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      plugin_handle = DuplicateHandle(plugin_socket->handle());
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result = PP_ERROR_FAILED;
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TOOD(ddorwin): Change the IPC to asynchronous: Queue an object containing
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // client and plugin_socket.release(), then return.
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // That message handler will then call client->BrokerConnected() with the
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // saved pipe handle.
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Temporarily, just call back.
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  client->BrokerConnected(ppapi::PlatformFileToInt(plugin_handle), result);
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace content
257