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/proxy/flash_clipboard_resource.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_message.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/pp_errors.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/proxy/ppapi_messages.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/shared_impl/ppapi_globals.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/shared_impl/var.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/shared_impl/var_tracker.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ppapi {
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace proxy {
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns whether the given clipboard type is valid.
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsValidClipboardType(PP_Flash_Clipboard_Type type) {
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return type == PP_FLASH_CLIPBOARD_TYPE_STANDARD ||
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         type == PP_FLASH_CLIPBOARD_TYPE_SELECTION;
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Convert a PP_Var to/from a string which is transmitted to the pepper host.
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// These functions assume the format is valid.
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PPVarToClipboardString(int32_t format,
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const PP_Var& var,
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            std::string* string_out) {
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (format == PP_FLASH_CLIPBOARD_FORMAT_PLAINTEXT ||
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      format == PP_FLASH_CLIPBOARD_FORMAT_HTML) {
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StringVar* string_var = StringVar::FromPPVar(var);
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!string_var)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *string_out = string_var->value();
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // All other formats are expected to be array buffers.
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ArrayBufferVar* array_buffer_var = ArrayBufferVar::FromPPVar(var);
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!array_buffer_var)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *string_out = std::string(static_cast<const char*>(array_buffer_var->Map()),
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              array_buffer_var->ByteLength());
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Var ClipboardStringToPPVar(int32_t format,
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              const std::string& string) {
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (format == PP_FLASH_CLIPBOARD_FORMAT_PLAINTEXT ||
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      format == PP_FLASH_CLIPBOARD_FORMAT_HTML) {
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return StringVar::StringToPPVar(string);
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // All other formats are expected to be array buffers.
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar(
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        string.size(), string.data());
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FlashClipboardResource::FlashClipboardResource(
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Connection connection, PP_Instance instance)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : PluginResource(connection, instance) {
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SendCreate(BROWSER, PpapiHostMsg_FlashClipboard_Create());
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FlashClipboardResource::~FlashClipboardResource() {
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)thunk::PPB_Flash_Clipboard_API*
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FlashClipboardResource::AsPPB_Flash_Clipboard_API() {
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return this;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)uint32_t FlashClipboardResource::RegisterCustomFormat(
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PP_Instance instance,
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* format_name) {
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check to see if the format has already been registered.
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint32_t format = clipboard_formats_.GetFormatID(format_name);
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (format != PP_FLASH_CLIPBOARD_FORMAT_INVALID)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return format;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int32_t result =
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SyncCall<PpapiPluginMsg_FlashClipboard_RegisterCustomFormatReply>(
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          BROWSER,
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          PpapiHostMsg_FlashClipboard_RegisterCustomFormat(format_name),
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          &format);
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result != PP_OK || format == PP_FLASH_CLIPBOARD_FORMAT_INVALID)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return PP_FLASH_CLIPBOARD_FORMAT_INVALID;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  clipboard_formats_.SetRegisteredFormat(format_name, format);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return format;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Bool FlashClipboardResource::IsFormatAvailable(
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PP_Instance instance,
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PP_Flash_Clipboard_Type clipboard_type,
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint32_t format) {
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (IsValidClipboardType(clipboard_type) &&
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (FlashClipboardFormatRegistry::IsValidPredefinedFormat(format) ||
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       clipboard_formats_.IsFormatRegistered(format))) {
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int32_t result = SyncCall<IPC::Message>(BROWSER,
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        PpapiHostMsg_FlashClipboard_IsFormatAvailable(clipboard_type, format));
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return result == PP_OK ? PP_TRUE : PP_FALSE;
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return PP_FALSE;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Var FlashClipboardResource::ReadData(
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PP_Instance instance,
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PP_Flash_Clipboard_Type clipboard_type,
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint32_t format) {
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string value;
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int32_t result =
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SyncCall<PpapiPluginMsg_FlashClipboard_ReadDataReply>(
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          BROWSER,
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          PpapiHostMsg_FlashClipboard_ReadData(clipboard_type, format),
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          &value);
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result != PP_OK)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return PP_MakeUndefined();
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ClipboardStringToPPVar(format, value);
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int32_t FlashClipboardResource::WriteData(
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PP_Instance instance,
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PP_Flash_Clipboard_Type clipboard_type,
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint32_t data_item_count,
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const uint32_t formats[],
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const PP_Var data_items[]) {
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!IsValidClipboardType(clipboard_type))
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return PP_ERROR_BADARGUMENT;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<uint32_t> formats_vector;
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<std::string> data_items_vector;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < data_item_count; ++i) {
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!clipboard_formats_.IsFormatRegistered(formats[i]) &&
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        !FlashClipboardFormatRegistry::IsValidPredefinedFormat(formats[i])) {
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return PP_ERROR_BADARGUMENT;
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    formats_vector.push_back(formats[i]);
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string string;
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!PPVarToClipboardString(formats[i], data_items[i], &string))
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return PP_ERROR_BADARGUMENT;
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    data_items_vector.push_back(string);
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Post(BROWSER,
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       PpapiHostMsg_FlashClipboard_WriteData(
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           static_cast<uint32_t>(clipboard_type),
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           formats_vector,
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           data_items_vector));
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Assume success, since it allows us to avoid a sync IPC.
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return PP_OK;
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)PP_Bool FlashClipboardResource::GetSequenceNumber(
1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    PP_Instance instance,
1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    PP_Flash_Clipboard_Type clipboard_type,
1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    uint64_t* sequence_number) {
1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int32_t result =
1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      SyncCall<PpapiPluginMsg_FlashClipboard_GetSequenceNumberReply>(
1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          BROWSER,
1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          PpapiHostMsg_FlashClipboard_GetSequenceNumber(clipboard_type),
1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          sequence_number);
1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return PP_FromBool(result == PP_OK);
1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace proxy
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace ppapi
169