Updating trunk VERSION from 2139.0 to 2140.0
[chromium-blink-merge.git] / ui / base / clipboard / clipboard_unittest.cc
blob72c07cf2c8ac8ba999ec40da529c246d91c52b80
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
3 // found in the LICENSE file.
5 #include "build/build_config.h"
7 #include <string>
9 #include "base/basictypes.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/message_loop/message_loop.h"
12 #include "base/pickle.h"
13 #include "base/run_loop.h"
14 #include "base/strings/string_util.h"
15 #include "base/strings/utf_string_conversions.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17 #include "testing/platform_test.h"
18 #include "third_party/skia/include/core/SkBitmap.h"
19 #include "third_party/skia/include/core/SkColor.h"
20 #include "third_party/skia/include/core/SkScalar.h"
21 #include "third_party/skia/include/core/SkUnPreMultiply.h"
22 #include "ui/base/clipboard/clipboard.h"
23 #include "ui/base/clipboard/scoped_clipboard_writer.h"
24 #include "ui/gfx/size.h"
26 #if defined(OS_WIN)
27 #include "ui/base/clipboard/clipboard_util_win.h"
28 #endif
30 #if defined(OS_ANDROID)
31 #include "base/android/jni_android.h"
32 #include "base/android/jni_string.h"
33 #endif
35 #if defined(USE_AURA)
36 #include "ui/events/platform/platform_event_source.h"
37 #endif
39 using base::ASCIIToUTF16;
40 using base::UTF8ToUTF16;
41 using base::UTF16ToUTF8;
43 namespace ui {
45 class ClipboardTest : public PlatformTest {
46 public:
47 #if defined(USE_AURA)
48 ClipboardTest() : event_source_(ui::PlatformEventSource::CreateDefault()) {}
49 #else
50 ClipboardTest() {}
51 #endif
53 static void WriteObjectsToClipboard(ui::Clipboard* clipboard,
54 const Clipboard::ObjectMap& objects) {
55 clipboard->WriteObjects(ui::CLIPBOARD_TYPE_COPY_PASTE, objects);
58 protected:
59 Clipboard& clipboard() { return clipboard_; }
61 void WriteObjectsToClipboard(const Clipboard::ObjectMap& objects) {
62 WriteObjectsToClipboard(&clipboard(), objects);
65 private:
66 base::MessageLoopForUI message_loop_;
67 #if defined(USE_AURA)
68 scoped_ptr<PlatformEventSource> event_source_;
69 #endif
70 Clipboard clipboard_;
73 namespace {
75 bool MarkupMatches(const base::string16& expected_markup,
76 const base::string16& actual_markup) {
77 return actual_markup.find(expected_markup) != base::string16::npos;
80 } // namespace
82 TEST_F(ClipboardTest, ClearTest) {
84 ScopedClipboardWriter clipboard_writer(&clipboard(),
85 CLIPBOARD_TYPE_COPY_PASTE);
86 clipboard_writer.WriteText(ASCIIToUTF16("clear me"));
89 clipboard().Clear(CLIPBOARD_TYPE_COPY_PASTE);
91 EXPECT_FALSE(clipboard().IsFormatAvailable(
92 Clipboard::GetPlainTextWFormatType(), CLIPBOARD_TYPE_COPY_PASTE));
93 EXPECT_FALSE(clipboard().IsFormatAvailable(
94 Clipboard::GetPlainTextFormatType(), CLIPBOARD_TYPE_COPY_PASTE));
97 TEST_F(ClipboardTest, TextTest) {
98 base::string16 text(ASCIIToUTF16("This is a base::string16!#$")), text_result;
99 std::string ascii_text;
102 ScopedClipboardWriter clipboard_writer(&clipboard(),
103 CLIPBOARD_TYPE_COPY_PASTE);
104 clipboard_writer.WriteText(text);
107 EXPECT_TRUE(clipboard().IsFormatAvailable(
108 Clipboard::GetPlainTextWFormatType(), CLIPBOARD_TYPE_COPY_PASTE));
109 EXPECT_TRUE(clipboard().IsFormatAvailable(Clipboard::GetPlainTextFormatType(),
110 CLIPBOARD_TYPE_COPY_PASTE));
111 clipboard().ReadText(CLIPBOARD_TYPE_COPY_PASTE, &text_result);
113 EXPECT_EQ(text, text_result);
114 clipboard().ReadAsciiText(CLIPBOARD_TYPE_COPY_PASTE, &ascii_text);
115 EXPECT_EQ(UTF16ToUTF8(text), ascii_text);
118 TEST_F(ClipboardTest, HTMLTest) {
119 base::string16 markup(ASCIIToUTF16("<string>Hi!</string>")), markup_result;
120 base::string16 plain(ASCIIToUTF16("Hi!")), plain_result;
121 std::string url("http://www.example.com/"), url_result;
124 ScopedClipboardWriter clipboard_writer(&clipboard(),
125 CLIPBOARD_TYPE_COPY_PASTE);
126 clipboard_writer.WriteText(plain);
127 clipboard_writer.WriteHTML(markup, url);
130 EXPECT_TRUE(clipboard().IsFormatAvailable(Clipboard::GetHtmlFormatType(),
131 CLIPBOARD_TYPE_COPY_PASTE));
132 uint32 ignored;
133 clipboard().ReadHTML(CLIPBOARD_TYPE_COPY_PASTE, &markup_result, &url_result,
134 &ignored, &ignored);
135 EXPECT_PRED2(MarkupMatches, markup, markup_result);
136 #if defined(OS_WIN)
137 // TODO(playmobil): It's not clear that non windows clipboards need to support
138 // this.
139 EXPECT_EQ(url, url_result);
140 #endif // defined(OS_WIN)
143 TEST_F(ClipboardTest, RTFTest) {
144 std::string rtf =
145 "{\\rtf1\\ansi{\\fonttbl\\f0\\fswiss Helvetica;}\\f0\\pard\n"
146 "This is some {\\b bold} text.\\par\n"
147 "}";
150 ScopedClipboardWriter clipboard_writer(&clipboard(),
151 CLIPBOARD_TYPE_COPY_PASTE);
152 clipboard_writer.WriteRTF(rtf);
155 EXPECT_TRUE(clipboard().IsFormatAvailable(Clipboard::GetRtfFormatType(),
156 CLIPBOARD_TYPE_COPY_PASTE));
157 std::string result;
158 clipboard().ReadRTF(CLIPBOARD_TYPE_COPY_PASTE, &result);
159 EXPECT_EQ(rtf, result);
162 // TODO(dnicoara) Enable test once Ozone implements clipboard support:
163 // crbug.com/361707
164 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) && !defined(USE_OZONE)
165 TEST_F(ClipboardTest, MultipleBufferTest) {
166 base::string16 text(ASCIIToUTF16("Standard")), text_result;
167 base::string16 markup(ASCIIToUTF16("<string>Selection</string>"));
168 std::string url("http://www.example.com/"), url_result;
171 ScopedClipboardWriter clipboard_writer(&clipboard(),
172 CLIPBOARD_TYPE_COPY_PASTE);
173 clipboard_writer.WriteText(text);
177 ScopedClipboardWriter clipboard_writer(&clipboard(),
178 CLIPBOARD_TYPE_SELECTION);
179 clipboard_writer.WriteHTML(markup, url);
182 EXPECT_TRUE(clipboard().IsFormatAvailable(Clipboard::GetPlainTextFormatType(),
183 CLIPBOARD_TYPE_COPY_PASTE));
184 EXPECT_FALSE(clipboard().IsFormatAvailable(
185 Clipboard::GetPlainTextFormatType(),
186 CLIPBOARD_TYPE_SELECTION));
188 EXPECT_FALSE(clipboard().IsFormatAvailable(Clipboard::GetHtmlFormatType(),
189 CLIPBOARD_TYPE_COPY_PASTE));
190 EXPECT_TRUE(clipboard().IsFormatAvailable(Clipboard::GetHtmlFormatType(),
191 CLIPBOARD_TYPE_SELECTION));
193 clipboard().ReadText(CLIPBOARD_TYPE_COPY_PASTE, &text_result);
194 EXPECT_EQ(text, text_result);
196 uint32 ignored;
197 base::string16 markup_result;
198 clipboard().ReadHTML(CLIPBOARD_TYPE_SELECTION,
199 &markup_result,
200 &url_result,
201 &ignored,
202 &ignored);
203 EXPECT_PRED2(MarkupMatches, markup, markup_result);
205 #endif
207 TEST_F(ClipboardTest, TrickyHTMLTest) {
208 base::string16 markup(ASCIIToUTF16("<em>Bye!<!--EndFragment --></em>")),
209 markup_result;
210 std::string url, url_result;
211 base::string16 plain(ASCIIToUTF16("Bye!")), plain_result;
214 ScopedClipboardWriter clipboard_writer(&clipboard(),
215 CLIPBOARD_TYPE_COPY_PASTE);
216 clipboard_writer.WriteText(plain);
217 clipboard_writer.WriteHTML(markup, url);
220 EXPECT_TRUE(clipboard().IsFormatAvailable(Clipboard::GetHtmlFormatType(),
221 CLIPBOARD_TYPE_COPY_PASTE));
222 uint32 ignored;
223 clipboard().ReadHTML(CLIPBOARD_TYPE_COPY_PASTE, &markup_result, &url_result,
224 &ignored, &ignored);
225 EXPECT_PRED2(MarkupMatches, markup, markup_result);
226 #if defined(OS_WIN)
227 // TODO(playmobil): It's not clear that non windows clipboards need to support
228 // this.
229 EXPECT_EQ(url, url_result);
230 #endif // defined(OS_WIN)
233 #if defined(OS_WIN)
234 TEST_F(ClipboardTest, UniodeHTMLTest) {
235 base::string16 markup(UTF8ToUTF16("<div>A \xc3\xb8 \xe6\xb0\xb4</div>")),
236 markup_result;
237 std::string url, url_result;
240 ScopedClipboardWriter clipboard_writer(&clipboard(),
241 CLIPBOARD_TYPE_COPY_PASTE);
242 clipboard_writer.WriteHTML(markup, url);
245 EXPECT_TRUE(clipboard().IsFormatAvailable(Clipboard::GetHtmlFormatType(),
246 CLIPBOARD_TYPE_COPY_PASTE));
247 uint32 fragment_start;
248 uint32 fragment_end;
249 clipboard().ReadHTML(CLIPBOARD_TYPE_COPY_PASTE, &markup_result, &url_result,
250 &fragment_start, &fragment_end);
251 EXPECT_PRED2(MarkupMatches, markup, markup_result);
252 EXPECT_EQ(url, url_result);
253 // Make sure that fragment indices were adjusted when converting.
254 EXPECT_EQ(36, fragment_start);
255 EXPECT_EQ(52, fragment_end);
257 #endif // defined(OS_WIN)
259 // TODO(estade): Port the following test (decide what target we use for urls)
260 #if !defined(OS_POSIX) || defined(OS_MACOSX)
261 TEST_F(ClipboardTest, BookmarkTest) {
262 base::string16 title(ASCIIToUTF16("The Example Company")), title_result;
263 std::string url("http://www.example.com/"), url_result;
266 ScopedClipboardWriter clipboard_writer(&clipboard(),
267 CLIPBOARD_TYPE_COPY_PASTE);
268 clipboard_writer.WriteBookmark(title, url);
271 EXPECT_TRUE(clipboard().IsFormatAvailable(Clipboard::GetUrlWFormatType(),
272 CLIPBOARD_TYPE_COPY_PASTE));
273 clipboard().ReadBookmark(&title_result, &url_result);
274 EXPECT_EQ(title, title_result);
275 EXPECT_EQ(url, url_result);
277 #endif // defined(OS_WIN)
279 TEST_F(ClipboardTest, MultiFormatTest) {
280 base::string16 text(ASCIIToUTF16("Hi!")), text_result;
281 base::string16 markup(ASCIIToUTF16("<strong>Hi!</string>")), markup_result;
282 std::string url("http://www.example.com/"), url_result;
283 std::string ascii_text;
286 ScopedClipboardWriter clipboard_writer(&clipboard(),
287 CLIPBOARD_TYPE_COPY_PASTE);
288 clipboard_writer.WriteHTML(markup, url);
289 clipboard_writer.WriteText(text);
292 EXPECT_TRUE(clipboard().IsFormatAvailable(Clipboard::GetHtmlFormatType(),
293 CLIPBOARD_TYPE_COPY_PASTE));
294 EXPECT_TRUE(clipboard().IsFormatAvailable(
295 Clipboard::GetPlainTextWFormatType(), CLIPBOARD_TYPE_COPY_PASTE));
296 EXPECT_TRUE(clipboard().IsFormatAvailable(
297 Clipboard::GetPlainTextFormatType(), CLIPBOARD_TYPE_COPY_PASTE));
298 uint32 ignored;
299 clipboard().ReadHTML(CLIPBOARD_TYPE_COPY_PASTE, &markup_result, &url_result,
300 &ignored, &ignored);
301 EXPECT_PRED2(MarkupMatches, markup, markup_result);
302 #if defined(OS_WIN)
303 // TODO(playmobil): It's not clear that non windows clipboards need to support
304 // this.
305 EXPECT_EQ(url, url_result);
306 #endif // defined(OS_WIN)
307 clipboard().ReadText(CLIPBOARD_TYPE_COPY_PASTE, &text_result);
308 EXPECT_EQ(text, text_result);
309 clipboard().ReadAsciiText(CLIPBOARD_TYPE_COPY_PASTE, &ascii_text);
310 EXPECT_EQ(UTF16ToUTF8(text), ascii_text);
313 TEST_F(ClipboardTest, URLTest) {
314 base::string16 url(ASCIIToUTF16("http://www.google.com/"));
317 ScopedClipboardWriter clipboard_writer(&clipboard(),
318 CLIPBOARD_TYPE_COPY_PASTE);
319 clipboard_writer.WriteURL(url);
322 EXPECT_TRUE(clipboard().IsFormatAvailable(
323 Clipboard::GetPlainTextWFormatType(), CLIPBOARD_TYPE_COPY_PASTE));
324 EXPECT_TRUE(clipboard().IsFormatAvailable(Clipboard::GetPlainTextFormatType(),
325 CLIPBOARD_TYPE_COPY_PASTE));
326 base::string16 text_result;
327 clipboard().ReadText(CLIPBOARD_TYPE_COPY_PASTE, &text_result);
329 EXPECT_EQ(text_result, url);
331 std::string ascii_text;
332 clipboard().ReadAsciiText(CLIPBOARD_TYPE_COPY_PASTE, &ascii_text);
333 EXPECT_EQ(UTF16ToUTF8(url), ascii_text);
335 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
336 ascii_text.clear();
337 clipboard().ReadAsciiText(CLIPBOARD_TYPE_SELECTION, &ascii_text);
338 EXPECT_EQ(UTF16ToUTF8(url), ascii_text);
339 #endif
342 // TODO(dcheng): The tests for copying to the clipboard also test IPC
343 // interaction... consider moving them to a different layer so we can
344 // consolidate the validation logic.
345 // Note that |bitmap_data| is not premultiplied!
346 static void TestBitmapWrite(Clipboard* clipboard,
347 const uint32* bitmap_data,
348 size_t bitmap_data_size,
349 const gfx::Size& size) {
350 // Create shared memory region.
351 base::SharedMemory shared_buf;
352 ASSERT_TRUE(shared_buf.CreateAndMapAnonymous(bitmap_data_size));
353 memcpy(shared_buf.memory(), bitmap_data, bitmap_data_size);
354 // CBF_SMBITMAP expects premultiplied bitmap data so do that now.
355 uint32* pixel_buffer = static_cast<uint32*>(shared_buf.memory());
356 for (int j = 0; j < size.height(); ++j) {
357 for (int i = 0; i < size.width(); ++i) {
358 uint32& pixel = pixel_buffer[i + j * size.width()];
359 pixel = SkPreMultiplyColor(pixel);
362 base::SharedMemoryHandle handle_to_share;
363 base::ProcessHandle current_process = base::kNullProcessHandle;
364 #if defined(OS_WIN)
365 current_process = GetCurrentProcess();
366 #endif
367 shared_buf.ShareToProcess(current_process, &handle_to_share);
368 ASSERT_TRUE(shared_buf.Unmap());
370 // Setup data for clipboard().
371 Clipboard::ObjectMapParam placeholder_param;
372 Clipboard::ObjectMapParam size_param;
373 const char* size_data = reinterpret_cast<const char*>(&size);
374 for (size_t i = 0; i < sizeof(size); ++i)
375 size_param.push_back(size_data[i]);
377 Clipboard::ObjectMapParams params;
378 params.push_back(placeholder_param);
379 params.push_back(size_param);
381 Clipboard::ObjectMap objects;
382 objects[Clipboard::CBF_SMBITMAP] = params;
383 ASSERT_TRUE(Clipboard::ReplaceSharedMemHandle(
384 &objects, handle_to_share, current_process));
386 ClipboardTest::WriteObjectsToClipboard(clipboard, objects);
388 EXPECT_TRUE(clipboard->IsFormatAvailable(Clipboard::GetBitmapFormatType(),
389 CLIPBOARD_TYPE_COPY_PASTE));
390 const SkBitmap& image = clipboard->ReadImage(CLIPBOARD_TYPE_COPY_PASTE);
391 EXPECT_EQ(size, gfx::Size(image.width(), image.height()));
392 SkAutoLockPixels image_lock(image);
393 for (int j = 0; j < image.height(); ++j) {
394 const uint32* row_address = image.getAddr32(0, j);
395 for (int i = 0; i < image.width(); ++i) {
396 int offset = i + j * image.width();
397 uint32 pixel = SkPreMultiplyColor(bitmap_data[offset]);
398 EXPECT_EQ(pixel, row_address[i])
399 << "i = " << i << ", j = " << j;
404 TEST_F(ClipboardTest, SharedBitmapTest) {
405 const uint32 fake_bitmap_1[] = {
406 0x46155189, 0xF6A55C8D, 0x79845674, 0xFA57BD89,
407 0x78FD46AE, 0x87C64F5A, 0x36EDC5AF, 0x4378F568,
408 0x91E9F63A, 0xC31EA14F, 0x69AB32DF, 0x643A3FD1,
411 SCOPED_TRACE("first bitmap");
412 TestBitmapWrite(
413 &clipboard(), fake_bitmap_1, sizeof(fake_bitmap_1), gfx::Size(4, 3));
416 const uint32 fake_bitmap_2[] = {
417 0x46155189, 0xF6A55C8D,
418 0x79845674, 0xFA57BD89,
419 0x78FD46AE, 0x87C64F5A,
420 0x36EDC5AF, 0x4378F568,
421 0x91E9F63A, 0xC31EA14F,
422 0x69AB32DF, 0x643A3FD1,
423 0xA6DF041D, 0x83046278,
426 SCOPED_TRACE("second bitmap");
427 TestBitmapWrite(
428 &clipboard(), fake_bitmap_2, sizeof(fake_bitmap_2), gfx::Size(2, 7));
432 namespace {
433 // A size class that just happens to have the same layout as gfx::Size!
434 struct UnsafeSize {
435 int width;
436 int height;
438 COMPILE_ASSERT(sizeof(UnsafeSize) == sizeof(gfx::Size),
439 UnsafeSize_must_be_same_size_as_gfx_Size);
440 } // namespace
442 TEST_F(ClipboardTest, SharedBitmapWithTwoNegativeSizes) {
443 Clipboard::ObjectMapParam placeholder_param;
444 void* crash_me = reinterpret_cast<void*>(57);
445 placeholder_param.resize(sizeof(crash_me));
446 memcpy(&placeholder_param.front(), &crash_me, sizeof(crash_me));
448 Clipboard::ObjectMapParam size_param;
449 UnsafeSize size = {-100, -100};
450 size_param.resize(sizeof(size));
451 memcpy(&size_param.front(), &size, sizeof(size));
453 Clipboard::ObjectMapParams params;
454 params.push_back(placeholder_param);
455 params.push_back(size_param);
457 Clipboard::ObjectMap objects;
458 objects[Clipboard::CBF_SMBITMAP] = params;
460 WriteObjectsToClipboard(objects);
461 EXPECT_FALSE(clipboard().IsFormatAvailable(Clipboard::GetBitmapFormatType(),
462 CLIPBOARD_TYPE_COPY_PASTE));
465 TEST_F(ClipboardTest, SharedBitmapWithOneNegativeSize) {
466 Clipboard::ObjectMapParam placeholder_param;
467 void* crash_me = reinterpret_cast<void*>(57);
468 placeholder_param.resize(sizeof(crash_me));
469 memcpy(&placeholder_param.front(), &crash_me, sizeof(crash_me));
471 Clipboard::ObjectMapParam size_param;
472 UnsafeSize size = {-100, 100};
473 size_param.resize(sizeof(size));
474 memcpy(&size_param.front(), &size, sizeof(size));
476 Clipboard::ObjectMapParams params;
477 params.push_back(placeholder_param);
478 params.push_back(size_param);
480 Clipboard::ObjectMap objects;
481 objects[Clipboard::CBF_SMBITMAP] = params;
483 WriteObjectsToClipboard(objects);
484 EXPECT_FALSE(clipboard().IsFormatAvailable(Clipboard::GetBitmapFormatType(),
485 CLIPBOARD_TYPE_COPY_PASTE));
488 TEST_F(ClipboardTest, BitmapWithSuperSize) {
489 Clipboard::ObjectMapParam placeholder_param;
490 void* crash_me = reinterpret_cast<void*>(57);
491 placeholder_param.resize(sizeof(crash_me));
492 memcpy(&placeholder_param.front(), &crash_me, sizeof(crash_me));
494 Clipboard::ObjectMapParam size_param;
495 // Width just big enough that bytes per row won't fit in a 32-bit
496 // representation.
497 gfx::Size size(0x20000000, 1);
498 size_param.resize(sizeof(size));
499 memcpy(&size_param.front(), &size, sizeof(size));
501 Clipboard::ObjectMapParams params;
502 params.push_back(placeholder_param);
503 params.push_back(size_param);
505 Clipboard::ObjectMap objects;
506 objects[Clipboard::CBF_SMBITMAP] = params;
508 WriteObjectsToClipboard(objects);
509 EXPECT_FALSE(clipboard().IsFormatAvailable(Clipboard::GetBitmapFormatType(),
510 CLIPBOARD_TYPE_COPY_PASTE));
513 TEST_F(ClipboardTest, BitmapWithSuperSize2) {
514 Clipboard::ObjectMapParam placeholder_param;
515 void* crash_me = reinterpret_cast<void*>(57);
516 placeholder_param.resize(sizeof(crash_me));
517 memcpy(&placeholder_param.front(), &crash_me, sizeof(crash_me));
519 Clipboard::ObjectMapParam size_param;
520 // Width and height large enough that SkBitmap::getSize() will be truncated.
521 gfx::Size size(0x0fffffff, 0x0fffffff);
522 size_param.resize(sizeof(size));
523 memcpy(&size_param.front(), &size, sizeof(size));
525 Clipboard::ObjectMapParams params;
526 params.push_back(placeholder_param);
527 params.push_back(size_param);
529 Clipboard::ObjectMap objects;
530 objects[Clipboard::CBF_SMBITMAP] = params;
532 WriteObjectsToClipboard(objects);
533 EXPECT_FALSE(clipboard().IsFormatAvailable(Clipboard::GetBitmapFormatType(),
534 CLIPBOARD_TYPE_COPY_PASTE));
537 TEST_F(ClipboardTest, DataTest) {
538 const ui::Clipboard::FormatType kFormat =
539 ui::Clipboard::GetFormatType("chromium/x-test-format");
540 std::string payload("test string");
541 Pickle write_pickle;
542 write_pickle.WriteString(payload);
545 ScopedClipboardWriter clipboard_writer(&clipboard(),
546 CLIPBOARD_TYPE_COPY_PASTE);
547 clipboard_writer.WritePickledData(write_pickle, kFormat);
550 ASSERT_TRUE(clipboard().IsFormatAvailable(
551 kFormat, CLIPBOARD_TYPE_COPY_PASTE));
552 std::string output;
553 clipboard().ReadData(kFormat, &output);
554 ASSERT_FALSE(output.empty());
556 Pickle read_pickle(output.data(), output.size());
557 PickleIterator iter(read_pickle);
558 std::string unpickled_string;
559 ASSERT_TRUE(read_pickle.ReadString(&iter, &unpickled_string));
560 EXPECT_EQ(payload, unpickled_string);
563 TEST_F(ClipboardTest, MultipleDataTest) {
564 const ui::Clipboard::FormatType kFormat1 =
565 ui::Clipboard::GetFormatType("chromium/x-test-format1");
566 std::string payload1("test string1");
567 Pickle write_pickle1;
568 write_pickle1.WriteString(payload1);
570 const ui::Clipboard::FormatType kFormat2 =
571 ui::Clipboard::GetFormatType("chromium/x-test-format2");
572 std::string payload2("test string2");
573 Pickle write_pickle2;
574 write_pickle2.WriteString(payload2);
577 ScopedClipboardWriter clipboard_writer(&clipboard(),
578 CLIPBOARD_TYPE_COPY_PASTE);
579 clipboard_writer.WritePickledData(write_pickle1, kFormat1);
580 // overwrite the previous pickle for fun
581 clipboard_writer.WritePickledData(write_pickle2, kFormat2);
584 ASSERT_TRUE(clipboard().IsFormatAvailable(
585 kFormat2, CLIPBOARD_TYPE_COPY_PASTE));
587 // Check string 2.
588 std::string output2;
589 clipboard().ReadData(kFormat2, &output2);
590 ASSERT_FALSE(output2.empty());
592 Pickle read_pickle2(output2.data(), output2.size());
593 PickleIterator iter2(read_pickle2);
594 std::string unpickled_string2;
595 ASSERT_TRUE(read_pickle2.ReadString(&iter2, &unpickled_string2));
596 EXPECT_EQ(payload2, unpickled_string2);
599 ScopedClipboardWriter clipboard_writer(&clipboard(),
600 CLIPBOARD_TYPE_COPY_PASTE);
601 clipboard_writer.WritePickledData(write_pickle2, kFormat2);
602 // overwrite the previous pickle for fun
603 clipboard_writer.WritePickledData(write_pickle1, kFormat1);
606 ASSERT_TRUE(clipboard().IsFormatAvailable(
607 kFormat1, CLIPBOARD_TYPE_COPY_PASTE));
609 // Check string 1.
610 std::string output1;
611 clipboard().ReadData(kFormat1, &output1);
612 ASSERT_FALSE(output1.empty());
614 Pickle read_pickle1(output1.data(), output1.size());
615 PickleIterator iter1(read_pickle1);
616 std::string unpickled_string1;
617 ASSERT_TRUE(read_pickle1.ReadString(&iter1, &unpickled_string1));
618 EXPECT_EQ(payload1, unpickled_string1);
621 #if !defined(OS_MACOSX) && !defined(OS_ANDROID)
622 TEST_F(ClipboardTest, HyperlinkTest) {
623 const std::string kTitle("The <Example> Company's \"home page\"");
624 const std::string kUrl("http://www.example.com?x=3&lt=3#\"'<>");
625 const std::string kExpectedHtml(
626 "<a href=\"http://www.example.com?x=3&amp;lt=3#&quot;&#39;&lt;&gt;\">"
627 "The &lt;Example&gt; Company&#39;s &quot;home page&quot;</a>");
629 std::string url_result;
630 base::string16 html_result;
632 ScopedClipboardWriter clipboard_writer(&clipboard(),
633 CLIPBOARD_TYPE_COPY_PASTE);
634 clipboard_writer.WriteHyperlink(ASCIIToUTF16(kTitle), kUrl);
637 EXPECT_TRUE(clipboard().IsFormatAvailable(Clipboard::GetHtmlFormatType(),
638 CLIPBOARD_TYPE_COPY_PASTE));
639 uint32 ignored;
640 clipboard().ReadHTML(CLIPBOARD_TYPE_COPY_PASTE, &html_result, &url_result,
641 &ignored, &ignored);
642 EXPECT_PRED2(MarkupMatches, ASCIIToUTF16(kExpectedHtml), html_result);
644 #endif
646 #if defined(OS_WIN) // Windows only tests.
647 TEST_F(ClipboardTest, WebSmartPasteTest) {
649 ScopedClipboardWriter clipboard_writer(&clipboard(),
650 CLIPBOARD_TYPE_COPY_PASTE);
651 clipboard_writer.WriteWebSmartPaste();
654 EXPECT_TRUE(clipboard().IsFormatAvailable(
655 Clipboard::GetWebKitSmartPasteFormatType(), CLIPBOARD_TYPE_COPY_PASTE));
658 void HtmlTestHelper(const std::string& cf_html,
659 const std::string& expected_html) {
660 std::string html;
661 ClipboardUtil::CFHtmlToHtml(cf_html, &html, NULL);
662 EXPECT_EQ(html, expected_html);
665 TEST_F(ClipboardTest, HtmlTest) {
666 // Test converting from CF_HTML format data with <!--StartFragment--> and
667 // <!--EndFragment--> comments, like from MS Word.
668 HtmlTestHelper("Version:1.0\r\n"
669 "StartHTML:0000000105\r\n"
670 "EndHTML:0000000199\r\n"
671 "StartFragment:0000000123\r\n"
672 "EndFragment:0000000161\r\n"
673 "\r\n"
674 "<html>\r\n"
675 "<body>\r\n"
676 "<!--StartFragment-->\r\n"
677 "\r\n"
678 "<p>Foo</p>\r\n"
679 "\r\n"
680 "<!--EndFragment-->\r\n"
681 "</body>\r\n"
682 "</html>\r\n\r\n",
683 "<p>Foo</p>");
685 // Test converting from CF_HTML format data without <!--StartFragment--> and
686 // <!--EndFragment--> comments, like from OpenOffice Writer.
687 HtmlTestHelper("Version:1.0\r\n"
688 "StartHTML:0000000105\r\n"
689 "EndHTML:0000000151\r\n"
690 "StartFragment:0000000121\r\n"
691 "EndFragment:0000000131\r\n"
692 "<html>\r\n"
693 "<body>\r\n"
694 "<p>Foo</p>\r\n"
695 "</body>\r\n"
696 "</html>\r\n\r\n",
697 "<p>Foo</p>");
699 #endif // defined(OS_WIN)
701 // Test writing all formats we have simultaneously.
702 TEST_F(ClipboardTest, WriteEverything) {
704 ScopedClipboardWriter writer(&clipboard(), CLIPBOARD_TYPE_COPY_PASTE);
705 writer.WriteText(UTF8ToUTF16("foo"));
706 writer.WriteURL(UTF8ToUTF16("foo"));
707 writer.WriteHTML(UTF8ToUTF16("foo"), "bar");
708 writer.WriteBookmark(UTF8ToUTF16("foo"), "bar");
709 writer.WriteHyperlink(ASCIIToUTF16("foo"), "bar");
710 writer.WriteWebSmartPaste();
711 // Left out: WriteFile, WriteFiles, WriteBitmapFromPixels, WritePickledData.
714 // Passes if we don't crash.
717 // TODO(dcheng): Fix this test for Android. It's rather involved, since the
718 // clipboard change listener is posted to the Java message loop, and spinning
719 // that loop from C++ to trigger the callback in the test requires a non-trivial
720 // amount of additional work.
721 #if !defined(OS_ANDROID)
722 // Simple test that the sequence number appears to change when the clipboard is
723 // written to.
724 // TODO(dcheng): Add a version to test CLIPBOARD_TYPE_SELECTION.
725 TEST_F(ClipboardTest, GetSequenceNumber) {
726 const uint64 first_sequence_number =
727 clipboard().GetSequenceNumber(CLIPBOARD_TYPE_COPY_PASTE);
730 ScopedClipboardWriter writer(&clipboard(), CLIPBOARD_TYPE_COPY_PASTE);
731 writer.WriteText(UTF8ToUTF16("World"));
734 // On some platforms, the sequence number is updated by a UI callback so pump
735 // the message loop to make sure we get the notification.
736 base::RunLoop().RunUntilIdle();
738 const uint64 second_sequence_number =
739 clipboard().GetSequenceNumber(CLIPBOARD_TYPE_COPY_PASTE);
741 EXPECT_NE(first_sequence_number, second_sequence_number);
743 #endif
745 #if defined(OS_ANDROID)
747 // Test that if another application writes some text to the pasteboard the
748 // clipboard properly invalidates other types.
749 TEST_F(ClipboardTest, InternalClipboardInvalidation) {
750 // Write a Webkit smart paste tag to our clipboard.
752 ScopedClipboardWriter clipboard_writer(&clipboard(),
753 CLIPBOARD_TYPE_COPY_PASTE);
754 clipboard_writer.WriteWebSmartPaste();
756 EXPECT_TRUE(clipboard().IsFormatAvailable(
757 Clipboard::GetWebKitSmartPasteFormatType(), CLIPBOARD_TYPE_COPY_PASTE));
760 // Simulate that another application copied something in the Clipboard
762 std::string new_value("Some text copied by some other app");
763 using base::android::ConvertUTF8ToJavaString;
764 using base::android::MethodID;
765 using base::android::ScopedJavaLocalRef;
767 JNIEnv* env = base::android::AttachCurrentThread();
768 ASSERT_TRUE(env);
770 jobject context = base::android::GetApplicationContext();
771 ASSERT_TRUE(context);
773 ScopedJavaLocalRef<jclass> context_class =
774 base::android::GetClass(env, "android/content/Context");
776 jmethodID get_system_service = MethodID::Get<MethodID::TYPE_INSTANCE>(
777 env, context_class.obj(), "getSystemService",
778 "(Ljava/lang/String;)Ljava/lang/Object;");
780 // Retrieve the system service.
781 ScopedJavaLocalRef<jstring> service_name = ConvertUTF8ToJavaString(
782 env, "clipboard");
783 ScopedJavaLocalRef<jobject> clipboard_manager(
784 env, env->CallObjectMethod(
785 context, get_system_service, service_name.obj()));
786 ASSERT_TRUE(clipboard_manager.obj() && !base::android::ClearException(env));
788 ScopedJavaLocalRef<jclass> clipboard_class =
789 base::android::GetClass(env, "android/text/ClipboardManager");
790 jmethodID set_text = MethodID::Get<MethodID::TYPE_INSTANCE>(
791 env, clipboard_class.obj(), "setText", "(Ljava/lang/CharSequence;)V");
792 ScopedJavaLocalRef<jstring> new_value_string = ConvertUTF8ToJavaString(
793 env, new_value.c_str());
795 // Will need to call toString as CharSequence is not always a String.
796 env->CallVoidMethod(clipboard_manager.obj(),
797 set_text,
798 new_value_string.obj());
800 // The WebKit smart paste tag should now be gone.
801 EXPECT_FALSE(clipboard().IsFormatAvailable(
802 Clipboard::GetWebKitSmartPasteFormatType(), CLIPBOARD_TYPE_COPY_PASTE));
804 // Make sure some text is available
805 EXPECT_TRUE(clipboard().IsFormatAvailable(
806 Clipboard::GetPlainTextWFormatType(), CLIPBOARD_TYPE_COPY_PASTE));
808 // Make sure the text is what we inserted while simulating the other app
809 std::string contents;
810 clipboard().ReadAsciiText(CLIPBOARD_TYPE_COPY_PASTE, &contents);
811 EXPECT_EQ(contents, new_value);
813 #endif
814 } // namespace ui