ppb_flash_message_loop_impl.cc revision b2df76ea8fec9e32f6f3718986dba0d95315b29c
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 "webkit/plugins/ppapi/ppb_flash_message_loop_impl.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/message_loop.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/pp_errors.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ppapi::thunk::PPB_Flash_MessageLoop_API;
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace webkit {
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ppapi {
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PPB_Flash_MessageLoop_Impl::State
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : public base::RefCounted<PPB_Flash_MessageLoop_Impl::State> {
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  State() : result_(PP_OK), run_called_(false), quit_called_(false) {
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int32_t result() const { return result_; }
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_result(int32_t result) { result_ = result; }
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool run_called() const { return run_called_; }
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_run_called() { run_called_ = true; }
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool quit_called() const { return quit_called_; }
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_quit_called() { quit_called_ = true; }
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const RunFromHostProxyCallback& run_callback() const { return run_callback_; }
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_run_callback(const RunFromHostProxyCallback& run_callback) {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    run_callback_ = run_callback;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int32_t result_;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool run_called_;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool quit_called_;
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunFromHostProxyCallback run_callback_;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PPB_Flash_MessageLoop_Impl::PPB_Flash_MessageLoop_Impl(PP_Instance instance)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : Resource(::ppapi::OBJECT_IS_IMPL, instance),
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      state_(new State()) {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PPB_Flash_MessageLoop_Impl::~PPB_Flash_MessageLoop_Impl() {
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // It is a no-op if either Run() hasn't been called or Quit() has been called
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to balance the call to Run().
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InternalQuit(PP_ERROR_ABORTED);
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Resource PPB_Flash_MessageLoop_Impl::Create(PP_Instance instance) {
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return (new PPB_Flash_MessageLoop_Impl(instance))->GetReference();
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PPB_Flash_MessageLoop_API*
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PPB_Flash_MessageLoop_Impl::AsPPB_Flash_MessageLoop_API() {
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return this;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int32_t PPB_Flash_MessageLoop_Impl::Run() {
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return InternalRun(RunFromHostProxyCallback());
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PPB_Flash_MessageLoop_Impl::RunFromHostProxy(
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const RunFromHostProxyCallback& callback) {
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InternalRun(callback);
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PPB_Flash_MessageLoop_Impl::Quit() {
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InternalQuit(PP_OK);
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int32_t PPB_Flash_MessageLoop_Impl::InternalRun(
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const RunFromHostProxyCallback& callback) {
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (state_->run_called()) {
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!callback.is_null())
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback.Run(PP_ERROR_FAILED);
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return PP_ERROR_FAILED;
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  state_->set_run_called();
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  state_->set_run_callback(callback);
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // It is possible that the PPB_Flash_MessageLoop_Impl object has been
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // destroyed when the nested message loop exits.
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<State> state_protector(state_);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
91b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    base::MessageLoop::ScopedNestableTaskAllower allow(
92b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        base::MessageLoop::current());
93b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    base::MessageLoop::current()->Run();
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Don't access data members of the class below.
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return state_protector->result();
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PPB_Flash_MessageLoop_Impl::InternalQuit(int32_t result) {
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!state_->run_called() || state_->quit_called())
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  state_->set_quit_called();
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  state_->set_result(result);
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
106b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  base::MessageLoop::current()->QuitNow();
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!state_->run_callback().is_null())
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    state_->run_callback().Run(result);
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace ppapi
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace webkit
114