clipboard_unittest.cc revision d0247b1b59f9c528cb6df88b4f2b9afaf80d181e
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.
4
5#include "build/build_config.h"
6
7#include <string>
8
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/strings/string_util.h"
14#include "base/strings/utf_string_conversions.h"
15#include "testing/gtest/include/gtest/gtest.h"
16#include "testing/platform_test.h"
17#include "third_party/skia/include/core/SkBitmap.h"
18#include "ui/base/clipboard/clipboard.h"
19#include "ui/base/clipboard/scoped_clipboard_writer.h"
20#include "ui/gfx/size.h"
21
22#if defined(OS_WIN)
23#include "ui/base/clipboard/clipboard_util_win.h"
24#endif
25
26#if defined(OS_ANDROID)
27#include "base/android/jni_android.h"
28#include "base/android/jni_string.h"
29#endif
30
31namespace ui {
32
33class ClipboardTest : public PlatformTest {
34 protected:
35  Clipboard& clipboard() { return clipboard_; }
36
37 private:
38  base::MessageLoopForUI message_loop_;
39  Clipboard clipboard_;
40};
41
42namespace {
43
44bool MarkupMatches(const string16& expected_markup,
45                   const string16& actual_markup) {
46  return actual_markup.find(expected_markup) != string16::npos;
47}
48
49}  // namespace
50
51TEST_F(ClipboardTest, ClearTest) {
52  {
53    ScopedClipboardWriter clipboard_writer(&clipboard(),
54                                           Clipboard::BUFFER_STANDARD);
55    clipboard_writer.WriteText(ASCIIToUTF16("clear me"));
56  }
57
58  clipboard().Clear(Clipboard::BUFFER_STANDARD);
59
60  EXPECT_FALSE(clipboard().IsFormatAvailable(
61      Clipboard::GetPlainTextWFormatType(), Clipboard::BUFFER_STANDARD));
62  EXPECT_FALSE(clipboard().IsFormatAvailable(
63      Clipboard::GetPlainTextFormatType(), Clipboard::BUFFER_STANDARD));
64}
65
66TEST_F(ClipboardTest, TextTest) {
67  string16 text(ASCIIToUTF16("This is a string16!#$")), text_result;
68  std::string ascii_text;
69
70  {
71    ScopedClipboardWriter clipboard_writer(&clipboard(),
72                                           Clipboard::BUFFER_STANDARD);
73    clipboard_writer.WriteText(text);
74  }
75
76  EXPECT_TRUE(clipboard().IsFormatAvailable(
77      Clipboard::GetPlainTextWFormatType(), Clipboard::BUFFER_STANDARD));
78  EXPECT_TRUE(clipboard().IsFormatAvailable(Clipboard::GetPlainTextFormatType(),
79                                            Clipboard::BUFFER_STANDARD));
80  clipboard().ReadText(Clipboard::BUFFER_STANDARD, &text_result);
81
82  EXPECT_EQ(text, text_result);
83  clipboard().ReadAsciiText(Clipboard::BUFFER_STANDARD, &ascii_text);
84  EXPECT_EQ(UTF16ToUTF8(text), ascii_text);
85}
86
87TEST_F(ClipboardTest, HTMLTest) {
88  string16 markup(ASCIIToUTF16("<string>Hi!</string>")), markup_result;
89  std::string url("http://www.example.com/"), url_result;
90
91  {
92    ScopedClipboardWriter clipboard_writer(&clipboard(),
93                                           Clipboard::BUFFER_STANDARD);
94    clipboard_writer.WriteHTML(markup, url);
95  }
96
97  EXPECT_TRUE(clipboard().IsFormatAvailable(Clipboard::GetHtmlFormatType(),
98                                            Clipboard::BUFFER_STANDARD));
99  uint32 ignored;
100  clipboard().ReadHTML(Clipboard::BUFFER_STANDARD, &markup_result, &url_result,
101                     &ignored, &ignored);
102  EXPECT_PRED2(MarkupMatches, markup, markup_result);
103#if defined(OS_WIN)
104  // TODO(playmobil): It's not clear that non windows clipboards need to support
105  // this.
106  EXPECT_EQ(url, url_result);
107#endif  // defined(OS_WIN)
108}
109
110TEST_F(ClipboardTest, RTFTest) {
111  std::string rtf =
112      "{\\rtf1\\ansi{\\fonttbl\\f0\\fswiss Helvetica;}\\f0\\pard\n"
113      "This is some {\\b bold} text.\\par\n"
114      "}";
115
116  {
117    ScopedClipboardWriter clipboard_writer(&clipboard(),
118                                           Clipboard::BUFFER_STANDARD);
119    clipboard_writer.WriteRTF(rtf);
120  }
121
122  EXPECT_TRUE(clipboard().IsFormatAvailable(Clipboard::GetRtfFormatType(),
123                                            Clipboard::BUFFER_STANDARD));
124  std::string result;
125  clipboard().ReadRTF(Clipboard::BUFFER_STANDARD, &result);
126  EXPECT_EQ(rtf, result);
127}
128
129#if defined(TOOLKIT_GTK)
130TEST_F(ClipboardTest, MultipleBufferTest) {
131  string16 text(ASCIIToUTF16("Standard")), text_result;
132  string16 markup(ASCIIToUTF16("<string>Selection</string>")), markup_result;
133  std::string url("http://www.example.com/"), url_result;
134
135  {
136    ScopedClipboardWriter clipboard_writer(&clipboard(),
137                                           Clipboard::BUFFER_STANDARD);
138    clipboard_writer.WriteText(text);
139  }
140
141  {
142    ScopedClipboardWriter clipboard_writer(&clipboard(),
143                                           Clipboard::BUFFER_SELECTION);
144    clipboard_writer.WriteHTML(markup, url);
145  }
146
147  EXPECT_TRUE(clipboard().IsFormatAvailable(Clipboard::GetPlainTextFormatType(),
148                                            Clipboard::BUFFER_STANDARD));
149  EXPECT_FALSE(clipboard().IsFormatAvailable(
150      Clipboard::GetPlainTextFormatType(),
151      Clipboard::BUFFER_SELECTION));
152
153  EXPECT_FALSE(clipboard().IsFormatAvailable(Clipboard::GetHtmlFormatType(),
154                                             Clipboard::BUFFER_STANDARD));
155  EXPECT_TRUE(clipboard().IsFormatAvailable(Clipboard::GetHtmlFormatType(),
156                                            Clipboard::BUFFER_SELECTION));
157
158  clipboard().ReadText(Clipboard::BUFFER_STANDARD, &text_result);
159  EXPECT_EQ(text, text_result);
160
161  uint32 ignored;
162  clipboard().ReadHTML(Clipboard::BUFFER_SELECTION, &markup_result, &url_result,
163                       &ignored, &ignored);
164  EXPECT_PRED2(MarkupMatches, markup, markup_result);
165}
166#endif
167
168TEST_F(ClipboardTest, TrickyHTMLTest) {
169  string16 markup(ASCIIToUTF16("<em>Bye!<!--EndFragment --></em>")),
170      markup_result;
171  std::string url, url_result;
172
173  {
174    ScopedClipboardWriter clipboard_writer(&clipboard(),
175                                           Clipboard::BUFFER_STANDARD);
176    clipboard_writer.WriteHTML(markup, url);
177  }
178
179  EXPECT_TRUE(clipboard().IsFormatAvailable(Clipboard::GetHtmlFormatType(),
180                                            Clipboard::BUFFER_STANDARD));
181  uint32 ignored;
182  clipboard().ReadHTML(Clipboard::BUFFER_STANDARD, &markup_result, &url_result,
183                       &ignored, &ignored);
184  EXPECT_PRED2(MarkupMatches, markup, markup_result);
185#if defined(OS_WIN)
186  // TODO(playmobil): It's not clear that non windows clipboards need to support
187  // this.
188  EXPECT_EQ(url, url_result);
189#endif  // defined(OS_WIN)
190}
191
192#if defined(OS_WIN)
193TEST_F(ClipboardTest, UniodeHTMLTest) {
194  string16 markup(UTF8ToUTF16("<div>A \xc3\xb8 \xe6\xb0\xb4</div>")),
195      markup_result;
196  std::string url, url_result;
197
198  {
199    ScopedClipboardWriter clipboard_writer(&clipboard(),
200                                           Clipboard::BUFFER_STANDARD);
201    clipboard_writer.WriteHTML(markup, url);
202  }
203
204  EXPECT_TRUE(clipboard().IsFormatAvailable(Clipboard::GetHtmlFormatType(),
205                                            Clipboard::BUFFER_STANDARD));
206  uint32 fragment_start;
207  uint32 fragment_end;
208  clipboard().ReadHTML(Clipboard::BUFFER_STANDARD, &markup_result, &url_result,
209                       &fragment_start, &fragment_end);
210  EXPECT_PRED2(MarkupMatches, markup, markup_result);
211  EXPECT_EQ(url, url_result);
212  // Make sure that fragment indices were adjusted when converting.
213  EXPECT_EQ(36, fragment_start);
214  EXPECT_EQ(52, fragment_end);
215}
216#endif  // defined(OS_WIN)
217
218#if defined(TOOLKIT_GTK)
219// Regression test for crbug.com/56298 (pasting empty HTML crashes Linux).
220TEST_F(ClipboardTest, EmptyHTMLTest) {
221  // ScopedClipboardWriter doesn't let us write empty data to the clipboard.
222  clipboard().clipboard_data_ = new Clipboard::TargetMap();
223  // The 1 is so the compiler doesn't warn about allocating an empty array.
224  char* empty = new char[1];
225  clipboard().InsertMapping("text/html", empty, 0U);
226  clipboard().SetGtkClipboard(Clipboard::BUFFER_STANDARD);
227
228  EXPECT_TRUE(clipboard().IsFormatAvailable(Clipboard::GetHtmlFormatType(),
229                                            Clipboard::BUFFER_STANDARD));
230  string16 markup_result;
231  std::string url_result;
232  uint32 ignored;
233  clipboard().ReadHTML(Clipboard::BUFFER_STANDARD, &markup_result, &url_result,
234                       &ignored, &ignored);
235  EXPECT_PRED2(MarkupMatches, string16(), markup_result);
236}
237#endif
238
239// TODO(estade): Port the following test (decide what target we use for urls)
240#if !defined(OS_POSIX) || defined(OS_MACOSX)
241TEST_F(ClipboardTest, BookmarkTest) {
242  string16 title(ASCIIToUTF16("The Example Company")), title_result;
243  std::string url("http://www.example.com/"), url_result;
244
245  {
246    ScopedClipboardWriter clipboard_writer(&clipboard(),
247                                           Clipboard::BUFFER_STANDARD);
248    clipboard_writer.WriteBookmark(title, url);
249  }
250
251  EXPECT_TRUE(clipboard().IsFormatAvailable(Clipboard::GetUrlWFormatType(),
252                                            Clipboard::BUFFER_STANDARD));
253  clipboard().ReadBookmark(&title_result, &url_result);
254  EXPECT_EQ(title, title_result);
255  EXPECT_EQ(url, url_result);
256}
257#endif  // defined(OS_WIN)
258
259TEST_F(ClipboardTest, MultiFormatTest) {
260  string16 text(ASCIIToUTF16("Hi!")), text_result;
261  string16 markup(ASCIIToUTF16("<strong>Hi!</string>")), markup_result;
262  std::string url("http://www.example.com/"), url_result;
263  std::string ascii_text;
264
265  {
266    ScopedClipboardWriter clipboard_writer(&clipboard(),
267                                           Clipboard::BUFFER_STANDARD);
268    clipboard_writer.WriteHTML(markup, url);
269    clipboard_writer.WriteText(text);
270  }
271
272  EXPECT_TRUE(clipboard().IsFormatAvailable(Clipboard::GetHtmlFormatType(),
273                                            Clipboard::BUFFER_STANDARD));
274  EXPECT_TRUE(clipboard().IsFormatAvailable(
275      Clipboard::GetPlainTextWFormatType(), Clipboard::BUFFER_STANDARD));
276  EXPECT_TRUE(clipboard().IsFormatAvailable(
277      Clipboard::GetPlainTextFormatType(), Clipboard::BUFFER_STANDARD));
278  uint32 ignored;
279  clipboard().ReadHTML(Clipboard::BUFFER_STANDARD, &markup_result, &url_result,
280                       &ignored, &ignored);
281  EXPECT_PRED2(MarkupMatches, markup, markup_result);
282#if defined(OS_WIN)
283  // TODO(playmobil): It's not clear that non windows clipboards need to support
284  // this.
285  EXPECT_EQ(url, url_result);
286#endif  // defined(OS_WIN)
287  clipboard().ReadText(Clipboard::BUFFER_STANDARD, &text_result);
288  EXPECT_EQ(text, text_result);
289  clipboard().ReadAsciiText(Clipboard::BUFFER_STANDARD, &ascii_text);
290  EXPECT_EQ(UTF16ToUTF8(text), ascii_text);
291}
292
293TEST_F(ClipboardTest, URLTest) {
294  string16 url(ASCIIToUTF16("http://www.google.com/"));
295
296  {
297    ScopedClipboardWriter clipboard_writer(&clipboard(),
298                                           Clipboard::BUFFER_STANDARD);
299    clipboard_writer.WriteURL(url);
300  }
301
302  EXPECT_TRUE(clipboard().IsFormatAvailable(
303      Clipboard::GetPlainTextWFormatType(), Clipboard::BUFFER_STANDARD));
304  EXPECT_TRUE(clipboard().IsFormatAvailable(Clipboard::GetPlainTextFormatType(),
305                                            Clipboard::BUFFER_STANDARD));
306  string16 text_result;
307  clipboard().ReadText(Clipboard::BUFFER_STANDARD, &text_result);
308
309  EXPECT_EQ(text_result, url);
310
311  std::string ascii_text;
312  clipboard().ReadAsciiText(Clipboard::BUFFER_STANDARD, &ascii_text);
313  EXPECT_EQ(UTF16ToUTF8(url), ascii_text);
314
315#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
316  ascii_text.clear();
317  clipboard().ReadAsciiText(Clipboard::BUFFER_SELECTION, &ascii_text);
318  EXPECT_EQ(UTF16ToUTF8(url), ascii_text);
319#endif
320}
321
322TEST_F(ClipboardTest, SharedBitmapTest) {
323  unsigned int fake_bitmap[] = {
324    0x46155189, 0xF6A55C8D, 0x79845674, 0xFA57BD89,
325    0x78FD46AE, 0x87C64F5A, 0x36EDC5AF, 0x4378F568,
326    0x91E9F63A, 0xC31EA14F, 0x69AB32DF, 0x643A3FD1,
327  };
328  gfx::Size fake_bitmap_size(3, 4);
329  uint32 bytes = sizeof(fake_bitmap);
330
331  // Create shared memory region.
332  base::SharedMemory shared_buf;
333  ASSERT_TRUE(shared_buf.CreateAndMapAnonymous(bytes));
334  memcpy(shared_buf.memory(), fake_bitmap, bytes);
335  base::SharedMemoryHandle handle_to_share;
336  base::ProcessHandle current_process = base::kNullProcessHandle;
337#if defined(OS_WIN)
338  current_process = GetCurrentProcess();
339#endif
340  shared_buf.ShareToProcess(current_process, &handle_to_share);
341  ASSERT_TRUE(shared_buf.Unmap());
342
343  // Setup data for clipboard().
344  Clipboard::ObjectMapParam placeholder_param;
345  Clipboard::ObjectMapParam size_param;
346  const char* size_data = reinterpret_cast<const char*>(&fake_bitmap_size);
347  for (size_t i = 0; i < sizeof(fake_bitmap_size); ++i)
348    size_param.push_back(size_data[i]);
349
350  Clipboard::ObjectMapParams params;
351  params.push_back(placeholder_param);
352  params.push_back(size_param);
353
354  Clipboard::ObjectMap objects;
355  objects[Clipboard::CBF_SMBITMAP] = params;
356  Clipboard::ReplaceSharedMemHandle(&objects, handle_to_share, current_process);
357
358  clipboard().WriteObjects(Clipboard::BUFFER_STANDARD,
359                           objects);
360
361  EXPECT_TRUE(clipboard().IsFormatAvailable(Clipboard::GetBitmapFormatType(),
362                                            Clipboard::BUFFER_STANDARD));
363}
364
365// The following test somehow fails on GTK and linux_aura. The image when read
366// back from the clipboard has the alpha channel set to 0xFF for some
367// reason. The other channels stay intact. So I am turning this on only for
368// aura.
369#if (defined(USE_AURA) && !(defined(OS_WIN) || !defined(OS_CHROMEOS))) || \
370    defined(OS_ANDROID)
371TEST_F(ClipboardTest, MultipleBitmapReadWriteTest) {
372  // Test first bitmap
373  unsigned int fake_bitmap_1[] = {
374    0x46155189, 0xF6A55C8D, 0x79845674, 0xFA57BD89,
375    0x78FD46AE, 0x87C64F5A, 0x36EDC5AF, 0x4378F568,
376    0x91E9F63A, 0xC31EA14F, 0x69AB32DF, 0x643A3FD1,
377  };
378  gfx::Size fake_bitmap_1_size(3, 4);
379  {
380    ScopedClipboardWriter clipboard_writer(&clipboard(),
381                                           Clipboard::BUFFER_STANDARD);
382    clipboard_writer.WriteBitmapFromPixels(fake_bitmap_1, fake_bitmap_1_size);
383  }
384  EXPECT_TRUE(clipboard().IsFormatAvailable(Clipboard::GetBitmapFormatType(),
385                                            Clipboard::BUFFER_STANDARD));
386  SkBitmap image_1 = clipboard().ReadImage(Clipboard::BUFFER_STANDARD);
387  EXPECT_EQ(fake_bitmap_1_size, gfx::Size(image_1.width(), image_1.height()));
388  unsigned int* pixels_1 = reinterpret_cast<unsigned int*>(image_1.getPixels());
389  for (int i = 0; i < fake_bitmap_1_size.width(); ++i) {
390    for (int j = 0; j < fake_bitmap_1_size.height(); ++j) {
391      int id = i * fake_bitmap_1_size.height() + j;
392      EXPECT_EQ(fake_bitmap_1[id], pixels_1[id]);
393    }
394  }
395
396  // Test second bitmap
397  unsigned int fake_bitmap_2[] = {
398    0x46155189, 0xF6A55C8D,
399    0x79845674, 0xFA57BD89,
400    0x78FD46AE, 0x87C64F5A,
401    0x36EDC5AF, 0x4378F568,
402    0x91E9F63A, 0xC31EA14F,
403    0x69AB32DF, 0x643A3FD1,
404    0xA6DF041D, 0x83046278,
405  };
406  gfx::Size fake_bitmap_2_size(7, 2);
407  {
408    ScopedClipboardWriter clipboard_writer(&clipboard(),
409                                           Clipboard::BUFFER_STANDARD);
410    clipboard_writer.WriteBitmapFromPixels(fake_bitmap_2, fake_bitmap_2_size);
411  }
412  EXPECT_TRUE(clipboard().IsFormatAvailable(Clipboard::GetBitmapFormatType(),
413                                            Clipboard::BUFFER_STANDARD));
414  SkBitmap image_2 = clipboard().ReadImage(Clipboard::BUFFER_STANDARD);
415  EXPECT_EQ(fake_bitmap_2_size, gfx::Size(image_2.width(), image_2.height()));
416  unsigned int* pixels_2 = reinterpret_cast<unsigned int*>(image_2.getPixels());
417  for (int i = 0; i < fake_bitmap_2_size.width(); ++i) {
418    for (int j = 0; j < fake_bitmap_2_size.height(); ++j) {
419      int id = i * fake_bitmap_2_size.height() + j;
420      EXPECT_EQ(fake_bitmap_2[id], pixels_2[id]);
421    }
422  }
423}
424#endif
425
426TEST_F(ClipboardTest, DataTest) {
427  const ui::Clipboard::FormatType kFormat =
428      ui::Clipboard::GetFormatType("chromium/x-test-format");
429  std::string payload("test string");
430  Pickle write_pickle;
431  write_pickle.WriteString(payload);
432
433  {
434    ScopedClipboardWriter clipboard_writer(&clipboard(),
435                                           Clipboard::BUFFER_STANDARD);
436    clipboard_writer.WritePickledData(write_pickle, kFormat);
437  }
438
439  ASSERT_TRUE(clipboard().IsFormatAvailable(
440      kFormat, Clipboard::BUFFER_STANDARD));
441  std::string output;
442  clipboard().ReadData(kFormat, &output);
443  ASSERT_FALSE(output.empty());
444
445  Pickle read_pickle(output.data(), output.size());
446  PickleIterator iter(read_pickle);
447  std::string unpickled_string;
448  ASSERT_TRUE(read_pickle.ReadString(&iter, &unpickled_string));
449  EXPECT_EQ(payload, unpickled_string);
450}
451
452TEST_F(ClipboardTest, MultipleDataTest) {
453  const ui::Clipboard::FormatType kFormat1 =
454      ui::Clipboard::GetFormatType("chromium/x-test-format1");
455  std::string payload1("test string1");
456  Pickle write_pickle1;
457  write_pickle1.WriteString(payload1);
458
459  const ui::Clipboard::FormatType kFormat2 =
460      ui::Clipboard::GetFormatType("chromium/x-test-format2");
461  std::string payload2("test string2");
462  Pickle write_pickle2;
463  write_pickle2.WriteString(payload2);
464
465  {
466    ScopedClipboardWriter clipboard_writer(&clipboard(),
467                                           Clipboard::BUFFER_STANDARD);
468    clipboard_writer.WritePickledData(write_pickle1, kFormat1);
469    // overwrite the previous pickle for fun
470    clipboard_writer.WritePickledData(write_pickle2, kFormat2);
471  }
472
473  ASSERT_TRUE(clipboard().IsFormatAvailable(
474      kFormat2, Clipboard::BUFFER_STANDARD));
475
476  // Check string 2.
477  std::string output2;
478  clipboard().ReadData(kFormat2, &output2);
479  ASSERT_FALSE(output2.empty());
480
481  Pickle read_pickle2(output2.data(), output2.size());
482  PickleIterator iter2(read_pickle2);
483  std::string unpickled_string2;
484  ASSERT_TRUE(read_pickle2.ReadString(&iter2, &unpickled_string2));
485  EXPECT_EQ(payload2, unpickled_string2);
486
487  {
488    ScopedClipboardWriter clipboard_writer(&clipboard(),
489                                           Clipboard::BUFFER_STANDARD);
490    clipboard_writer.WritePickledData(write_pickle2, kFormat2);
491    // overwrite the previous pickle for fun
492    clipboard_writer.WritePickledData(write_pickle1, kFormat1);
493  }
494
495  ASSERT_TRUE(clipboard().IsFormatAvailable(
496      kFormat1, Clipboard::BUFFER_STANDARD));
497
498  // Check string 1.
499  std::string output1;
500  clipboard().ReadData(kFormat1, &output1);
501  ASSERT_FALSE(output1.empty());
502
503  Pickle read_pickle1(output1.data(), output1.size());
504  PickleIterator iter1(read_pickle1);
505  std::string unpickled_string1;
506  ASSERT_TRUE(read_pickle1.ReadString(&iter1, &unpickled_string1));
507  EXPECT_EQ(payload1, unpickled_string1);
508}
509
510#if defined(OS_WIN)  // Windows only tests.
511TEST_F(ClipboardTest, HyperlinkTest) {
512  const std::string kTitle("The Example Company");
513  const std::string kUrl("http://www.example.com/");
514  const std::string kExpectedHtml("<a href=\"http://www.example.com/\">"
515                                  "The Example Company</a>");
516  std::string url_result;
517  string16 html_result;
518
519  {
520    ScopedClipboardWriter clipboard_writer(&clipboard(),
521                                           Clipboard::BUFFER_STANDARD);
522    clipboard_writer.WriteHyperlink(ASCIIToUTF16(kTitle), kUrl);
523  }
524
525  EXPECT_TRUE(clipboard().IsFormatAvailable(Clipboard::GetHtmlFormatType(),
526                                            Clipboard::BUFFER_STANDARD));
527  uint32 ignored;
528  clipboard().ReadHTML(Clipboard::BUFFER_STANDARD, &html_result, &url_result,
529                       &ignored, &ignored);
530  EXPECT_PRED2(MarkupMatches, ASCIIToUTF16(kExpectedHtml), html_result);
531}
532
533TEST_F(ClipboardTest, WebSmartPasteTest) {
534  {
535    ScopedClipboardWriter clipboard_writer(&clipboard(),
536                                           Clipboard::BUFFER_STANDARD);
537    clipboard_writer.WriteWebSmartPaste();
538  }
539
540  EXPECT_TRUE(clipboard().IsFormatAvailable(
541      Clipboard::GetWebKitSmartPasteFormatType(), Clipboard::BUFFER_STANDARD));
542}
543
544TEST_F(ClipboardTest, BitmapTest) {
545  unsigned int fake_bitmap[] = {
546    0x46155189, 0xF6A55C8D, 0x79845674, 0xFA57BD89,
547    0x78FD46AE, 0x87C64F5A, 0x36EDC5AF, 0x4378F568,
548    0x91E9F63A, 0xC31EA14F, 0x69AB32DF, 0x643A3FD1,
549  };
550
551  {
552    ScopedClipboardWriter clipboard_writer(&clipboard(),
553                                           Clipboard::BUFFER_STANDARD);
554    clipboard_writer.WriteBitmapFromPixels(fake_bitmap, gfx::Size(3, 4));
555  }
556
557  EXPECT_TRUE(clipboard().IsFormatAvailable(Clipboard::GetBitmapFormatType(),
558                                            Clipboard::BUFFER_STANDARD));
559}
560
561void HtmlTestHelper(const std::string& cf_html,
562                    const std::string& expected_html) {
563  std::string html;
564  ClipboardUtil::CFHtmlToHtml(cf_html, &html, NULL);
565  EXPECT_EQ(html, expected_html);
566}
567
568TEST_F(ClipboardTest, HtmlTest) {
569  // Test converting from CF_HTML format data with <!--StartFragment--> and
570  // <!--EndFragment--> comments, like from MS Word.
571  HtmlTestHelper("Version:1.0\r\n"
572                 "StartHTML:0000000105\r\n"
573                 "EndHTML:0000000199\r\n"
574                 "StartFragment:0000000123\r\n"
575                 "EndFragment:0000000161\r\n"
576                 "\r\n"
577                 "<html>\r\n"
578                 "<body>\r\n"
579                 "<!--StartFragment-->\r\n"
580                 "\r\n"
581                 "<p>Foo</p>\r\n"
582                 "\r\n"
583                 "<!--EndFragment-->\r\n"
584                 "</body>\r\n"
585                 "</html>\r\n\r\n",
586                 "<p>Foo</p>");
587
588  // Test converting from CF_HTML format data without <!--StartFragment--> and
589  // <!--EndFragment--> comments, like from OpenOffice Writer.
590  HtmlTestHelper("Version:1.0\r\n"
591                 "StartHTML:0000000105\r\n"
592                 "EndHTML:0000000151\r\n"
593                 "StartFragment:0000000121\r\n"
594                 "EndFragment:0000000131\r\n"
595                 "<html>\r\n"
596                 "<body>\r\n"
597                 "<p>Foo</p>\r\n"
598                 "</body>\r\n"
599                 "</html>\r\n\r\n",
600                 "<p>Foo</p>");
601}
602#endif  // defined(OS_WIN)
603
604// Test writing all formats we have simultaneously.
605TEST_F(ClipboardTest, WriteEverything) {
606  {
607    ScopedClipboardWriter writer(&clipboard(), Clipboard::BUFFER_STANDARD);
608    writer.WriteText(UTF8ToUTF16("foo"));
609    writer.WriteURL(UTF8ToUTF16("foo"));
610    writer.WriteHTML(UTF8ToUTF16("foo"), "bar");
611    writer.WriteBookmark(UTF8ToUTF16("foo"), "bar");
612    writer.WriteHyperlink(ASCIIToUTF16("foo"), "bar");
613    writer.WriteWebSmartPaste();
614    // Left out: WriteFile, WriteFiles, WriteBitmapFromPixels, WritePickledData.
615  }
616
617  // Passes if we don't crash.
618}
619
620#if defined(OS_ANDROID)
621
622// Test that if another application writes some text to the pasteboard the
623// clipboard properly invalidates other types.
624TEST_F(ClipboardTest, InternalClipboardInvalidation) {
625  const unsigned int kFakeBitmap[] = {
626    0x46155189, 0xF6A55C8D, 0x79845674, 0xFA57BD89,
627    0x78FD46AE, 0x87C64F5A, 0x36EDC5AF, 0x4378F568,
628    0x91E9F63A, 0xC31EA14F, 0x69AB32DF, 0x643A3FD1,
629  };
630
631  // Write a bitmap in our clipboard().
632  {
633    ScopedClipboardWriter clipboard_writer(&clipboard(),
634                                           Clipboard::BUFFER_STANDARD);
635    clipboard_writer.WriteBitmapFromPixels(kFakeBitmap, gfx::Size(3, 4));
636  }
637
638  //
639  // Simulate that another application copied something in the Clipboard
640  //
641  std::string new_value("Some text copied by some other app");
642  using base::android::ConvertUTF8ToJavaString;
643  using base::android::MethodID;
644  using base::android::ScopedJavaLocalRef;
645
646  JNIEnv* env = base::android::AttachCurrentThread();
647  ASSERT_TRUE(env);
648
649  jobject context = base::android::GetApplicationContext();
650  ASSERT_TRUE(context);
651
652  ScopedJavaLocalRef<jclass> context_class =
653      base::android::GetClass(env, "android/content/Context");
654
655  jmethodID get_system_service = MethodID::Get<MethodID::TYPE_INSTANCE>(
656      env, context_class.obj(), "getSystemService",
657      "(Ljava/lang/String;)Ljava/lang/Object;");
658
659  // Retrieve the system service.
660  ScopedJavaLocalRef<jstring> service_name = ConvertUTF8ToJavaString(
661      env, "clipboard");
662  ScopedJavaLocalRef<jobject> clipboard_manager(
663      env, env->CallObjectMethod(
664        context, get_system_service, service_name.obj()));
665  ASSERT_TRUE(clipboard_manager.obj() && !base::android::ClearException(env));
666
667  ScopedJavaLocalRef<jclass> clipboard_class =
668      base::android::GetClass(env, "android/text/ClipboardManager");
669  jmethodID set_text = MethodID::Get<MethodID::TYPE_INSTANCE>(
670      env, clipboard_class.obj(), "setText", "(Ljava/lang/CharSequence;)V");
671  ScopedJavaLocalRef<jstring> new_value_string = ConvertUTF8ToJavaString(
672      env, new_value.c_str());
673
674  // Will need to call toString as CharSequence is not always a String.
675  env->CallVoidMethod(clipboard_manager.obj(),
676                      set_text,
677                      new_value_string.obj());
678
679  // The bitmap that should have been available should be gone.
680  EXPECT_FALSE(clipboard().IsFormatAvailable(Clipboard::GetBitmapFormatType(),
681                                             Clipboard::BUFFER_STANDARD));
682
683  // Make sure some text is available
684  EXPECT_TRUE(clipboard().IsFormatAvailable(
685      Clipboard::GetPlainTextWFormatType(), Clipboard::BUFFER_STANDARD));
686
687  // Make sure the text is what we inserted while simulating the other app
688  std::string contents;
689  clipboard().ReadAsciiText(Clipboard::BUFFER_STANDARD, &contents);
690  EXPECT_EQ(contents, new_value);
691}
692#endif
693}  // namespace ui
694