• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
IsValidClipboardType(PP_Flash_Clipboard_Type type)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.
PPVarToClipboardString(int32_t format,const PP_Var & var,std::string * string_out)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 
ClipboardStringToPPVar(int32_t format,const std::string & string)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 
FlashClipboardResource(Connection connection,PP_Instance instance)61 FlashClipboardResource::FlashClipboardResource(
62     Connection connection, PP_Instance instance)
63     : PluginResource(connection, instance) {
64   SendCreate(BROWSER, PpapiHostMsg_FlashClipboard_Create());
65 }
66 
~FlashClipboardResource()67 FlashClipboardResource::~FlashClipboardResource() {
68 }
69 
70 thunk::PPB_Flash_Clipboard_API*
AsPPB_Flash_Clipboard_API()71 FlashClipboardResource::AsPPB_Flash_Clipboard_API() {
72   return this;
73 }
74 
RegisterCustomFormat(PP_Instance instance,const char * format_name)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 
IsFormatAvailable(PP_Instance instance,PP_Flash_Clipboard_Type clipboard_type,uint32_t format)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 
ReadData(PP_Instance instance,PP_Flash_Clipboard_Type clipboard_type,uint32_t format)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 
WriteData(PP_Instance instance,PP_Flash_Clipboard_Type clipboard_type,uint32_t data_item_count,const uint32_t formats[],const PP_Var data_items[])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 
GetSequenceNumber(PP_Instance instance,PP_Flash_Clipboard_Type clipboard_type,uint64_t * sequence_number)155 PP_Bool FlashClipboardResource::GetSequenceNumber(
156     PP_Instance instance,
157     PP_Flash_Clipboard_Type clipboard_type,
158     uint64_t* sequence_number) {
159   int32_t result =
160       SyncCall<PpapiPluginMsg_FlashClipboard_GetSequenceNumberReply>(
161           BROWSER,
162           PpapiHostMsg_FlashClipboard_GetSequenceNumber(clipboard_type),
163           sequence_number);
164   return PP_FromBool(result == PP_OK);
165 }
166 
167 }  // namespace proxy
168 }  // namespace ppapi
169