Home | History | Annotate | Download | only in proxy
      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 
     18 using ppapi::thunk::PPB_Flash_MessageLoop_API;
     19 
     20 namespace ppapi {
     21 namespace proxy {
     22 namespace {
     23 
     24 class 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 
     42 FlashMessageLoop::FlashMessageLoop(const HostResource& resource)
     43     : Resource(OBJECT_IS_PROXY, resource) {
     44 }
     45 
     46 FlashMessageLoop::~FlashMessageLoop() {
     47 }
     48 
     49 PPB_Flash_MessageLoop_API* FlashMessageLoop::AsPPB_Flash_MessageLoop_API() {
     50   return this;
     51 }
     52 
     53 int32_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 
     62 void FlashMessageLoop::Quit() {
     63   PluginDispatcher::GetForResource(this)->Send(
     64       new PpapiHostMsg_PPBFlashMessageLoop_Quit(
     65           API_ID_PPB_FLASH_MESSAGELOOP, host_resource()));
     66 }
     67 
     68 void FlashMessageLoop::RunFromHostProxy(
     69     const RunFromHostProxyCallback& callback) {
     70   // This should never be called on the plugin side.
     71   NOTREACHED();
     72 }
     73 
     74 }  // namespace
     75 
     76 PPB_Flash_MessageLoop_Proxy::PPB_Flash_MessageLoop_Proxy(Dispatcher* dispatcher)
     77     : InterfaceProxy(dispatcher) {
     78 }
     79 
     80 PPB_Flash_MessageLoop_Proxy::~PPB_Flash_MessageLoop_Proxy() {
     81 }
     82 
     83 // static
     84 PP_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 
     98 bool 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 
    119 void 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 
    130 void 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 
    148 void 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 
    156 void 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