Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / ui / base / clipboard / clipboard_android.cc
index 34d4a83..8b25b7c 100644 (file)
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "ui/base/clipboard/clipboard.h"
+#include "ui/base/clipboard/clipboard_android.h"
 
 #include "base/android/jni_string.h"
 #include "base/lazy_instance.h"
@@ -11,7 +11,6 @@
 #include "base/synchronization/lock.h"
 #include "jni/Clipboard_jni.h"
 #include "third_party/skia/include/core/SkBitmap.h"
-#include "ui/base/clipboard/clipboard_android_initialization.h"
 #include "ui/gfx/size.h"
 
 // TODO:(andrewhayden) Support additional formats in Android: Bitmap, URI, HTML,
@@ -129,44 +128,56 @@ void ClipboardMap::Clear() {
 
 // If the internal map contains a plain-text entry and it does not match that
 // in the Android clipboard, clear the map and insert the Android text into it.
+// If there is an HTML entry in the Android clipboard it gets inserted in the
+// map.
 void ClipboardMap::SyncWithAndroidClipboard() {
   lock_.AssertAcquired();
   JNIEnv* env = AttachCurrentThread();
 
+  // Update the plain text clipboard entry
   std::map<std::string, std::string>::const_iterator it =
     map_.find(kPlainTextFormat);
-
-  if (!Java_Clipboard_hasPlainText(env, clipboard_manager_.obj())) {
-    if (it != map_.end())
+  ScopedJavaLocalRef<jstring> java_string_text =
+      Java_Clipboard_getCoercedText(env, clipboard_manager_.obj());
+  if (java_string_text.obj()) {
+    std::string android_string = ConvertJavaStringToUTF8(java_string_text);
+    if (!android_string.empty() &&
+        (it == map_.end() || it->second != android_string)) {
+      // There is a different string in the Android clipboard than we have.
+      // Clear the map on our side.
+      map_.clear();
+      map_[kPlainTextFormat] = android_string;
+    }
+  } else {
+    if (it != map_.end()) {
       // We have plain text on this side, but Android doesn't. Nuke ours.
       map_.clear();
-    return;
+    }
   }
 
-  ScopedJavaLocalRef<jstring> java_string =
-      Java_Clipboard_getCoercedText(env, clipboard_manager_.obj());
-
-  if (!java_string.obj()) {
-    // Tolerate a null value from the Java side, even though that should not
-    // happen since hasPlainText has already returned true.
-    // Should only happen if someone is using the clipboard on multiple
-    // threads and clears it out after hasPlainText but before we get here...
-    if (it != map_.end())
-      // We have plain text on this side, but Android doesn't. Nuke ours.
-      map_.clear();
+  if (!Java_Clipboard_isHTMLClipboardSupported(env)) {
     return;
   }
 
-  // If Android text differs from ours (or we have none), then copy Android's.
-  std::string android_string = ConvertJavaStringToUTF8(java_string);
-  if (it == map_.end() || it->second != android_string) {
-    map_.clear();
-    map_[kPlainTextFormat] = android_string;
+  // Update the html clipboard entry
+  ScopedJavaLocalRef<jstring> java_string_html =
+      Java_Clipboard_getHTMLText(env, clipboard_manager_.obj());
+  if (java_string_html.obj()) {
+    std::string android_string = ConvertJavaStringToUTF8(java_string_html);
+    if (!android_string.empty()) {
+      map_[kHTMLFormat] = android_string;
+      return;
+    }
+  }
+  it = map_.find(kHTMLFormat);
+  if (it != map_.end()) {
+    map_.erase(kHTMLFormat);
   }
 }
 
 }  // namespace
 
+// Clipboard::FormatType implementation.
 Clipboard::FormatType::FormatType() {
 }
 
@@ -191,26 +202,77 @@ bool Clipboard::FormatType::Equals(const FormatType& other) const {
   return data_ == other.data_;
 }
 
-Clipboard::Clipboard() {
-  DCHECK(CalledOnValidThread());
+// Various predefined FormatTypes.
+// static
+Clipboard::FormatType Clipboard::GetFormatType(
+    const std::string& format_string) {
+  return FormatType::Deserialize(format_string);
+}
+
+// static
+const Clipboard::FormatType& Clipboard::GetPlainTextFormatType() {
+  CR_DEFINE_STATIC_LOCAL(FormatType, type, (kPlainTextFormat));
+  return type;
+}
+
+// static
+const Clipboard::FormatType& Clipboard::GetPlainTextWFormatType() {
+  CR_DEFINE_STATIC_LOCAL(FormatType, type, (kPlainTextFormat));
+  return type;
+}
+
+// static
+const Clipboard::FormatType& Clipboard::GetWebKitSmartPasteFormatType() {
+  CR_DEFINE_STATIC_LOCAL(FormatType, type, (kWebKitSmartPasteFormat));
+  return type;
+}
+
+// static
+const Clipboard::FormatType& Clipboard::GetHtmlFormatType() {
+  CR_DEFINE_STATIC_LOCAL(FormatType, type, (kHTMLFormat));
+  return type;
+}
+
+// static
+const Clipboard::FormatType& Clipboard::GetRtfFormatType() {
+  CR_DEFINE_STATIC_LOCAL(FormatType, type, (kRTFFormat));
+  return type;
+}
+
+// static
+const Clipboard::FormatType& Clipboard::GetBitmapFormatType() {
+  CR_DEFINE_STATIC_LOCAL(FormatType, type, (kBitmapFormat));
+  return type;
+}
+
+// static
+const Clipboard::FormatType& Clipboard::GetWebCustomDataFormatType() {
+  CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypeWebCustomData));
+  return type;
+}
+
+// static
+const Clipboard::FormatType& Clipboard::GetPepperCustomDataFormatType() {
+  CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypePepperCustomData));
+  return type;
+}
+
+// Clipboard factory method.
+// static
+Clipboard* Clipboard::Create() {
+  return new ClipboardAndroid;
 }
 
