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 "ppapi/tests/test_flash_clipboard.h"
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"
18 // http://crbug.com/176822
20 REGISTER_TEST_CASE(FlashClipboard
);
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
;
29 TestFlashClipboard::TestFlashClipboard(TestingInstance
* instance
)
30 : TestCase(instance
) {
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
);
45 bool TestFlashClipboard::ReadStringVar(uint32_t format
, std::string
* result
) {
47 bool success
= pp::flash::Clipboard::ReadData(
49 PP_FLASH_CLIPBOARD_TYPE_STANDARD
,
52 if (success
&& text
.is_string()) {
53 *result
= text
.AsString();
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(
65 PP_FLASH_CLIPBOARD_TYPE_STANDARD
,
71 bool TestFlashClipboard::IsFormatAvailableMatches(uint32_t format
,
73 for (int i
= 0; i
< kMaxIntervals
; ++i
) {
74 bool is_available
= pp::flash::Clipboard::IsFormatAvailable(
76 PP_FLASH_CLIPBOARD_TYPE_STANDARD
,
78 if (is_available
== expected
)
81 PlatformSleep(kIntervalMs
);
86 bool TestFlashClipboard::ReadPlainTextMatches(const std::string
& expected
) {
87 for (int i
= 0; i
< kMaxIntervals
; ++i
) {
89 bool success
= ReadStringVar(PP_FLASH_CLIPBOARD_FORMAT_PLAINTEXT
, &result
);
90 if (success
&& result
== expected
)
93 PlatformSleep(kIntervalMs
);
98 bool TestFlashClipboard::ReadHTMLMatches(const std::string
& expected
) {
99 for (int i
= 0; i
< kMaxIntervals
; ++i
) {
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
) {
112 PlatformSleep(kIntervalMs
);
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
;
125 PlatformSleep(kIntervalMs
);
127 return next_sequence_number
;
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
,
135 ASSERT_TRUE(ReadPlainTextMatches(input
));
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
));
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"
154 pp::VarArrayBuffer
array_buffer(static_cast<uint32_t>(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(
161 PP_FLASH_CLIPBOARD_TYPE_STANDARD
,
165 ASSERT_TRUE(IsFormatAvailableMatches(PP_FLASH_CLIPBOARD_FORMAT_RTF
, true));
168 ASSERT_TRUE(pp::flash::Clipboard::ReadData(
170 PP_FLASH_CLIPBOARD_TYPE_STANDARD
,
171 PP_FLASH_CLIPBOARD_FORMAT_RTF
,
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(),
183 std::string
TestFlashClipboard::TestReadWriteCustomData() {
184 std::string custom_data
= "custom_data";
185 pp::VarArrayBuffer
array_buffer(static_cast<uint32_t>(custom_data
.size()));
186 char* bytes
= static_cast<char*>(array_buffer
.Map());
187 std::copy(custom_data
.begin(), custom_data
.end(), bytes
);
189 pp::flash::Clipboard::RegisterCustomFormat(instance_
, "my-format");
190 ASSERT_NE(static_cast<uint32_t>(PP_FLASH_CLIPBOARD_FORMAT_INVALID
),
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(
197 PP_FLASH_CLIPBOARD_TYPE_STANDARD
,
201 ASSERT_TRUE(IsFormatAvailableMatches(format_id
, true));
203 pp::Var custom_data_result
;
204 ASSERT_TRUE(pp::flash::Clipboard::ReadData(
206 PP_FLASH_CLIPBOARD_TYPE_STANDARD
,
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(),
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(
228 PP_FLASH_CLIPBOARD_TYPE_STANDARD
,
231 ASSERT_TRUE(success
);
232 ASSERT_TRUE(IsFormatAvailableMatches(PP_FLASH_CLIPBOARD_FORMAT_PLAINTEXT
,
234 ASSERT_TRUE(IsFormatAvailableMatches(PP_FLASH_CLIPBOARD_FORMAT_HTML
, true));
235 ASSERT_TRUE(ReadPlainTextMatches(data
[0].AsString()));
236 ASSERT_TRUE(ReadHTMLMatches(data
[1].AsString()));
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
,
246 bool success
= pp::flash::Clipboard::WriteData(
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
,
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));
263 ASSERT_FALSE(ReadStringVar(invalid_format
, &unused
));
268 std::string
TestFlashClipboard::TestRegisterCustomFormat() {
269 // Test an empty name is rejected.
271 pp::flash::Clipboard::RegisterCustomFormat(instance_
, std::string());
272 ASSERT_EQ(static_cast<uint32_t>(PP_FLASH_CLIPBOARD_FORMAT_INVALID
),
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
),
279 // Make sure the format doesn't collide with predefined formats.
280 ASSERT_NE(static_cast<uint32_t>(PP_FLASH_CLIPBOARD_FORMAT_PLAINTEXT
),
282 ASSERT_NE(static_cast<uint32_t>(PP_FLASH_CLIPBOARD_FORMAT_HTML
),
284 ASSERT_NE(static_cast<uint32_t>(PP_FLASH_CLIPBOARD_FORMAT_RTF
),
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
);
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
);
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
));
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
;
312 // Test the sequence number changes after writing some custom data.
313 std::string custom_data
= "custom_data";
314 pp::VarArrayBuffer
array_buffer(static_cast<uint32_t>(custom_data
.size()));
315 char* bytes
= static_cast<char*>(array_buffer
.Map());
316 std::copy(custom_data
.begin(), custom_data
.end(), bytes
);
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
,
325 sequence_number_after
= GetSequenceNumber(sequence_number_before
);
326 ASSERT_NE(sequence_number_before
, sequence_number_after
);
327 sequence_number_before
= sequence_number_after
;
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(
333 PP_FLASH_CLIPBOARD_TYPE_STANDARD
,
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
;
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
);