15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/tests/test_flash_clipboard.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/instance.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/module.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/point.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/private/flash_clipboard.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/var.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/var_array_buffer.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/tests/testing_instance.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// http://crbug.com/176822
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if !defined(OS_WIN)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)REGISTER_TEST_CASE(FlashClipboard);
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// WriteData() sends an async request to the browser process. As a result, the
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// string written may not be reflected by IsFormatAvailable() or ReadPlainText()
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// immediately. We need to wait and retry.
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kIntervalMs = 250;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kMaxIntervals = kActionTimeoutMs / kIntervalMs;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TestFlashClipboard::TestFlashClipboard(TestingInstance* instance)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : TestCase(instance) {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TestFlashClipboard::RunTests(const std::string& filter) {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RUN_TEST(ReadWritePlainText, filter);
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RUN_TEST(ReadWriteHTML, filter);
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RUN_TEST(ReadWriteRTF, filter);
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RUN_TEST(ReadWriteCustomData, filter);
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RUN_TEST(ReadWriteMultipleFormats, filter);
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RUN_TEST(Clear, filter);
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RUN_TEST(InvalidFormat, filter);
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RUN_TEST(RegisterCustomFormat, filter);
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RUN_TEST(GetSequenceNumber, filter);
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TestFlashClipboard::ReadStringVar(uint32_t format, std::string* result) {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::Var text;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool success = pp::flash::Clipboard::ReadData(
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      instance_,
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PP_FLASH_CLIPBOARD_TYPE_STANDARD,
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      format,
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &text);
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (success && text.is_string()) {
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *result = text.AsString();
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TestFlashClipboard::WriteStringVar(uint32_t format,
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        const std::string& text) {
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<uint32_t> formats_vector(1, format);
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<pp::Var> data_vector(1, pp::Var(text));
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool success = pp::flash::Clipboard::WriteData(
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      instance_,
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PP_FLASH_CLIPBOARD_TYPE_STANDARD,
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      formats_vector,
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_vector);
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return success;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TestFlashClipboard::IsFormatAvailableMatches(uint32_t format,
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                  bool expected) {
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < kMaxIntervals; ++i) {
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool is_available = pp::flash::Clipboard::IsFormatAvailable(
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        instance_,
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        PP_FLASH_CLIPBOARD_TYPE_STANDARD,
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        format);
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (is_available == expected)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PlatformSleep(kIntervalMs);
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TestFlashClipboard::ReadPlainTextMatches(const std::string& expected) {
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < kMaxIntervals; ++i) {
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string result;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool success = ReadStringVar(PP_FLASH_CLIPBOARD_FORMAT_PLAINTEXT, &result);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (success && result == expected)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PlatformSleep(kIntervalMs);
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TestFlashClipboard::ReadHTMLMatches(const std::string& expected) {
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < kMaxIntervals; ++i) {
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string result;
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool success = ReadStringVar(PP_FLASH_CLIPBOARD_FORMAT_HTML, &result);
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Harmless markup may be inserted around the copied html on some
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // platforms, so just check that the pasted string contains the
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // copied string. Also check that we only paste the copied fragment, see
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // http://code.google.com/p/chromium/issues/detail?id=130827.
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (success && result.find(expected) != std::string::npos &&
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        result.find("<!--StartFragment-->") == std::string::npos &&
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        result.find("<!--EndFragment-->") == std::string::npos) {
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PlatformSleep(kIntervalMs);
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)uint64_t TestFlashClipboard::GetSequenceNumber(uint64_t last_sequence_number) {
1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  uint64_t next_sequence_number = last_sequence_number;
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (int i = 0; i < kMaxIntervals; ++i) {
1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    pp::flash::Clipboard::GetSequenceNumber(
1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        instance_, PP_FLASH_CLIPBOARD_TYPE_STANDARD, &next_sequence_number);
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (next_sequence_number != last_sequence_number)
1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return next_sequence_number;
1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    PlatformSleep(kIntervalMs);
1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return next_sequence_number;
1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestFlashClipboard::TestReadWritePlainText() {
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string input = "Hello world plain text!";
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(WriteStringVar(PP_FLASH_CLIPBOARD_FORMAT_PLAINTEXT, input));
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(IsFormatAvailableMatches(PP_FLASH_CLIPBOARD_FORMAT_PLAINTEXT,
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       true));
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(ReadPlainTextMatches(input));
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PASS();
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestFlashClipboard::TestReadWriteHTML() {
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string input = "Hello world html!";
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(WriteStringVar(PP_FLASH_CLIPBOARD_FORMAT_HTML, input));
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(IsFormatAvailableMatches(PP_FLASH_CLIPBOARD_FORMAT_HTML, true));
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(ReadHTMLMatches(input));
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PASS();
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestFlashClipboard::TestReadWriteRTF() {
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string rtf_string =
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "{\\rtf1\\ansi{\\fonttbl\\f0\\fswiss Helvetica;}\\f0\\pard\n"
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "This is some {\\b bold} text.\\par\n"
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "}";
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::VarArrayBuffer array_buffer(rtf_string.size());
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char* bytes = static_cast<char*>(array_buffer.Map());
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::copy(rtf_string.data(), rtf_string.data() + rtf_string.size(), bytes);
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<uint32_t> formats_vector(1, PP_FLASH_CLIPBOARD_FORMAT_RTF);
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<pp::Var> data_vector(1, array_buffer);
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(pp::flash::Clipboard::WriteData(
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      instance_,
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PP_FLASH_CLIPBOARD_TYPE_STANDARD,
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      formats_vector,
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_vector));
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(IsFormatAvailableMatches(PP_FLASH_CLIPBOARD_FORMAT_RTF, true));
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::Var rtf_result;
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(pp::flash::Clipboard::ReadData(
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        instance_,
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        PP_FLASH_CLIPBOARD_TYPE_STANDARD,
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        PP_FLASH_CLIPBOARD_FORMAT_RTF,
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &rtf_result));
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(rtf_result.is_array_buffer());
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::VarArrayBuffer array_buffer_result(rtf_result);
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(array_buffer_result.ByteLength() == array_buffer.ByteLength());
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char* bytes_result = static_cast<char*>(array_buffer_result.Map());
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(std::equal(bytes, bytes + array_buffer.ByteLength(),
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bytes_result));
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PASS();
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestFlashClipboard::TestReadWriteCustomData() {
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string custom_data = "custom_data";
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::VarArrayBuffer array_buffer(custom_data.size());
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char* bytes = static_cast<char*>(array_buffer.Map());
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::copy(custom_data.begin(), custom_data.end(), bytes);
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint32_t format_id =
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pp::flash::Clipboard::RegisterCustomFormat(instance_, "my-format");
1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_NE(static_cast<uint32_t>(PP_FLASH_CLIPBOARD_FORMAT_INVALID),
1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            format_id);
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<uint32_t> formats_vector(1, format_id);
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<pp::Var> data_vector(1, array_buffer);
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(pp::flash::Clipboard::WriteData(
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      instance_,
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PP_FLASH_CLIPBOARD_TYPE_STANDARD,
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      formats_vector,
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_vector));
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(IsFormatAvailableMatches(format_id, true));
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::Var custom_data_result;
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(pp::flash::Clipboard::ReadData(
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      instance_,
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PP_FLASH_CLIPBOARD_TYPE_STANDARD,
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      format_id,
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &custom_data_result));
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(custom_data_result.is_array_buffer());
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::VarArrayBuffer array_buffer_result(custom_data_result);
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(array_buffer_result.ByteLength(), array_buffer.ByteLength());
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char* bytes_result = static_cast<char*>(array_buffer_result.Map());
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(std::equal(bytes, bytes + array_buffer.ByteLength(),
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bytes_result));
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PASS();
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestFlashClipboard::TestReadWriteMultipleFormats() {
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<uint32_t> formats;
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<pp::Var> data;
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  formats.push_back(PP_FLASH_CLIPBOARD_FORMAT_PLAINTEXT);
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data.push_back(pp::Var("plain text"));
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  formats.push_back(PP_FLASH_CLIPBOARD_FORMAT_HTML);
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data.push_back(pp::Var("html"));
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool success = pp::flash::Clipboard::WriteData(
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      instance_,
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PP_FLASH_CLIPBOARD_TYPE_STANDARD,
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      formats,
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data);
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(success);
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(IsFormatAvailableMatches(PP_FLASH_CLIPBOARD_FORMAT_PLAINTEXT,
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       true));
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(IsFormatAvailableMatches(PP_FLASH_CLIPBOARD_FORMAT_HTML, true));
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(ReadPlainTextMatches(data[0].AsString()));
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(ReadHTMLMatches(data[1].AsString()));
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PASS();
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestFlashClipboard::TestClear() {
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string input = "Hello world plain text!";
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(WriteStringVar(PP_FLASH_CLIPBOARD_FORMAT_PLAINTEXT, input));
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(IsFormatAvailableMatches(PP_FLASH_CLIPBOARD_FORMAT_PLAINTEXT,
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       true));
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool success = pp::flash::Clipboard::WriteData(
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      instance_,
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PP_FLASH_CLIPBOARD_TYPE_STANDARD,
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::vector<uint32_t>(),
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::vector<pp::Var>());
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(success);
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(IsFormatAvailableMatches(PP_FLASH_CLIPBOARD_FORMAT_PLAINTEXT,
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       false));
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PASS();
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestFlashClipboard::TestInvalidFormat() {
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint32_t invalid_format = 999;
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(WriteStringVar(invalid_format, "text"));
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(IsFormatAvailableMatches(invalid_format, false));
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string unused;
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(ReadStringVar(invalid_format, &unused));
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PASS();
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestFlashClipboard::TestRegisterCustomFormat() {
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test an empty name is rejected.
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint32_t format_id =
271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      pp::flash::Clipboard::RegisterCustomFormat(instance_, std::string());
2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(static_cast<uint32_t>(PP_FLASH_CLIPBOARD_FORMAT_INVALID),
2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            format_id);
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test a valid format name.
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  format_id = pp::flash::Clipboard::RegisterCustomFormat(instance_, "a-b");
2775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_NE(static_cast<uint32_t>(PP_FLASH_CLIPBOARD_FORMAT_INVALID),
2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            format_id);
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure the format doesn't collide with predefined formats.
2805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_NE(static_cast<uint32_t>(PP_FLASH_CLIPBOARD_FORMAT_PLAINTEXT),
2815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            format_id);
2825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_NE(static_cast<uint32_t>(PP_FLASH_CLIPBOARD_FORMAT_HTML),
2835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            format_id);
2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_NE(static_cast<uint32_t>(PP_FLASH_CLIPBOARD_FORMAT_RTF),
2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            format_id);
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that if the same name is registered, the same id comes out.
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint32_t format_id2 =
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pp::flash::Clipboard::RegisterCustomFormat(instance_, "a-b");
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(format_id, format_id2);
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that the second format registered has a different id.
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint32_t format_id3 =
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pp::flash::Clipboard::RegisterCustomFormat(instance_, "a-b-c");
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_NE(format_id, format_id3);
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PASS();
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)std::string TestFlashClipboard::TestGetSequenceNumber() {
3015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  uint64_t sequence_number_before = 0;
3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  uint64_t sequence_number_after = 0;
3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(pp::flash::Clipboard::GetSequenceNumber(
3045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      instance_, PP_FLASH_CLIPBOARD_TYPE_STANDARD, &sequence_number_before));
3055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Test the sequence number changes after writing html.
3075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(WriteStringVar(PP_FLASH_CLIPBOARD_FORMAT_HTML, "<html>"));
3085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  sequence_number_after = GetSequenceNumber(sequence_number_before);
3095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_NE(sequence_number_before, sequence_number_after);
3105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  sequence_number_before = sequence_number_after;
3115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Test the sequence number changes after writing some custom data.
3135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string custom_data = "custom_data";
3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  pp::VarArrayBuffer array_buffer(custom_data.size());
3155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  char* bytes = static_cast<char*>(array_buffer.Map());
3165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::copy(custom_data.begin(), custom_data.end(), bytes);
3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  uint32_t format_id =
3185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      pp::flash::Clipboard::RegisterCustomFormat(instance_, "my-format");
3195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::vector<uint32_t> formats_vector(1, format_id);
3205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::vector<pp::Var> data_vector(1, array_buffer);
3215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(pp::flash::Clipboard::WriteData(instance_,
3225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                              PP_FLASH_CLIPBOARD_TYPE_STANDARD,
3235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                              formats_vector,
3245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                              data_vector));
3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  sequence_number_after = GetSequenceNumber(sequence_number_before);
3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_NE(sequence_number_before, sequence_number_after);
3275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  sequence_number_before = sequence_number_after;
3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Read the data and make sure the sequence number doesn't change.
3305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  pp::Var custom_data_result;
3315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(pp::flash::Clipboard::ReadData(
3325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      instance_,
3335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      PP_FLASH_CLIPBOARD_TYPE_STANDARD,
3345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      format_id,
3355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      &custom_data_result));
3365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(pp::flash::Clipboard::GetSequenceNumber(
3375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      instance_, PP_FLASH_CLIPBOARD_TYPE_STANDARD, &sequence_number_after));
3385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(sequence_number_before, sequence_number_after);
3395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  sequence_number_before = sequence_number_after;
3405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Clear the clipboard and check the sequence number changes.
3425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  pp::flash::Clipboard::WriteData(instance_,
3435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                  PP_FLASH_CLIPBOARD_TYPE_STANDARD,
3445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                  std::vector<uint32_t>(),
3455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                  std::vector<pp::Var>());
3465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  sequence_number_after = GetSequenceNumber(sequence_number_before);
3475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_NE(sequence_number_before, sequence_number_after);
3485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  PASS();
3505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
351