-Clipboard::~Clipboard() {
+// ClipboardAndroid implementation.
+ClipboardAndroid::ClipboardAndroid() {
   DCHECK(CalledOnValidThread());
 }
 
-// Main entry point used to write several values in the clipboard.
-void Clipboard::WriteObjects(ClipboardType type, const ObjectMap& objects) {
+ClipboardAndroid::~ClipboardAndroid() {
   DCHECK(CalledOnValidThread());
-  DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE);
-  g_map.Get().Clear();
-  for (ObjectMap::const_iterator iter = objects.begin();
-       iter != objects.end(); ++iter) {
-    DispatchObject(static_cast<ObjectType>(iter->first), iter->second);
-  }
 }
 
-uint64 Clipboard::GetSequenceNumber(ClipboardType /* type */) {
+uint64 ClipboardAndroid::GetSequenceNumber(ClipboardType /* type */) {
   DCHECK(CalledOnValidThread());
   // TODO: implement this. For now this interface will advertise
   // that the clipboard never changes. That's fine as long as we
@@ -218,22 +280,22 @@ uint64 Clipboard::GetSequenceNumber(ClipboardType /* type */) {
   return 0;
 }
 
-bool Clipboard::IsFormatAvailable(const Clipboard::FormatType& format,
-                                  ClipboardType type) const {
+bool ClipboardAndroid::IsFormatAvailable(const Clipboard::FormatType& format,
+                                         ClipboardType type) const {
   DCHECK(CalledOnValidThread());
   DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE);
-  return g_map.Get().HasFormat(format.data());
+  return g_map.Get().HasFormat(format.ToString());
 }
 
-void Clipboard::Clear(ClipboardType type) {
+void ClipboardAndroid::Clear(ClipboardType type) {
   DCHECK(CalledOnValidThread());
   DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE);
   g_map.Get().Clear();
 }
 
-void Clipboard::ReadAvailableTypes(ClipboardType type,
-                                   std::vector<string16>* types,
-                                   bool* contains_filenames) const {
+void ClipboardAndroid::ReadAvailableTypes(ClipboardType type,
+                                          std::vector<base::string16>* types,
+                                          bool* contains_filenames) const {
   DCHECK(CalledOnValidThread());
   DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE);
 
@@ -248,44 +310,46 @@ void Clipboard::ReadAvailableTypes(ClipboardType type,
   *contains_filenames = false;
 }
 
-void Clipboard::ReadText(ClipboardType type, string16* result) const {
+void ClipboardAndroid::ReadText(ClipboardType type,
+                                base::string16* result) const {
   DCHECK(CalledOnValidThread());
   DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE);
   std::string utf8;
   ReadAsciiText(type, &utf8);
-  *result = UTF8ToUTF16(utf8);
+  *result = base::UTF8ToUTF16(utf8);
 }
 
-void Clipboard::ReadAsciiText(ClipboardType type, std::string* result) const {
+void ClipboardAndroid::ReadAsciiText(ClipboardType type,
+                                     std::string* result) const {
   DCHECK(CalledOnValidThread());
   DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE);
   *result = g_map.Get().Get(kPlainTextFormat);
 }
 
 // Note: |src_url| isn't really used. It is only implemented in Windows
-void Clipboard::ReadHTML(ClipboardType type,
-                         string16* markup,
-                         std::string* src_url,
-                         uint32* fragment_start,
-                         uint32* fragment_end) const {
+void ClipboardAndroid::ReadHTML(ClipboardType type,
+                                base::string16* markup,
+                                std::string* src_url,
+                                uint32* fragment_start,
+                                uint32* fragment_end) const {
   DCHECK(CalledOnValidThread());
   DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE);
   if (src_url)
     src_url->clear();
 
   std::string input = g_map.Get().Get(kHTMLFormat);
-  *markup = UTF8ToUTF16(input);
+  *markup = base::UTF8ToUTF16(input);
 
   *fragment_start = 0;
   *fragment_end = static_cast<uint32>(markup->length());
 }
 
-void Clipboard::ReadRTF(ClipboardType type, std::string* result) const {
+void ClipboardAndroid::ReadRTF(ClipboardType type, std::string* result) const {
   DCHECK(CalledOnValidThread());
   NOTIMPLEMENTED();
 }
 
-SkBitmap Clipboard::ReadImage(ClipboardType type) const {
+SkBitmap ClipboardAndroid::ReadImage(ClipboardType type) const {
   DCHECK(CalledOnValidThread());
   DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE);
   std::string input = g_map.Get().Get(kBitmapFormat);
@@ -295,137 +359,96 @@ SkBitmap Clipboard::ReadImage(ClipboardType type) const {
     DCHECK_LE(sizeof(gfx::Size), input.size());
     const gfx::Size* size = reinterpret_cast<const gfx::Size*>(input.data());
 
-    bmp.setConfig(
-        SkBitmap::kARGB_8888_Config, size->width(), size->height(), 0);
-    bmp.allocPixels();
+    bmp.allocN32Pixels(size->width(), size->height());
 
-    int bm_size = size->width() * size->height() * 4;
-    DCHECK_EQ(sizeof(gfx::Size) + bm_size, input.size());
+    DCHECK_EQ(sizeof(gfx::Size) + bmp.getSize(), input.size());
 
-    memcpy(bmp.getPixels(), input.data() + sizeof(gfx::Size), bm_size);
+    memcpy(bmp.getPixels(), input.data() + sizeof(gfx::Size), bmp.getSize());
   }
   return bmp;
 }
 
-void Clipboard::ReadCustomData(ClipboardType clipboard_type,
-                               const string16& type,
-                               string16* result) const {
+void ClipboardAndroid::ReadCustomData(ClipboardType clipboard_type,
+                                      const base::string16& type,
+                                      base::string16* result) const {
   DCHECK(CalledOnValidThread());
   NOTIMPLEMENTED();
 }
 
-void Clipboard::ReadBookmark(string16* title, std::string* url) const {
+void ClipboardAndroid::ReadBookmark(base::string16* title,
+                                    std::string* url) const {
   DCHECK(CalledOnValidThread());
   NOTIMPLEMENTED();
 }
 
-void Clipboard::ReadData(const Clipboard::FormatType& format,
-                         std::string* result) const {
+void ClipboardAndroid::ReadData(const Clipboard::FormatType& format,
+                                std::string* result) const {
   DCHECK(CalledOnValidThread());
-  *result = g_map.Get().Get(format.data());
-}
-
-// static
-Clipboard::FormatType Clipboard::GetFormatType(
-    const std::string& format_string) {
-  return FormatType::Deserialize(format_string);
-}
-
-// static
-const Clipboard::FormatType& Clipboard::GetPlainTextFormatType() {
-  CR_DEFINE_STATIC_LOCAL(FormatType, type, (kPlainTextFormat));
-  return type;
+  *result = g_map.Get().Get(format.ToString());
 }
 
-// static
-const Clipboard::FormatType& Clipboard::GetPlainTextWFormatType() {
-  CR_DEFINE_STATIC_LOCAL(FormatType, type, (kPlainTextFormat));
-  return type;
-}
-
-// static
-const Clipboard::FormatType& Clipboard::GetWebKitSmartPasteFormatType() {
-  CR_DEFINE_STATIC_LOCAL(FormatType, type, (kWebKitSmartPasteFormat));
-  return type;
-}
-
-// static
-const Clipboard::FormatType& Clipboard::GetHtmlFormatType() {
-  CR_DEFINE_STATIC_LOCAL(FormatType, type, (kHTMLFormat));
-  return type;
-}
-
-// static
-const Clipboard::FormatType& Clipboard::GetRtfFormatType() {
-  CR_DEFINE_STATIC_LOCAL(FormatType, type, (kRTFFormat));
-  return type;
-}
-
-// static
-const Clipboard::FormatType& Clipboard::GetBitmapFormatType() {
-  CR_DEFINE_STATIC_LOCAL(FormatType, type, (kBitmapFormat));
-  return type;
-}
-
-// static
-const Clipboard::FormatType& Clipboard::GetWebCustomDataFormatType() {
-  CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypeWebCustomData));
-  return type;
-}
-
-// static
-const Clipboard::FormatType& Clipboard::GetPepperCustomDataFormatType() {
-  CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypePepperCustomData));
-  return type;
+// Main entry point used to write several values in the clipboard.
+void ClipboardAndroid::WriteObjects(ClipboardType type,
+                                    const ObjectMap& objects) {
+  DCHECK(CalledOnValidThread());
+  DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE);
+  g_map.Get().Clear();
+  for (ObjectMap::const_iterator iter = objects.begin(); iter != objects.end();
+       ++iter) {
+    DispatchObject(static_cast<ObjectType>(iter->first), iter->second);
+  }
 }
 
-void Clipboard::WriteText(const char* text_data, size_t text_len) {
+void ClipboardAndroid::WriteText(const char* text_data, size_t text_len) {
   g_map.Get().Set(kPlainTextFormat, std::string(text_data, text_len));
 }
 
-void Clipboard::WriteHTML(const char* markup_data,
-                          size_t markup_len,
-                          const char* url_data,
-                          size_t url_len) {
+void ClipboardAndroid::WriteHTML(const char* markup_data,
+                                 size_t markup_len,
+                                 const char* url_data,
+                                 size_t url_len) {
   g_map.Get().Set(kHTMLFormat, std::string(markup_data, markup_len));
 }
 
-void Clipboard::WriteRTF(const char* rtf_data, size_t data_len) {
+void ClipboardAndroid::WriteRTF(const char* rtf_data, size_t data_len) {
   NOTIMPLEMENTED();
 }
 
 // Note: according to other platforms implementations, this really writes the
 // URL spec.
-void Clipboard::WriteBookmark(const char* title_data, size_t title_len,
-                              const char* url_data, size_t url_len) {
+void ClipboardAndroid::WriteBookmark(const char* title_data,
+                                     size_t title_len,
+                                     const char* url_data,
+                                     size_t url_len) {
   g_map.Get().Set(kBookmarkFormat, std::string(url_data, url_len));
 }
 
 // Write an extra flavor that signifies WebKit was the last to modify the
 // pasteboard. This flavor has no data.
-void Clipboard::WriteWebSmartPaste() {
+void ClipboardAndroid::WriteWebSmartPaste() {
   g_map.Get().Set(kWebKitSmartPasteFormat, std::string());
 }
 
-// All platforms use gfx::Size for size data but it is passed as a const char*
-// Further, pixel_data is expected to be 32 bits per pixel
 // Note: we implement this to pass all unit tests but it is currently unclear
 // how some code would consume this.
-void Clipboard::WriteBitmap(const char* pixel_data, const char* size_data) {
-  const gfx::Size* size = reinterpret_cast<const gfx::Size*>(size_data);
-  int bm_size = size->width() * size->height() * 4;
-
-  std::string packed(size_data, sizeof(gfx::Size));
-  packed += std::string(pixel_data, bm_size);
+void ClipboardAndroid::WriteBitmap(const SkBitmap& bitmap) {
+  gfx::Size size(bitmap.width(), bitmap.height());
+
+  std::string packed(reinterpret_cast<const char*>(&size), sizeof(size));
+  {
+    SkAutoLockPixels bitmap_lock(bitmap);
+    packed += std::string(static_cast<const char*>(bitmap.getPixels()),
+                          bitmap.getSize());
+  }
   g_map.Get().Set(kBitmapFormat, packed);
 }
 
-void Clipboard::WriteData(const Clipboard::FormatType& format,
-                          const char* data_data, size_t data_len) {
-  g_map.Get().Set(format.data(), std::string(data_data, data_len));
+void ClipboardAndroid::WriteData(const Clipboard::FormatType& format,
+                                 const char* data_data,
+                                 size_t data_len) {
+  g_map.Get().Set(format.ToString(), std::string(data_data, data_len));
 }
 
-// See clipboard_android_initialization.h for more information.
 bool RegisterClipboardAndroid(JNIEnv* env) {
   return RegisterNativesImpl(env);
 }