Home | History | Annotate | Download | only in tests
      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 
     29 TestFlashClipboard::TestFlashClipboard(TestingInstance* instance)
     30     : TestCase(instance) {
     31 }
     32 
     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 
     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 
     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 
     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 
     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 
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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