• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "ppapi/tests/test_flash_clipboard.h"
6 
7 #include <algorithm>
8 #include <vector>
9 
10 #include "ppapi/cpp/instance.h"
11 #include "ppapi/cpp/module.h"
12 #include "ppapi/cpp/point.h"
13 #include "ppapi/cpp/private/flash_clipboard.h"
14 #include "ppapi/cpp/var.h"
15 #include "ppapi/cpp/var_array_buffer.h"
16 #include "ppapi/tests/testing_instance.h"
17 
18 // http://crbug.com/176822
19 #if !defined(OS_WIN)
20 REGISTER_TEST_CASE(FlashClipboard);
21 #endif
22 
23 // WriteData() sends an async request to the browser process. As a result, the
24 // string written may not be reflected by IsFormatAvailable() or ReadPlainText()
25 // immediately. We need to wait and retry.
26 const int kIntervalMs = 250;
27 const int kMaxIntervals = kActionTimeoutMs / kIntervalMs;
28 
TestFlashClipboard(TestingInstance * instance)29 TestFlashClipboard::TestFlashClipboard(TestingInstance* instance)
30     : TestCase(instance) {
31 }
32 
RunTests(const std::string & filter)33 void TestFlashClipboard::RunTests(const std::string& filter) {
34   RUN_TEST(ReadWritePlainText, filter);
35   RUN_TEST(ReadWriteHTML, filter);
36   RUN_TEST(ReadWriteRTF, filter);
37   RUN_TEST(ReadWriteCustomData, filter);
38   RUN_TEST(ReadWriteMultipleFormats, filter);
39   RUN_TEST(Clear, filter);
40   RUN_TEST(InvalidFormat, filter);
41   RUN_TEST(RegisterCustomFormat, filter);
42   RUN_TEST(GetSequenceNumber, filter);
43 }
44 
ReadStringVar(uint32_t format,std::string * result)45 bool TestFlashClipboard::ReadStringVar(uint32_t format, std::string* result) {
46   pp::Var text;
47   bool success = pp::flash::Clipboard::ReadData(
48       instance_,
49       PP_FLASH_CLIPBOARD_TYPE_STANDARD,
50       format,
51       &text);
52   if (success && text.is_string()) {
53     *result = text.AsString();
54     return true;
55   }
56   return false;
57 }
58 
WriteStringVar(uint32_t format,const std::string & text)59 bool TestFlashClipboard::WriteStringVar(uint32_t format,
60                                         const std::string& text) {
61   std::vector<uint32_t> formats_vector(1, format);
62   std::vector<pp::Var> data_vector(1, pp::Var(text));
63   bool success = pp::flash::Clipboard::WriteData(
64       instance_,
65       PP_FLASH_CLIPBOARD_TYPE_STANDARD,
66       formats_vector,
67       data_vector);
68   return success;
69 }
70 
IsFormatAvailableMatches(uint32_t format,bool expected)71 bool TestFlashClipboard::IsFormatAvailableMatches(uint32_t format,
72                                                   bool expected) {
73   for (int i = 0; i < kMaxIntervals; ++i) {
74     bool is_available = pp::flash::Clipboard::IsFormatAvailable(
75         instance_,
76         PP_FLASH_CLIPBOARD_TYPE_STANDARD,
77         format);
78     if (is_available == expected)
79       return true;
80 
81     PlatformSleep(kIntervalMs);
82   }
83   return false;
84 }
85 
ReadPlainTextMatches(const std::string & expected)86 bool TestFlashClipboard::ReadPlainTextMatches(const std::string& expected) {
87   for (int i = 0; i < kMaxIntervals; ++i) {
88     std::string result;
89     bool success = ReadStringVar(PP_FLASH_CLIPBOARD_FORMAT_PLAINTEXT, &result);
90     if (success && result == expected)
91       return true;
92 
93     PlatformSleep(kIntervalMs);
94   }
95   return false;
96 }
97 
ReadHTMLMatches(const std::string & expected)98 bool TestFlashClipboard::ReadHTMLMatches(const std::string& expected) {
99   for (int i = 0; i < kMaxIntervals; ++i) {
100     std::string result;
101     bool success = ReadStringVar(PP_FLASH_CLIPBOARD_FORMAT_HTML, &result);
102     // Harmless markup may be inserted around the copied html on some
103     // platforms, so just check that the pasted string contains the
104     // copied string. Also check that we only paste the copied fragment, see
105     // http://code.google.com/p/chromium/issues/detail?id=130827.
106     if (success && result.find(expected) != std::string::npos &&
107         result.find("<!--StartFragment-->") == std::string::npos &&
108         result.find("<!--EndFragment-->") == std::string::npos) {
109       return true;
110     }
111 
112     PlatformSleep(kIntervalMs);
113   }
114   return false;
115 }
116 
GetSequenceNumber(uint64_t last_sequence_number)117 uint64_t TestFlashClipboard::GetSequenceNumber(uint64_t last_sequence_number) {
118   uint64_t next_sequence_number = last_sequence_number;
119   for (int i = 0; i < kMaxIntervals; ++i) {
120     pp::flash::Clipboard::GetSequenceNumber(
121         instance_, PP_FLASH_CLIPBOARD_TYPE_STANDARD, &next_sequence_number);
122     if (next_sequence_number != last_sequence_number)
123       return next_sequence_number;
124 
125     PlatformSleep(kIntervalMs);
126   }
127   return next_sequence_number;
128 }
129 
TestReadWritePlainText()130 std::string TestFlashClipboard::TestReadWritePlainText() {
131   std::string input = "Hello world plain text!";
132   ASSERT_TRUE(WriteStringVar(PP_FLASH_CLIPBOARD_FORMAT_PLAINTEXT, input));
133   ASSERT_TRUE(IsFormatAvailableMatches(PP_FLASH_CLIPBOARD_FORMAT_PLAINTEXT,
134                                        true));
135   ASSERT_TRUE(ReadPlainTextMatches(input));
136 
137   PASS();
138 }
139 
TestReadWriteHTML()140 std::string TestFlashClipboard::TestReadWriteHTML() {
141   std::string input = "Hello world html!";
142   ASSERT_TRUE(WriteStringVar(PP_FLASH_CLIPBOARD_FORMAT_HTML, input));
143   ASSERT_TRUE(IsFormatAvailableMatches(PP_FLASH_CLIPBOARD_FORMAT_HTML, true));
144   ASSERT_TRUE(ReadHTMLMatches(input));
145 
146   PASS();
147 }
148 
TestReadWriteRTF()149 std::string TestFlashClipboard::TestReadWriteRTF() {
150   std::string rtf_string =
151         "{\\rtf1\\ansi{\\fonttbl\\f0\\fswiss Helvetica;}\\f0\\pard\n"
152         "This is some {\\b bold} text.\\par\n"
153         "}";
154   pp::VarArrayBuffer array_buffer(rtf_string.size());
155   char* bytes = static_cast<char*>(array_buffer.Map());
156   std::copy(rtf_string.data(), rtf_string.data() + rtf_string.size(), bytes);
157   std::vector<uint32_t> formats_vector(1, PP_FLASH_CLIPBOARD_FORMAT_RTF);
158   std::vector<pp::Var> data_vector(1, array_buffer);
159   ASSERT_TRUE(pp::flash::Clipboard::WriteData(
160       instance_,
161       PP_FLASH_CLIPBOARD_TYPE_STANDARD,
162       formats_vector,
163       data_vector));
164 
165   ASSERT_TRUE(IsFormatAvailableMatches(PP_FLASH_CLIPBOARD_FORMAT_RTF, true));
166 
167   pp::Var rtf_result;
168   ASSERT_TRUE(pp::flash::Clipboard::ReadData(
169         instance_,
170         PP_FLASH_CLIPBOARD_TYPE_STANDARD,
171         PP_FLASH_CLIPBOARD_FORMAT_RTF,
172         &rtf_result));
173   ASSERT_TRUE(rtf_result.is_array_buffer());
174   pp::VarArrayBuffer array_buffer_result(rtf_result);
175   ASSERT_TRUE(array_buffer_result.ByteLength() == array_buffer.ByteLength());
176   char* bytes_result = static_cast<char*>(array_buffer_result.Map());
177   ASSERT_TRUE(std::equal(bytes, bytes + array_buffer.ByteLength(),
178       bytes_result));
179 
180   PASS();
181 }
182 
TestReadWriteCustomData()183 std::string TestFlashClipboard::TestReadWriteCustomData() {
184   std::string custom_data = "custom_data";
185   pp::VarArrayBuffer array_buffer(custom_data.size());
186   char* bytes = static_cast<char*>(array_buffer.Map());
187   std::copy(custom_data.begin(), custom_data.end(), bytes);
188   uint32_t format_id =
189       pp::flash::Clipboard::RegisterCustomFormat(instance_, "my-format");
190   ASSERT_NE(static_cast<uint32_t>(PP_FLASH_CLIPBOARD_FORMAT_INVALID),
191             format_id);
192 
193   std::vector<uint32_t> formats_vector(1, format_id);
194   std::vector<pp::Var> data_vector(1, array_buffer);
195   ASSERT_TRUE(pp::flash::Clipboard::WriteData(
196       instance_,
197       PP_FLASH_CLIPBOARD_TYPE_STANDARD,
198       formats_vector,
199       data_vector));
200 
201   ASSERT_TRUE(IsFormatAvailableMatches(format_id, true));
202 
203   pp::Var custom_data_result;
204   ASSERT_TRUE(pp::flash::Clipboard::ReadData(
205       instance_,
206       PP_FLASH_CLIPBOARD_TYPE_STANDARD,
207       format_id,
208       &custom_data_result));
209   ASSERT_TRUE(custom_data_result.is_array_buffer());
210   pp::VarArrayBuffer array_buffer_result(custom_data_result);
211   ASSERT_EQ(array_buffer_result.ByteLength(), array_buffer.ByteLength());
212   char* bytes_result = static_cast<char*>(array_buffer_result.Map());
213   ASSERT_TRUE(std::equal(bytes, bytes + array_buffer.ByteLength(),
214       bytes_result));
215 
216   PASS();
217 }
218 
TestReadWriteMultipleFormats()219 std::string TestFlashClipboard::TestReadWriteMultipleFormats() {
220   std::vector<uint32_t> formats;
221   std::vector<pp::Var> data;
222   formats.push_back(PP_FLASH_CLIPBOARD_FORMAT_PLAINTEXT);
223   data.push_back(pp::Var("plain text"));
224   formats.push_back(PP_FLASH_CLIPBOARD_FORMAT_HTML);
225   data.push_back(pp::Var("html"));
226   bool success = pp::flash::Clipboard::WriteData(
227       instance_,
228       PP_FLASH_CLIPBOARD_TYPE_STANDARD,
229       formats,
230       data);
231   ASSERT_TRUE(success);
232   ASSERT_TRUE(IsFormatAvailableMatches(PP_FLASH_CLIPBOARD_FORMAT_PLAINTEXT,
233                                        true));
234   ASSERT_TRUE(IsFormatAvailableMatches(PP_FLASH_CLIPBOARD_FORMAT_HTML, true));
235   ASSERT_TRUE(ReadPlainTextMatches(data[0].AsString()));
236   ASSERT_TRUE(ReadHTMLMatches(data[1].AsString()));
237 
238   PASS();
239 }
240 
TestClear()241 std::string TestFlashClipboard::TestClear() {
242   std::string input = "Hello world plain text!";
243   ASSERT_TRUE(WriteStringVar(PP_FLASH_CLIPBOARD_FORMAT_PLAINTEXT, input));
244   ASSERT_TRUE(IsFormatAvailableMatches(PP_FLASH_CLIPBOARD_FORMAT_PLAINTEXT,
245                                        true));
246   bool success = pp::flash::Clipboard::WriteData(
247       instance_,
248       PP_FLASH_CLIPBOARD_TYPE_STANDARD,
249       std::vector<uint32_t>(),
250       std::vector<pp::Var>());
251   ASSERT_TRUE(success);
252   ASSERT_TRUE(IsFormatAvailableMatches(PP_FLASH_CLIPBOARD_FORMAT_PLAINTEXT,
253                                        false));
254 
255   PASS();
256 }
257 
TestInvalidFormat()258 std::string TestFlashClipboard::TestInvalidFormat() {
259   uint32_t invalid_format = 999;
260   ASSERT_FALSE(WriteStringVar(invalid_format, "text"));
261   ASSERT_TRUE(IsFormatAvailableMatches(invalid_format, false));
262   std::string unused;
263   ASSERT_FALSE(ReadStringVar(invalid_format, &unused));
264 
265   PASS();
266 }
267 
TestRegisterCustomFormat()268 std::string TestFlashClipboard::TestRegisterCustomFormat() {
269   // Test an empty name is rejected.
270   uint32_t format_id =
271       pp::flash::Clipboard::RegisterCustomFormat(instance_, std::string());
272   ASSERT_EQ(static_cast<uint32_t>(PP_FLASH_CLIPBOARD_FORMAT_INVALID),
273             format_id);
274 
275   // Test a valid format name.
276   format_id = pp::flash::Clipboard::RegisterCustomFormat(instance_, "a-b");
277   ASSERT_NE(static_cast<uint32_t>(PP_FLASH_CLIPBOARD_FORMAT_INVALID),
278             format_id);
279   // Make sure the format doesn't collide with predefined formats.
280   ASSERT_NE(static_cast<uint32_t>(PP_FLASH_CLIPBOARD_FORMAT_PLAINTEXT),
281             format_id);
282   ASSERT_NE(static_cast<uint32_t>(PP_FLASH_CLIPBOARD_FORMAT_HTML),
283             format_id);
284   ASSERT_NE(static_cast<uint32_t>(PP_FLASH_CLIPBOARD_FORMAT_RTF),
285             format_id);
286 
287   // Check that if the same name is registered, the same id comes out.
288   uint32_t format_id2 =
289       pp::flash::Clipboard::RegisterCustomFormat(instance_, "a-b");
290   ASSERT_EQ(format_id, format_id2);
291 
292   // Check that the second format registered has a different id.
293   uint32_t format_id3 =
294       pp::flash::Clipboard::RegisterCustomFormat(instance_, "a-b-c");
295   ASSERT_NE(format_id, format_id3);
296 
297   PASS();
298 }
299 
TestGetSequenceNumber()300 std::string TestFlashClipboard::TestGetSequenceNumber() {
301   uint64_t sequence_number_before = 0;
302   uint64_t sequence_number_after = 0;
303   ASSERT_TRUE(pp::flash::Clipboard::GetSequenceNumber(
304       instance_, PP_FLASH_CLIPBOARD_TYPE_STANDARD, &sequence_number_before));
305 
306   // Test the sequence number changes after writing html.
307   ASSERT_TRUE(WriteStringVar(PP_FLASH_CLIPBOARD_FORMAT_HTML, "<html>"));
308   sequence_number_after = GetSequenceNumber(sequence_number_before);
309   ASSERT_NE(sequence_number_before, sequence_number_after);
310   sequence_number_before = sequence_number_after;
311 
312   // Test the sequence number changes after writing some custom data.
313   std::string custom_data = "custom_data";
314   pp::VarArrayBuffer array_buffer(custom_data.size());
315   char* bytes = static_cast<char*>(array_buffer.Map());
316   std::copy(custom_data.begin(), custom_data.end(), bytes);
317   uint32_t format_id =
318       pp::flash::Clipboard::RegisterCustomFormat(instance_, "my-format");
319   std::vector<uint32_t> formats_vector(1, format_id);
320   std::vector<pp::Var> data_vector(1, array_buffer);
321   ASSERT_TRUE(pp::flash::Clipboard::WriteData(instance_,
322                                               PP_FLASH_CLIPBOARD_TYPE_STANDARD,
323                                               formats_vector,
324                                               data_vector));
325   sequence_number_after = GetSequenceNumber(sequence_number_before);
326   ASSERT_NE(sequence_number_before, sequence_number_after);
327   sequence_number_before = sequence_number_after;
328 
329   // Read the data and make sure the sequence number doesn't change.
330   pp::Var custom_data_result;
331   ASSERT_TRUE(pp::flash::Clipboard::ReadData(
332       instance_,
333       PP_FLASH_CLIPBOARD_TYPE_STANDARD,
334       format_id,
335       &custom_data_result));
336   ASSERT_TRUE(pp::flash::Clipboard::GetSequenceNumber(
337       instance_, PP_FLASH_CLIPBOARD_TYPE_STANDARD, &sequence_number_after));
338   ASSERT_EQ(sequence_number_before, sequence_number_after);
339   sequence_number_before = sequence_number_after;
340 
341   // Clear the clipboard and check the sequence number changes.
342   pp::flash::Clipboard::WriteData(instance_,
343                                   PP_FLASH_CLIPBOARD_TYPE_STANDARD,
344                                   std::vector<uint32_t>(),
345                                   std::vector<pp::Var>());
346   sequence_number_after = GetSequenceNumber(sequence_number_before);
347   ASSERT_NE(sequence_number_before, sequence_number_after);
348 
349   PASS();
350 }
351