diff options
author | Yuzhu Shen <yzshen@chromium.org> | 2016-02-11 09:18:46 -0800 |
---|---|---|
committer | Yuzhu Shen <yzshen@chromium.org> | 2016-02-11 17:20:19 +0000 |
commit | 8093f1f141848e3672ef778764c18e844f1e5198 (patch) | |
tree | b4f1eace3f0bb7f7699fe4e5920822fe7f881aa2 | |
parent | 2d55f8d50bb9fa4a5fcafd8ab479deb92b68ca1d (diff) | |
download | chromium_src-8093f1f141848e3672ef778764c18e844f1e5198.zip chromium_src-8093f1f141848e3672ef778764c18e844f1e5198.tar.gz chromium_src-8093f1f141848e3672ef778764c18e844f1e5198.tar.bz2 |
Fix PPB_Flash_MessageLoop.
This CL suspends script callbacks and resource loads while running nested message loop using PPB_Flash_MessageLoop.
BUG=569496
Review URL: https://codereview.chromium.org/1559113002
Cr-Commit-Position: refs/heads/master@{#374529}
(cherry picked from commit dd77c2a41c72589d929db0592565125ca629fb2c)
Review URL: https://codereview.chromium.org/1691513004 .
Cr-Commit-Position: refs/branch-heads/2623@{#365}
Cr-Branched-From: 92d77538a86529ca35f9220bd3cd512cbea1f086-refs/heads/master@{#369907}
-rw-r--r-- | chrome/test/ppapi/ppapi_browsertest.cc | 1 | ||||
-rw-r--r-- | content/renderer/pepper/ppb_flash_message_loop_impl.cc | 5 | ||||
-rw-r--r-- | ppapi/tests/test_flash_message_loop.cc | 117 | ||||
-rw-r--r-- | ppapi/tests/test_flash_message_loop.h | 22 |
4 files changed, 137 insertions, 8 deletions
diff --git a/chrome/test/ppapi/ppapi_browsertest.cc b/chrome/test/ppapi/ppapi_browsertest.cc index 5337514..1ced08f 100644 --- a/chrome/test/ppapi/ppapi_browsertest.cc +++ b/chrome/test/ppapi/ppapi_browsertest.cc @@ -1105,6 +1105,7 @@ IN_PROC_BROWSER_TEST_F(PPAPINaClPNaClNonSfiTest, MAYBE_PNACL_NONSFI(View)) { RunTest( \ LIST_TEST(FlashMessageLoop_Basics) \ LIST_TEST(FlashMessageLoop_RunWithoutQuit) \ + LIST_TEST(FlashMessageLoop_SuspendScriptCallbackWhileRunning) \ ) #if defined(OS_LINUX) // Disabled due to flakiness http://crbug.com/316925 diff --git a/content/renderer/pepper/ppb_flash_message_loop_impl.cc b/content/renderer/pepper/ppb_flash_message_loop_impl.cc index b64abe6..89ac5ad 100644 --- a/content/renderer/pepper/ppb_flash_message_loop_impl.cc +++ b/content/renderer/pepper/ppb_flash_message_loop_impl.cc @@ -7,6 +7,7 @@ #include "base/callback.h" #include "base/message_loop/message_loop.h" #include "ppapi/c/pp_errors.h" +#include "third_party/WebKit/public/web/WebView.h" using ppapi::thunk::PPB_Flash_MessageLoop_API; @@ -87,7 +88,11 @@ int32_t PPB_Flash_MessageLoop_Impl::InternalRun( { base::MessageLoop::ScopedNestableTaskAllower allow( base::MessageLoop::current()); + blink::WebView::willEnterModalLoop(); + base::MessageLoop::current()->Run(); + + blink::WebView::didExitModalLoop(); } // Don't access data members of the class below. diff --git a/ppapi/tests/test_flash_message_loop.cc b/ppapi/tests/test_flash_message_loop.cc index e7cb318..2043cbe 100644 --- a/ppapi/tests/test_flash_message_loop.cc +++ b/ppapi/tests/test_flash_message_loop.cc @@ -5,27 +5,97 @@ #include "ppapi/tests/test_flash_message_loop.h" #include "ppapi/c/pp_macros.h" +#include "ppapi/c/ppb_var.h" #include "ppapi/cpp/core.h" +#include "ppapi/cpp/dev/scriptable_object_deprecated.h" #include "ppapi/cpp/logging.h" #include "ppapi/cpp/module.h" #include "ppapi/cpp/private/flash_message_loop.h" #include "ppapi/tests/testing_instance.h" +namespace { + +const char kDidRunScriptCallback[] = "DidRunScriptCallback"; + +} // namespace + +class TestFlashMessageLoop::InstanceSO + : public pp::deprecated::ScriptableObject { + public: + explicit InstanceSO(TestFlashMessageLoop* owner) : owner_(owner) {} + + ~InstanceSO() override { + if (owner_) + owner_->clear_instance_so(); + } + + // pp::deprecated::ScriptableObject overrides. + bool HasMethod(const pp::Var& name, pp::Var* exception) override { + if (!name.is_string()) + return false; + return name.AsString() == kDidRunScriptCallback; + } + + pp::Var Call(const pp::Var& method_name, + const std::vector<pp::Var>& args, + pp::Var* exception) override { + if (!method_name.is_string()) + return false; + std::string name = method_name.AsString(); + + if (name == kDidRunScriptCallback) { + if (args.size() != 0) { + *exception = pp::Var("Bad argument to DidRunScriptCallback()"); + } else if (owner_) { + owner_->DidRunScriptCallback(); + } + } else { + *exception = pp::Var("Bad function call"); + } + + return pp::Var(); + } + + void clear_owner() { owner_ = nullptr; } + + private: + TestFlashMessageLoop* owner_; +}; + REGISTER_TEST_CASE(FlashMessageLoop); TestFlashMessageLoop::TestFlashMessageLoop(TestingInstance* instance) : TestCase(instance), - message_loop_(NULL), - callback_factory_(this) { -} + message_loop_(nullptr), + instance_so_(nullptr), + suspend_script_callback_result_(false), + callback_factory_(this) {} TestFlashMessageLoop::~TestFlashMessageLoop() { PP_DCHECK(!message_loop_); + + ResetTestObject(); + if (instance_so_) + instance_so_->clear_owner(); } void TestFlashMessageLoop::RunTests(const std::string& filter) { RUN_TEST(Basics, filter); RUN_TEST(RunWithoutQuit, filter); + RUN_TEST(SuspendScriptCallbackWhileRunning, filter); +} + +void TestFlashMessageLoop::DidRunScriptCallback() { + // Script callbacks are not supposed to run while the Flash message loop is + // running. + if (message_loop_) + suspend_script_callback_result_ = false; +} + +pp::deprecated::ScriptableObject* TestFlashMessageLoop::CreateTestObject() { + if (!instance_so_) + instance_so_ = new InstanceSO(this); + return instance_so_; } std::string TestFlashMessageLoop::TestBasics() { @@ -38,7 +108,7 @@ std::string TestFlashMessageLoop::TestBasics() { ASSERT_TRUE(message_loop_); delete message_loop_; - message_loop_ = NULL; + message_loop_ = nullptr; ASSERT_EQ(PP_OK, result); PASS(); @@ -54,7 +124,7 @@ std::string TestFlashMessageLoop::TestRunWithoutQuit() { if (message_loop_) { delete message_loop_; - message_loop_ = NULL; + message_loop_ = nullptr; ASSERT_TRUE(false); } @@ -62,6 +132,41 @@ std::string TestFlashMessageLoop::TestRunWithoutQuit() { PASS(); } +std::string TestFlashMessageLoop::TestSuspendScriptCallbackWhileRunning() { + suspend_script_callback_result_ = true; + message_loop_ = new pp::flash::MessageLoop(instance_); + + pp::CompletionCallback callback = callback_factory_.NewCallback( + &TestFlashMessageLoop::TestSuspendScriptCallbackTask); + pp::Module::Get()->core()->CallOnMainThread(0, callback); + message_loop_->Run(); + + ASSERT_TRUE(message_loop_); + delete message_loop_; + message_loop_ = nullptr; + + ASSERT_TRUE(suspend_script_callback_result_); + PASS(); +} + +void TestFlashMessageLoop::TestSuspendScriptCallbackTask(int32_t unused) { + pp::Var exception; + pp::Var rev = instance_->ExecuteScript( + "(function() {" + " function delayedHandler() {" + " document.getElementById('plugin').DidRunScriptCallback();" + " }" + " setTimeout(delayedHandler, 1);" + "})()", + &exception); + if (!exception.is_undefined()) + suspend_script_callback_result_ = false; + + pp::CompletionCallback callback = + callback_factory_.NewCallback(&TestFlashMessageLoop::QuitMessageLoopTask); + pp::Module::Get()->core()->CallOnMainThread(500, callback); +} + void TestFlashMessageLoop::QuitMessageLoopTask(int32_t unused) { if (message_loop_) message_loop_->Quit(); @@ -72,7 +177,7 @@ void TestFlashMessageLoop::QuitMessageLoopTask(int32_t unused) { void TestFlashMessageLoop::DestroyMessageLoopResourceTask(int32_t unused) { if (message_loop_) { delete message_loop_; - message_loop_ = NULL; + message_loop_ = nullptr; } else { PP_NOTREACHED(); } diff --git a/ppapi/tests/test_flash_message_loop.h b/ppapi/tests/test_flash_message_loop.h index b284eed..31b2791 100644 --- a/ppapi/tests/test_flash_message_loop.h +++ b/ppapi/tests/test_flash_message_loop.h @@ -20,19 +20,37 @@ class MessageLoop; class TestFlashMessageLoop : public TestCase { public: explicit TestFlashMessageLoop(TestingInstance* instance); - virtual ~TestFlashMessageLoop(); + ~TestFlashMessageLoop() override; // TestCase implementation. - virtual void RunTests(const std::string& filter); + void RunTests(const std::string& filter) override; + + void clear_instance_so() { instance_so_ = nullptr; } + + void DidRunScriptCallback(); private: + // ScriptableObject implementation. + class InstanceSO; + + // TestCase protected overrides. + pp::deprecated::ScriptableObject* CreateTestObject() override; + std::string TestBasics(); std::string TestRunWithoutQuit(); + std::string TestSuspendScriptCallbackWhileRunning(); + void TestSuspendScriptCallbackTask(int32_t unused); void QuitMessageLoopTask(int32_t unused); void DestroyMessageLoopResourceTask(int32_t unused); pp::flash::MessageLoop* message_loop_; + + // The scriptable object and result storage for the + // SuspendScriptCallbackWhileRunning test. + InstanceSO* instance_so_; + bool suspend_script_callback_result_; + pp::CompletionCallbackFactory<TestFlashMessageLoop> callback_factory_; }; |