// 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(reply))); EnterHostFromHostResource 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 enter(flash_message_loop); if (enter.succeeded()) enter.object()->Quit(); } void PPB_Flash_MessageLoop_Proxy::WillQuitSoon( scoped_ptr reply_message, int32_t result) { PpapiHostMsg_PPBFlashMessageLoop_Run::WriteReplyParams(reply_message.get(), result); Send(reply_message.release()); } } // namespace proxy } // namespace ppapi