15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/proxy/ppb_flash_message_loop_proxy.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/pp_errors.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/private/ppb_flash_message_loop.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/proxy/enter_proxy.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/proxy/plugin_dispatcher.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/proxy/ppapi_messages.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/shared_impl/resource.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/thunk/enter.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/thunk/ppb_flash_message_loop_api.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/thunk/resource_creation_api.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ppapi::thunk::PPB_Flash_MessageLoop_API;
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ppapi {
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace proxy {
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class FlashMessageLoop : public PPB_Flash_MessageLoop_API, public Resource {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit FlashMessageLoop(const HostResource& resource);
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~FlashMessageLoop();
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Resource overrides.
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual PPB_Flash_MessageLoop_API* AsPPB_Flash_MessageLoop_API() OVERRIDE;
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // PPB_Flash_MesssageLoop_API implementation.
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int32_t Run() OVERRIDE;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Quit() OVERRIDE;
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void RunFromHostProxy(
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const RunFromHostProxyCallback& callback) OVERRIDE;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FlashMessageLoop);
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FlashMessageLoop::FlashMessageLoop(const HostResource& resource)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : Resource(OBJECT_IS_PROXY, resource) {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FlashMessageLoop::~FlashMessageLoop() {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PPB_Flash_MessageLoop_API* FlashMessageLoop::AsPPB_Flash_MessageLoop_API() {
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return this;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int32_t FlashMessageLoop::Run() {
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int32_t result = PP_ERROR_FAILED;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC::SyncMessage* msg = new PpapiHostMsg_PPBFlashMessageLoop_Run(
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      API_ID_PPB_FLASH_MESSAGELOOP, host_resource(), &result);
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  msg->EnableMessagePumping();
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PluginDispatcher::GetForResource(this)->Send(msg);
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FlashMessageLoop::Quit() {
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PluginDispatcher::GetForResource(this)->Send(
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new PpapiHostMsg_PPBFlashMessageLoop_Quit(
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          API_ID_PPB_FLASH_MESSAGELOOP, host_resource()));
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FlashMessageLoop::RunFromHostProxy(
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const RunFromHostProxyCallback& callback) {
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This should never be called on the plugin side.
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED();
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PPB_Flash_MessageLoop_Proxy::PPB_Flash_MessageLoop_Proxy(Dispatcher* dispatcher)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : InterfaceProxy(dispatcher) {
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PPB_Flash_MessageLoop_Proxy::~PPB_Flash_MessageLoop_Proxy() {
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Resource PPB_Flash_MessageLoop_Proxy::CreateProxyResource(
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PP_Instance instance) {
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance);
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!dispatcher)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 0;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HostResource result;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dispatcher->Send(new PpapiHostMsg_PPBFlashMessageLoop_Create(
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      API_ID_PPB_FLASH_MESSAGELOOP, instance, &result));
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result.is_null())
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 0;
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return (new FlashMessageLoop(result))->GetReference();
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PPB_Flash_MessageLoop_Proxy::OnMessageReceived(const IPC::Message& msg) {
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!dispatcher()->permissions().HasPermission(PERMISSION_FLASH))
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool handled = true;
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC_BEGIN_MESSAGE_MAP(PPB_Flash_MessageLoop_Proxy, msg)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFlashMessageLoop_Create,
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        OnMsgCreate)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We cannot use IPC_MESSAGE_HANDLER here. Because it tries to send the sync
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // message reply after the handler returns. However, in this case, the
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // PPB_Flash_MessageLoop_Proxy object may be destroyed before the handler
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // returns.
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER_DELAY_REPLY(PpapiHostMsg_PPBFlashMessageLoop_Run,
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    OnMsgRun)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFlashMessageLoop_Quit,
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        OnMsgQuit)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_UNHANDLED(handled = false)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC_END_MESSAGE_MAP()
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return handled;
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PPB_Flash_MessageLoop_Proxy::OnMsgCreate(PP_Instance instance,
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              HostResource* result) {
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!dispatcher()->permissions().HasPermission(PERMISSION_FLASH))
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  thunk::EnterResourceCreation enter(instance);
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (enter.succeeded()) {
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result->SetHostResource(
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        instance, enter.functions()->CreateFlashMessageLoop(instance));
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PPB_Flash_MessageLoop_Proxy::OnMsgRun(
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HostResource& flash_message_loop,
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC::Message* reply) {
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!dispatcher()->permissions().HasPermission(PERMISSION_FLASH))
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PPB_Flash_MessageLoop_API::RunFromHostProxyCallback callback =
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&PPB_Flash_MessageLoop_Proxy::WillQuitSoon, AsWeakPtr(),
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Passed(scoped_ptr<IPC::Message>(reply)));
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EnterHostFromHostResource<PPB_Flash_MessageLoop_API>
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      enter(flash_message_loop);
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (enter.succeeded())
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    enter.object()->RunFromHostProxy(callback);
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    callback.Run(PP_ERROR_BADRESOURCE);
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PPB_Flash_MessageLoop_Proxy::OnMsgQuit(
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ppapi::HostResource& flash_message_loop) {
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EnterHostFromHostResource<PPB_Flash_MessageLoop_API>
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      enter(flash_message_loop);
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (enter.succeeded())
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    enter.object()->Quit();
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PPB_Flash_MessageLoop_Proxy::WillQuitSoon(
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<IPC::Message> reply_message,
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int32_t result) {
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PpapiHostMsg_PPBFlashMessageLoop_Run::WriteReplyParams(reply_message.get(),
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                         result);
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Send(reply_message.release());
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace proxy
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace ppapi
166