Upstream version 10.38.222.0
[platform/framework/web/crosswalk.git] / src / content / shell / renderer / test_runner / TestPlugin.cpp
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/shell/renderer/test_runner/TestPlugin.h"
6
7 #include "base/basictypes.h"
8 #include "base/bind.h"
9 #include "base/logging.h"
10 #include "base/memory/shared_memory.h"
11 #include "base/strings/stringprintf.h"
12 #include "content/public/renderer/render_thread.h"
13 #include "content/shell/renderer/test_runner/WebTestDelegate.h"
14 #include "third_party/skia/include/core/SkBitmap.h"
15 #include "third_party/skia/include/core/SkCanvas.h"
16 #include "third_party/skia/include/core/SkColor.h"
17 #include "third_party/WebKit/public/platform/Platform.h"
18 #include "third_party/WebKit/public/platform/WebCompositorSupport.h"
19 #include "third_party/WebKit/public/platform/WebGraphicsContext3D.h"
20 #include "third_party/WebKit/public/web/WebFrame.h"
21 #include "third_party/WebKit/public/web/WebInputEvent.h"
22 #include "third_party/WebKit/public/web/WebKit.h"
23 #include "third_party/WebKit/public/web/WebPluginParams.h"
24 #include "third_party/WebKit/public/web/WebTouchPoint.h"
25 #include "third_party/WebKit/public/web/WebUserGestureIndicator.h"
26
27 using namespace blink;
28
29 namespace content {
30
31 namespace {
32
33 // GLenum values copied from gl2.h.
34 #define GL_FALSE                  0
35 #define GL_TRUE                   1
36 #define GL_ONE                    1
37 #define GL_TRIANGLES              0x0004
38 #define GL_ONE_MINUS_SRC_ALPHA    0x0303
39 #define GL_DEPTH_TEST             0x0B71
40 #define GL_BLEND                  0x0BE2
41 #define GL_SCISSOR_TEST           0x0B90
42 #define GL_TEXTURE_2D             0x0DE1
43 #define GL_FLOAT                  0x1406
44 #define GL_RGBA                   0x1908
45 #define GL_UNSIGNED_BYTE          0x1401
46 #define GL_TEXTURE_MAG_FILTER     0x2800
47 #define GL_TEXTURE_MIN_FILTER     0x2801
48 #define GL_TEXTURE_WRAP_S         0x2802
49 #define GL_TEXTURE_WRAP_T         0x2803
50 #define GL_NEAREST                0x2600
51 #define GL_COLOR_BUFFER_BIT       0x4000
52 #define GL_CLAMP_TO_EDGE          0x812F
53 #define GL_ARRAY_BUFFER           0x8892
54 #define GL_STATIC_DRAW            0x88E4
55 #define GL_FRAGMENT_SHADER        0x8B30
56 #define GL_VERTEX_SHADER          0x8B31
57 #define GL_COMPILE_STATUS         0x8B81
58 #define GL_LINK_STATUS            0x8B82
59 #define GL_COLOR_ATTACHMENT0      0x8CE0
60 #define GL_FRAMEBUFFER_COMPLETE   0x8CD5
61 #define GL_FRAMEBUFFER            0x8D40
62
63 void premultiplyAlpha(const unsigned colorIn[3], float alpha, float colorOut[4])
64 {
65     for (int i = 0; i < 3; ++i)
66         colorOut[i] = (colorIn[i] / 255.0f) * alpha;
67
68     colorOut[3] = alpha;
69 }
70
71 const char* pointState(WebTouchPoint::State state)
72 {
73     switch (state) {
74     case WebTouchPoint::StateReleased:
75         return "Released";
76     case WebTouchPoint::StatePressed:
77         return "Pressed";
78     case WebTouchPoint::StateMoved:
79         return "Moved";
80     case WebTouchPoint::StateCancelled:
81         return "Cancelled";
82     default:
83         return "Unknown";
84     }
85 }
86
87 void printTouchList(WebTestDelegate* delegate, const WebTouchPoint* points, int length)
88 {
89     for (int i = 0; i < length; ++i) {
90       delegate->printMessage(base::StringPrintf("* %.2f, %.2f: %s\n",
91                                                 points[i].position.x,
92                                                 points[i].position.y,
93                                                 pointState(points[i].state)));
94     }
95 }
96
97 void printEventDetails(WebTestDelegate* delegate, const WebInputEvent& event)
98 {
99     if (WebInputEvent::isTouchEventType(event.type)) {
100         const WebTouchEvent& touch = static_cast<const WebTouchEvent&>(event);
101         printTouchList(delegate, touch.touches, touch.touchesLength);
102         printTouchList(delegate, touch.changedTouches, touch.changedTouchesLength);
103         printTouchList(delegate, touch.targetTouches, touch.targetTouchesLength);
104     } else if (WebInputEvent::isMouseEventType(event.type) || event.type == WebInputEvent::MouseWheel) {
105         const WebMouseEvent& mouse = static_cast<const WebMouseEvent&>(event);
106         delegate->printMessage(
107             base::StringPrintf("* %d, %d\n", mouse.x, mouse.y));
108     } else if (WebInputEvent::isGestureEventType(event.type)) {
109         const WebGestureEvent& gesture = static_cast<const WebGestureEvent&>(event);
110         delegate->printMessage(
111             base::StringPrintf("* %d, %d\n", gesture.x, gesture.y));
112     }
113 }
114
115 WebPluginContainer::TouchEventRequestType parseTouchEventRequestType(const WebString& string)
116 {
117     if (string == WebString::fromUTF8("raw"))
118         return WebPluginContainer::TouchEventRequestTypeRaw;
119     if (string == WebString::fromUTF8("synthetic"))
120         return WebPluginContainer::TouchEventRequestTypeSynthesizedMouse;
121     return WebPluginContainer::TouchEventRequestTypeNone;
122 }
123
124 void deferredDelete(void* context)
125 {
126     TestPlugin* plugin = static_cast<TestPlugin*>(context);
127     delete plugin;
128 }
129
130 }
131
132 TestPlugin::TestPlugin(WebFrame* frame, const WebPluginParams& params, WebTestDelegate* delegate)
133     : m_frame(frame)
134     , m_delegate(delegate)
135     , m_container(0)
136     , m_context(0)
137     , m_colorTexture(0)
138     , m_mailboxChanged(false)
139     , m_framebuffer(0)
140     , m_touchEventRequest(WebPluginContainer::TouchEventRequestTypeNone)
141     , m_reRequestTouchEvents(false)
142     , m_printEventDetails(false)
143     , m_printUserGestureStatus(false)
144     , m_canProcessDrag(false)
145     , m_isPersistent(params.mimeType == pluginPersistsMimeType())
146     , m_canCreateWithoutRenderer(params.mimeType == canCreateWithoutRendererMimeType())
147 {
148     const CR_DEFINE_STATIC_LOCAL(WebString, kAttributePrimitive, ("primitive"));
149     const CR_DEFINE_STATIC_LOCAL(WebString, kAttributeBackgroundColor, ("background-color"));
150     const CR_DEFINE_STATIC_LOCAL(WebString, kAttributePrimitiveColor, ("primitive-color"));
151     const CR_DEFINE_STATIC_LOCAL(WebString, kAttributeOpacity, ("opacity"));
152     const CR_DEFINE_STATIC_LOCAL(WebString, kAttributeAcceptsTouch, ("accepts-touch"));
153     const CR_DEFINE_STATIC_LOCAL(WebString, kAttributeReRequestTouchEvents, ("re-request-touch"));
154     const CR_DEFINE_STATIC_LOCAL(WebString, kAttributePrintEventDetails, ("print-event-details"));
155     const CR_DEFINE_STATIC_LOCAL(WebString, kAttributeCanProcessDrag, ("can-process-drag"));
156     const CR_DEFINE_STATIC_LOCAL(WebString, kAttributePrintUserGestureStatus, ("print-user-gesture-status"));
157
158     DCHECK_EQ(params.attributeNames.size(), params.attributeValues.size());
159     size_t size = params.attributeNames.size();
160     for (size_t i = 0; i < size; ++i) {
161         const WebString& attributeName = params.attributeNames[i];
162         const WebString& attributeValue = params.attributeValues[i];
163
164         if (attributeName == kAttributePrimitive)
165             m_scene.primitive = parsePrimitive(attributeValue);
166         else if (attributeName == kAttributeBackgroundColor)
167             parseColor(attributeValue, m_scene.backgroundColor);
168         else if (attributeName == kAttributePrimitiveColor)
169             parseColor(attributeValue, m_scene.primitiveColor);
170         else if (attributeName == kAttributeOpacity)
171             m_scene.opacity = parseOpacity(attributeValue);
172         else if (attributeName == kAttributeAcceptsTouch)
173             m_touchEventRequest = parseTouchEventRequestType(attributeValue);
174         else if (attributeName == kAttributeReRequestTouchEvents)
175             m_reRequestTouchEvents = parseBoolean(attributeValue);
176         else if (attributeName == kAttributePrintEventDetails)
177             m_printEventDetails = parseBoolean(attributeValue);
178         else if (attributeName == kAttributeCanProcessDrag)
179             m_canProcessDrag = parseBoolean(attributeValue);
180         else if (attributeName == kAttributePrintUserGestureStatus)
181             m_printUserGestureStatus = parseBoolean(attributeValue);
182     }
183     if (m_canCreateWithoutRenderer)
184         m_delegate->printMessage(std::string("TestPlugin: canCreateWithoutRenderer\n"));
185 }
186
187 TestPlugin::~TestPlugin()
188 {
189 }
190
191 bool TestPlugin::initialize(WebPluginContainer* container)
192 {
193     WebGraphicsContext3D::Attributes attrs;
194     m_context = Platform::current()->createOffscreenGraphicsContext3D(attrs);
195     if (m_context && !m_context->makeContextCurrent()) {
196         delete m_context;
197         m_context = 0;
198     }
199
200     if (!initScene())
201         return false;
202
203     m_layer = cc::TextureLayer::CreateForMailbox(this);
204     m_webLayer = make_scoped_ptr(InstantiateWebLayer(m_layer));
205     m_container = container;
206     m_container->setWebLayer(m_webLayer.get());
207     if (m_reRequestTouchEvents) {
208         m_container->requestTouchEventType(WebPluginContainer::TouchEventRequestTypeSynthesizedMouse);
209         m_container->requestTouchEventType(WebPluginContainer::TouchEventRequestTypeRaw);
210     }
211     m_container->requestTouchEventType(m_touchEventRequest);
212     m_container->setWantsWheelEvents(true);
213     return true;
214 }
215
216 void TestPlugin::destroy()
217 {
218     if (m_layer.get())
219         m_layer->ClearTexture();
220     if (m_container)
221         m_container->setWebLayer(0);
222     m_webLayer.reset();
223     m_layer = NULL;
224     destroyScene();
225
226     delete m_context;
227     m_context = 0;
228
229     m_container = 0;
230     m_frame = 0;
231
232     Platform::current()->callOnMainThread(deferredDelete, this);
233 }
234
235 NPObject* TestPlugin::scriptableObject()
236 {
237     return 0;
238 }
239
240 bool TestPlugin::canProcessDrag() const
241 {
242     return m_canProcessDrag;
243 }
244
245 void TestPlugin::updateGeometry(const WebRect& frameRect, const WebRect& clipRect, const WebVector<WebRect>& cutOutsRects, bool isVisible)
246 {
247     if (clipRect == m_rect)
248         return;
249     m_rect = clipRect;
250
251     if (m_rect.isEmpty()) {
252         m_textureMailbox = cc::TextureMailbox();
253     } else if (m_context) {
254         m_context->viewport(0, 0, m_rect.width, m_rect.height);
255
256         m_context->bindTexture(GL_TEXTURE_2D, m_colorTexture);
257         m_context->texParameteri(
258             GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
259         m_context->texParameteri(
260             GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
261         m_context->texParameteri(
262             GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
263         m_context->texParameteri(
264             GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
265         m_context->texImage2D(GL_TEXTURE_2D,
266                               0,
267                               GL_RGBA,
268                               m_rect.width,
269                               m_rect.height,
270                               0,
271                               GL_RGBA,
272                               GL_UNSIGNED_BYTE,
273                               0);
274         m_context->bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
275         m_context->framebufferTexture2D(GL_FRAMEBUFFER,
276                                         GL_COLOR_ATTACHMENT0,
277                                         GL_TEXTURE_2D,
278                                         m_colorTexture,
279                                         0);
280
281         drawSceneGL();
282
283         gpu::Mailbox mailbox;
284         m_context->genMailboxCHROMIUM(mailbox.name);
285         m_context->produceTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
286         m_context->flush();
287         uint32 syncPoint = m_context->insertSyncPoint();
288         m_textureMailbox = cc::TextureMailbox(mailbox, GL_TEXTURE_2D, syncPoint);
289     } else {
290         size_t bytes = 4 * m_rect.width * m_rect.height;
291         scoped_ptr<base::SharedMemory> bitmap =
292             RenderThread::Get()->HostAllocateSharedMemoryBuffer(bytes);
293         if (!bitmap->Map(bytes)) {
294             m_textureMailbox = cc::TextureMailbox();
295         } else {
296             drawSceneSoftware(bitmap->memory(), bytes);
297             m_textureMailbox = cc::TextureMailbox(
298                 bitmap.get(), gfx::Size(m_rect.width, m_rect.height));
299             m_sharedBitmap = bitmap.Pass();
300         }
301     }
302
303     m_mailboxChanged = true;
304     m_layer->SetNeedsDisplay();
305 }
306
307 bool TestPlugin::acceptsInputEvents()
308 {
309     return true;
310 }
311
312 bool TestPlugin::isPlaceholder()
313 {
314     return false;
315 }
316
317 static void ignoreReleaseCallback(uint32 sync_point, bool lost) {}
318
319 static void releaseSharedMemory(scoped_ptr<base::SharedMemory> bitmap,
320                                 uint32 sync_point,
321                                 bool lost) {}
322
323 bool TestPlugin::PrepareTextureMailbox(
324     cc::TextureMailbox* mailbox,
325     scoped_ptr<cc::SingleReleaseCallback>* releaseCallback,
326     bool useSharedMemory) {
327     if (!m_mailboxChanged)
328         return false;
329     *mailbox = m_textureMailbox;
330     if (m_textureMailbox.IsTexture()) {
331       *releaseCallback =
332           cc::SingleReleaseCallback::Create(base::Bind(&ignoreReleaseCallback));
333     } else {
334       *releaseCallback = cc::SingleReleaseCallback::Create(
335           base::Bind(&releaseSharedMemory, base::Passed(&m_sharedBitmap)));
336     }
337     m_mailboxChanged = false;
338     return true;
339 }
340
341 TestPlugin::Primitive TestPlugin::parsePrimitive(const WebString& string)
342 {
343     const CR_DEFINE_STATIC_LOCAL(WebString, kPrimitiveNone, ("none"));
344     const CR_DEFINE_STATIC_LOCAL(WebString, kPrimitiveTriangle, ("triangle"));
345
346     Primitive primitive = PrimitiveNone;
347     if (string == kPrimitiveNone)
348         primitive = PrimitiveNone;
349     else if (string == kPrimitiveTriangle)
350         primitive = PrimitiveTriangle;
351     else
352         NOTREACHED();
353     return primitive;
354 }
355
356 // FIXME: This method should already exist. Use it.
357 // For now just parse primary colors.
358 void TestPlugin::parseColor(const WebString& string, unsigned color[3])
359 {
360     color[0] = color[1] = color[2] = 0;
361     if (string == "black")
362         return;
363
364     if (string == "red")
365         color[0] = 255;
366     else if (string == "green")
367         color[1] = 255;
368     else if (string == "blue")
369         color[2] = 255;
370     else
371         NOTREACHED();
372 }
373
374 float TestPlugin::parseOpacity(const WebString& string)
375 {
376     return static_cast<float>(atof(string.utf8().data()));
377 }
378
379 bool TestPlugin::parseBoolean(const WebString& string)
380 {
381     const CR_DEFINE_STATIC_LOCAL(WebString, kPrimitiveTrue, ("true"));
382     return string == kPrimitiveTrue;
383 }
384
385 bool TestPlugin::initScene()
386 {
387     if (!m_context)
388         return true;
389
390     float color[4];
391     premultiplyAlpha(m_scene.backgroundColor, m_scene.opacity, color);
392
393     m_colorTexture = m_context->createTexture();
394     m_framebuffer = m_context->createFramebuffer();
395
396     m_context->viewport(0, 0, m_rect.width, m_rect.height);
397     m_context->disable(GL_DEPTH_TEST);
398     m_context->disable(GL_SCISSOR_TEST);
399
400     m_context->clearColor(color[0], color[1], color[2], color[3]);
401
402     m_context->enable(GL_BLEND);
403     m_context->blendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
404
405     return m_scene.primitive != PrimitiveNone ? initProgram() && initPrimitive() : true;
406 }
407
408 void TestPlugin::drawSceneGL() {
409     m_context->viewport(0, 0, m_rect.width, m_rect.height);
410     m_context->clear(GL_COLOR_BUFFER_BIT);
411
412     if (m_scene.primitive != PrimitiveNone)
413         drawPrimitive();
414 }
415
416 void TestPlugin::drawSceneSoftware(void* memory, size_t bytes) {
417     DCHECK_EQ(bytes, m_rect.width * m_rect.height * 4u);
418
419     SkColor backgroundColor =
420             SkColorSetARGB(static_cast<uint8>(m_scene.opacity * 255),
421                            m_scene.backgroundColor[0],
422                            m_scene.backgroundColor[1],
423                            m_scene.backgroundColor[2]);
424
425     const SkImageInfo info = SkImageInfo::MakeN32Premul(m_rect.width,
426                                                         m_rect.height);
427     SkBitmap bitmap;
428     bitmap.installPixels(info, memory, info.minRowBytes());
429     SkCanvas canvas(bitmap);
430     canvas.clear(backgroundColor);
431
432     if (m_scene.primitive != PrimitiveNone) {
433         DCHECK_EQ(PrimitiveTriangle, m_scene.primitive);
434         SkColor foregroundColor =
435                 SkColorSetARGB(static_cast<uint8>(m_scene.opacity * 255),
436                                m_scene.primitiveColor[0],
437                                m_scene.primitiveColor[1],
438                                m_scene.primitiveColor[2]);
439         SkPath trianglePath;
440         trianglePath.moveTo(0.5f * m_rect.width, 0.9f * m_rect.height);
441         trianglePath.lineTo(0.1f * m_rect.width, 0.1f * m_rect.height);
442         trianglePath.lineTo(0.9f * m_rect.width, 0.1f * m_rect.height);
443         SkPaint paint;
444         paint.setColor(foregroundColor);
445         paint.setStyle(SkPaint::kFill_Style);
446         canvas.drawPath(trianglePath, paint);
447     }
448 }
449
450 void TestPlugin::destroyScene()
451 {
452     if (m_scene.program) {
453         m_context->deleteProgram(m_scene.program);
454         m_scene.program = 0;
455     }
456     if (m_scene.vbo) {
457         m_context->deleteBuffer(m_scene.vbo);
458         m_scene.vbo = 0;
459     }
460
461     if (m_framebuffer) {
462         m_context->deleteFramebuffer(m_framebuffer);
463         m_framebuffer = 0;
464     }
465
466     if (m_colorTexture) {
467         m_context->deleteTexture(m_colorTexture);
468         m_colorTexture = 0;
469     }
470 }
471
472 bool TestPlugin::initProgram()
473 {
474     const std::string vertexSource(
475         "attribute vec4 position;  \n"
476         "void main() {             \n"
477         "  gl_Position = position; \n"
478         "}                         \n"
479     );
480
481     const std::string fragmentSource(
482         "precision mediump float; \n"
483         "uniform vec4 color;      \n"
484         "void main() {            \n"
485         "  gl_FragColor = color;  \n"
486         "}                        \n"
487     );
488
489     m_scene.program = loadProgram(vertexSource, fragmentSource);
490     if (!m_scene.program)
491         return false;
492
493     m_scene.colorLocation = m_context->getUniformLocation(m_scene.program, "color");
494     m_scene.positionLocation = m_context->getAttribLocation(m_scene.program, "position");
495     return true;
496 }
497
498 bool TestPlugin::initPrimitive()
499 {
500     DCHECK_EQ(m_scene.primitive, PrimitiveTriangle);
501
502     m_scene.vbo = m_context->createBuffer();
503     if (!m_scene.vbo)
504         return false;
505
506     const float vertices[] = {
507         0.0f,  0.8f, 0.0f,
508         -0.8f, -0.8f, 0.0f,
509         0.8f, -0.8f, 0.0f };
510     m_context->bindBuffer(GL_ARRAY_BUFFER, m_scene.vbo);
511     m_context->bufferData(GL_ARRAY_BUFFER, sizeof(vertices), 0, GL_STATIC_DRAW);
512     m_context->bufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices);
513     return true;
514 }
515
516 void TestPlugin::drawPrimitive()
517 {
518     DCHECK_EQ(m_scene.primitive, PrimitiveTriangle);
519     DCHECK(m_scene.vbo);
520     DCHECK(m_scene.program);
521
522     m_context->useProgram(m_scene.program);
523
524     // Bind primitive color.
525     float color[4];
526     premultiplyAlpha(m_scene.primitiveColor, m_scene.opacity, color);
527     m_context->uniform4f(m_scene.colorLocation, color[0], color[1], color[2], color[3]);
528
529     // Bind primitive vertices.
530     m_context->bindBuffer(GL_ARRAY_BUFFER, m_scene.vbo);
531     m_context->enableVertexAttribArray(m_scene.positionLocation);
532     m_context->vertexAttribPointer(m_scene.positionLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
533     m_context->drawArrays(GL_TRIANGLES, 0, 3);
534 }
535
536 unsigned TestPlugin::loadShader(unsigned type, const std::string& source)
537 {
538     unsigned shader = m_context->createShader(type);
539     if (shader) {
540         m_context->shaderSource(shader, source.data());
541         m_context->compileShader(shader);
542
543         int compiled = 0;
544         m_context->getShaderiv(shader, GL_COMPILE_STATUS, &compiled);
545         if (!compiled) {
546             m_context->deleteShader(shader);
547             shader = 0;
548         }
549     }
550     return shader;
551 }
552
553 unsigned TestPlugin::loadProgram(const std::string& vertexSource, const std::string& fragmentSource)
554 {
555     unsigned vertexShader = loadShader(GL_VERTEX_SHADER, vertexSource);
556     unsigned fragmentShader = loadShader(GL_FRAGMENT_SHADER, fragmentSource);
557     unsigned program = m_context->createProgram();
558     if (vertexShader && fragmentShader && program) {
559         m_context->attachShader(program, vertexShader);
560         m_context->attachShader(program, fragmentShader);
561         m_context->linkProgram(program);
562
563         int linked = 0;
564         m_context->getProgramiv(program, GL_LINK_STATUS, &linked);
565         if (!linked) {
566             m_context->deleteProgram(program);
567             program = 0;
568         }
569     }
570     if (vertexShader)
571         m_context->deleteShader(vertexShader);
572     if (fragmentShader)
573         m_context->deleteShader(fragmentShader);
574
575     return program;
576 }
577
578 bool TestPlugin::handleInputEvent(const WebInputEvent& event, WebCursorInfo& info)
579 {
580     const char* eventName = 0;
581     switch (event.type) {
582     case WebInputEvent::Undefined:           eventName = "unknown"; break;
583
584     case WebInputEvent::MouseDown:           eventName = "MouseDown"; break;
585     case WebInputEvent::MouseUp:             eventName = "MouseUp"; break;
586     case WebInputEvent::MouseMove:           eventName = "MouseMove"; break;
587     case WebInputEvent::MouseEnter:          eventName = "MouseEnter"; break;
588     case WebInputEvent::MouseLeave:          eventName = "MouseLeave"; break;
589     case WebInputEvent::ContextMenu:         eventName = "ContextMenu"; break;
590
591     case WebInputEvent::MouseWheel:          eventName = "MouseWheel"; break;
592
593     case WebInputEvent::RawKeyDown:          eventName = "RawKeyDown"; break;
594     case WebInputEvent::KeyDown:             eventName = "KeyDown"; break;
595     case WebInputEvent::KeyUp:               eventName = "KeyUp"; break;
596     case WebInputEvent::Char:                eventName = "Char"; break;
597
598     case WebInputEvent::GestureScrollBegin:  eventName = "GestureScrollBegin"; break;
599     case WebInputEvent::GestureScrollEnd:    eventName = "GestureScrollEnd"; break;
600     case WebInputEvent::GestureScrollUpdateWithoutPropagation:
601     case WebInputEvent::GestureScrollUpdate: eventName = "GestureScrollUpdate"; break;
602     case WebInputEvent::GestureFlingStart:   eventName = "GestureFlingStart"; break;
603     case WebInputEvent::GestureFlingCancel:  eventName = "GestureFlingCancel"; break;
604     case WebInputEvent::GestureTap:          eventName = "GestureTap"; break;
605     case WebInputEvent::GestureTapUnconfirmed:
606                                              eventName = "GestureTapUnconfirmed"; break;
607     case WebInputEvent::GestureTapDown:      eventName = "GestureTapDown"; break;
608     case WebInputEvent::GestureShowPress:    eventName = "GestureShowPress"; break;
609     case WebInputEvent::GestureTapCancel:    eventName = "GestureTapCancel"; break;
610     case WebInputEvent::GestureDoubleTap:    eventName = "GestureDoubleTap"; break;
611     case WebInputEvent::GestureTwoFingerTap: eventName = "GestureTwoFingerTap"; break;
612     case WebInputEvent::GestureLongPress:    eventName = "GestureLongPress"; break;
613     case WebInputEvent::GestureLongTap:      eventName = "GestureLongTap"; break;
614     case WebInputEvent::GesturePinchBegin:   eventName = "GesturePinchBegin"; break;
615     case WebInputEvent::GesturePinchEnd:     eventName = "GesturePinchEnd"; break;
616     case WebInputEvent::GesturePinchUpdate:  eventName = "GesturePinchUpdate"; break;
617
618     case WebInputEvent::TouchStart:          eventName = "TouchStart"; break;
619     case WebInputEvent::TouchMove:           eventName = "TouchMove"; break;
620     case WebInputEvent::TouchEnd:            eventName = "TouchEnd"; break;
621     case WebInputEvent::TouchCancel:         eventName = "TouchCancel"; break;
622     }
623
624     m_delegate->printMessage(std::string("Plugin received event: ") + (eventName ? eventName : "unknown") + "\n");
625     if (m_printEventDetails)
626         printEventDetails(m_delegate, event);
627     if (m_printUserGestureStatus)
628         m_delegate->printMessage(std::string("* ") + (WebUserGestureIndicator::isProcessingUserGesture() ? "" : "not ") + "handling user gesture\n");
629     if (m_isPersistent)
630         m_delegate->printMessage(std::string("TestPlugin: isPersistent\n"));
631     return false;
632 }
633
634 bool TestPlugin::handleDragStatusUpdate(WebDragStatus dragStatus, const WebDragData&, WebDragOperationsMask, const WebPoint& position, const WebPoint& screenPosition)
635 {
636     const char* dragStatusName = 0;
637     switch (dragStatus) {
638     case WebDragStatusEnter:
639         dragStatusName = "DragEnter";
640         break;
641     case WebDragStatusOver:
642         dragStatusName = "DragOver";
643         break;
644     case WebDragStatusLeave:
645         dragStatusName = "DragLeave";
646         break;
647     case WebDragStatusDrop:
648         dragStatusName = "DragDrop";
649         break;
650     case WebDragStatusUnknown:
651         NOTREACHED();
652     }
653     m_delegate->printMessage(std::string("Plugin received event: ") + dragStatusName + "\n");
654     return false;
655 }
656
657 TestPlugin* TestPlugin::create(WebFrame* frame, const WebPluginParams& params, WebTestDelegate* delegate)
658 {
659     return new TestPlugin(frame, params, delegate);
660 }
661
662 const WebString& TestPlugin::mimeType()
663 {
664     const CR_DEFINE_STATIC_LOCAL(WebString, kMimeType, ("application/x-webkit-test-webplugin"));
665     return kMimeType;
666 }
667
668 const WebString& TestPlugin::canCreateWithoutRendererMimeType()
669 {
670     const CR_DEFINE_STATIC_LOCAL(WebString, kCanCreateWithoutRendererMimeType, ("application/x-webkit-test-webplugin-can-create-without-renderer"));
671     return kCanCreateWithoutRendererMimeType;
672 }
673
674 const WebString& TestPlugin::pluginPersistsMimeType()
675 {
676     const CR_DEFINE_STATIC_LOCAL(WebString, kPluginPersistsMimeType, ("application/x-webkit-test-webplugin-persistent"));
677     return kPluginPersistsMimeType;
678 }
679
680 bool TestPlugin::isSupportedMimeType(const WebString& mimeType)
681 {
682     return mimeType == TestPlugin::mimeType()
683            || mimeType == pluginPersistsMimeType()
684            || mimeType == canCreateWithoutRendererMimeType();
685 }
686
687 }  // namespace content