ppb_broker_impl.cc revision bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3
1// Copyright (c) 2012 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 "content/renderer/pepper/ppb_broker_impl.h"
6
7#include "base/logging.h"
8#include "content/renderer/pepper/common.h"
9#include "content/renderer/pepper/plugin_module.h"
10#include "content/renderer/pepper/ppapi_plugin_instance_impl.h"
11#include "content/renderer/pepper/resource_helper.h"
12#include "ppapi/shared_impl/platform_file.h"
13#include "third_party/WebKit/public/web/WebDocument.h"
14#include "third_party/WebKit/public/web/WebElement.h"
15#include "third_party/WebKit/public/web/WebPluginContainer.h"
16
17using ppapi::PlatformFileToInt;
18using ppapi::thunk::PPB_Broker_API;
19using ppapi::TrackedCallback;
20
21namespace webkit {
22namespace ppapi {
23
24// PPB_Broker_Impl ------------------------------------------------------
25
26PPB_Broker_Impl::PPB_Broker_Impl(PP_Instance instance)
27    : Resource(::ppapi::OBJECT_IS_IMPL, instance),
28      broker_(NULL),
29      connect_callback_(),
30      pipe_handle_(PlatformFileToInt(base::kInvalidPlatformFileValue)) {
31}
32
33PPB_Broker_Impl::~PPB_Broker_Impl() {
34  if (broker_) {
35    broker_->Disconnect(this);
36    broker_ = NULL;
37  }
38
39  // The plugin owns the handle.
40  pipe_handle_ = PlatformFileToInt(base::kInvalidPlatformFileValue);
41}
42
43PPB_Broker_API* PPB_Broker_Impl::AsPPB_Broker_API() {
44  return this;
45}
46
47int32_t PPB_Broker_Impl::Connect(
48    scoped_refptr<TrackedCallback> connect_callback) {
49  // TODO(ddorwin): Return PP_ERROR_FAILED if plugin is in-process.
50
51  if (broker_) {
52    // May only be called once.
53    return PP_ERROR_FAILED;
54  }
55
56  PluginInstanceImpl* plugin_instance = ResourceHelper::GetPluginInstance(this);
57  if (!plugin_instance)
58    return PP_ERROR_FAILED;
59
60  // The callback must be populated now in case we are connected to the broker
61  // and BrokerConnected is called before ConnectToBroker returns.
62  // Because it must be created now, it must be aborted and cleared if
63  // ConnectToBroker fails.
64  connect_callback_ = connect_callback;
65
66  broker_ = plugin_instance->delegate()->ConnectToBroker(this);
67  if (!broker_) {
68    connect_callback_->Abort();
69    return PP_ERROR_FAILED;
70  }
71
72  return PP_OK_COMPLETIONPENDING;
73}
74
75int32_t PPB_Broker_Impl::GetHandle(int32_t* handle) {
76  if (pipe_handle_ == PlatformFileToInt(base::kInvalidPlatformFileValue))
77    return PP_ERROR_FAILED;  // Handle not set yet.
78  *handle = pipe_handle_;
79  return PP_OK;
80}
81
82GURL PPB_Broker_Impl::GetDocumentUrl() {
83  PluginInstanceImpl* plugin_instance = ResourceHelper::GetPluginInstance(this);
84  return plugin_instance->container()->element().document().url();
85}
86
87// Transfers ownership of the handle to the plugin.
88void PPB_Broker_Impl::BrokerConnected(int32_t handle, int32_t result) {
89  DCHECK(pipe_handle_ ==
90         PlatformFileToInt(base::kInvalidPlatformFileValue));
91  DCHECK(result == PP_OK ||
92         handle == PlatformFileToInt(base::kInvalidPlatformFileValue));
93
94  pipe_handle_ = handle;
95
96  // Synchronous calls are not supported.
97  DCHECK(TrackedCallback::IsPending(connect_callback_));
98
99  connect_callback_->Run(result);
100}
101
102}  // namespace ppapi
103}  // namespace webkit
104