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/test_plugin.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/web_test_delegate.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 namespace content { 28 29 namespace { 30 31 // GLenum values copied from gl2.h. 32 #define GL_FALSE 0 33 #define GL_TRUE 1 34 #define GL_ONE 1 35 #define GL_TRIANGLES 0x0004 36 #define GL_ONE_MINUS_SRC_ALPHA 0x0303 37 #define GL_DEPTH_TEST 0x0B71 38 #define GL_BLEND 0x0BE2 39 #define GL_SCISSOR_TEST 0x0B90 40 #define GL_TEXTURE_2D 0x0DE1 41 #define GL_FLOAT 0x1406 42 #define GL_RGBA 0x1908 43 #define GL_UNSIGNED_BYTE 0x1401 44 #define GL_TEXTURE_MAG_FILTER 0x2800 45 #define GL_TEXTURE_MIN_FILTER 0x2801 46 #define GL_TEXTURE_WRAP_S 0x2802 47 #define GL_TEXTURE_WRAP_T 0x2803 48 #define GL_NEAREST 0x2600 49 #define GL_COLOR_BUFFER_BIT 0x4000 50 #define GL_CLAMP_TO_EDGE 0x812F 51 #define GL_ARRAY_BUFFER 0x8892 52 #define GL_STATIC_DRAW 0x88E4 53 #define GL_FRAGMENT_SHADER 0x8B30 54 #define GL_VERTEX_SHADER 0x8B31 55 #define GL_COMPILE_STATUS 0x8B81 56 #define GL_LINK_STATUS 0x8B82 57 #define GL_COLOR_ATTACHMENT0 0x8CE0 58 #define GL_FRAMEBUFFER_COMPLETE 0x8CD5 59 #define GL_FRAMEBUFFER 0x8D40 60 61 void PremultiplyAlpha(const unsigned color_in[3], 62 float alpha, 63 float color_out[4]) { 64 for (int i = 0; i < 3; ++i) 65 color_out[i] = (color_in[i] / 255.0f) * alpha; 66 67 color_out[3] = alpha; 68 } 69 70 const char* PointState(blink::WebTouchPoint::State state) { 71 switch (state) { 72 case blink::WebTouchPoint::StateReleased: 73 return "Released"; 74 case blink::WebTouchPoint::StatePressed: 75 return "Pressed"; 76 case blink::WebTouchPoint::StateMoved: 77 return "Moved"; 78 case blink::WebTouchPoint::StateCancelled: 79 return "Cancelled"; 80 default: 81 return "Unknown"; 82 } 83 } 84 85 void PrintTouchList(WebTestDelegate* delegate, 86 const blink::WebTouchPoint* points, 87 int length) { 88 for (int i = 0; i < length; ++i) { 89 delegate->PrintMessage(base::StringPrintf("* %.2f, %.2f: %s\n", 90 points[i].position.x, 91 points[i].position.y, 92 PointState(points[i].state))); 93 } 94 } 95 96 void PrintEventDetails(WebTestDelegate* delegate, 97 const blink::WebInputEvent& event) { 98 if (blink::WebInputEvent::isTouchEventType(event.type)) { 99 const blink::WebTouchEvent& touch = 100 static_cast<const blink::WebTouchEvent&>(event); 101 PrintTouchList(delegate, touch.touches, touch.touchesLength); 102 } else if (blink::WebInputEvent::isMouseEventType(event.type) || 103 event.type == blink::WebInputEvent::MouseWheel) { 104 const blink::WebMouseEvent& mouse = 105 static_cast<const blink::WebMouseEvent&>(event); 106 delegate->PrintMessage(base::StringPrintf("* %d, %d\n", mouse.x, mouse.y)); 107 } else if (blink::WebInputEvent::isGestureEventType(event.type)) { 108 const blink::WebGestureEvent& gesture = 109 static_cast<const blink::WebGestureEvent&>(event); 110 delegate->PrintMessage( 111 base::StringPrintf("* %d, %d\n", gesture.x, gesture.y)); 112 } 113 } 114 115 blink::WebPluginContainer::TouchEventRequestType ParseTouchEventRequestType( 116 const blink::WebString& string) { 117 if (string == blink::WebString::fromUTF8("raw")) 118 return blink::WebPluginContainer::TouchEventRequestTypeRaw; 119 if (string == blink::WebString::fromUTF8("synthetic")) 120 return blink::WebPluginContainer::TouchEventRequestTypeSynthesizedMouse; 121 return blink::WebPluginContainer::TouchEventRequestTypeNone; 122 } 123 124 void DeferredDelete(void* context) { 125 TestPlugin* plugin = static_cast<TestPlugin*>(context); 126 delete plugin; 127 } 128 129 } // namespace 130 131 TestPlugin::TestPlugin(blink::WebFrame* frame, 132 const blink::WebPluginParams& params, 133 WebTestDelegate* delegate) 134 : frame_(frame), 135 delegate_(delegate), 136 container_(0), 137 context_(0), 138 color_texture_(0), 139 mailbox_changed_(false), 140 framebuffer_(0), 141 touch_event_request_( 142 blink::WebPluginContainer::TouchEventRequestTypeNone), 143 re_request_touch_events_(false), 144 print_event_details_(false), 145 print_user_gesture_status_(false), 146 can_process_drag_(false), 147 is_persistent_(params.mimeType == PluginPersistsMimeType()), 148 can_create_without_renderer_(params.mimeType == 149 CanCreateWithoutRendererMimeType()) { 150 const CR_DEFINE_STATIC_LOCAL( 151 blink::WebString, kAttributePrimitive, ("primitive")); 152 const CR_DEFINE_STATIC_LOCAL( 153 blink::WebString, kAttributeBackgroundColor, ("background-color")); 154 const CR_DEFINE_STATIC_LOCAL( 155 blink::WebString, kAttributePrimitiveColor, ("primitive-color")); 156 const CR_DEFINE_STATIC_LOCAL( 157 blink::WebString, kAttributeOpacity, ("opacity")); 158 const CR_DEFINE_STATIC_LOCAL( 159 blink::WebString, kAttributeAcceptsTouch, ("accepts-touch")); 160 const CR_DEFINE_STATIC_LOCAL( 161 blink::WebString, kAttributeReRequestTouchEvents, ("re-request-touch")); 162 const CR_DEFINE_STATIC_LOCAL( 163 blink::WebString, kAttributePrintEventDetails, ("print-event-details")); 164 const CR_DEFINE_STATIC_LOCAL( 165 blink::WebString, kAttributeCanProcessDrag, ("can-process-drag")); 166 const CR_DEFINE_STATIC_LOCAL(blink::WebString, 167 kAttributePrintUserGestureStatus, 168 ("print-user-gesture-status")); 169 170 DCHECK_EQ(params.attributeNames.size(), params.attributeValues.size()); 171 size_t size = params.attributeNames.size(); 172 for (size_t i = 0; i < size; ++i) { 173 const blink::WebString& attribute_name = params.attributeNames[i]; 174 const blink::WebString& attribute_value = params.attributeValues[i]; 175 176 if (attribute_name == kAttributePrimitive) 177 scene_.primitive = ParsePrimitive(attribute_value); 178 else if (attribute_name == kAttributeBackgroundColor) 179 ParseColor(attribute_value, scene_.background_color); 180 else if (attribute_name == kAttributePrimitiveColor) 181 ParseColor(attribute_value, scene_.primitive_color); 182 else if (attribute_name == kAttributeOpacity) 183 scene_.opacity = ParseOpacity(attribute_value); 184 else if (attribute_name == kAttributeAcceptsTouch) 185 touch_event_request_ = ParseTouchEventRequestType(attribute_value); 186 else if (attribute_name == kAttributeReRequestTouchEvents) 187 re_request_touch_events_ = ParseBoolean(attribute_value); 188 else if (attribute_name == kAttributePrintEventDetails) 189 print_event_details_ = ParseBoolean(attribute_value); 190 else if (attribute_name == kAttributeCanProcessDrag) 191 can_process_drag_ = ParseBoolean(attribute_value); 192 else if (attribute_name == kAttributePrintUserGestureStatus) 193 print_user_gesture_status_ = ParseBoolean(attribute_value); 194 } 195 if (can_create_without_renderer_) 196 delegate_->PrintMessage( 197 std::string("TestPlugin: canCreateWithoutRenderer\n")); 198 } 199 200 TestPlugin::~TestPlugin() { 201 } 202 203 bool TestPlugin::initialize(blink::WebPluginContainer* container) { 204 blink::WebGraphicsContext3D::Attributes attrs; 205 context_ = 206 blink::Platform::current()->createOffscreenGraphicsContext3D(attrs); 207 208 if (!InitScene()) 209 return false; 210 211 layer_ = cc::TextureLayer::CreateForMailbox(this); 212 web_layer_ = make_scoped_ptr(InstantiateWebLayer(layer_)); 213 container_ = container; 214 container_->setWebLayer(web_layer_.get()); 215 if (re_request_touch_events_) { 216 container_->requestTouchEventType( 217 blink::WebPluginContainer::TouchEventRequestTypeSynthesizedMouse); 218 container_->requestTouchEventType( 219 blink::WebPluginContainer::TouchEventRequestTypeRaw); 220 } 221 container_->requestTouchEventType(touch_event_request_); 222 container_->setWantsWheelEvents(true); 223 return true; 224 } 225 226 void TestPlugin::destroy() { 227 if (layer_.get()) 228 layer_->ClearTexture(); 229 if (container_) 230 container_->setWebLayer(0); 231 web_layer_.reset(); 232 layer_ = NULL; 233 DestroyScene(); 234 235 delete context_; 236 context_ = 0; 237 238 container_ = 0; 239 frame_ = 0; 240 241 blink::Platform::current()->callOnMainThread(DeferredDelete, this); 242 } 243 244 NPObject* TestPlugin::scriptableObject() { 245 return 0; 246 } 247 248 bool TestPlugin::canProcessDrag() const { 249 return can_process_drag_; 250 } 251 252 void TestPlugin::updateGeometry( 253 const blink::WebRect& frame_rect, 254 const blink::WebRect& clip_rect, 255 const blink::WebVector<blink::WebRect>& cut_outs_rects, 256 bool is_visible) { 257 if (clip_rect == rect_) 258 return; 259 rect_ = clip_rect; 260 261 if (rect_.isEmpty()) { 262 texture_mailbox_ = cc::TextureMailbox(); 263 } else if (context_) { 264 context_->viewport(0, 0, rect_.width, rect_.height); 265 266 context_->bindTexture(GL_TEXTURE_2D, color_texture_); 267 context_->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 268 context_->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 269 context_->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 270 context_->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 271 context_->texImage2D(GL_TEXTURE_2D, 272 0, 273 GL_RGBA, 274 rect_.width, 275 rect_.height, 276 0, 277 GL_RGBA, 278 GL_UNSIGNED_BYTE, 279 0); 280 context_->bindFramebuffer(GL_FRAMEBUFFER, framebuffer_); 281 context_->framebufferTexture2D( 282 GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color_texture_, 0); 283 284 DrawSceneGL(); 285 286 gpu::Mailbox mailbox; 287 context_->genMailboxCHROMIUM(mailbox.name); 288 context_->produceTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name); 289 context_->flush(); 290 uint32 sync_point = context_->insertSyncPoint(); 291 texture_mailbox_ = cc::TextureMailbox(mailbox, GL_TEXTURE_2D, sync_point); 292 } else { 293 size_t bytes = 4 * rect_.width * rect_.height; 294 scoped_ptr<base::SharedMemory> bitmap = 295 RenderThread::Get()->HostAllocateSharedMemoryBuffer(bytes); 296 if (!bitmap->Map(bytes)) { 297 texture_mailbox_ = cc::TextureMailbox(); 298 } else { 299 DrawSceneSoftware(bitmap->memory(), bytes); 300 texture_mailbox_ = cc::TextureMailbox( 301 bitmap.get(), gfx::Size(rect_.width, rect_.height)); 302 shared_bitmap_ = bitmap.Pass(); 303 } 304 } 305 306 mailbox_changed_ = true; 307 layer_->SetNeedsDisplay(); 308 } 309 310 bool TestPlugin::acceptsInputEvents() { 311 return true; 312 } 313 314 bool TestPlugin::isPlaceholder() { 315 return false; 316 } 317 318 static void IgnoreReleaseCallback(uint32 sync_point, bool lost) { 319 } 320 321 static void ReleaseSharedMemory(scoped_ptr<base::SharedMemory> bitmap, 322 uint32 sync_point, 323 bool lost) { 324 } 325 326 bool TestPlugin::PrepareTextureMailbox( 327 cc::TextureMailbox* mailbox, 328 scoped_ptr<cc::SingleReleaseCallback>* release_callback, 329 bool use_shared_memory) { 330 if (!mailbox_changed_) 331 return false; 332 *mailbox = texture_mailbox_; 333 if (texture_mailbox_.IsTexture()) { 334 *release_callback = 335 cc::SingleReleaseCallback::Create(base::Bind(&IgnoreReleaseCallback)); 336 } else { 337 *release_callback = cc::SingleReleaseCallback::Create( 338 base::Bind(&ReleaseSharedMemory, base::Passed(&shared_bitmap_))); 339 } 340 mailbox_changed_ = false; 341 return true; 342 } 343 344 TestPlugin::Primitive TestPlugin::ParsePrimitive( 345 const blink::WebString& string) { 346 const CR_DEFINE_STATIC_LOCAL(blink::WebString, kPrimitiveNone, ("none")); 347 const CR_DEFINE_STATIC_LOCAL( 348 blink::WebString, kPrimitiveTriangle, ("triangle")); 349 350 Primitive primitive = PrimitiveNone; 351 if (string == kPrimitiveNone) 352 primitive = PrimitiveNone; 353 else if (string == kPrimitiveTriangle) 354 primitive = PrimitiveTriangle; 355 else 356 NOTREACHED(); 357 return primitive; 358 } 359 360 // FIXME: This method should already exist. Use it. 361 // For now just parse primary colors. 362 void TestPlugin::ParseColor(const blink::WebString& string, unsigned color[3]) { 363 color[0] = color[1] = color[2] = 0; 364 if (string == "black") 365 return; 366 367 if (string == "red") 368 color[0] = 255; 369 else if (string == "green") 370 color[1] = 255; 371 else if (string == "blue") 372 color[2] = 255; 373 else 374 NOTREACHED(); 375 } 376 377 float TestPlugin::ParseOpacity(const blink::WebString& string) { 378 return static_cast<float>(atof(string.utf8().data())); 379 } 380 381 bool TestPlugin::ParseBoolean(const blink::WebString& string) { 382 const CR_DEFINE_STATIC_LOCAL(blink::WebString, kPrimitiveTrue, ("true")); 383 return string == kPrimitiveTrue; 384 } 385 386 bool TestPlugin::InitScene() { 387 if (!context_) 388 return true; 389 390 float color[4]; 391 PremultiplyAlpha(scene_.background_color, scene_.opacity, color); 392 393 color_texture_ = context_->createTexture(); 394 framebuffer_ = context_->createFramebuffer(); 395 396 context_->viewport(0, 0, rect_.width, rect_.height); 397 context_->disable(GL_DEPTH_TEST); 398 context_->disable(GL_SCISSOR_TEST); 399 400 context_->clearColor(color[0], color[1], color[2], color[3]); 401 402 context_->enable(GL_BLEND); 403 context_->blendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); 404 405 return scene_.primitive != PrimitiveNone ? InitProgram() && InitPrimitive() 406 : true; 407 } 408 409 void TestPlugin::DrawSceneGL() { 410 context_->viewport(0, 0, rect_.width, rect_.height); 411 context_->clear(GL_COLOR_BUFFER_BIT); 412 413 if (scene_.primitive != PrimitiveNone) 414 DrawPrimitive(); 415 } 416 417 void TestPlugin::DrawSceneSoftware(void* memory, size_t bytes) { 418 DCHECK_EQ(bytes, rect_.width * rect_.height * 4u); 419 420 SkColor background_color = 421 SkColorSetARGB(static_cast<uint8>(scene_.opacity * 255), 422 scene_.background_color[0], 423 scene_.background_color[1], 424 scene_.background_color[2]); 425 426 const SkImageInfo info = 427 SkImageInfo::MakeN32Premul(rect_.width, rect_.height); 428 SkBitmap bitmap; 429 bitmap.installPixels(info, memory, info.minRowBytes()); 430 SkCanvas canvas(bitmap); 431 canvas.clear(background_color); 432 433 if (scene_.primitive != PrimitiveNone) { 434 DCHECK_EQ(PrimitiveTriangle, scene_.primitive); 435 SkColor foreground_color = 436 SkColorSetARGB(static_cast<uint8>(scene_.opacity * 255), 437 scene_.primitive_color[0], 438 scene_.primitive_color[1], 439 scene_.primitive_color[2]); 440 SkPath triangle_path; 441 triangle_path.moveTo(0.5f * rect_.width, 0.9f * rect_.height); 442 triangle_path.lineTo(0.1f * rect_.width, 0.1f * rect_.height); 443 triangle_path.lineTo(0.9f * rect_.width, 0.1f * rect_.height); 444 SkPaint paint; 445 paint.setColor(foreground_color); 446 paint.setStyle(SkPaint::kFill_Style); 447 canvas.drawPath(triangle_path, paint); 448 } 449 } 450 451 void TestPlugin::DestroyScene() { 452 if (scene_.program) { 453 context_->deleteProgram(scene_.program); 454 scene_.program = 0; 455 } 456 if (scene_.vbo) { 457 context_->deleteBuffer(scene_.vbo); 458 scene_.vbo = 0; 459 } 460 461 if (framebuffer_) { 462 context_->deleteFramebuffer(framebuffer_); 463 framebuffer_ = 0; 464 } 465 466 if (color_texture_) { 467 context_->deleteTexture(color_texture_); 468 color_texture_ = 0; 469 } 470 } 471 472 bool TestPlugin::InitProgram() { 473 const std::string vertex_source( 474 "attribute vec4 position; \n" 475 "void main() { \n" 476 " gl_Position = position; \n" 477 "} \n"); 478 479 const std::string fragment_source( 480 "precision mediump float; \n" 481 "uniform vec4 color; \n" 482 "void main() { \n" 483 " gl_FragColor = color; \n" 484 "} \n"); 485 486 scene_.program = LoadProgram(vertex_source, fragment_source); 487 if (!scene_.program) 488 return false; 489 490 scene_.color_location = context_->getUniformLocation(scene_.program, "color"); 491 scene_.position_location = 492 context_->getAttribLocation(scene_.program, "position"); 493 return true; 494 } 495 496 bool TestPlugin::InitPrimitive() { 497 DCHECK_EQ(scene_.primitive, PrimitiveTriangle); 498 499 scene_.vbo = context_->createBuffer(); 500 if (!scene_.vbo) 501 return false; 502 503 const float vertices[] = {0.0f, 0.8f, 0.0f, -0.8f, -0.8f, 504 0.0f, 0.8f, -0.8f, 0.0f}; 505 context_->bindBuffer(GL_ARRAY_BUFFER, scene_.vbo); 506 context_->bufferData(GL_ARRAY_BUFFER, sizeof(vertices), 0, GL_STATIC_DRAW); 507 context_->bufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices); 508 return true; 509 } 510 511 void TestPlugin::DrawPrimitive() { 512 DCHECK_EQ(scene_.primitive, PrimitiveTriangle); 513 DCHECK(scene_.vbo); 514 DCHECK(scene_.program); 515 516 context_->useProgram(scene_.program); 517 518 // Bind primitive color. 519 float color[4]; 520 PremultiplyAlpha(scene_.primitive_color, scene_.opacity, color); 521 context_->uniform4f( 522 scene_.color_location, color[0], color[1], color[2], color[3]); 523 524 // Bind primitive vertices. 525 context_->bindBuffer(GL_ARRAY_BUFFER, scene_.vbo); 526 context_->enableVertexAttribArray(scene_.position_location); 527 context_->vertexAttribPointer( 528 scene_.position_location, 3, GL_FLOAT, GL_FALSE, 0, 0); 529 context_->drawArrays(GL_TRIANGLES, 0, 3); 530 } 531 532 unsigned TestPlugin::LoadShader(unsigned type, const std::string& source) { 533 unsigned shader = context_->createShader(type); 534 if (shader) { 535 context_->shaderSource(shader, source.data()); 536 context_->compileShader(shader); 537 538 int compiled = 0; 539 context_->getShaderiv(shader, GL_COMPILE_STATUS, &compiled); 540 if (!compiled) { 541 context_->deleteShader(shader); 542 shader = 0; 543 } 544 } 545 return shader; 546 } 547 548 unsigned TestPlugin::LoadProgram(const std::string& vertex_source, 549 const std::string& fragment_source) { 550 unsigned vertex_shader = LoadShader(GL_VERTEX_SHADER, vertex_source); 551 unsigned fragment_shader = LoadShader(GL_FRAGMENT_SHADER, fragment_source); 552 unsigned program = context_->createProgram(); 553 if (vertex_shader && fragment_shader && program) { 554 context_->attachShader(program, vertex_shader); 555 context_->attachShader(program, fragment_shader); 556 context_->linkProgram(program); 557 558 int linked = 0; 559 context_->getProgramiv(program, GL_LINK_STATUS, &linked); 560 if (!linked) { 561 context_->deleteProgram(program); 562 program = 0; 563 } 564 } 565 if (vertex_shader) 566 context_->deleteShader(vertex_shader); 567 if (fragment_shader) 568 context_->deleteShader(fragment_shader); 569 570 return program; 571 } 572 573 bool TestPlugin::handleInputEvent(const blink::WebInputEvent& event, 574 blink::WebCursorInfo& info) { 575 const char* event_name = 0; 576 switch (event.type) { 577 case blink::WebInputEvent::Undefined: 578 event_name = "unknown"; 579 break; 580 581 case blink::WebInputEvent::MouseDown: 582 event_name = "MouseDown"; 583 break; 584 case blink::WebInputEvent::MouseUp: 585 event_name = "MouseUp"; 586 break; 587 case blink::WebInputEvent::MouseMove: 588 event_name = "MouseMove"; 589 break; 590 case blink::WebInputEvent::MouseEnter: 591 event_name = "MouseEnter"; 592 break; 593 case blink::WebInputEvent::MouseLeave: 594 event_name = "MouseLeave"; 595 break; 596 case blink::WebInputEvent::ContextMenu: 597 event_name = "ContextMenu"; 598 break; 599 600 case blink::WebInputEvent::MouseWheel: 601 event_name = "MouseWheel"; 602 break; 603 604 case blink::WebInputEvent::RawKeyDown: 605 event_name = "RawKeyDown"; 606 break; 607 case blink::WebInputEvent::KeyDown: 608 event_name = "KeyDown"; 609 break; 610 case blink::WebInputEvent::KeyUp: 611 event_name = "KeyUp"; 612 break; 613 case blink::WebInputEvent::Char: 614 event_name = "Char"; 615 break; 616 617 case blink::WebInputEvent::GestureScrollBegin: 618 event_name = "GestureScrollBegin"; 619 break; 620 case blink::WebInputEvent::GestureScrollEnd: 621 event_name = "GestureScrollEnd"; 622 break; 623 case blink::WebInputEvent::GestureScrollUpdateWithoutPropagation: 624 case blink::WebInputEvent::GestureScrollUpdate: 625 event_name = "GestureScrollUpdate"; 626 break; 627 case blink::WebInputEvent::GestureFlingStart: 628 event_name = "GestureFlingStart"; 629 break; 630 case blink::WebInputEvent::GestureFlingCancel: 631 event_name = "GestureFlingCancel"; 632 break; 633 case blink::WebInputEvent::GestureTap: 634 event_name = "GestureTap"; 635 break; 636 case blink::WebInputEvent::GestureTapUnconfirmed: 637 event_name = "GestureTapUnconfirmed"; 638 break; 639 case blink::WebInputEvent::GestureTapDown: 640 event_name = "GestureTapDown"; 641 break; 642 case blink::WebInputEvent::GestureShowPress: 643 event_name = "GestureShowPress"; 644 break; 645 case blink::WebInputEvent::GestureTapCancel: 646 event_name = "GestureTapCancel"; 647 break; 648 case blink::WebInputEvent::GestureDoubleTap: 649 event_name = "GestureDoubleTap"; 650 break; 651 case blink::WebInputEvent::GestureTwoFingerTap: 652 event_name = "GestureTwoFingerTap"; 653 break; 654 case blink::WebInputEvent::GestureLongPress: 655 event_name = "GestureLongPress"; 656 break; 657 case blink::WebInputEvent::GestureLongTap: 658 event_name = "GestureLongTap"; 659 break; 660 case blink::WebInputEvent::GesturePinchBegin: 661 event_name = "GesturePinchBegin"; 662 break; 663 case blink::WebInputEvent::GesturePinchEnd: 664 event_name = "GesturePinchEnd"; 665 break; 666 case blink::WebInputEvent::GesturePinchUpdate: 667 event_name = "GesturePinchUpdate"; 668 break; 669 670 case blink::WebInputEvent::TouchStart: 671 event_name = "TouchStart"; 672 break; 673 case blink::WebInputEvent::TouchMove: 674 event_name = "TouchMove"; 675 break; 676 case blink::WebInputEvent::TouchEnd: 677 event_name = "TouchEnd"; 678 break; 679 case blink::WebInputEvent::TouchCancel: 680 event_name = "TouchCancel"; 681 break; 682 } 683 684 delegate_->PrintMessage(std::string("Plugin received event: ") + 685 (event_name ? event_name : "unknown") + "\n"); 686 if (print_event_details_) 687 PrintEventDetails(delegate_, event); 688 if (print_user_gesture_status_) 689 delegate_->PrintMessage( 690 std::string("* ") + 691 (blink::WebUserGestureIndicator::isProcessingUserGesture() ? "" 692 : "not ") + 693 "handling user gesture\n"); 694 if (is_persistent_) 695 delegate_->PrintMessage(std::string("TestPlugin: isPersistent\n")); 696 return false; 697 } 698 699 bool TestPlugin::handleDragStatusUpdate( 700 blink::WebDragStatus drag_status, 701 const blink::WebDragData& data, 702 blink::WebDragOperationsMask mask, 703 const blink::WebPoint& position, 704 const blink::WebPoint& screen_position) { 705 const char* drag_status_name = 0; 706 switch (drag_status) { 707 case blink::WebDragStatusEnter: 708 drag_status_name = "DragEnter"; 709 break; 710 case blink::WebDragStatusOver: 711 drag_status_name = "DragOver"; 712 break; 713 case blink::WebDragStatusLeave: 714 drag_status_name = "DragLeave"; 715 break; 716 case blink::WebDragStatusDrop: 717 drag_status_name = "DragDrop"; 718 break; 719 case blink::WebDragStatusUnknown: 720 NOTREACHED(); 721 } 722 delegate_->PrintMessage(std::string("Plugin received event: ") + 723 drag_status_name + "\n"); 724 return false; 725 } 726 727 TestPlugin* TestPlugin::create(blink::WebFrame* frame, 728 const blink::WebPluginParams& params, 729 WebTestDelegate* delegate) { 730 return new TestPlugin(frame, params, delegate); 731 } 732 733 const blink::WebString& TestPlugin::MimeType() { 734 const CR_DEFINE_STATIC_LOCAL( 735 blink::WebString, kMimeType, ("application/x-webkit-test-webplugin")); 736 return kMimeType; 737 } 738 739 const blink::WebString& TestPlugin::CanCreateWithoutRendererMimeType() { 740 const CR_DEFINE_STATIC_LOCAL( 741 blink::WebString, 742 kCanCreateWithoutRendererMimeType, 743 ("application/x-webkit-test-webplugin-can-create-without-renderer")); 744 return kCanCreateWithoutRendererMimeType; 745 } 746 747 const blink::WebString& TestPlugin::PluginPersistsMimeType() { 748 const CR_DEFINE_STATIC_LOCAL( 749 blink::WebString, 750 kPluginPersistsMimeType, 751 ("application/x-webkit-test-webplugin-persistent")); 752 return kPluginPersistsMimeType; 753 } 754 755 bool TestPlugin::IsSupportedMimeType(const blink::WebString& mime_type) { 756 return mime_type == TestPlugin::MimeType() || 757 mime_type == PluginPersistsMimeType() || 758 mime_type == CanCreateWithoutRendererMimeType(); 759 } 760 761 } // namespace content 762