Home | History | Annotate | Download | only in proxy
      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/proxy/flash_clipboard_resource.h"
      6 
      7 #include "ipc/ipc_message.h"
      8 #include "ppapi/c/pp_errors.h"
      9 #include "ppapi/proxy/ppapi_messages.h"
     10 #include "ppapi/shared_impl/ppapi_globals.h"
     11 #include "ppapi/shared_impl/var.h"
     12 #include "ppapi/shared_impl/var_tracker.h"
     13 
     14 namespace ppapi {
     15 namespace proxy {
     16 
     17 namespace {
     18 
     19 // Returns whether the given clipboard type is valid.
     20 bool IsValidClipboardType(PP_Flash_Clipboard_Type type) {
     21   return type == PP_FLASH_CLIPBOARD_TYPE_STANDARD ||
     22          type == PP_FLASH_CLIPBOARD_TYPE_SELECTION;
     23 }
     24 
     25 // Convert a PP_Var to/from a string which is transmitted to the pepper host.
     26 // These functions assume the format is valid.
     27 bool PPVarToClipboardString(int32_t format,
     28                             const PP_Var& var,
     29                             std::string* string_out) {
     30   if (format == PP_FLASH_CLIPBOARD_FORMAT_PLAINTEXT ||
     31       format == PP_FLASH_CLIPBOARD_FORMAT_HTML) {
     32     StringVar* string_var = StringVar::FromPPVar(var);
     33     if (!string_var)
     34       return false;
     35     *string_out = string_var->value();
     36     return true;
     37   } else {
     38     // All other formats are expected to be array buffers.
     39     ArrayBufferVar* array_buffer_var = ArrayBufferVar::FromPPVar(var);
     40     if (!array_buffer_var)
     41       return false;
     42     *string_out = std::string(static_cast<const char*>(array_buffer_var->Map()),
     43                               array_buffer_var->ByteLength());
     44     return true;
     45   }
     46 }
     47 
     48 PP_Var ClipboardStringToPPVar(int32_t format,
     49                               const std::string& string) {
     50   if (format == PP_FLASH_CLIPBOARD_FORMAT_PLAINTEXT ||
     51       format == PP_FLASH_CLIPBOARD_FORMAT_HTML) {
     52     return StringVar::StringToPPVar(string);
     53   } else {
     54     // All other formats are expected to be array buffers.
     55     return PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar(
     56         string.size(), string.data());
     57   }
     58 }
     59 }  // namespace
     60 
     61 FlashClipboardResource::FlashClipboardResource(
     62     Connection connection, PP_Instance instance)
     63     : PluginResource(connection, instance) {
     64   SendCreate(BROWSER, PpapiHostMsg_FlashClipboard_Create());
     65 }
     66 
     67 FlashClipboardResource::~FlashClipboardResource() {
     68 }
     69 
     70 thunk::PPB_Flash_Clipboard_API*
     71 FlashClipboardResource::AsPPB_Flash_Clipboard_API() {
     72   return this;
     73 }
     74 
     75 uint32_t FlashClipboardResource::RegisterCustomFormat(
     76     PP_Instance instance,
     77     const char* format_name) {
     78   // Check to see if the format has already been registered.
     79   uint32_t format = clipboard_formats_.GetFormatID(format_name);
     80   if (format != PP_FLASH_CLIPBOARD_FORMAT_INVALID)
     81     return format;
     82   int32_t result =
     83       SyncCall<PpapiPluginMsg_FlashClipboard_RegisterCustomFormatReply>(
     84           BROWSER,
     85           PpapiHostMsg_FlashClipboard_RegisterCustomFormat(format_name),
     86           &format);
     87   if (result != PP_OK || format == PP_FLASH_CLIPBOARD_FORMAT_INVALID)
     88     return PP_FLASH_CLIPBOARD_FORMAT_INVALID;
     89   clipboard_formats_.SetRegisteredFormat(format_name, format);
     90   return format;
     91 }
     92 
     93 PP_Bool FlashClipboardResource::IsFormatAvailable(
     94     PP_Instance instance,
     95     PP_Flash_Clipboard_Type clipboard_type,
     96     uint32_t format) {
     97   if (IsValidClipboardType(clipboard_type) &&
     98       (FlashClipboardFormatRegistry::IsValidPredefinedFormat(format) ||
     99        clipboard_formats_.IsFormatRegistered(format))) {
    100     int32_t result = SyncCall<IPC::Message>(BROWSER,
    101         PpapiHostMsg_FlashClipboard_IsFormatAvailable(clipboard_type, format));
    102     return result == PP_OK ? PP_TRUE : PP_FALSE;
    103   }
    104   return PP_FALSE;
    105 }
    106 
    107 PP_Var FlashClipboardResource::ReadData(
    108     PP_Instance instance,
    109     PP_Flash_Clipboard_Type clipboard_type,
    110     uint32_t format) {
    111   std::string value;
    112   int32_t result =
    113       SyncCall<PpapiPluginMsg_FlashClipboard_ReadDataReply>(
    114           BROWSER,
    115           PpapiHostMsg_FlashClipboard_ReadData(clipboard_type, format),
    116           &value);
    117   if (result != PP_OK)
    118     return PP_MakeUndefined();
    119 
    120   return ClipboardStringToPPVar(format, value);
    121 }
    122 
    123 int32_t FlashClipboardResource::WriteData(
    124     PP_Instance instance,
    125     PP_Flash_Clipboard_Type clipboard_type,
    126     uint32_t data_item_count,
    127     const uint32_t formats[],
    128     const PP_Var data_items[]) {
    129   if (!IsValidClipboardType(clipboard_type))
    130       return PP_ERROR_BADARGUMENT;
    131   std::vector<uint32_t> formats_vector;
    132   std::vector<std::string> data_items_vector;
    133   for (size_t i = 0; i < data_item_count; ++i) {
    134     if (!clipboard_formats_.IsFormatRegistered(formats[i]) &&
    135         !FlashClipboardFormatRegistry::IsValidPredefinedFormat(formats[i])) {
    136       return PP_ERROR_BADARGUMENT;
    137     }
    138     formats_vector.push_back(formats[i]);
    139     std::string string;
    140     if (!PPVarToClipboardString(formats[i], data_items[i], &string))
    141       return PP_ERROR_BADARGUMENT;
    142     data_items_vector.push_back(string);
    143   }
    144 
    145   Post(BROWSER,
    146        PpapiHostMsg_FlashClipboard_WriteData(
    147            static_cast<uint32_t>(clipboard_type),
    148            formats_vector,
    149            data_items_vector));
    150 
    151   // Assume success, since it allows us to avoid a sync IPC.
    152   return PP_OK;
    153 }
    154 
    155 }  // namespace proxy
    156 }  // namespace ppapi
    157