ppp_messaging_proxy.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
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 "ppapi/proxy/ppp_messaging_proxy.h"
6
7#include <algorithm>
8
9#include "ppapi/c/ppp_messaging.h"
10#include "ppapi/proxy/host_dispatcher.h"
11#include "ppapi/proxy/plugin_resource_tracker.h"
12#include "ppapi/proxy/plugin_var_tracker.h"
13#include "ppapi/proxy/ppapi_messages.h"
14#include "ppapi/proxy/serialized_var.h"
15#include "ppapi/shared_impl/ppapi_globals.h"
16#include "ppapi/shared_impl/proxy_lock.h"
17#include "ppapi/shared_impl/var_tracker.h"
18
19namespace ppapi {
20namespace proxy {
21
22namespace {
23
24#if !defined(OS_NACL)
25void HandleMessage(PP_Instance instance, PP_Var message_data) {
26  HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance);
27  if (!dispatcher || (message_data.type == PP_VARTYPE_OBJECT)) {
28    // The dispatcher should always be valid, and the browser should never send
29    // an 'object' var over PPP_Messaging.
30    NOTREACHED();
31    return;
32  }
33
34  dispatcher->Send(new PpapiMsg_PPPMessaging_HandleMessage(
35      API_ID_PPP_MESSAGING,
36      instance,
37      SerializedVarSendInputShmem(dispatcher, message_data, instance)));
38}
39
40static const PPP_Messaging messaging_interface = {
41  &HandleMessage
42};
43#else
44// The NaCl plugin doesn't need the host side interface - stub it out.
45static const PPP_Messaging messaging_interface = {};
46#endif  // !defined(OS_NACL)
47
48InterfaceProxy* CreateMessagingProxy(Dispatcher* dispatcher) {
49  return new PPP_Messaging_Proxy(dispatcher);
50}
51
52}  // namespace
53
54PPP_Messaging_Proxy::PPP_Messaging_Proxy(Dispatcher* dispatcher)
55    : InterfaceProxy(dispatcher),
56      ppp_messaging_impl_(NULL) {
57  if (dispatcher->IsPlugin()) {
58    ppp_messaging_impl_ = static_cast<const PPP_Messaging*>(
59        dispatcher->local_get_interface()(PPP_MESSAGING_INTERFACE));
60  }
61}
62
63PPP_Messaging_Proxy::~PPP_Messaging_Proxy() {
64}
65
66// static
67const InterfaceProxy::Info* PPP_Messaging_Proxy::GetInfo() {
68  static const Info info = {
69    &messaging_interface,
70    PPP_MESSAGING_INTERFACE,
71    API_ID_PPP_MESSAGING,
72    false,
73    &CreateMessagingProxy,
74  };
75  return &info;
76}
77
78bool PPP_Messaging_Proxy::OnMessageReceived(const IPC::Message& msg) {
79  if (!dispatcher()->IsPlugin())
80    return false;
81
82  bool handled = true;
83  IPC_BEGIN_MESSAGE_MAP(PPP_Messaging_Proxy, msg)
84    IPC_MESSAGE_HANDLER(PpapiMsg_PPPMessaging_HandleMessage,
85                        OnMsgHandleMessage)
86    IPC_MESSAGE_UNHANDLED(handled = false)
87  IPC_END_MESSAGE_MAP()
88  return handled;
89}
90
91void PPP_Messaging_Proxy::OnMsgHandleMessage(
92    PP_Instance instance, SerializedVarReceiveInput message_data) {
93  PP_Var received_var(message_data.GetForInstance(dispatcher(), instance));
94  // SerializedVarReceiveInput will decrement the reference count, but we want
95  // to give the recipient a reference.
96  PpapiGlobals::Get()->GetVarTracker()->AddRefVar(received_var);
97  CallWhileUnlocked(ppp_messaging_impl_->HandleMessage,
98                    instance,
99                    received_var);
100}
101
102}  // namespace proxy
103}  // namespace ppapi
104