| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 // | 4 // |
| 5 // Note: This header doesn't use REGISTER_TYPED_TEST_CASE_P like most | 5 // Note: This header doesn't use REGISTER_TYPED_TEST_CASE_P like most |
| 6 // type-parameterized gtests. There are lot of test cases in here that are only | 6 // type-parameterized gtests. There are lot of test cases in here that are only |
| 7 // enabled on certain platforms. However, preprocessor directives in macro | 7 // enabled on certain platforms. However, preprocessor directives in macro |
| 8 // arguments result in undefined behavior (and don't work on MSVC). Instead, | 8 // arguments result in undefined behavior (and don't work on MSVC). Instead, |
| 9 // 'parameterized' tests should typedef TypesToTest (which is used to | 9 // 'parameterized' tests should typedef TypesToTest (which is used to |
| 10 // instantiate the tests using the TYPED_TEST_CASE macro) and then #include this | 10 // instantiate the tests using the TYPED_TEST_CASE macro) and then #include this |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 54 #if defined(USE_AURA) | 54 #if defined(USE_AURA) |
| 55 ClipboardTest() | 55 ClipboardTest() |
| 56 : event_source_(PlatformEventSource::CreateDefault()), | 56 : event_source_(PlatformEventSource::CreateDefault()), |
| 57 clipboard_(ClipboardTraits::Create()) {} | 57 clipboard_(ClipboardTraits::Create()) {} |
| 58 #else | 58 #else |
| 59 ClipboardTest() : clipboard_(ClipboardTraits::Create()) {} | 59 ClipboardTest() : clipboard_(ClipboardTraits::Create()) {} |
| 60 #endif | 60 #endif |
| 61 | 61 |
| 62 ~ClipboardTest() override { ClipboardTraits::Destroy(clipboard_); } | 62 ~ClipboardTest() override { ClipboardTraits::Destroy(clipboard_); } |
| 63 | 63 |
| 64 static void WriteObjectsToClipboard(ui::Clipboard* clipboard, | |
| 65 const Clipboard::ObjectMap& objects) { | |
| 66 clipboard->WriteObjects(ui::CLIPBOARD_TYPE_COPY_PASTE, objects); | |
| 67 } | |
| 68 | |
| 69 protected: | 64 protected: |
| 70 Clipboard& clipboard() { return *clipboard_; } | 65 Clipboard& clipboard() { return *clipboard_; } |
| 71 | 66 |
| 72 void WriteObjectsToClipboard(const Clipboard::ObjectMap& objects) { | |
| 73 WriteObjectsToClipboard(&clipboard(), objects); | |
| 74 } | |
| 75 | |
| 76 private: | 67 private: |
| 77 base::MessageLoopForUI message_loop_; | 68 base::MessageLoopForUI message_loop_; |
| 78 #if defined(USE_AURA) | 69 #if defined(USE_AURA) |
| 79 scoped_ptr<PlatformEventSource> event_source_; | 70 scoped_ptr<PlatformEventSource> event_source_; |
| 80 #endif | 71 #endif |
| 81 // ui::Clipboard has a protected destructor, so scoped_ptr doesn't work here. | 72 // ui::Clipboard has a protected destructor, so scoped_ptr doesn't work here. |
| 82 Clipboard* const clipboard_; | 73 Clipboard* const clipboard_; |
| 83 }; | 74 }; |
| 84 | 75 |
| 85 // Hack for tests that need to call static methods of ClipboardTest. | 76 // Hack for tests that need to call static methods of ClipboardTest. |
| (...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 342 EXPECT_EQ(UTF16ToUTF8(url), ascii_text); | 333 EXPECT_EQ(UTF16ToUTF8(url), ascii_text); |
| 343 | 334 |
| 344 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) && \ | 335 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) && \ |
| 345 !defined(OS_CHROMEOS) | 336 !defined(OS_CHROMEOS) |
| 346 ascii_text.clear(); | 337 ascii_text.clear(); |
| 347 this->clipboard().ReadAsciiText(CLIPBOARD_TYPE_SELECTION, &ascii_text); | 338 this->clipboard().ReadAsciiText(CLIPBOARD_TYPE_SELECTION, &ascii_text); |
| 348 EXPECT_EQ(UTF16ToUTF8(url), ascii_text); | 339 EXPECT_EQ(UTF16ToUTF8(url), ascii_text); |
| 349 #endif | 340 #endif |
| 350 } | 341 } |
| 351 | 342 |
| 352 // TODO(dcheng): The tests for copying to the clipboard also test IPC | |
| 353 // interaction... consider moving them to a different layer so we can | |
| 354 // consolidate the validation logic. | |
| 355 // Note that |bitmap_data| is not premultiplied! | |
| 356 static void TestBitmapWrite(Clipboard* clipboard, | 343 static void TestBitmapWrite(Clipboard* clipboard, |
| 357 const uint32* bitmap_data, | 344 const gfx::Size& size, |
| 358 size_t bitmap_data_size, | 345 const uint32* bitmap_data) { |
| 359 const gfx::Size& size) { | 346 { |
| 360 // Create shared memory region. | 347 ScopedClipboardWriter scw(CLIPBOARD_TYPE_COPY_PASTE); |
| 361 base::SharedMemory shared_buf; | 348 SkBitmap bitmap; |
| 362 ASSERT_TRUE(shared_buf.CreateAndMapAnonymous(bitmap_data_size)); | 349 ASSERT_TRUE(bitmap.setInfo( |
| 363 memcpy(shared_buf.memory(), bitmap_data, bitmap_data_size); | 350 SkImageInfo::MakeN32Premul(size.width(), size.height()))); |
| 364 // CBF_SMBITMAP expects premultiplied bitmap data so do that now. | 351 bitmap.setPixels( |
| 365 uint32* pixel_buffer = static_cast<uint32*>(shared_buf.memory()); | 352 const_cast<void*>(reinterpret_cast<const void*>(bitmap_data))); |
| 366 for (int j = 0; j < size.height(); ++j) { | 353 scw.WriteImage(bitmap); |
| 367 for (int i = 0; i < size.width(); ++i) { | |
| 368 uint32& pixel = pixel_buffer[i + j * size.width()]; | |
| 369 pixel = SkPreMultiplyColor(pixel); | |
| 370 } | |
| 371 } | 354 } |
| 372 base::SharedMemoryHandle handle_to_share; | |
| 373 base::ProcessHandle current_process = base::kNullProcessHandle; | |
| 374 #if defined(OS_WIN) | |
| 375 current_process = GetCurrentProcess(); | |
| 376 #endif | |
| 377 shared_buf.ShareToProcess(current_process, &handle_to_share); | |
| 378 ASSERT_TRUE(shared_buf.Unmap()); | |
| 379 | |
| 380 // Setup data for clipboard(). | |
| 381 Clipboard::ObjectMapParam placeholder_param; | |
| 382 Clipboard::ObjectMapParam size_param; | |
| 383 const char* size_data = reinterpret_cast<const char*>(&size); | |
| 384 for (size_t i = 0; i < sizeof(size); ++i) | |
| 385 size_param.push_back(size_data[i]); | |
| 386 | |
| 387 Clipboard::ObjectMapParams params; | |
| 388 params.push_back(placeholder_param); | |
| 389 params.push_back(size_param); | |
| 390 | |
| 391 Clipboard::ObjectMap objects; | |
| 392 objects[Clipboard::CBF_SMBITMAP] = params; | |
| 393 ASSERT_TRUE(Clipboard::ReplaceSharedMemHandle(&objects, handle_to_share, | |
| 394 current_process)); | |
| 395 | |
| 396 // This is pretty ugly, but the template type parameter is irrelevant... and | |
| 397 // this test will be going away anyway. | |
| 398 ClipboardTest<NullClipboardTraits>::WriteObjectsToClipboard(clipboard, | |
| 399 objects); | |
| 400 | 355 |
| 401 EXPECT_TRUE(clipboard->IsFormatAvailable(Clipboard::GetBitmapFormatType(), | 356 EXPECT_TRUE(clipboard->IsFormatAvailable(Clipboard::GetBitmapFormatType(), |
| 402 CLIPBOARD_TYPE_COPY_PASTE)); | 357 CLIPBOARD_TYPE_COPY_PASTE)); |
| 403 const SkBitmap& image = clipboard->ReadImage(CLIPBOARD_TYPE_COPY_PASTE); | 358 const SkBitmap& image = clipboard->ReadImage(CLIPBOARD_TYPE_COPY_PASTE); |
| 404 EXPECT_EQ(size, gfx::Size(image.width(), image.height())); | 359 EXPECT_EQ(size, gfx::Size(image.width(), image.height())); |
| 405 SkAutoLockPixels image_lock(image); | 360 SkAutoLockPixels image_lock(image); |
| 406 for (int j = 0; j < image.height(); ++j) { | 361 for (int j = 0; j < image.height(); ++j) { |
| 407 const uint32* row_address = image.getAddr32(0, j); | 362 const uint32* row_address = image.getAddr32(0, j); |
| 408 for (int i = 0; i < image.width(); ++i) { | 363 for (int i = 0; i < image.width(); ++i) { |
| 409 int offset = i + j * image.width(); | 364 int offset = i + j * image.width(); |
| 410 uint32 pixel = SkPreMultiplyColor(bitmap_data[offset]); | 365 EXPECT_EQ(bitmap_data[offset], row_address[i]) << "i = " << i |
| 411 EXPECT_EQ(pixel, row_address[i]) << "i = " << i << ", j = " << j; | 366 << ", j = " << j; |
| 412 } | 367 } |
| 413 } | 368 } |
| 414 } | 369 } |
| 415 | 370 |
| 416 TYPED_TEST(ClipboardTest, SharedBitmapTest) { | 371 TYPED_TEST(ClipboardTest, SharedBitmapTest) { |
| 417 const uint32 fake_bitmap_1[] = { | 372 const uint32 fake_bitmap_1[] = { |
| 418 0x46155189, 0xF6A55C8D, 0x79845674, 0xFA57BD89, | 373 0x46061626, 0xf69f5988, 0x793f2937, 0xfa55b986, |
| 419 0x78FD46AE, 0x87C64F5A, 0x36EDC5AF, 0x4378F568, | 374 0x78772152, 0x87692a30, 0x36322a25, 0x4320401b, |
| 420 0x91E9F63A, 0xC31EA14F, 0x69AB32DF, 0x643A3FD1, | 375 0x91848c21, 0xc3177b3c, 0x6946155c, 0x64171952, |
| 421 }; | 376 }; |
| 422 { | 377 { |
| 423 SCOPED_TRACE("first bitmap"); | 378 SCOPED_TRACE("first bitmap"); |
| 424 TestBitmapWrite(&this->clipboard(), fake_bitmap_1, sizeof(fake_bitmap_1), | 379 TestBitmapWrite(&this->clipboard(), gfx::Size(4, 3), fake_bitmap_1); |
| 425 gfx::Size(4, 3)); | |
| 426 } | 380 } |
| 427 | 381 |
| 428 const uint32 fake_bitmap_2[] = { | 382 const uint32 fake_bitmap_2[] = { |
| 429 0x46155189, 0xF6A55C8D, | 383 0x46061626, 0xf69f5988, |
| 430 0x79845674, 0xFA57BD89, | 384 0x793f2937, 0xfa55b986, |
| 431 0x78FD46AE, 0x87C64F5A, | 385 0x78772152, 0x87692a30, |
| 432 0x36EDC5AF, 0x4378F568, | 386 0x36322a25, 0x4320401b, |
| 433 0x91E9F63A, 0xC31EA14F, | 387 0x91848c21, 0xc3177b3c, |
| 434 0x69AB32DF, 0x643A3FD1, | 388 0x6946155c, 0x64171952, |
| 435 0xA6DF041D, 0x83046278, | 389 0xa6910313, 0x8302323e, |
| 436 }; | 390 }; |
| 437 { | 391 { |
| 438 SCOPED_TRACE("second bitmap"); | 392 SCOPED_TRACE("second bitmap"); |
| 439 TestBitmapWrite(&this->clipboard(), fake_bitmap_2, sizeof(fake_bitmap_2), | 393 TestBitmapWrite(&this->clipboard(), gfx::Size(2, 7), fake_bitmap_2); |
| 440 gfx::Size(2, 7)); | |
| 441 } | 394 } |
| 442 } | 395 } |
| 443 | 396 |
| 444 namespace { | |
| 445 // A size class that just happens to have the same layout as gfx::Size! | |
| 446 struct UnsafeSize { | |
| 447 int width; | |
| 448 int height; | |
| 449 }; | |
| 450 COMPILE_ASSERT(sizeof(UnsafeSize) == sizeof(gfx::Size), | |
| 451 UnsafeSize_must_be_same_size_as_gfx_Size); | |
| 452 } // namespace | |
| 453 | |
| 454 TYPED_TEST(ClipboardTest, SharedBitmapWithTwoNegativeSizes) { | |
| 455 Clipboard::ObjectMapParam placeholder_param; | |
| 456 void* crash_me = reinterpret_cast<void*>(57); | |
| 457 placeholder_param.resize(sizeof(crash_me)); | |
| 458 memcpy(&placeholder_param.front(), &crash_me, sizeof(crash_me)); | |
| 459 | |
| 460 Clipboard::ObjectMapParam size_param; | |
| 461 UnsafeSize size = {-100, -100}; | |
| 462 size_param.resize(sizeof(size)); | |
| 463 memcpy(&size_param.front(), &size, sizeof(size)); | |
| 464 | |
| 465 Clipboard::ObjectMapParams params; | |
| 466 params.push_back(placeholder_param); | |
| 467 params.push_back(size_param); | |
| 468 | |
| 469 Clipboard::ObjectMap objects; | |
| 470 objects[Clipboard::CBF_SMBITMAP] = params; | |
| 471 | |
| 472 this->WriteObjectsToClipboard(objects); | |
| 473 EXPECT_FALSE(this->clipboard().IsFormatAvailable( | |
| 474 Clipboard::GetBitmapFormatType(), CLIPBOARD_TYPE_COPY_PASTE)); | |
| 475 } | |
| 476 | |
| 477 TYPED_TEST(ClipboardTest, SharedBitmapWithOneNegativeSize) { | |
| 478 Clipboard::ObjectMapParam placeholder_param; | |
| 479 void* crash_me = reinterpret_cast<void*>(57); | |
| 480 placeholder_param.resize(sizeof(crash_me)); | |
| 481 memcpy(&placeholder_param.front(), &crash_me, sizeof(crash_me)); | |
| 482 | |
| 483 Clipboard::ObjectMapParam size_param; | |
| 484 UnsafeSize size = {-100, 100}; | |
| 485 size_param.resize(sizeof(size)); | |
| 486 memcpy(&size_param.front(), &size, sizeof(size)); | |
| 487 | |
| 488 Clipboard::ObjectMapParams params; | |
| 489 params.push_back(placeholder_param); | |
| 490 params.push_back(size_param); | |
| 491 | |
| 492 Clipboard::ObjectMap objects; | |
| 493 objects[Clipboard::CBF_SMBITMAP] = params; | |
| 494 | |
| 495 this->WriteObjectsToClipboard(objects); | |
| 496 EXPECT_FALSE(this->clipboard().IsFormatAvailable( | |
| 497 Clipboard::GetBitmapFormatType(), CLIPBOARD_TYPE_COPY_PASTE)); | |
| 498 } | |
| 499 | |
| 500 TYPED_TEST(ClipboardTest, BitmapWithSuperSize) { | |
| 501 Clipboard::ObjectMapParam placeholder_param; | |
| 502 void* crash_me = reinterpret_cast<void*>(57); | |
| 503 placeholder_param.resize(sizeof(crash_me)); | |
| 504 memcpy(&placeholder_param.front(), &crash_me, sizeof(crash_me)); | |
| 505 | |
| 506 Clipboard::ObjectMapParam size_param; | |
| 507 // Width just big enough that bytes per row won't fit in a 32-bit | |
| 508 // representation. | |
| 509 gfx::Size size(0x20000000, 1); | |
| 510 size_param.resize(sizeof(size)); | |
| 511 memcpy(&size_param.front(), &size, sizeof(size)); | |
| 512 | |
| 513 Clipboard::ObjectMapParams params; | |
| 514 params.push_back(placeholder_param); | |
| 515 params.push_back(size_param); | |
| 516 | |
| 517 Clipboard::ObjectMap objects; | |
| 518 objects[Clipboard::CBF_SMBITMAP] = params; | |
| 519 | |
| 520 this->WriteObjectsToClipboard(objects); | |
| 521 EXPECT_FALSE(this->clipboard().IsFormatAvailable( | |
| 522 Clipboard::GetBitmapFormatType(), CLIPBOARD_TYPE_COPY_PASTE)); | |
| 523 } | |
| 524 | |
| 525 TYPED_TEST(ClipboardTest, BitmapWithSuperSize2) { | |
| 526 Clipboard::ObjectMapParam placeholder_param; | |
| 527 void* crash_me = reinterpret_cast<void*>(57); | |
| 528 placeholder_param.resize(sizeof(crash_me)); | |
| 529 memcpy(&placeholder_param.front(), &crash_me, sizeof(crash_me)); | |
| 530 | |
| 531 Clipboard::ObjectMapParam size_param; | |
| 532 // Width and height large enough that SkBitmap::getSize() will be truncated. | |
| 533 gfx::Size size(0x0fffffff, 0x0fffffff); | |
| 534 size_param.resize(sizeof(size)); | |
| 535 memcpy(&size_param.front(), &size, sizeof(size)); | |
| 536 | |
| 537 Clipboard::ObjectMapParams params; | |
| 538 params.push_back(placeholder_param); | |
| 539 params.push_back(size_param); | |
| 540 | |
| 541 Clipboard::ObjectMap objects; | |
| 542 objects[Clipboard::CBF_SMBITMAP] = params; | |
| 543 | |
| 544 this->WriteObjectsToClipboard(objects); | |
| 545 EXPECT_FALSE(this->clipboard().IsFormatAvailable( | |
| 546 Clipboard::GetBitmapFormatType(), CLIPBOARD_TYPE_COPY_PASTE)); | |
| 547 } | |
| 548 | |
| 549 TYPED_TEST(ClipboardTest, DataTest) { | 397 TYPED_TEST(ClipboardTest, DataTest) { |
| 550 const ui::Clipboard::FormatType kFormat = | 398 const ui::Clipboard::FormatType kFormat = |
| 551 ui::Clipboard::GetFormatType("chromium/x-test-format"); | 399 ui::Clipboard::GetFormatType("chromium/x-test-format"); |
| 552 std::string payload("test string"); | 400 std::string payload("test string"); |
| 553 Pickle write_pickle; | 401 Pickle write_pickle; |
| 554 write_pickle.WriteString(payload); | 402 write_pickle.WriteString(payload); |
| 555 | 403 |
| 556 { | 404 { |
| 557 ScopedClipboardWriter clipboard_writer(CLIPBOARD_TYPE_COPY_PASTE); | 405 ScopedClipboardWriter clipboard_writer(CLIPBOARD_TYPE_COPY_PASTE); |
| 558 clipboard_writer.WritePickledData(write_pickle, kFormat); | 406 clipboard_writer.WritePickledData(write_pickle, kFormat); |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 748 base::RunLoop().RunUntilIdle(); | 596 base::RunLoop().RunUntilIdle(); |
| 749 | 597 |
| 750 const uint64 second_sequence_number = | 598 const uint64 second_sequence_number = |
| 751 this->clipboard().GetSequenceNumber(CLIPBOARD_TYPE_COPY_PASTE); | 599 this->clipboard().GetSequenceNumber(CLIPBOARD_TYPE_COPY_PASTE); |
| 752 | 600 |
| 753 EXPECT_NE(first_sequence_number, second_sequence_number); | 601 EXPECT_NE(first_sequence_number, second_sequence_number); |
| 754 } | 602 } |
| 755 #endif | 603 #endif |
| 756 | 604 |
| 757 } // namespace ui | 605 } // namespace ui |
| OLD | NEW |