ppb_flash_message_loop_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/ppb_flash_message_loop_proxy.h"
6
7#include "base/bind.h"
8#include "ppapi/c/pp_errors.h"
9#include "ppapi/c/private/ppb_flash_message_loop.h"
10#include "ppapi/proxy/enter_proxy.h"
11#include "ppapi/proxy/plugin_dispatcher.h"
12#include "ppapi/proxy/ppapi_messages.h"
13#include "ppapi/shared_impl/resource.h"
14#include "ppapi/thunk/enter.h"
15#include "ppapi/thunk/ppb_flash_message_loop_api.h"
16#include "ppapi/thunk/resource_creation_api.h"
17
18using ppapi::thunk::PPB_Flash_MessageLoop_API;
19
20namespace ppapi {
21namespace proxy {
22namespace {
23
24class FlashMessageLoop : public PPB_Flash_MessageLoop_API, public Resource {
25 public:
26  explicit FlashMessageLoop(const HostResource& resource);
27  virtual ~FlashMessageLoop();
28
29  // Resource overrides.
30  virtual PPB_Flash_MessageLoop_API* AsPPB_Flash_MessageLoop_API() OVERRIDE;
31
32  // PPB_Flash_MesssageLoop_API implementation.
33  virtual int32_t Run() OVERRIDE;
34  virtual void Quit() OVERRIDE;
35  virtual void RunFromHostProxy(
36      const RunFromHostProxyCallback& callback) OVERRIDE;
37
38 private:
39  DISALLOW_COPY_AND_ASSIGN(FlashMessageLoop);
40};
41
42FlashMessageLoop::FlashMessageLoop(const HostResource& resource)
43    : Resource(OBJECT_IS_PROXY, resource) {
44}
45
46FlashMessageLoop::~FlashMessageLoop() {
47}
48
49PPB_Flash_MessageLoop_API* FlashMessageLoop::AsPPB_Flash_MessageLoop_API() {
50  return this;
51}
52
53int32_t FlashMessageLoop::Run() {
54  int32_t result = PP_ERROR_FAILED;
55  IPC::SyncMessage* msg = new PpapiHostMsg_PPBFlashMessageLoop_Run(
56      API_ID_PPB_FLASH_MESSAGELOOP, host_resource(), &result);
57  msg->EnableMessagePumping();
58  PluginDispatcher::GetForResource(this)->Send(msg);
59  return result;
60}
61
62void FlashMessageLoop::Quit() {
63  PluginDispatcher::GetForResource(this)->Send(
64      new PpapiHostMsg_PPBFlashMessageLoop_Quit(
65          API_ID_PPB_FLASH_MESSAGELOOP, host_resource()));
66}
67
68void FlashMessageLoop::RunFromHostProxy(
69    const RunFromHostProxyCallback& callback) {
70  // This should never be called on the plugin side.
71  NOTREACHED();
72}
73
74}  // namespace
75
76PPB_Flash_MessageLoop_Proxy::PPB_Flash_MessageLoop_Proxy(Dispatcher* dispatcher)
77    : InterfaceProxy(dispatcher) {
78}
79
80PPB_Flash_MessageLoop_Proxy::~PPB_Flash_MessageLoop_Proxy() {
81}
82
83// static
84PP_Resource PPB_Flash_MessageLoop_Proxy::CreateProxyResource(
85    PP_Instance instance) {
86  PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance);
87  if (!dispatcher)
88    return 0;
89
90  HostResource result;
91  dispatcher->Send(new PpapiHostMsg_PPBFlashMessageLoop_Create(
92      API_ID_PPB_FLASH_MESSAGELOOP, instance, &result));
93  if (result.is_null())
94    return 0;
95  return (new FlashMessageLoop(result))->GetReference();
96}
97
98bool PPB_Flash_MessageLoop_Proxy::OnMessageReceived(const IPC::Message& msg) {
99  if (!dispatcher()->permissions().HasPermission(PERMISSION_FLASH))
100    return false;
101
102  bool handled = true;
103  IPC_BEGIN_MESSAGE_MAP(PPB_Flash_MessageLoop_Proxy, msg)
104    IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFlashMessageLoop_Create,
105                        OnMsgCreate)
106    // We cannot use IPC_MESSAGE_HANDLER here. Because it tries to send the sync
107    // message reply after the handler returns. However, in this case, the
108    // PPB_Flash_MessageLoop_Proxy object may be destroyed before the handler
109    // returns.
110    IPC_MESSAGE_HANDLER_DELAY_REPLY(PpapiHostMsg_PPBFlashMessageLoop_Run,
111                                    OnMsgRun)
112    IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFlashMessageLoop_Quit,
113                        OnMsgQuit)
114    IPC_MESSAGE_UNHANDLED(handled = false)
115  IPC_END_MESSAGE_MAP()
116  return handled;
117}
118
119void PPB_Flash_MessageLoop_Proxy::OnMsgCreate(PP_Instance instance,
120                                              HostResource* result) {
121  if (!dispatcher()->permissions().HasPermission(PERMISSION_FLASH))
122    return;
123  thunk::EnterResourceCreation enter(instance);
124  if (enter.succeeded()) {
125    result->SetHostResource(
126        instance, enter.functions()->CreateFlashMessageLoop(instance));
127  }
128}
129
130void PPB_Flash_MessageLoop_Proxy::OnMsgRun(
131    const HostResource& flash_message_loop,
132    IPC::Message* reply) {
133  if (!dispatcher()->permissions().HasPermission(PERMISSION_FLASH))
134    return;
135
136  PPB_Flash_MessageLoop_API::RunFromHostProxyCallback callback =
137      base::Bind(&PPB_Flash_MessageLoop_Proxy::WillQuitSoon, AsWeakPtr(),
138                 base::Passed(scoped_ptr<IPC::Message>(reply)));
139
140  EnterHostFromHostResource<PPB_Flash_MessageLoop_API>
141      enter(flash_message_loop);
142  if (enter.succeeded())
143    enter.object()->RunFromHostProxy(callback);
144  else
145    callback.Run(PP_ERROR_BADRESOURCE);
146}
147
148void PPB_Flash_MessageLoop_Proxy::OnMsgQuit(
149    const ppapi::HostResource& flash_message_loop) {
150  EnterHostFromHostResource<PPB_Flash_MessageLoop_API>
151      enter(flash_message_loop);
152  if (enter.succeeded())
153    enter.object()->Quit();
154}
155
156void PPB_Flash_MessageLoop_Proxy::WillQuitSoon(
157    scoped_ptr<IPC::Message> reply_message,
158    int32_t result) {
159  PpapiHostMsg_PPBFlashMessageLoop_Run::WriteReplyParams(reply_message.get(),
160                                                         result);
161  Send(reply_message.release());
162}
163
164}  // namespace proxy
165}  // namespace ppapi
166