summaryrefslogtreecommitdiffstats
path: root/ppapi/proxy/ppb_flash_message_loop_proxy.cc
diff options
context:
space:
mode:
authoryzshen@chromium.org <yzshen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-01-31 09:19:17 +0000
committeryzshen@chromium.org <yzshen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-01-31 09:19:17 +0000
commitcd2af395e8429a30bcee9e7ad7ec9f4b680c924d (patch)
treeacdc2fa6ef032a0c88b2a2f7729e15ae07a73254 /ppapi/proxy/ppb_flash_message_loop_proxy.cc
parentbefff0575c078d9353e48a125575b429e4b8b5f1 (diff)
downloadchromium_src-cd2af395e8429a30bcee9e7ad7ec9f4b680c924d.zip
chromium_src-cd2af395e8429a30bcee9e7ad7ec9f4b680c924d.tar.gz
chromium_src-cd2af395e8429a30bcee9e7ad7ec9f4b680c924d.tar.bz2
Introduce PPB_Flash_MessageLoop interface for Pepper Flash.
Comparing with PPB_Flash.RunMessageLoop/QuitMessageLoop, this new interface avoids leaking nested message loops. If Quit() is not called to balance the call to Run(), the outermost message loop will be quitted when the resource is destroyed. BUG=109340 TEST=test_flash_message_loop.{h,cc} Review URL: http://codereview.chromium.org/9188045 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@119873 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi/proxy/ppb_flash_message_loop_proxy.cc')
-rw-r--r--ppapi/proxy/ppb_flash_message_loop_proxy.cc157
1 files changed, 157 insertions, 0 deletions
diff --git a/ppapi/proxy/ppb_flash_message_loop_proxy.cc b/ppapi/proxy/ppb_flash_message_loop_proxy.cc
new file mode 100644
index 0000000..a06e8c8
--- /dev/null
+++ b/ppapi/proxy/ppb_flash_message_loop_proxy.cc
@@ -0,0 +1,157 @@
+// 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(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) {
+ 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) {
+ 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) {
+ 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