| 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 |