diff options
author | dcheng <dcheng@chromium.org> | 2015-12-02 18:46:41 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-12-03 02:47:19 +0000 |
commit | 0d93c1a79b3c4cc3b633e9f6e1fbae6cf1611f64 (patch) | |
tree | 6813cfb43077ef6801dbc9e68abb9d67a2703dd5 /ppapi | |
parent | db38f0f9b20d50863d9520294065b7307aa633e7 (diff) | |
download | chromium_src-0d93c1a79b3c4cc3b633e9f6e1fbae6cf1611f64.zip chromium_src-0d93c1a79b3c4cc3b633e9f6e1fbae6cf1611f64.tar.gz chromium_src-0d93c1a79b3c4cc3b633e9f6e1fbae6cf1611f64.tar.bz2 |
Implement a basic PPAPI plugin for Blink layout tests.
The plugin is automatically registered in layout tests using the
MIME type application/x-blink-test-plugin. Several layout tests
have also been migrated to use the new plugin.
Implementing the plugin also revealed a bug in PPAPI and the
layout test runner:
- Retrieving the key code via PPAPI always returned KeyA on Mac.
- The layout test runner explicitly set DYLD_FRAMEWORK_PATH,
making it hard to load the plugin from the right location.
BUG=474535
Review URL: https://codereview.chromium.org/1480303002
Cr-Commit-Position: refs/heads/master@{#362872}
Diffstat (limited to 'ppapi')
-rw-r--r-- | ppapi/BUILD.gn | 12 | ||||
-rw-r--r-- | ppapi/ppapi_tests.gypi | 19 | ||||
-rw-r--r-- | ppapi/tests/blink_test_plugin.cc | 179 |
3 files changed, 210 insertions, 0 deletions
diff --git a/ppapi/BUILD.gn b/ppapi/BUILD.gn index dc76515..818736e 100644 --- a/ppapi/BUILD.gn +++ b/ppapi/BUILD.gn @@ -70,6 +70,18 @@ shared_library("power_saver_test_plugin") { ] } +shared_library("blink_test_plugin") { + sources = [ + "tests/blink_test_plugin.cc", + ] + + deps = [ + "//build/config/sanitizers:deps", + "//ppapi/cpp", + "//ppapi/shared_impl", + ] +} + test("ppapi_unittests") { sources = [ "host/resource_message_filter_unittest.cc", diff --git a/ppapi/ppapi_tests.gypi b/ppapi/ppapi_tests.gypi index 830933e..e0c21fb 100644 --- a/ppapi/ppapi_tests.gypi +++ b/ppapi/ppapi_tests.gypi @@ -101,6 +101,25 @@ ], }, { + # GN version: //ppapi:blink_test_plugin + 'target_name': 'blink_test_plugin', + 'type': 'loadable_module', + 'sources': [ + 'tests/blink_test_plugin.cc', + ], + 'dependencies': [ + 'ppapi.gyp:ppapi_cpp', + 'ppapi_internal.gyp:ppapi_shared', + ], + 'conditions': [ + ['OS=="mac"', { + 'mac_bundle': 1, + 'product_name': 'blink_test_plugin', + 'product_extension': 'plugin', + }], + ], + }, + { # GN version: //ppapi/proxy:test_support # //ppapi/shared_impl:test_support 'target_name': 'ppapi_unittest_shared', diff --git a/ppapi/tests/blink_test_plugin.cc b/ppapi/tests/blink_test_plugin.cc new file mode 100644 index 0000000..91de50b --- /dev/null +++ b/ppapi/tests/blink_test_plugin.cc @@ -0,0 +1,179 @@ +// Copyright 2015 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 <sstream> +#include <utility> + +#include "ppapi/cpp/completion_callback.h" +#include "ppapi/cpp/graphics_2d.h" +#include "ppapi/cpp/image_data.h" +#include "ppapi/cpp/input_event.h" +#include "ppapi/cpp/instance.h" +#include "ppapi/cpp/module.h" + +namespace { + +void DummyCompletionCallback(void*, int32_t) {} + +// This is a simple C++ Pepper plugin for Blink layout tests. +// +// Layout tests can instantiate this plugin by requesting the mime type +// application/x-blink-test-plugin. When possible, tests should use the +// startAfterLoadAndFinish() helper in resources/plugin.js to perform work +// after the plugin has loaded. +// +// The plugin also exposes several other features for testing convenience: +// - On first paint, the plugin posts a 'loaded' message to its owner element. +// - On subsequent paints, the plugin posts a 'painted' message instead. +// - Keyboard and mouse input events are logged to the console. +class BlinkTestInstance : public pp::Instance { + public: + explicit BlinkTestInstance(PP_Instance instance) + : pp::Instance(instance), first_paint_(true) {} + ~BlinkTestInstance() override {} + + bool Init(uint32_t argc, const char* argn[], const char* argv[]) { + return RequestFilteringInputEvents(PP_INPUTEVENT_CLASS_MOUSE | + PP_INPUTEVENT_CLASS_KEYBOARD) == PP_OK; + } + + void DidChangeView(const pp::View& view) override { + view_ = view; + device_context_ = pp::Graphics2D(this, view_.GetRect().size(), true); + if (!BindGraphics(device_context_)) + return; + + // Since we draw a static image, we only need to make a new frame when + // the device is initialized or the view size changes. + Paint(); + } + + void DidChangeFocus(bool has_focus) override { + LogMessage("DidChangeFocus(", has_focus, ")"); + } + + bool HandleInputEvent(const pp::InputEvent& event) override { + switch (event.GetType()) { + case PP_INPUTEVENT_TYPE_MOUSEDOWN: + LogMouseEvent("Down", event); + break; + case PP_INPUTEVENT_TYPE_MOUSEUP: + LogMouseEvent("Up", event); + break; + case PP_INPUTEVENT_TYPE_KEYDOWN: + LogKeyboardEvent("Down", event); + break; + case PP_INPUTEVENT_TYPE_KEYUP: + LogKeyboardEvent("Up", event); + break; + case PP_INPUTEVENT_TYPE_MOUSEMOVE: + case PP_INPUTEVENT_TYPE_MOUSEENTER: + case PP_INPUTEVENT_TYPE_MOUSELEAVE: + case PP_INPUTEVENT_TYPE_RAWKEYDOWN: + case PP_INPUTEVENT_TYPE_CHAR: + // Just swallow these events without any logging. + return true; + default: + LogMessage("Unexpected input event with type = ", event.GetType()); + return false; + } + return true; + } + + private: + void Paint() { + pp::ImageData image(this, PP_IMAGEDATAFORMAT_BGRA_PREMUL, + view_.GetRect().size(), true); + if (image.is_null()) + return; + + // Draw blue and green checkerboard pattern to show "interesting" keyframe. + const int kSquareSizePixels = 8; + for (int y = 0; y < view_.GetRect().size().height(); ++y) { + for (int x = 0; x < view_.GetRect().size().width(); ++x) { + int x_square = x / kSquareSizePixels; + int y_square = y / kSquareSizePixels; + uint32_t color = ((x_square + y_square) % 2) ? 0xFF0000FF : 0xFF00FF00; + *image.GetAddr32(pp::Point(x, y)) = color; + } + } + + device_context_.ReplaceContents(&image); + device_context_.Flush( + pp::CompletionCallback(&DummyCompletionCallback, nullptr)); + + // TODO(dcheng): In theory, this should wait for the flush to complete + // before claiming that it's painted. In practice, this is difficult: when + // running layout tests, a frame is typically only generated at the end of + // the layout test. Sending the completion message in the callback results + // in a deadlock: the test wants to wait for the plugin to paint, but the + // plugin won't paint until the test completes. This seems to be Good + // Enoughâ„¢ for now. + if (first_paint_) { + first_paint_ = false; + PostMessage(pp::Var("loaded")); + } else { + PostMessage(pp::Var("painted")); + } + } + + void LogMouseEvent(const std::string& type, const pp::InputEvent& event) { + pp::MouseInputEvent mouse_event(event); + pp::Point mouse_position = mouse_event.GetPosition(); + LogMessage("Mouse", type, " at (", mouse_position.x(), ",", + mouse_position.y(), ")"); + } + + void LogKeyboardEvent(const std::string& type, const pp::InputEvent& event) { + pp::KeyboardInputEvent keyboard_event(event); + LogMessage("Key", type, " '", keyboard_event.GetCode().AsString(), "'"); + } + + // Template magic to cover the lack of base::StringPrintf. + template <typename... Args> + void LogMessage(const Args&... args) { + std::ostringstream ss; + ss << std::boolalpha; + LogMessageHelper(&ss, args...); + } + + template <typename Arg, typename... Args> + void LogMessageHelper(std::ostringstream* os, + const Arg& arg, + const Args&... args) { + *os << arg; + LogMessageHelper(os, args...); + } + + template <typename Arg> + void LogMessageHelper(std::ostringstream* os, const Arg& arg) { + *os << arg; + LogToConsoleWithSource(PP_LOGLEVEL_LOG, pp::Var("Blink Test Plugin"), + pp::Var(os->str())); + } + + bool first_paint_; + pp::View view_; + pp::Graphics2D device_context_; +}; + +class BlinkTestModule : public pp::Module { + public: + BlinkTestModule() {} + virtual ~BlinkTestModule() {} + + virtual pp::Instance* CreateInstance(PP_Instance instance) { + return new BlinkTestInstance(instance); + } +}; + +} // namespace + +namespace pp { + +Module* CreateModule() { + return new BlinkTestModule(); +} + +} // namespace pp |