| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "ppapi/proxy/ppb_flash_message_loop_proxy.h" |
| |
| #include "base/bind.h" |
| #include "ppapi/c/pp_errors.h" |
| #include "ppapi/c/private/ppb_flash_message_loop.h" |
| #include "ppapi/proxy/enter_proxy.h" |
| #include "ppapi/proxy/plugin_dispatcher.h" |
| #include "ppapi/proxy/ppapi_messages.h" |
| #include "ppapi/shared_impl/resource.h" |
| #include "ppapi/thunk/enter.h" |
| #include "ppapi/thunk/ppb_flash_message_loop_api.h" |
| #include "ppapi/thunk/resource_creation_api.h" |
| |
| using ppapi::thunk::PPB_Flash_MessageLoop_API; |
| |
| namespace ppapi { |
| namespace proxy { |
| namespace { |
| |
| class FlashMessageLoop : public PPB_Flash_MessageLoop_API, public Resource { |
| public: |
| explicit FlashMessageLoop(const HostResource& resource); |
| virtual ~FlashMessageLoop(); |
| |
| // Resource overrides. |
| virtual PPB_Flash_MessageLoop_API* AsPPB_Flash_MessageLoop_API() OVERRIDE; |
| |
| // PPB_Flash_MesssageLoop_API implementation. |
| virtual int32_t Run() OVERRIDE; |
| virtual void Quit() OVERRIDE; |
| virtual void RunFromHostProxy( |
| const RunFromHostProxyCallback& callback) OVERRIDE; |
| |
| private: |
| DISALLOW_COPY_AND_ASSIGN(FlashMessageLoop); |
| }; |
| |
| FlashMessageLoop::FlashMessageLoop(const HostResource& resource) |
| : Resource(OBJECT_IS_PROXY, resource) { |
| } |
| |
| FlashMessageLoop::~FlashMessageLoop() { |
| } |
| |
| PPB_Flash_MessageLoop_API* FlashMessageLoop::AsPPB_Flash_MessageLoop_API() { |
| return this; |
| } |
| |
| int32_t FlashMessageLoop::Run() { |
| int32_t result = PP_ERROR_FAILED; |
| IPC::SyncMessage* msg = new PpapiHostMsg_PPBFlashMessageLoop_Run( |
| API_ID_PPB_FLASH_MESSAGELOOP, host_resource(), &result); |
| msg->EnableMessagePumping(); |
| PluginDispatcher::GetForResource(this)->Send(msg); |
| return result; |
| } |
| |
| void FlashMessageLoop::Quit() { |
| PluginDispatcher::GetForResource(this)->Send( |
| new PpapiHostMsg_PPBFlashMessageLoop_Quit( |
| API_ID_PPB_FLASH_MESSAGELOOP, host_resource())); |
| } |
| |
| void FlashMessageLoop::RunFromHostProxy( |
| const RunFromHostProxyCallback& callback) { |
| // This should never be called on the plugin side. |
| NOTREACHED(); |
| } |
| |
| } // namespace |
| |
| PPB_Flash_MessageLoop_Proxy::PPB_Flash_MessageLoop_Proxy(Dispatcher* dispatcher) |
| : InterfaceProxy(dispatcher) { |
| } |
| |
| PPB_Flash_MessageLoop_Proxy::~PPB_Flash_MessageLoop_Proxy() { |
| } |
| |
| // static |
| PP_Resource PPB_Flash_MessageLoop_Proxy::CreateProxyResource( |
| PP_Instance instance) { |
| PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance); |
| if (!dispatcher) |
| return 0; |
| |
| HostResource result; |
| dispatcher->Send(new PpapiHostMsg_PPBFlashMessageLoop_Create( |
| API_ID_PPB_FLASH_MESSAGELOOP, instance, &result)); |
| if (result.is_null()) |
| return 0; |
| return (new FlashMessageLoop(result))->GetReference(); |
| } |
| |
| bool PPB_Flash_MessageLoop_Proxy::OnMessageReceived(const IPC::Message& msg) { |
| if (!dispatcher()->permissions().HasPermission(PERMISSION_FLASH)) |
| return false; |
| |
| bool handled = true; |
| IPC_BEGIN_MESSAGE_MAP(PPB_Flash_MessageLoop_Proxy, msg) |
| IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFlashMessageLoop_Create, |
| OnMsgCreate) |
| // We cannot use IPC_MESSAGE_HANDLER here. Because it tries to send the sync |
| // message reply after the handler returns. However, in this case, the |
| // PPB_Flash_MessageLoop_Proxy object may be destroyed before the handler |
| // returns. |
| IPC_MESSAGE_HANDLER_DELAY_REPLY(PpapiHostMsg_PPBFlashMessageLoop_Run, |
| OnMsgRun) |
| IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFlashMessageLoop_Quit, |
| OnMsgQuit) |
| IPC_MESSAGE_UNHANDLED(handled = false) |
| IPC_END_MESSAGE_MAP() |
| return handled; |
| } |
| |
| void PPB_Flash_MessageLoop_Proxy::OnMsgCreate(PP_Instance instance, |
| HostResource* result) { |
| if (!dispatcher()->permissions().HasPermission(PERMISSION_FLASH)) |
| return; |
| thunk::EnterResourceCreation enter(instance); |
| if (enter.succeeded()) { |
| result->SetHostResource( |
| instance, enter.functions()->CreateFlashMessageLoop(instance)); |
| } |
| } |
| |
| void PPB_Flash_MessageLoop_Proxy::OnMsgRun( |
| const HostResource& flash_message_loop, |
| IPC::Message* reply) { |
| if (!dispatcher()->permissions().HasPermission(PERMISSION_FLASH)) |
| return; |
| |
| PPB_Flash_MessageLoop_API::RunFromHostProxyCallback callback = |
| base::Bind(&PPB_Flash_MessageLoop_Proxy::WillQuitSoon, AsWeakPtr(), |
| base::Passed(scoped_ptr<IPC::Message>(reply))); |
| |
| EnterHostFromHostResource<PPB_Flash_MessageLoop_API> |
| enter(flash_message_loop); |
| if (enter.succeeded()) |
| enter.object()->RunFromHostProxy(callback); |
| else |
| callback.Run(PP_ERROR_BADRESOURCE); |
| } |
| |
| void PPB_Flash_MessageLoop_Proxy::OnMsgQuit( |
| const ppapi::HostResource& flash_message_loop) { |
| EnterHostFromHostResource<PPB_Flash_MessageLoop_API> |
| enter(flash_message_loop); |
| if (enter.succeeded()) |
| enter.object()->Quit(); |
| } |
| |
| void PPB_Flash_MessageLoop_Proxy::WillQuitSoon( |
| scoped_ptr<IPC::Message> reply_message, |
| int32_t result) { |
| PpapiHostMsg_PPBFlashMessageLoop_Run::WriteReplyParams(reply_message.get(), |
| result); |
| Send(reply_message.release()); |
| } |
| |
| } // namespace proxy |
| } // namespace ppapi |