[VD][MultiControl] Support ReadPng for copy&paste 56/317756/1
authorchenshurong <shurong.chen@samsung.com>
Sat, 14 Sep 2024 07:22:47 +0000 (15:22 +0800)
committerchenshurong <shurong.chen@samsung.com>
Sat, 14 Sep 2024 07:24:53 +0000 (15:24 +0800)
1. Png replaces Bitmap on upstream, support ReadPng for copy&paste.
2. EFL have supported multi type data(mainly html type and text type),
   and Multi Control app also will set text and html type data is have,
   so don't need convert text to html on our side, and also don't need
   check text data when check whether html format is Available.

Change-Id: I86032e1ce5c5903ee6d589b54cf120609d40cce5
Signed-off-by: chenshurong <shurong.chen@samsung.com>
tizen_src/chromium_impl/ui/base/clipboard/clipboard_efl.cc
tizen_src/chromium_impl/ui/base/clipboard/clipboard_helper_efl_wayland.cc
tizen_src/chromium_impl/ui/base/clipboard/clipboard_helper_efl_wayland.h

index 4b2bd98610c68b9a4d7839ea99931c84617eeb0d..46cc0839103aa518024249a8ee77a4f38aff3463 100644 (file)
@@ -105,8 +105,14 @@ void ClipboardEfl::ReadAvailableTypes(
 
   if (IsFormatAvailable(ClipboardFormatType::RtfType(), type, data_dst))
     types->push_back(base::UTF8ToUTF16(kMimeTypeRTF));
+#if BUILDFLAG(IS_TIZEN_TV)
+  // TODO(crbug.com/1201018): BitmapType been removed.
+  if (IsFormatAvailable(ClipboardFormatType::PngType(), type, data_dst))
+    types->push_back(base::UTF8ToUTF16(kMimeTypePNG));
+#else
   if (IsFormatAvailable(ClipboardFormatType::BitmapType(), type, data_dst))
     types->push_back(base::UTF8ToUTF16(kMimeTypePNG));
+#endif
 }
 
 void ClipboardEfl::ReadText(ClipboardBuffer type,
@@ -166,9 +172,26 @@ void ClipboardEfl::ReadRTF(ClipboardBuffer type,
 void ClipboardEfl::ReadPng(ClipboardBuffer buffer,
                            const DataTransferEndpoint* data_dst,
                            ReadPngCallback callback) const {
-  // Return an empty data for avoiding block the following process.
+#if BUILDFLAG(IS_TIZEN_TV)
+  DCHECK(CalledOnValidThread());
+  DCHECK_EQ(buffer, ClipboardBuffer::kCopyPaste);
+
+  std::string result;
+  ClipboardHelperEfl::GetInstance()->RetrieveClipboardItem(
+      &result, ClipboardDataTypeEfl::IMAGE);
+
+  if (result.empty()) {
+    std::move(callback).Run(std::vector<uint8_t>());
+    return;
+  }
+
+  std::vector<uint8_t> png_data(result.begin(), result.end());
+  std::move(callback).Run(png_data);
+
+#else
   std::move(callback).Run(std::vector<uint8_t>());
   NOTIMPLEMENTED();
+#endif
 }
 
 void ClipboardEfl::ReadBookmark(const DataTransferEndpoint* data_dst,
index e81c8fe695fdc8d646565f34b0325d9d8d2b8e3b..f852d7945ccd7f78f07e9d229315166211b4d7fa 100644 (file)
@@ -50,16 +50,21 @@ bool ClipboardHelperEfl::IsFormatAvailable(
     const ui::ClipboardFormatType& format) const {
   // Poor man's format check.
   std::string format_text(format.ToString());
+  bool ret = false;
   if (format_text.find("text/plain") != std::string::npos) {
-    return !clipboard_text().empty();
+    ret = !clipboard_text().empty();
+    LOG(INFO) << "IsFormatAvailable, format:text/plain, available:" << ret;
   } else if (format_text.find("text/html") != std::string::npos) {
+    ret = !clipboard_html().empty();
+    LOG(INFO) << "IsFormatAvailable, format:text/html, available:" << ret;
 #if BUILDFLAG(IS_TIZEN_TV)
-    return (!clipboard_html().empty() || !clipboard_text().empty());
-#else
-    return !clipboard_html().empty();
+  } else if (format_text.find("image/png") != std::string::npos) {
+    ret = !clipboard_image().empty();
+    LOG(INFO) << "IsFormatAvailable, format:image/png, available:" << ret;
 #endif
   }
-  return false;
+
+  return ret;
 }
 
 void ClipboardHelperEfl::SetData(const std::string& data,
@@ -147,6 +152,24 @@ void ClipboardHelperEfl::Clear() {
                         ELM_SEL_FORMAT_TEXT, nullptr, 0);
 }
 
+std::string ClipboardHelperEfl::GetImageBytesFromFile(const std::string& path) {
+  if (path.empty()) {
+    LOG(ERROR) << "image file_path is empty";
+    return std::string();
+  }
+
+  absl::optional<std::vector<uint8_t>> bytes =
+      base::ReadFileToBytes(base::FilePath(path));
+  if (!bytes.has_value()) {
+    LOG(ERROR) << "image bytes is empty";
+    return std::string();
+  }
+
+  std::string image_bytes(bytes.value().begin(), bytes.value().end());
+  LOG(INFO) << "GetPngBytesFromFile, image bytes:" << image_bytes;
+  return image_bytes;
+}
+
 std::string ClipboardHelperEfl::GetImageTypeFromPath(const std::string& path) {
   std::string::size_type len = path.length();
   std::string::size_type back_pos = path.rfind(".");
@@ -187,7 +210,8 @@ bool ClipboardHelperEfl::Base64ImageTagFromImagePath(const std::string& path,
 // this for security reasons). To work around this limitation we convert local
 // images to base64 encoded data URI.
 bool ClipboardHelperEfl::ConvertImgTagToBase64(const std::string& tag,
-                                               std::string* out_tag) {
+                                               std::string* out_tag,
+                                               std::string* file_path) {
   std::string::size_type front_pos = tag.find(kHTMLImageFromClipboardAppFront);
   if (front_pos == std::string::npos)
     return false;
@@ -203,6 +227,7 @@ bool ClipboardHelperEfl::ConvertImgTagToBase64(const std::string& tag,
   }
 
   std::string image_path = front_stripped.substr(0, back_pos);
+  *file_path = image_path;
   LOG(INFO) << "[CLIPBOARD] image_path:" << image_path;
   return Base64ImageTagFromImagePath(image_path, out_tag);
 }
@@ -227,17 +252,16 @@ bool ClipboardHelperEfl::RetrieveClipboardItem(
     return true;
   } else if (elm_format == ELM_SEL_FORMAT_HTML) {
     *data = clipboard_html();
-    // When text is copied from another app and the webview has focus,
-    // only the callback function for the text is received.
-    // So there is no html text.
-    // However, if we try to paste html from a page,
-    // it will fall back to html text.
-    if (data->empty())
-      *data = clipboard_text();
-
     LOG(INFO) << "[CLIPBOARD] RetrieveClipboardItem! ELM_SEL_FORMAT_HTML! - "
               << *data;
     return true;
+#if BUILDFLAG(IS_TIZEN_TV)
+  } else if (elm_format == ELM_SEL_FORMAT_IMAGE) {
+    *data = clipboard_image();
+    LOG(INFO) << "[CLIPBOARD] RetrieveClipboardItem! ELM_SEL_FORMAT_IMAGE! - "
+              << *data;
+    return true;
+#endif
   }
 
   LOG(ERROR) << "[CLIPBOARD] Unexpected selection data format: "
@@ -261,10 +285,12 @@ void ClipboardHelperEfl::RefreshClipboard() {
 
   // We need to get both html and plain text from clipboard.
 #if BUILDFLAG(IS_TIZEN_TV)
-  LOG(INFO)
-      << "[CLIPBOARD] clear clipboard_contents_ and clipboard_contents_html_!!";
+  LOG(INFO) << "[CLIPBOARD] clear "
+               "clipboard_contents_,clipboard_contents_html_,clipboard_"
+               "contents_image_!!";
   clipboard_contents_.clear();
   clipboard_contents_html_.clear();
+  clipboard_contents_image_.clear();
   elm_cnp_selection_get(source_widget_, ELM_SEL_TYPE_CLIPBOARD,
                         ELM_SEL_FORMAT_HTML, SelectionGetCbHTML, this);
   elm_cnp_selection_get(source_widget_, ELM_SEL_TYPE_CLIPBOARD,
@@ -304,10 +330,17 @@ Eina_Bool ClipboardHelperEfl::SelectionGetCbHTML(void* data,
   // with local file path, which can't be used in normal web pages.
   // See comment in ::ConvertImgTagToBase64
   std::string img_tag;
-  if (ConvertImgTagToBase64(selection_data, &img_tag)) {
+  std::string file_path;
+  if (ConvertImgTagToBase64(selection_data, &img_tag, &file_path)) {
     self->clipboard_contents_html_ = img_tag;
-    LOG(INFO) << "[CLIPBOARD] image type, set selection_data to html : "
+    LOG(INFO) << "[CLIPBOARD] set selection_data to html : "
               << self->clipboard_contents_html_;
+
+#if BUILDFLAG(IS_TIZEN_TV)
+    self->clipboard_contents_image_ = GetImageBytesFromFile(file_path);
+    LOG(INFO) << "[CLIPBOARD] set selection_data to image : "
+              << self->clipboard_contents_image_;
+#endif
   } else {
     LOG(INFO) << "[CLIPBOARD] set selection_data to html : " << selection_data;
     self->clipboard_contents_html_ = selection_data;
@@ -454,7 +487,8 @@ void ClipboardHelperEfl::ProcessClipboardAppEvent(Elm_Selection_Data* ev,
     clipboard_contents_from_clipboard_app_ = selection_data;
   } else {
     std::string img_tag;
-    if (ConvertImgTagToBase64(selection_data, &img_tag)) {
+    std::string file_path;
+    if (ConvertImgTagToBase64(selection_data, &img_tag, &file_path)) {
       clipboard_contents_html_from_clipboard_app_ = img_tag;
     } else {
       clipboard_contents_html_from_clipboard_app_ = selection_data;
index 8d6ab7ab7a1e9490f30eea1714f0e53ee4d1dbd7..ac5063b0de29aca3ac7eccef73ec116389d64f5a 100644 (file)
@@ -76,12 +76,14 @@ class COMPONENT_EXPORT(UI_BASE) ClipboardHelperEfl {
   static Eina_Bool SelectionGetCbAppText(void* data,
                                          Evas_Object* obj,
                                          Elm_Selection_Data* ev);
+  static std::string GetImageBytesFromFile(const std::string& path);
   static std::string GetImageTypeFromPath(const std::string& path);
 
   static bool Base64ImageTagFromImagePath(const std::string& path,
                                           std::string* image_html);
   static bool ConvertImgTagToBase64(const std::string& tag,
-                                    std::string* out_tag);
+                                    std::string* out_tag,
+                                    std::string* file_path);
 
   static void CbhmOnNameOwnerChanged(void* data,
                                      const char* bus,
@@ -108,6 +110,11 @@ class COMPONENT_EXPORT(UI_BASE) ClipboardHelperEfl {
     return paste_from_clipboard_app_ ? clipboard_contents_from_clipboard_app_
                                      : clipboard_contents_;
   }
+#if BUILDFLAG(IS_TIZEN_TV)
+  const std::string& clipboard_image() const {
+    return clipboard_contents_image_;
+  }
+#endif
 
   void CbhmEldbusInit();
   void CbhmEldbusDeinit();
@@ -122,6 +129,9 @@ class COMPONENT_EXPORT(UI_BASE) ClipboardHelperEfl {
   std::string clipboard_contents_html_from_clipboard_app_;
   std::string clipboard_contents_;
   std::string clipboard_contents_from_clipboard_app_;
+#if BUILDFLAG(IS_TIZEN_TV)
+  std::string clipboard_contents_image_;
+#endif
 
   // Clipboard app integration:
   Eldbus_Proxy* eldbus_proxy_;