blob: 2043cbeb11c6b01f8662ccf28702a9006268f3f9 [file] [log] [blame]
// 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/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_(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() {
message_loop_ = new pp::flash::MessageLoop(instance_);
pp::CompletionCallback callback = callback_factory_.NewCallback(
&TestFlashMessageLoop::QuitMessageLoopTask);
pp::Module::Get()->core()->CallOnMainThread(0, callback);
int32_t result = message_loop_->Run();
ASSERT_TRUE(message_loop_);
delete message_loop_;
message_loop_ = nullptr;
ASSERT_EQ(PP_OK, result);
PASS();
}
std::string TestFlashMessageLoop::TestRunWithoutQuit() {
message_loop_ = new pp::flash::MessageLoop(instance_);
pp::CompletionCallback callback = callback_factory_.NewCallback(
&TestFlashMessageLoop::DestroyMessageLoopResourceTask);
pp::Module::Get()->core()->CallOnMainThread(0, callback);
int32_t result = message_loop_->Run();
if (message_loop_) {
delete message_loop_;
message_loop_ = nullptr;
ASSERT_TRUE(false);
}
ASSERT_EQ(PP_ERROR_ABORTED, result);
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();
else
PP_NOTREACHED();
}
void TestFlashMessageLoop::DestroyMessageLoopResourceTask(int32_t unused) {
if (message_loop_) {
delete message_loop_;
message_loop_ = nullptr;
} else {
PP_NOTREACHED();
}
}