OLD | NEW |
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_android.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" |
11 #include "base/synchronization/lock.h" | 11 #include "base/synchronization/lock.h" |
12 #include "jni/Clipboard_jni.h" | 12 #include "jni/Clipboard_jni.h" |
13 #include "third_party/skia/include/core/SkBitmap.h" | 13 #include "third_party/skia/include/core/SkBitmap.h" |
14 #include "ui/base/clipboard/clipboard_android_initialization.h" | |
15 #include "ui/gfx/size.h" | 14 #include "ui/gfx/size.h" |
16 | 15 |
17 // TODO:(andrewhayden) Support additional formats in Android: Bitmap, URI, HTML, | 16 // TODO:(andrewhayden) Support additional formats in Android: Bitmap, URI, HTML, |
18 // HTML+text now that Android's clipboard system supports them, then nuke the | 17 // HTML+text now that Android's clipboard system supports them, then nuke the |
19 // legacy implementation note below. | 18 // legacy implementation note below. |
20 | 19 |
21 // Legacy implementation note: | 20 // Legacy implementation note: |
22 // The Android clipboard system used to only support text format. So we used the | 21 // The Android clipboard system used to only support text format. So we used the |
23 // Android system when some text was added or retrieved from the system. For | 22 // Android system when some text was added or retrieved from the system. For |
24 // anything else, we STILL store the value in some process wide static | 23 // anything else, we STILL store the value in some process wide static |
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
251 CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypeWebCustomData)); | 250 CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypeWebCustomData)); |
252 return type; | 251 return type; |
253 } | 252 } |
254 | 253 |
255 // static | 254 // static |
256 const Clipboard::FormatType& Clipboard::GetPepperCustomDataFormatType() { | 255 const Clipboard::FormatType& Clipboard::GetPepperCustomDataFormatType() { |
257 CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypePepperCustomData)); | 256 CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypePepperCustomData)); |
258 return type; | 257 return type; |
259 } | 258 } |
260 | 259 |
261 // Clipboard implementation. | 260 // Clipboard factory method. |
262 Clipboard::Clipboard() { | 261 // static |
| 262 Clipboard* Clipboard::Create() { |
| 263 return new ClipboardAndroid; |
| 264 } |
| 265 |
| 266 // ClipboardAndroid implementation. |
| 267 ClipboardAndroid::ClipboardAndroid() { |
263 DCHECK(CalledOnValidThread()); | 268 DCHECK(CalledOnValidThread()); |
264 } | 269 } |
265 | 270 |
266 Clipboard::~Clipboard() { | 271 ClipboardAndroid::~ClipboardAndroid() { |
267 DCHECK(CalledOnValidThread()); | 272 DCHECK(CalledOnValidThread()); |
268 } | 273 } |
269 | 274 |
270 uint64 Clipboard::GetSequenceNumber(ClipboardType /* type */) { | 275 uint64 ClipboardAndroid::GetSequenceNumber(ClipboardType /* type */) { |
271 DCHECK(CalledOnValidThread()); | 276 DCHECK(CalledOnValidThread()); |
272 // TODO: implement this. For now this interface will advertise | 277 // TODO: implement this. For now this interface will advertise |
273 // that the clipboard never changes. That's fine as long as we | 278 // that the clipboard never changes. That's fine as long as we |
274 // don't rely on this signal. | 279 // don't rely on this signal. |
275 return 0; | 280 return 0; |
276 } | 281 } |
277 | 282 |
278 bool Clipboard::IsFormatAvailable(const Clipboard::FormatType& format, | 283 bool ClipboardAndroid::IsFormatAvailable(const Clipboard::FormatType& format, |
279 ClipboardType type) const { | 284 ClipboardType type) const { |
280 DCHECK(CalledOnValidThread()); | 285 DCHECK(CalledOnValidThread()); |
281 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); | 286 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); |
282 return g_map.Get().HasFormat(format.data()); | 287 return g_map.Get().HasFormat(format.ToString()); |
283 } | 288 } |
284 | 289 |
285 void Clipboard::Clear(ClipboardType type) { | 290 void ClipboardAndroid::Clear(ClipboardType type) { |
286 DCHECK(CalledOnValidThread()); | 291 DCHECK(CalledOnValidThread()); |
287 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); | 292 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); |
288 g_map.Get().Clear(); | 293 g_map.Get().Clear(); |
289 } | 294 } |
290 | 295 |
291 void Clipboard::ReadAvailableTypes(ClipboardType type, | 296 void ClipboardAndroid::ReadAvailableTypes(ClipboardType type, |
292 std::vector<base::string16>* types, | 297 std::vector<base::string16>* types, |
293 bool* contains_filenames) const { | 298 bool* contains_filenames) const { |
294 DCHECK(CalledOnValidThread()); | 299 DCHECK(CalledOnValidThread()); |
295 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); | 300 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); |
296 | 301 |
297 if (!types || !contains_filenames) { | 302 if (!types || !contains_filenames) { |
298 NOTREACHED(); | 303 NOTREACHED(); |
299 return; | 304 return; |
300 } | 305 } |
301 | 306 |
302 NOTIMPLEMENTED(); | 307 NOTIMPLEMENTED(); |
303 | 308 |
304 types->clear(); | 309 types->clear(); |
305 *contains_filenames = false; | 310 *contains_filenames = false; |
306 } | 311 } |
307 | 312 |
308 void Clipboard::ReadText(ClipboardType type, base::string16* result) const { | 313 void ClipboardAndroid::ReadText(ClipboardType type, |
| 314 base::string16* result) const { |
309 DCHECK(CalledOnValidThread()); | 315 DCHECK(CalledOnValidThread()); |
310 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); | 316 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); |
311 std::string utf8; | 317 std::string utf8; |
312 ReadAsciiText(type, &utf8); | 318 ReadAsciiText(type, &utf8); |
313 *result = base::UTF8ToUTF16(utf8); | 319 *result = base::UTF8ToUTF16(utf8); |
314 } | 320 } |
315 | 321 |
316 void Clipboard::ReadAsciiText(ClipboardType type, std::string* result) const { | 322 void ClipboardAndroid::ReadAsciiText(ClipboardType type, |
| 323 std::string* result) const { |
317 DCHECK(CalledOnValidThread()); | 324 DCHECK(CalledOnValidThread()); |
318 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); | 325 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); |
319 *result = g_map.Get().Get(kPlainTextFormat); | 326 *result = g_map.Get().Get(kPlainTextFormat); |
320 } | 327 } |
321 | 328 |
322 // Note: |src_url| isn't really used. It is only implemented in Windows | 329 // Note: |src_url| isn't really used. It is only implemented in Windows |
323 void Clipboard::ReadHTML(ClipboardType type, | 330 void ClipboardAndroid::ReadHTML(ClipboardType type, |
324 base::string16* markup, | 331 base::string16* markup, |
325 std::string* src_url, | 332 std::string* src_url, |
326 uint32* fragment_start, | 333 uint32* fragment_start, |
327 uint32* fragment_end) const { | 334 uint32* fragment_end) const { |
328 DCHECK(CalledOnValidThread()); | 335 DCHECK(CalledOnValidThread()); |
329 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); | 336 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); |
330 if (src_url) | 337 if (src_url) |
331 src_url->clear(); | 338 src_url->clear(); |
332 | 339 |
333 std::string input = g_map.Get().Get(kHTMLFormat); | 340 std::string input = g_map.Get().Get(kHTMLFormat); |
334 *markup = base::UTF8ToUTF16(input); | 341 *markup = base::UTF8ToUTF16(input); |
335 | 342 |
336 *fragment_start = 0; | 343 *fragment_start = 0; |
337 *fragment_end = static_cast<uint32>(markup->length()); | 344 *fragment_end = static_cast<uint32>(markup->length()); |
338 } | 345 } |
339 | 346 |
340 void Clipboard::ReadRTF(ClipboardType type, std::string* result) const { | 347 void ClipboardAndroid::ReadRTF(ClipboardType type, std::string* result) const { |
341 DCHECK(CalledOnValidThread()); | 348 DCHECK(CalledOnValidThread()); |
342 NOTIMPLEMENTED(); | 349 NOTIMPLEMENTED(); |
343 } | 350 } |
344 | 351 |
345 SkBitmap Clipboard::ReadImage(ClipboardType type) const { | 352 SkBitmap ClipboardAndroid::ReadImage(ClipboardType type) const { |
346 DCHECK(CalledOnValidThread()); | 353 DCHECK(CalledOnValidThread()); |
347 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); | 354 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); |
348 std::string input = g_map.Get().Get(kBitmapFormat); | 355 std::string input = g_map.Get().Get(kBitmapFormat); |
349 | 356 |
350 SkBitmap bmp; | 357 SkBitmap bmp; |
351 if (!input.empty()) { | 358 if (!input.empty()) { |
352 DCHECK_LE(sizeof(gfx::Size), input.size()); | 359 DCHECK_LE(sizeof(gfx::Size), input.size()); |
353 const gfx::Size* size = reinterpret_cast<const gfx::Size*>(input.data()); | 360 const gfx::Size* size = reinterpret_cast<const gfx::Size*>(input.data()); |
354 | 361 |
355 bmp.allocN32Pixels(size->width(), size->height()); | 362 bmp.allocN32Pixels(size->width(), size->height()); |
356 | 363 |
357 DCHECK_EQ(sizeof(gfx::Size) + bmp.getSize(), input.size()); | 364 DCHECK_EQ(sizeof(gfx::Size) + bmp.getSize(), input.size()); |
358 | 365 |
359 memcpy(bmp.getPixels(), input.data() + sizeof(gfx::Size), bmp.getSize()); | 366 memcpy(bmp.getPixels(), input.data() + sizeof(gfx::Size), bmp.getSize()); |
360 } | 367 } |
361 return bmp; | 368 return bmp; |
362 } | 369 } |
363 | 370 |
364 void Clipboard::ReadCustomData(ClipboardType clipboard_type, | 371 void ClipboardAndroid::ReadCustomData(ClipboardType clipboard_type, |
365 const base::string16& type, | 372 const base::string16& type, |
366 base::string16* result) const { | 373 base::string16* result) const { |
367 DCHECK(CalledOnValidThread()); | 374 DCHECK(CalledOnValidThread()); |
368 NOTIMPLEMENTED(); | 375 NOTIMPLEMENTED(); |
369 } | 376 } |
370 | 377 |
371 void Clipboard::ReadBookmark(base::string16* title, std::string* url) const { | 378 void ClipboardAndroid::ReadBookmark(base::string16* title, |
| 379 std::string* url) const { |
372 DCHECK(CalledOnValidThread()); | 380 DCHECK(CalledOnValidThread()); |
373 NOTIMPLEMENTED(); | 381 NOTIMPLEMENTED(); |
374 } | 382 } |
375 | 383 |
376 void Clipboard::ReadData(const Clipboard::FormatType& format, | 384 void ClipboardAndroid::ReadData(const Clipboard::FormatType& format, |
377 std::string* result) const { | 385 std::string* result) const { |
378 DCHECK(CalledOnValidThread()); | 386 DCHECK(CalledOnValidThread()); |
379 *result = g_map.Get().Get(format.data()); | 387 *result = g_map.Get().Get(format.ToString()); |
380 } | 388 } |
381 | 389 |
382 // Main entry point used to write several values in the clipboard. | 390 // Main entry point used to write several values in the clipboard. |
383 void Clipboard::WriteObjects(ClipboardType type, const ObjectMap& objects) { | 391 void ClipboardAndroid::WriteObjects(ClipboardType type, |
| 392 const ObjectMap& objects) { |
384 DCHECK(CalledOnValidThread()); | 393 DCHECK(CalledOnValidThread()); |
385 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); | 394 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); |
386 g_map.Get().Clear(); | 395 g_map.Get().Clear(); |
387 for (ObjectMap::const_iterator iter = objects.begin(); | 396 for (ObjectMap::const_iterator iter = objects.begin(); iter != objects.end(); |
388 iter != objects.end(); ++iter) { | 397 ++iter) { |
389 DispatchObject(static_cast<ObjectType>(iter->first), iter->second); | 398 DispatchObject(static_cast<ObjectType>(iter->first), iter->second); |
390 } | 399 } |
391 } | 400 } |
392 | 401 |
393 void Clipboard::WriteText(const char* text_data, size_t text_len) { | 402 void ClipboardAndroid::WriteText(const char* text_data, size_t text_len) { |
394 g_map.Get().Set(kPlainTextFormat, std::string(text_data, text_len)); | 403 g_map.Get().Set(kPlainTextFormat, std::string(text_data, text_len)); |
395 } | 404 } |
396 | 405 |
397 void Clipboard::WriteHTML(const char* markup_data, | 406 void ClipboardAndroid::WriteHTML(const char* markup_data, |
398 size_t markup_len, | 407 size_t markup_len, |
399 const char* url_data, | 408 const char* url_data, |
400 size_t url_len) { | 409 size_t url_len) { |
401 g_map.Get().Set(kHTMLFormat, std::string(markup_data, markup_len)); | 410 g_map.Get().Set(kHTMLFormat, std::string(markup_data, markup_len)); |
402 } | 411 } |
403 | 412 |
404 void Clipboard::WriteRTF(const char* rtf_data, size_t data_len) { | 413 void ClipboardAndroid::WriteRTF(const char* rtf_data, size_t data_len) { |
405 NOTIMPLEMENTED(); | 414 NOTIMPLEMENTED(); |
406 } | 415 } |
407 | 416 |
408 // Note: according to other platforms implementations, this really writes the | 417 // Note: according to other platforms implementations, this really writes the |
409 // URL spec. | 418 // URL spec. |
410 void Clipboard::WriteBookmark(const char* title_data, size_t title_len, | 419 void ClipboardAndroid::WriteBookmark(const char* title_data, |
411 const char* url_data, size_t url_len) { | 420 size_t title_len, |
| 421 const char* url_data, |
| 422 size_t url_len) { |
412 g_map.Get().Set(kBookmarkFormat, std::string(url_data, url_len)); | 423 g_map.Get().Set(kBookmarkFormat, std::string(url_data, url_len)); |
413 } | 424 } |
414 | 425 |
415 // Write an extra flavor that signifies WebKit was the last to modify the | 426 // Write an extra flavor that signifies WebKit was the last to modify the |
416 // pasteboard. This flavor has no data. | 427 // pasteboard. This flavor has no data. |
417 void Clipboard::WriteWebSmartPaste() { | 428 void ClipboardAndroid::WriteWebSmartPaste() { |
418 g_map.Get().Set(kWebKitSmartPasteFormat, std::string()); | 429 g_map.Get().Set(kWebKitSmartPasteFormat, std::string()); |
419 } | 430 } |
420 | 431 |
421 // Note: we implement this to pass all unit tests but it is currently unclear | 432 // Note: we implement this to pass all unit tests but it is currently unclear |
422 // how some code would consume this. | 433 // how some code would consume this. |
423 void Clipboard::WriteBitmap(const SkBitmap& bitmap) { | 434 void ClipboardAndroid::WriteBitmap(const SkBitmap& bitmap) { |
424 gfx::Size size(bitmap.width(), bitmap.height()); | 435 gfx::Size size(bitmap.width(), bitmap.height()); |
425 | 436 |
426 std::string packed(reinterpret_cast<const char*>(&size), sizeof(size)); | 437 std::string packed(reinterpret_cast<const char*>(&size), sizeof(size)); |
427 { | 438 { |
428 SkAutoLockPixels bitmap_lock(bitmap); | 439 SkAutoLockPixels bitmap_lock(bitmap); |
429 packed += std::string(static_cast<const char*>(bitmap.getPixels()), | 440 packed += std::string(static_cast<const char*>(bitmap.getPixels()), |
430 bitmap.getSize()); | 441 bitmap.getSize()); |
431 } | 442 } |
432 g_map.Get().Set(kBitmapFormat, packed); | 443 g_map.Get().Set(kBitmapFormat, packed); |
433 } | 444 } |
434 | 445 |
435 void Clipboard::WriteData(const Clipboard::FormatType& format, | 446 void ClipboardAndroid::WriteData(const Clipboard::FormatType& format, |
436 const char* data_data, size_t data_len) { | 447 const char* data_data, |
437 g_map.Get().Set(format.data(), std::string(data_data, data_len)); | 448 size_t data_len) { |
| 449 g_map.Get().Set(format.ToString(), std::string(data_data, data_len)); |
438 } | 450 } |
439 | 451 |
440 // See clipboard_android_initialization.h for more information. | |
441 bool RegisterClipboardAndroid(JNIEnv* env) { | 452 bool RegisterClipboardAndroid(JNIEnv* env) { |
442 return RegisterNativesImpl(env); | 453 return RegisterNativesImpl(env); |
443 } | 454 } |
444 | 455 |
445 } // namespace ui | 456 } // namespace ui |
OLD | NEW |