summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYuzhu Shen <yzshen@chromium.org>2016-02-11 09:18:46 -0800
committerYuzhu Shen <yzshen@chromium.org>2016-02-11 17:20:19 +0000
commit8093f1f141848e3672ef778764c18e844f1e5198 (patch)
treeb4f1eace3f0bb7f7699fe4e5920822fe7f881aa2
parent2d55f8d50bb9fa4a5fcafd8ab479deb92b68ca1d (diff)
downloadchromium_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.cc1
-rw-r--r--content/renderer/pepper/ppb_flash_message_loop_impl.cc5
-rw-r--r--ppapi/tests/test_flash_message_loop.cc117
-rw-r--r--ppapi/tests/test_flash_message_loop.h22
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_;
};