1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
|
// 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 "base/macros.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);
~FlashMessageLoop() override;
// Resource overrides.
PPB_Flash_MessageLoop_API* AsPPB_Flash_MessageLoop_API() override;
// PPB_Flash_MesssageLoop_API implementation.
int32_t Run() override;
void Quit() override;
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(std::unique_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(
std::unique_ptr<IPC::Message> reply_message,
int32_t result) {
PpapiHostMsg_PPBFlashMessageLoop_Run::WriteReplyParams(reply_message.get(),
result);
Send(reply_message.release());
}
} // namespace proxy
} // namespace ppapi
|