Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(109)

Side by Side Diff: ui/base/clipboard/clipboard_android.cc

Issue 59023007: Enable pasting HTML content from the Android clipboard (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/base/clipboard/clipboard.h" 5 #include "ui/base/clipboard/clipboard.h"
6 6
7 #include "base/android/jni_string.h" 7 #include "base/android/jni_string.h"
8 #include "base/lazy_instance.h" 8 #include "base/lazy_instance.h"
9 #include "base/stl_util.h" 9 #include "base/stl_util.h"
10 #include "base/strings/utf_string_conversions.h" 10 #include "base/strings/utf_string_conversions.h"
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
121 } 121 }
122 122
123 void ClipboardMap::Clear() { 123 void ClipboardMap::Clear() {
124 JNIEnv* env = AttachCurrentThread(); 124 JNIEnv* env = AttachCurrentThread();
125 base::AutoLock lock(lock_); 125 base::AutoLock lock(lock_);
126 map_.clear(); 126 map_.clear();
127 Java_Clipboard_setText(env, clipboard_manager_.obj(), NULL); 127 Java_Clipboard_setText(env, clipboard_manager_.obj(), NULL);
128 } 128 }
129 129
130 // If the internal map contains a plain-text entry and it does not match that 130 // If the internal map contains a plain-text entry and it does not match that
131 // in the Android clipboard, clear the map and insert the Android text into it. 131 // in the Android clipboard, clear the map and insert the Android text into it.
joth 2013/11/12 01:45:39 this comment sounds out of date (well, incomplete)
Kristian Monsen 2013/11/12 04:27:23 Done.
132 void ClipboardMap::SyncWithAndroidClipboard() { 132 void ClipboardMap::SyncWithAndroidClipboard() {
133 lock_.AssertAcquired(); 133 lock_.AssertAcquired();
134 JNIEnv* env = AttachCurrentThread(); 134 JNIEnv* env = AttachCurrentThread();
135 135
136 // Update the plain text clipboard entry
136 std::map<std::string, std::string>::const_iterator it = 137 std::map<std::string, std::string>::const_iterator it =
137 map_.find(kPlainTextFormat); 138 map_.find(kPlainTextFormat);
138 139 ScopedJavaLocalRef<jstring> java_string_text =
139 if (!Java_Clipboard_hasPlainText(env, clipboard_manager_.obj())) { 140 Java_Clipboard_getCoercedText(env, clipboard_manager_.obj());
140 if (it != map_.end()) 141 if (java_string_text.obj()) {
142 std::string android_string = ConvertJavaStringToUTF8(java_string_text);
143 if (it == map_.end() || it->second != android_string) {
joth 2013/11/12 01:45:39 the change from hasPlainText() method to the code
Kristian Monsen 2013/11/12 04:27:23 I mostly did not want to quit when there was not p
144 // There is a different string in the Android clipboard than we have.
145 // Clear the map on our side.
146 map_.clear();
147 map_[kPlainTextFormat] = android_string;
148 }
149 } else {
150 if (it != map_.end()) {
141 // We have plain text on this side, but Android doesn't. Nuke ours. 151 // We have plain text on this side, but Android doesn't. Nuke ours.
142 map_.clear(); 152 map_.clear();
143 return; 153 }
144 } 154 }
145 155
146 ScopedJavaLocalRef<jstring> java_string = 156 // Update the html clipboard entry
147 Java_Clipboard_getCoercedText(env, clipboard_manager_.obj()); 157 ScopedJavaLocalRef<jstring> java_string_html =
148 158 Java_Clipboard_getHtmlText(env, clipboard_manager_.obj());
149 if (!java_string.obj()) { 159 if (java_string_html.obj()) {
150 // Tolerate a null value from the Java side, even though that should not 160 map_[kHTMLFormat] = ConvertJavaStringToUTF8(java_string_html);
joth 2013/11/12 01:45:39 the memory overhead of stashing two copies of ever
Kristian Monsen 2013/11/12 04:27:23 We don't really need the map as I understand, can
151 // happen since hasPlainText has already returned true.
152 // Should only happen if someone is using the clipboard on multiple
153 // threads and clears it out after hasPlainText but before we get here...
154 if (it != map_.end())
155 // We have plain text on this side, but Android doesn't. Nuke ours.
156 map_.clear();
157 return;
158 }
159
160 // If Android text differs from ours (or we have none), then copy Android's.
161 std::string android_string = ConvertJavaStringToUTF8(java_string);
162 if (it == map_.end() || it->second != android_string) {
163 map_.clear();
164 map_[kPlainTextFormat] = android_string;
165 } 161 }
166 } 162 }
167 163
168 } // namespace 164 } // namespace
169 165
170 Clipboard::FormatType::FormatType() { 166 Clipboard::FormatType::FormatType() {
171 } 167 }
172 168
173 Clipboard::FormatType::FormatType(const std::string& native_format) 169 Clipboard::FormatType::FormatType(const std::string& native_format)
174 : data_(native_format) { 170 : data_(native_format) {
(...skipping 18 matching lines...) Expand all
193 189
194 Clipboard::Clipboard() { 190 Clipboard::Clipboard() {
195 DCHECK(CalledOnValidThread()); 191 DCHECK(CalledOnValidThread());
196 } 192 }
197 193
198 Clipboard::~Clipboard() { 194 Clipboard::~Clipboard() {
199 DCHECK(CalledOnValidThread()); 195 DCHECK(CalledOnValidThread());
200 } 196 }
201 197
202 // Main entry point used to write several values in the clipboard. 198 // Main entry point used to write several values in the clipboard.
203 void Clipboard::WriteObjects(ClipboardType type, const ObjectMap& objects) { 199 void Clipboard::WriteObjects(Buffer buffer, const ObjectMap& objects) {
204 DCHECK(CalledOnValidThread()); 200 DCHECK(CalledOnValidThread());
205 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); 201 DCHECK_EQ(buffer, BUFFER_STANDARD);
joth 2013/11/12 01:45:39 are all these edits from here down intended? look
Kristian Monsen 2013/11/12 02:17:36 No, need a manual merge here. Will fix.
206 g_map.Get().Clear(); 202 g_map.Get().Clear();
207 for (ObjectMap::const_iterator iter = objects.begin(); 203 for (ObjectMap::const_iterator iter = objects.begin();
208 iter != objects.end(); ++iter) { 204 iter != objects.end(); ++iter) {
209 DispatchObject(static_cast<ObjectType>(iter->first), iter->second); 205 DispatchObject(static_cast<ObjectType>(iter->first), iter->second);
210 } 206 }
211 } 207 }
212 208
213 uint64 Clipboard::GetSequenceNumber(ClipboardType /* type */) { 209 uint64 Clipboard::GetSequenceNumber(Clipboard::Buffer /* buffer */) {
214 DCHECK(CalledOnValidThread()); 210 DCHECK(CalledOnValidThread());
215 // TODO: implement this. For now this interface will advertise 211 // TODO: implement this. For now this interface will advertise
216 // that the clipboard never changes. That's fine as long as we 212 // that the clipboard never changes. That's fine as long as we
217 // don't rely on this signal. 213 // don't rely on this signal.
218 return 0; 214 return 0;
219 } 215 }
220 216
221 bool Clipboard::IsFormatAvailable(const Clipboard::FormatType& format, 217 bool Clipboard::IsFormatAvailable(const Clipboard::FormatType& format,
222 ClipboardType type) const { 218 Clipboard::Buffer buffer) const {
223 DCHECK(CalledOnValidThread()); 219 DCHECK(CalledOnValidThread());
224 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); 220 DCHECK_EQ(buffer, BUFFER_STANDARD);
225 return g_map.Get().HasFormat(format.data()); 221 return g_map.Get().HasFormat(format.data());
226 } 222 }
227 223
228 void Clipboard::Clear(ClipboardType type) { 224 void Clipboard::Clear(Buffer buffer) {
229 DCHECK(CalledOnValidThread()); 225 DCHECK(CalledOnValidThread());
230 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); 226 DCHECK_EQ(buffer, BUFFER_STANDARD);
231 g_map.Get().Clear(); 227 g_map.Get().Clear();
232 } 228 }
233 229
234 void Clipboard::ReadAvailableTypes(ClipboardType type, 230 void Clipboard::ReadAvailableTypes(Buffer buffer, std::vector<string16>* types,
235 std::vector<string16>* types,
236 bool* contains_filenames) const { 231 bool* contains_filenames) const {
237 DCHECK(CalledOnValidThread()); 232 DCHECK(CalledOnValidThread());
238 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); 233 DCHECK_EQ(buffer, BUFFER_STANDARD);
239 234
240 if (!types || !contains_filenames) { 235 if (!types || !contains_filenames) {
241 NOTREACHED(); 236 NOTREACHED();
242 return; 237 return;
243 } 238 }
244 239
245 NOTIMPLEMENTED(); 240 NOTIMPLEMENTED();
246 241
247 types->clear(); 242 types->clear();
248 *contains_filenames = false; 243 *contains_filenames = false;
249 } 244 }
250 245
251 void Clipboard::ReadText(ClipboardType type, string16* result) const { 246 void Clipboard::ReadText(Clipboard::Buffer buffer, string16* result) const {
252 DCHECK(CalledOnValidThread()); 247 DCHECK(CalledOnValidThread());
253 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); 248 DCHECK_EQ(buffer, BUFFER_STANDARD);
254 std::string utf8; 249 std::string utf8;
255 ReadAsciiText(type, &utf8); 250 ReadAsciiText(buffer, &utf8);
256 *result = UTF8ToUTF16(utf8); 251 *result = UTF8ToUTF16(utf8);
257 } 252 }
258 253
259 void Clipboard::ReadAsciiText(ClipboardType type, std::string* result) const { 254 void Clipboard::ReadAsciiText(Clipboard::Buffer buffer,
255 std::string* result) const {
260 DCHECK(CalledOnValidThread()); 256 DCHECK(CalledOnValidThread());
261 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); 257 DCHECK_EQ(buffer, BUFFER_STANDARD);
262 *result = g_map.Get().Get(kPlainTextFormat); 258 *result = g_map.Get().Get(kPlainTextFormat);
263 } 259 }
264 260
265 // Note: |src_url| isn't really used. It is only implemented in Windows 261 // Note: |src_url| isn't really used. It is only implemented in Windows
266 void Clipboard::ReadHTML(ClipboardType type, 262 void Clipboard::ReadHTML(Clipboard::Buffer buffer,
267 string16* markup, 263 string16* markup,
268 std::string* src_url, 264 std::string* src_url,
269 uint32* fragment_start, 265 uint32* fragment_start,
270 uint32* fragment_end) const { 266 uint32* fragment_end) const {
271 DCHECK(CalledOnValidThread()); 267 DCHECK(CalledOnValidThread());
272 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); 268 DCHECK_EQ(buffer, BUFFER_STANDARD);
273 if (src_url) 269 if (src_url)
274 src_url->clear(); 270 src_url->clear();
275 271
276 std::string input = g_map.Get().Get(kHTMLFormat); 272 std::string input = g_map.Get().Get(kHTMLFormat);
277 *markup = UTF8ToUTF16(input); 273 *markup = UTF8ToUTF16(input);
278 274
279 *fragment_start = 0; 275 *fragment_start = 0;
280 *fragment_end = static_cast<uint32>(markup->length()); 276 *fragment_end = static_cast<uint32>(markup->length());
281 } 277 }
282 278
283 void Clipboard::ReadRTF(ClipboardType type, std::string* result) const { 279 void Clipboard::ReadRTF(Buffer buffer, std::string* result) const {
284 DCHECK(CalledOnValidThread()); 280 DCHECK(CalledOnValidThread());
285 NOTIMPLEMENTED(); 281 NOTIMPLEMENTED();
286 } 282 }
287 283
288 SkBitmap Clipboard::ReadImage(ClipboardType type) const { 284 SkBitmap Clipboard::ReadImage(Buffer buffer) const {
289 DCHECK(CalledOnValidThread()); 285 DCHECK(CalledOnValidThread());
290 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); 286 DCHECK_EQ(buffer, BUFFER_STANDARD);
291 std::string input = g_map.Get().Get(kBitmapFormat); 287 std::string input = g_map.Get().Get(kBitmapFormat);
292 288
293 SkBitmap bmp; 289 SkBitmap bmp;
294 if (!input.empty()) { 290 if (!input.empty()) {
295 DCHECK_LE(sizeof(gfx::Size), input.size()); 291 DCHECK_LE(sizeof(gfx::Size), input.size());
296 const gfx::Size* size = reinterpret_cast<const gfx::Size*>(input.data()); 292 const gfx::Size* size = reinterpret_cast<const gfx::Size*>(input.data());
297 293
298 bmp.setConfig( 294 bmp.setConfig(
299 SkBitmap::kARGB_8888_Config, size->width(), size->height(), 0); 295 SkBitmap::kARGB_8888_Config, size->width(), size->height(), 0);
300 bmp.allocPixels(); 296 bmp.allocPixels();
301 297
302 int bm_size = size->width() * size->height() * 4; 298 int bm_size = size->width() * size->height() * 4;
303 DCHECK_EQ(sizeof(gfx::Size) + bm_size, input.size()); 299 DCHECK_EQ(sizeof(gfx::Size) + bm_size, input.size());
304 300
305 memcpy(bmp.getPixels(), input.data() + sizeof(gfx::Size), bm_size); 301 memcpy(bmp.getPixels(), input.data() + sizeof(gfx::Size), bm_size);
306 } 302 }
307 return bmp; 303 return bmp;
308 } 304 }
309 305
310 void Clipboard::ReadCustomData(ClipboardType clipboard_type, 306 void Clipboard::ReadCustomData(Buffer buffer,
311 const string16& type, 307 const string16& type,
312 string16* result) const { 308 string16* result) const {
313 DCHECK(CalledOnValidThread()); 309 DCHECK(CalledOnValidThread());
314 NOTIMPLEMENTED(); 310 NOTIMPLEMENTED();
315 } 311 }
316 312
317 void Clipboard::ReadBookmark(string16* title, std::string* url) const { 313 void Clipboard::ReadBookmark(string16* title, std::string* url) const {
318 DCHECK(CalledOnValidThread()); 314 DCHECK(CalledOnValidThread());
319 NOTIMPLEMENTED(); 315 NOTIMPLEMENTED();
320 } 316 }
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
424 const char* data_data, size_t data_len) { 420 const char* data_data, size_t data_len) {
425 g_map.Get().Set(format.data(), std::string(data_data, data_len)); 421 g_map.Get().Set(format.data(), std::string(data_data, data_len));
426 } 422 }
427 423
428 // See clipboard_android_initialization.h for more information. 424 // See clipboard_android_initialization.h for more information.
429 bool RegisterClipboardAndroid(JNIEnv* env) { 425 bool RegisterClipboardAndroid(JNIEnv* env) {
430 return RegisterNativesImpl(env); 426 return RegisterNativesImpl(env);
431 } 427 }
432 428
433 } // namespace ui 429 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698