Home | History | Annotate | Download | only in runner
      1 /*
      2  * Copyright (C) 2011 Google Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  *
      8  * 1.  Redistributions of source code must retain the above copyright
      9  *     notice, this list of conditions and the following disclaimer.
     10  * 2.  Redistributions in binary form must reproduce the above copyright
     11  *     notice, this list of conditions and the following disclaimer in the
     12  *     documentation and/or other materials provided with the distribution.
     13  *
     14  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
     15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     16  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     17  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
     18  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     19  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     20  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
     21  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     23  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 
     26 #include "TestPlugin.h"
     27 
     28 #include "TestCommon.h"
     29 #include "public/platform/Platform.h"
     30 #include "public/platform/WebCompositorSupport.h"
     31 #include "public/platform/WebGraphicsContext3D.h"
     32 #include "public/testing/WebTestDelegate.h"
     33 #include "public/web/WebFrame.h"
     34 #include "public/web/WebInputEvent.h"
     35 #include "public/web/WebKit.h"
     36 #include "public/web/WebPluginParams.h"
     37 #include "public/web/WebTouchPoint.h"
     38 #include "public/web/WebUserGestureIndicator.h"
     39 
     40 using namespace blink;
     41 using namespace std;
     42 
     43 namespace WebTestRunner {
     44 
     45 namespace {
     46 
     47 // GLenum values copied from gl2.h.
     48 #define GL_FALSE                  0
     49 #define GL_TRUE                   1
     50 #define GL_ONE                    1
     51 #define GL_TRIANGLES              0x0004
     52 #define GL_ONE_MINUS_SRC_ALPHA    0x0303
     53 #define GL_DEPTH_TEST             0x0B71
     54 #define GL_BLEND                  0x0BE2
     55 #define GL_SCISSOR_TEST           0x0B90
     56 #define GL_TEXTURE_2D             0x0DE1
     57 #define GL_FLOAT                  0x1406
     58 #define GL_RGBA                   0x1908
     59 #define GL_UNSIGNED_BYTE          0x1401
     60 #define GL_TEXTURE_MAG_FILTER     0x2800
     61 #define GL_TEXTURE_MIN_FILTER     0x2801
     62 #define GL_TEXTURE_WRAP_S         0x2802
     63 #define GL_TEXTURE_WRAP_T         0x2803
     64 #define GL_NEAREST                0x2600
     65 #define GL_COLOR_BUFFER_BIT       0x4000
     66 #define GL_CLAMP_TO_EDGE          0x812F
     67 #define GL_ARRAY_BUFFER           0x8892
     68 #define GL_STATIC_DRAW            0x88E4
     69 #define GL_FRAGMENT_SHADER        0x8B30
     70 #define GL_VERTEX_SHADER          0x8B31
     71 #define GL_COMPILE_STATUS         0x8B81
     72 #define GL_LINK_STATUS            0x8B82
     73 #define GL_COLOR_ATTACHMENT0      0x8CE0
     74 #define GL_FRAMEBUFFER_COMPLETE   0x8CD5
     75 #define GL_FRAMEBUFFER            0x8D40
     76 
     77 void premultiplyAlpha(const unsigned colorIn[3], float alpha, float colorOut[4])
     78 {
     79     for (int i = 0; i < 3; ++i)
     80         colorOut[i] = (colorIn[i] / 255.0f) * alpha;
     81 
     82     colorOut[3] = alpha;
     83 }
     84 
     85 const char* pointState(WebTouchPoint::State state)
     86 {
     87     switch (state) {
     88     case WebTouchPoint::StateReleased:
     89         return "Released";
     90     case WebTouchPoint::StatePressed:
     91         return "Pressed";
     92     case WebTouchPoint::StateMoved:
     93         return "Moved";
     94     case WebTouchPoint::StateCancelled:
     95         return "Cancelled";
     96     default:
     97         return "Unknown";
     98     }
     99 
    100     BLINK_ASSERT_NOT_REACHED();
    101     return 0;
    102 }
    103 
    104 void printTouchList(WebTestDelegate* delegate, const WebTouchPoint* points, int length)
    105 {
    106     for (int i = 0; i < length; ++i) {
    107         char buffer[100];
    108         snprintf(buffer, sizeof(buffer), "* %d, %d: %s\n", points[i].position.x, points[i].position.y, pointState(points[i].state));
    109         delegate->printMessage(buffer);
    110     }
    111 }
    112 
    113 void printEventDetails(WebTestDelegate* delegate, const WebInputEvent& event)
    114 {
    115     if (WebInputEvent::isTouchEventType(event.type)) {
    116         const WebTouchEvent& touch = static_cast<const WebTouchEvent&>(event);
    117         printTouchList(delegate, touch.touches, touch.touchesLength);
    118         printTouchList(delegate, touch.changedTouches, touch.changedTouchesLength);
    119         printTouchList(delegate, touch.targetTouches, touch.targetTouchesLength);
    120     } else if (WebInputEvent::isMouseEventType(event.type) || event.type == WebInputEvent::MouseWheel) {
    121         const WebMouseEvent& mouse = static_cast<const WebMouseEvent&>(event);
    122         char buffer[100];
    123         snprintf(buffer, sizeof(buffer), "* %d, %d\n", mouse.x, mouse.y);
    124         delegate->printMessage(buffer);
    125     } else if (WebInputEvent::isGestureEventType(event.type)) {
    126         const WebGestureEvent& gesture = static_cast<const WebGestureEvent&>(event);
    127         char buffer[100];
    128         snprintf(buffer, sizeof(buffer), "* %d, %d\n", gesture.x, gesture.y);
    129         delegate->printMessage(buffer);
    130     }
    131 }
    132 
    133 WebPluginContainer::TouchEventRequestType parseTouchEventRequestType(const WebString& string)
    134 {
    135     if (string == WebString::fromUTF8("raw"))
    136         return WebPluginContainer::TouchEventRequestTypeRaw;
    137     if (string == WebString::fromUTF8("synthetic"))
    138         return WebPluginContainer::TouchEventRequestTypeSynthesizedMouse;
    139     return WebPluginContainer::TouchEventRequestTypeNone;
    140 }
    141 
    142 void deferredDelete(void* context)
    143 {
    144     TestPlugin* plugin = static_cast<TestPlugin*>(context);
    145     delete plugin;
    146 }
    147 
    148 }
    149 
    150 
    151 TestPlugin::TestPlugin(WebFrame* frame, const WebPluginParams& params, WebTestDelegate* delegate)
    152     : m_frame(frame)
    153     , m_delegate(delegate)
    154     , m_container(0)
    155     , m_context(0)
    156     , m_colorTexture(0)
    157     , m_mailboxChanged(false)
    158     , m_framebuffer(0)
    159     , m_touchEventRequest(WebPluginContainer::TouchEventRequestTypeNone)
    160     , m_reRequestTouchEvents(false)
    161     , m_printEventDetails(false)
    162     , m_printUserGestureStatus(false)
    163     , m_canProcessDrag(false)
    164 {
    165     static const WebString kAttributePrimitive = WebString::fromUTF8("primitive");
    166     static const WebString kAttributeBackgroundColor = WebString::fromUTF8("background-color");
    167     static const WebString kAttributePrimitiveColor = WebString::fromUTF8("primitive-color");
    168     static const WebString kAttributeOpacity = WebString::fromUTF8("opacity");
    169     static const WebString kAttributeAcceptsTouch = WebString::fromUTF8("accepts-touch");
    170     static const WebString kAttributeReRequestTouchEvents = WebString::fromUTF8("re-request-touch");
    171     static const WebString kAttributePrintEventDetails = WebString::fromUTF8("print-event-details");
    172     static const WebString kAttributeCanProcessDrag = WebString::fromUTF8("can-process-drag");
    173     static const WebString kAttributePrintUserGestureStatus = WebString::fromUTF8("print-user-gesture-status");
    174 
    175     BLINK_ASSERT(params.attributeNames.size() == params.attributeValues.size());
    176     size_t size = params.attributeNames.size();
    177     for (size_t i = 0; i < size; ++i) {
    178         const WebString& attributeName = params.attributeNames[i];
    179         const WebString& attributeValue = params.attributeValues[i];
    180 
    181         if (attributeName == kAttributePrimitive)
    182             m_scene.primitive = parsePrimitive(attributeValue);
    183         else if (attributeName == kAttributeBackgroundColor)
    184             parseColor(attributeValue, m_scene.backgroundColor);
    185         else if (attributeName == kAttributePrimitiveColor)
    186             parseColor(attributeValue, m_scene.primitiveColor);
    187         else if (attributeName == kAttributeOpacity)
    188             m_scene.opacity = parseOpacity(attributeValue);
    189         else if (attributeName == kAttributeAcceptsTouch)
    190             m_touchEventRequest = parseTouchEventRequestType(attributeValue);
    191         else if (attributeName == kAttributeReRequestTouchEvents)
    192             m_reRequestTouchEvents = parseBoolean(attributeValue);
    193         else if (attributeName == kAttributePrintEventDetails)
    194             m_printEventDetails = parseBoolean(attributeValue);
    195         else if (attributeName == kAttributeCanProcessDrag)
    196             m_canProcessDrag = parseBoolean(attributeValue);
    197         else if (attributeName == kAttributePrintUserGestureStatus)
    198             m_printUserGestureStatus = parseBoolean(attributeValue);
    199     }
    200 }
    201 
    202 TestPlugin::~TestPlugin()
    203 {
    204 }
    205 
    206 bool TestPlugin::initialize(WebPluginContainer* container)
    207 {
    208     WebGraphicsContext3D::Attributes attrs;
    209     m_context = Platform::current()->createOffscreenGraphicsContext3D(attrs);
    210     if (!m_context)
    211         return false;
    212 
    213     if (!m_context->makeContextCurrent())
    214         return false;
    215 
    216     if (!initScene())
    217         return false;
    218 
    219     m_layer = WebScopedPtr<WebExternalTextureLayer>(Platform::current()->compositorSupport()->createExternalTextureLayer(this));
    220     m_container = container;
    221     m_container->setWebLayer(m_layer->layer());
    222     if (m_reRequestTouchEvents) {
    223         m_container->requestTouchEventType(WebPluginContainer::TouchEventRequestTypeSynthesizedMouse);
    224         m_container->requestTouchEventType(WebPluginContainer::TouchEventRequestTypeRaw);
    225     }
    226     m_container->requestTouchEventType(m_touchEventRequest);
    227     m_container->setWantsWheelEvents(true);
    228     return true;
    229 }
    230 
    231 void TestPlugin::destroy()
    232 {
    233     if (m_layer.get())
    234         m_layer->clearTexture();
    235     if (m_container)
    236         m_container->setWebLayer(0);
    237     m_layer.reset();
    238     destroyScene();
    239 
    240     delete m_context;
    241     m_context = 0;
    242 
    243     m_container = 0;
    244     m_frame = 0;
    245 
    246     Platform::current()->callOnMainThread(deferredDelete, this);
    247 }
    248 
    249 void TestPlugin::updateGeometry(const WebRect& frameRect, const WebRect& clipRect, const WebVector<WebRect>& cutOutsRects, bool isVisible)
    250 {
    251     if (clipRect == m_rect)
    252         return;
    253     m_rect = clipRect;
    254     if (m_rect.isEmpty())
    255         return;
    256 
    257     m_context->reshapeWithScaleFactor(m_rect.width, m_rect.height, 1.f);
    258     m_context->viewport(0, 0, m_rect.width, m_rect.height);
    259 
    260     m_context->bindTexture(GL_TEXTURE_2D, m_colorTexture);
    261     m_context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    262     m_context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    263     m_context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    264     m_context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    265     m_context->texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_rect.width, m_rect.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
    266     m_context->bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
    267     m_context->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_colorTexture, 0);
    268 
    269     drawScene();
    270 
    271     m_context->genMailboxCHROMIUM(m_mailbox.name);
    272     m_context->produceTextureCHROMIUM(GL_TEXTURE_2D, m_mailbox.name);
    273 
    274     m_context->flush();
    275     m_layer->layer()->invalidate();
    276     m_mailboxChanged = true;
    277 }
    278 
    279 bool TestPlugin::prepareMailbox(blink::WebExternalTextureMailbox* mailbox, blink::WebExternalBitmap*)
    280 {
    281     if (!m_mailboxChanged)
    282         return false;
    283     *mailbox = m_mailbox;
    284     m_mailboxChanged = false;
    285     return true;
    286 }
    287 
    288 void TestPlugin::mailboxReleased(const blink::WebExternalTextureMailbox&)
    289 {
    290 }
    291 
    292 TestPlugin::Primitive TestPlugin::parsePrimitive(const WebString& string)
    293 {
    294     static const WebString kPrimitiveNone = WebString::fromUTF8("none");
    295     static const WebString kPrimitiveTriangle = WebString::fromUTF8("triangle");
    296 
    297     Primitive primitive = PrimitiveNone;
    298     if (string == kPrimitiveNone)
    299         primitive = PrimitiveNone;
    300     else if (string == kPrimitiveTriangle)
    301         primitive = PrimitiveTriangle;
    302     else
    303         BLINK_ASSERT_NOT_REACHED();
    304     return primitive;
    305 }
    306 
    307 // FIXME: This method should already exist. Use it.
    308 // For now just parse primary colors.
    309 void TestPlugin::parseColor(const WebString& string, unsigned color[3])
    310 {
    311     color[0] = color[1] = color[2] = 0;
    312     if (string == "black")
    313         return;
    314 
    315     if (string == "red")
    316         color[0] = 255;
    317     else if (string == "green")
    318         color[1] = 255;
    319     else if (string == "blue")
    320         color[2] = 255;
    321     else
    322         BLINK_ASSERT_NOT_REACHED();
    323 }
    324 
    325 float TestPlugin::parseOpacity(const WebString& string)
    326 {
    327     return static_cast<float>(atof(string.utf8().data()));
    328 }
    329 
    330 bool TestPlugin::parseBoolean(const WebString& string)
    331 {
    332     static const WebString kPrimitiveTrue = WebString::fromUTF8("true");
    333     return string == kPrimitiveTrue;
    334 }
    335 
    336 bool TestPlugin::initScene()
    337 {
    338     float color[4];
    339     premultiplyAlpha(m_scene.backgroundColor, m_scene.opacity, color);
    340 
    341     m_colorTexture = m_context->createTexture();
    342     m_framebuffer = m_context->createFramebuffer();
    343 
    344     m_context->viewport(0, 0, m_rect.width, m_rect.height);
    345     m_context->disable(GL_DEPTH_TEST);
    346     m_context->disable(GL_SCISSOR_TEST);
    347 
    348     m_context->clearColor(color[0], color[1], color[2], color[3]);
    349 
    350     m_context->enable(GL_BLEND);
    351     m_context->blendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
    352 
    353     return m_scene.primitive != PrimitiveNone ? initProgram() && initPrimitive() : true;
    354 }
    355 
    356 void TestPlugin::drawScene()
    357 {
    358     m_context->viewport(0, 0, m_rect.width, m_rect.height);
    359     m_context->clear(GL_COLOR_BUFFER_BIT);
    360 
    361     if (m_scene.primitive != PrimitiveNone)
    362         drawPrimitive();
    363 }
    364 
    365 void TestPlugin::destroyScene()
    366 {
    367     if (m_scene.program) {
    368         m_context->deleteProgram(m_scene.program);
    369         m_scene.program = 0;
    370     }
    371     if (m_scene.vbo) {
    372         m_context->deleteBuffer(m_scene.vbo);
    373         m_scene.vbo = 0;
    374     }
    375 
    376     if (m_framebuffer) {
    377         m_context->deleteFramebuffer(m_framebuffer);
    378         m_framebuffer = 0;
    379     }
    380 
    381     if (m_colorTexture) {
    382         m_context->deleteTexture(m_colorTexture);
    383         m_colorTexture = 0;
    384     }
    385 }
    386 
    387 bool TestPlugin::initProgram()
    388 {
    389     const string vertexSource(
    390         "attribute vec4 position;  \n"
    391         "void main() {             \n"
    392         "  gl_Position = position; \n"
    393         "}                         \n"
    394     );
    395 
    396     const string fragmentSource(
    397         "precision mediump float; \n"
    398         "uniform vec4 color;      \n"
    399         "void main() {            \n"
    400         "  gl_FragColor = color;  \n"
    401         "}                        \n"
    402     );
    403 
    404     m_scene.program = loadProgram(vertexSource, fragmentSource);
    405     if (!m_scene.program)
    406         return false;
    407 
    408     m_scene.colorLocation = m_context->getUniformLocation(m_scene.program, "color");
    409     m_scene.positionLocation = m_context->getAttribLocation(m_scene.program, "position");
    410     return true;
    411 }
    412 
    413 bool TestPlugin::initPrimitive()
    414 {
    415     BLINK_ASSERT(m_scene.primitive == PrimitiveTriangle);
    416 
    417     m_scene.vbo = m_context->createBuffer();
    418     if (!m_scene.vbo)
    419         return false;
    420 
    421     const float vertices[] = {
    422         0.0f,  0.8f, 0.0f,
    423         -0.8f, -0.8f, 0.0f,
    424         0.8f, -0.8f, 0.0f };
    425     m_context->bindBuffer(GL_ARRAY_BUFFER, m_scene.vbo);
    426     m_context->bufferData(GL_ARRAY_BUFFER, sizeof(vertices), 0, GL_STATIC_DRAW);
    427     m_context->bufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices);
    428     return true;
    429 }
    430 
    431 void TestPlugin::drawPrimitive()
    432 {
    433     BLINK_ASSERT(m_scene.primitive == PrimitiveTriangle);
    434     BLINK_ASSERT(m_scene.vbo);
    435     BLINK_ASSERT(m_scene.program);
    436 
    437     m_context->useProgram(m_scene.program);
    438 
    439     // Bind primitive color.
    440     float color[4];
    441     premultiplyAlpha(m_scene.primitiveColor, m_scene.opacity, color);
    442     m_context->uniform4f(m_scene.colorLocation, color[0], color[1], color[2], color[3]);
    443 
    444     // Bind primitive vertices.
    445     m_context->bindBuffer(GL_ARRAY_BUFFER, m_scene.vbo);
    446     m_context->enableVertexAttribArray(m_scene.positionLocation);
    447     m_context->vertexAttribPointer(m_scene.positionLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
    448     m_context->drawArrays(GL_TRIANGLES, 0, 3);
    449 }
    450 
    451 unsigned TestPlugin::loadShader(unsigned type, const string& source)
    452 {
    453     unsigned shader = m_context->createShader(type);
    454     if (shader) {
    455         m_context->shaderSource(shader, source.data());
    456         m_context->compileShader(shader);
    457 
    458         int compiled = 0;
    459         m_context->getShaderiv(shader, GL_COMPILE_STATUS, &compiled);
    460         if (!compiled) {
    461             m_context->deleteShader(shader);
    462             shader = 0;
    463         }
    464     }
    465     return shader;
    466 }
    467 
    468 unsigned TestPlugin::loadProgram(const string& vertexSource, const string& fragmentSource)
    469 {
    470     unsigned vertexShader = loadShader(GL_VERTEX_SHADER, vertexSource);
    471     unsigned fragmentShader = loadShader(GL_FRAGMENT_SHADER, fragmentSource);
    472     unsigned program = m_context->createProgram();
    473     if (vertexShader && fragmentShader && program) {
    474         m_context->attachShader(program, vertexShader);
    475         m_context->attachShader(program, fragmentShader);
    476         m_context->linkProgram(program);
    477 
    478         int linked = 0;
    479         m_context->getProgramiv(program, GL_LINK_STATUS, &linked);
    480         if (!linked) {
    481             m_context->deleteProgram(program);
    482             program = 0;
    483         }
    484     }
    485     if (vertexShader)
    486         m_context->deleteShader(vertexShader);
    487     if (fragmentShader)
    488         m_context->deleteShader(fragmentShader);
    489 
    490     return program;
    491 }
    492 
    493 bool TestPlugin::handleInputEvent(const WebInputEvent& event, WebCursorInfo& info)
    494 {
    495     const char* eventName = 0;
    496     switch (event.type) {
    497     case WebInputEvent::Undefined:           eventName = "unknown"; break;
    498 
    499     case WebInputEvent::MouseDown:           eventName = "MouseDown"; break;
    500     case WebInputEvent::MouseUp:             eventName = "MouseUp"; break;
    501     case WebInputEvent::MouseMove:           eventName = "MouseMove"; break;
    502     case WebInputEvent::MouseEnter:          eventName = "MouseEnter"; break;
    503     case WebInputEvent::MouseLeave:          eventName = "MouseLeave"; break;
    504     case WebInputEvent::ContextMenu:         eventName = "ContextMenu"; break;
    505 
    506     case WebInputEvent::MouseWheel:          eventName = "MouseWheel"; break;
    507 
    508     case WebInputEvent::RawKeyDown:          eventName = "RawKeyDown"; break;
    509     case WebInputEvent::KeyDown:             eventName = "KeyDown"; break;
    510     case WebInputEvent::KeyUp:               eventName = "KeyUp"; break;
    511     case WebInputEvent::Char:                eventName = "Char"; break;
    512 
    513     case WebInputEvent::GestureScrollBegin:  eventName = "GestureScrollBegin"; break;
    514     case WebInputEvent::GestureScrollEnd:    eventName = "GestureScrollEnd"; break;
    515     case WebInputEvent::GestureScrollUpdateWithoutPropagation:
    516     case WebInputEvent::GestureScrollUpdate: eventName = "GestureScrollUpdate"; break;
    517     case WebInputEvent::GestureFlingStart:   eventName = "GestureFlingStart"; break;
    518     case WebInputEvent::GestureFlingCancel:  eventName = "GestureFlingCancel"; break;
    519     case WebInputEvent::GestureTap:          eventName = "GestureTap"; break;
    520     case WebInputEvent::GestureTapUnconfirmed:
    521                                              eventName = "GestureTapUnconfirmed"; break;
    522     case WebInputEvent::GestureTapDown:      eventName = "GestureTapDown"; break;
    523     case WebInputEvent::GestureShowPress:    eventName = "GestureShowPress"; break;
    524     case WebInputEvent::GestureTapCancel:    eventName = "GestureTapCancel"; break;
    525     case WebInputEvent::GestureDoubleTap:    eventName = "GestureDoubleTap"; break;
    526     case WebInputEvent::GestureTwoFingerTap: eventName = "GestureTwoFingerTap"; break;
    527     case WebInputEvent::GestureLongPress:    eventName = "GestureLongPress"; break;
    528     case WebInputEvent::GestureLongTap:      eventName = "GestureLongTap"; break;
    529     case WebInputEvent::GesturePinchBegin:   eventName = "GesturePinchBegin"; break;
    530     case WebInputEvent::GesturePinchEnd:     eventName = "GesturePinchEnd"; break;
    531     case WebInputEvent::GesturePinchUpdate:  eventName = "GesturePinchUpdate"; break;
    532 
    533     case WebInputEvent::TouchStart:          eventName = "TouchStart"; break;
    534     case WebInputEvent::TouchMove:           eventName = "TouchMove"; break;
    535     case WebInputEvent::TouchEnd:            eventName = "TouchEnd"; break;
    536     case WebInputEvent::TouchCancel:         eventName = "TouchCancel"; break;
    537     }
    538 
    539     m_delegate->printMessage(std::string("Plugin received event: ") + (eventName ? eventName : "unknown") + "\n");
    540     if (m_printEventDetails)
    541         printEventDetails(m_delegate, event);
    542     if (m_printUserGestureStatus)
    543         m_delegate->printMessage(std::string("* ") + (WebUserGestureIndicator::isProcessingUserGesture() ? "" : "not ") + "handling user gesture\n");
    544     return false;
    545 }
    546 
    547 bool TestPlugin::handleDragStatusUpdate(WebDragStatus dragStatus, const WebDragData&, WebDragOperationsMask, const WebPoint& position, const WebPoint& screenPosition)
    548 {
    549     const char* dragStatusName = 0;
    550     switch (dragStatus) {
    551     case WebDragStatusEnter:
    552         dragStatusName = "DragEnter";
    553         break;
    554     case WebDragStatusOver:
    555         dragStatusName = "DragOver";
    556         break;
    557     case WebDragStatusLeave:
    558         dragStatusName = "DragLeave";
    559         break;
    560     case WebDragStatusDrop:
    561         dragStatusName = "DragDrop";
    562         break;
    563     case WebDragStatusUnknown:
    564         BLINK_ASSERT_NOT_REACHED();
    565     }
    566     m_delegate->printMessage(std::string("Plugin received event: ") + dragStatusName + "\n");
    567     return false;
    568 }
    569 
    570 TestPlugin* TestPlugin::create(WebFrame* frame, const WebPluginParams& params, WebTestDelegate* delegate)
    571 {
    572     return new TestPlugin(frame, params, delegate);
    573 }
    574 
    575 const WebString& TestPlugin::mimeType()
    576 {
    577     static const WebString kMimeType = WebString::fromUTF8("application/x-webkit-test-webplugin");
    578     return kMimeType;
    579 }
    580 
    581 }
    582