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