Use Hit_Test_Param to pass hit test infos between processes.
authorArnaud Renevier <a.renevier@samsung.com>
Wed, 25 Mar 2015 22:49:24 +0000 (15:49 -0700)
committerYoungsoo Choi <kenshin.choi@samsung.com>
Tue, 10 Jul 2018 06:57:09 +0000 (06:57 +0000)
When we do a hit test, ewk api forces us to get the list of node
attributes (as Eina_Hash*). Those informations cannot be copied from
render to browser process. So, we are using a hack to get the list of
attributes (we are passing them along with Hit_Test as a std::map and
parse them only in the render process).

We have two objects: Ewk_Hit_Test and _Ewk_Hit_Test. Ewk_Hit_Test owns a
_Ewk_Hit_Test. It would be great to simplify that, but because of the
forementionned hacks, it is diffcult.

This patch uses creates Hit_Test_Param struct, that can be passed
between processes. With that info, _Ewk_Hit_Test is only created on the
browser side.

This patch also fixes ewk_hit_test_image_buffer_get is currently broken.

Change-Id: If1c72714a2b20018c24c6247c6c4d092fdbb7fd3
Signed-off-by: Arnaud Renevier <a.renevier@samsung.com>
12 files changed:
tizen_src/ewk/efl_integration/browser/web_view_browser_message_filter.cc
tizen_src/ewk/efl_integration/common/hit_test_params.h [new file with mode: 0644]
tizen_src/ewk/efl_integration/common/render_messages_ewk.h
tizen_src/ewk/efl_integration/efl_integration.gypi
tizen_src/ewk/efl_integration/eweb_view.cc
tizen_src/ewk/efl_integration/eweb_view.h
tizen_src/ewk/efl_integration/private/ewk_hit_test_private.cc
tizen_src/ewk/efl_integration/private/ewk_hit_test_private.h
tizen_src/ewk/efl_integration/renderer/render_view_observer_efl.cc
tizen_src/ewk/efl_integration/renderer/render_view_observer_efl.h
tizen_src/ewk/efl_integration/tizen_webview/public/tw_hit_test.cc
tizen_src/ewk/efl_integration/tizen_webview/public/tw_hit_test.h

index a967869..d08d58c 100644 (file)
@@ -7,6 +7,7 @@
 #include "common/web_contents_utils.h"
 #include "common/render_messages_ewk.h"
 #include "common/error_params.h"
+#include "common/hit_test_params.h"
 #include "content/common/view_messages.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_observer.h"
@@ -61,6 +62,7 @@ class WebViewBrowserMessageFilterPrivate
   void OnReceivedHitTestAsyncData(int render_view,
                                   const _Ewk_Hit_Test& hit_test_data,
                                   const NodeAttributesMap& node_attributes,
+                                  const Hit_Test_Params& params,
                                   int64_t request_id) {
     DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 
@@ -75,7 +77,7 @@ class WebViewBrowserMessageFilterPrivate
 
     if (render_view_host && render_view_host->GetRoutingID() == render_view) {
       web_view_->DispatchAsyncHitTestData(hit_test_data,
-                                          node_attributes, request_id);
+                                          node_attributes, params, request_id);
     }
   }
 
diff --git a/tizen_src/ewk/efl_integration/common/hit_test_params.h b/tizen_src/ewk/efl_integration/common/hit_test_params.h
new file mode 100644 (file)
index 0000000..49e3645
--- /dev/null
@@ -0,0 +1,96 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef HIT_TEST_PARAMS_H_
+#define HIT_TEST_PARAMS_H_
+
+#include <map>
+#include <string>
+
+#include "ipc/ipc_message.h"
+#include "ipc/ipc_param_traits.h"
+#include "ui/gfx/size.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+
+#include "ui/gfx/ipc/gfx_param_traits.h"
+
+typedef std::map<std::string, std::string> NodeAttributesMap;
+
+/*
+namespace IPC {
+
+template <>
+struct ParamTraits<SkBitmap> {
+  static void Write(Message* msg, const SkBitmap& bitmap) {
+    if (!msg->WriteInt(bitmap.colorType()))
+      return;
+    if (!msg->WriteInt(bitmap.alphaType()))
+      return;
+    if (!msg->WriteInt(bitmap.width()))
+      return;
+    if (!msg->WriteInt(bitmap.height()))
+      return;
+    // XXX: should we use mapped memory instead?
+    if (!msg->WriteData(static_cast<const char*>(bitmap.getPixels()), bitmap.getSize()))
+      return;
+  }
+
+  static bool Read(const Message* m, PickleIterator* iter, SkBitmap* bitmap)  {
+    int colorType, alphaType;
+    int width, height;
+    int data_len;
+    const char* data;
+
+    if (!iter->ReadInt(&colorType))
+      return false;
+
+    if (!iter->ReadInt(&alphaType))
+      return false;
+
+    if (!iter->ReadInt(&width))
+      return false;
+
+    if (!iter->ReadInt(&height))
+      return false;
+
+    if (!iter->ReadData(&data, &data_len))
+      return false;
+
+    bitmap->setInfo(SkImageInfo::Make(width, height, static_cast<SkColorType>(colorType), static_cast<SkAlphaType>(alphaType)), 0);
+    bitmap->setPixels(static_cast<void*>(const_cast<char*>(data)));
+
+    return true;
+  }
+
+  static void Log(const SkBitmap&, std::string* l) {
+    l->append("<SkBitmap>");
+  }
+};
+
+}  // namespace IPC
+*/
+
+struct Hit_Test_Params {
+  int context;
+  std::string linkURI;
+  std::string linkTitle; // the title of link
+  std::string linkLabel; // the text of the link
+  std::string imageURI;
+  std::string mediaURI;
+  bool isEditable;
+  int mode;
+
+  struct Node_Data {
+    std::string tagName;      // tag name for hit element
+    std::string nodeValue;    // node value for hit element
+    NodeAttributesMap attributes;
+  } nodeData;
+
+  struct Image_Data {
+    std::string fileNameExtension; // image filename extension for hit element
+    SkBitmap imageBitmap;          // image pixels data
+  } imageData;
+};
+
+#endif // HIT_TEST_PARAMS_H_
index ef644bc..2f26095 100644 (file)
@@ -6,6 +6,7 @@
 
 #include "base/values.h"
 #include "common//print_pages_params.h"
+#include "common/hit_test_params.h"
 #include "common/error_params.h"
 #include "common/cache_params_efl.h"
 #include "common/navigation_policy_params.h"
@@ -44,6 +45,30 @@ IPC_STRUCT_TRAITS_BEGIN(ErrorParams)
   IPC_STRUCT_TRAITS_MEMBER(domain)
 IPC_STRUCT_TRAITS_END()
 
+IPC_STRUCT_TRAITS_BEGIN(Hit_Test_Params::Node_Data)
+  IPC_STRUCT_TRAITS_MEMBER(tagName)
+  IPC_STRUCT_TRAITS_MEMBER(nodeValue)
+  IPC_STRUCT_TRAITS_MEMBER(attributes)
+IPC_STRUCT_TRAITS_END()
+
+IPC_STRUCT_TRAITS_BEGIN(Hit_Test_Params::Image_Data)
+  IPC_STRUCT_TRAITS_MEMBER(fileNameExtension)
+  IPC_STRUCT_TRAITS_MEMBER(imageBitmap)
+IPC_STRUCT_TRAITS_END()
+
+IPC_STRUCT_TRAITS_BEGIN(Hit_Test_Params)
+  IPC_STRUCT_TRAITS_MEMBER(context)
+  IPC_STRUCT_TRAITS_MEMBER(linkURI)
+  IPC_STRUCT_TRAITS_MEMBER(linkTitle)
+  IPC_STRUCT_TRAITS_MEMBER(linkLabel)
+  IPC_STRUCT_TRAITS_MEMBER(imageURI)
+  IPC_STRUCT_TRAITS_MEMBER(mediaURI)
+  IPC_STRUCT_TRAITS_MEMBER(isEditable)
+  IPC_STRUCT_TRAITS_MEMBER(mode)
+  IPC_STRUCT_TRAITS_MEMBER(nodeData)
+  IPC_STRUCT_TRAITS_MEMBER(imageData)
+IPC_STRUCT_TRAITS_END()
+
 IPC_ENUM_TRAITS(Ewk_CSP_Header_Type)
 
 IPC_ENUM_TRAITS(tizen_webview::Hit_Test_Mode)
@@ -161,10 +186,11 @@ IPC_MESSAGE_CONTROL3(EwkViewHostMsg_HitTestReply,
                     _Ewk_Hit_Test, /* Ewk Hit test data without node map */
                     NodeAttributesMap /* node attributes */)
 
-IPC_MESSAGE_CONTROL4(EwkViewHostMsg_HitTestAsyncReply,
+IPC_MESSAGE_CONTROL5(EwkViewHostMsg_HitTestAsyncReply,
                     int, /* render_view_id */
                     _Ewk_Hit_Test, /* Ewk Hit test data without node map */
                     NodeAttributesMap, /* node attributes */
+                    Hit_Test_Params,
                     int64_t /* request id */)
 
 IPC_MESSAGE_ROUTED1(EwkViewMsg_DidFailLoadWithError,
index b37a0ab..76e6e25 100644 (file)
       'common/content_switches_efl.h',
       'common/editing_messages.h',
       'common/error_params.h',
+      'common/hit_test_params.h',
       'common/message_generator_ewk.h',
       'common/message_generator_ewk.cc',
       'common/navigation_policy_params.cc',
index a3d9f57..724202b 100644 (file)
@@ -1514,7 +1514,7 @@ Eina_Bool EWebView::AsyncRequestHitTestDataAtBlinkCords(int x, int y,
 }
 
 void EWebView::DispatchAsyncHitTestData(const _Ewk_Hit_Test& hit_test_data,
-    const NodeAttributesMap& node_attributes, int64_t request_id) {
+    const NodeAttributesMap& node_attributes, const Hit_Test_Params& params, int64_t request_id) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 
   std::map<int64_t, WebViewAsyncRequestHitTestDataCallback*>::iterator it =
@@ -1524,8 +1524,9 @@ void EWebView::DispatchAsyncHitTestData(const _Ewk_Hit_Test& hit_test_data,
     return;
   _Ewk_Hit_Test data = hit_test_data;
   data.nodeData.PopulateNodeAtributes(node_attributes);
-  tizen_webview::Hit_Test hit_test(data);
-  it->second->Run(&hit_test, this);
+  scoped_ptr<tizen_webview::Hit_Test> hit_test(new tizen_webview::Hit_Test(params));
+
+  it->second->Run(hit_test.get(), this);
   delete it->second;
   hit_test_callback_.erase(it);
 }
index fbcdb7b..e44a548 100644 (file)
@@ -362,7 +362,7 @@ class EWebView {
       tizen_webview::Hit_Test_Mode mode,
       tizen_webview::View_Hit_Test_Request_Callback,
       void* user_data);
-  void DispatchAsyncHitTestData(const _Ewk_Hit_Test& hit_test_data, const NodeAttributesMap& node_attributes, int64_t request_id);
+  void DispatchAsyncHitTestData(const _Ewk_Hit_Test& hit_test_data, const NodeAttributesMap& node_attributes, const Hit_Test_Params& params, int64_t request_id);
   void UpdateHitTestData(const _Ewk_Hit_Test& hit_test_data, const NodeAttributesMap& node_attributes);
 
   int current_find_request_id() const { return current_find_request_id_; }
index 0dea03f..6669fa5 100644 (file)
@@ -29,6 +29,31 @@ _Ewk_Hit_Test::_Ewk_Hit_Test(const _Ewk_Hit_Test& other)
       imageData(other.imageData) {
 }
 
+_Ewk_Hit_Test::_Ewk_Hit_Test(const Hit_Test_Params& params)
+    : context(static_cast<tizen_webview::Hit_Test_Result_Context>(params.context)),
+      linkURI(params.linkURI),
+      linkTitle(params.linkTitle),
+      linkLabel(params.linkLabel),
+      imageURI(params.imageURI),
+      mediaURI(params.mediaURI),
+      isEditable(params.isEditable),
+      mode(static_cast<tizen_webview::Hit_Test_Mode>(params.mode)) {
+  nodeData.tagName = params.nodeData.tagName;
+  nodeData.nodeValue = params.nodeData.nodeValue;
+  imageData.fileNameExtension = params.imageData.fileNameExtension;
+  params.imageData.imageBitmap.deepCopyTo(&(imageData.imageBitmap));
+
+  const NodeAttributesMap& nodeAttributes = params.nodeData.attributes;
+  if (!nodeAttributes.empty()) {
+    nodeData.attributeHash = eina_hash_string_superfast_new(FreeHitTestAttributeHashData);
+    NodeAttributesMap::const_iterator attributeMapEnd = nodeAttributes.end();
+    for (NodeAttributesMap::const_iterator it = nodeAttributes.begin(); it != attributeMapEnd; ++it) {
+      eina_hash_add(nodeData.attributeHash, it->first.c_str(), eina_stringshare_add(it->second.c_str()));
+    }
+  }
+
+}
+
 _Ewk_Hit_Test::Hit_Test_Node_Data::Hit_Test_Node_Data()
     : attributeHash(NULL) {
 }
index 8d945d0..045365e 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <Eina.h>
 
+#include "common/hit_test_params.h"
 #include <tizen_webview/public/tw_hit_test.h>
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "tizen_webview/public/tw_hit_test.h"
@@ -20,6 +21,7 @@ typedef std::map<std::string, std::string> NodeAttributesMap;
 struct _Ewk_Hit_Test {
   _Ewk_Hit_Test();
   _Ewk_Hit_Test(const _Ewk_Hit_Test& other);
+  _Ewk_Hit_Test(const Hit_Test_Params& params);
   // TODO: check whether bitwise assignment is acceptable (e.g, attributeHash)
   // If not, proper implementation for below should be added:
   // _Ewk_Hit_Test& operator=(const _Ewk_Hit_Test&);
index c415855..7d9a10c 100644 (file)
@@ -15,6 +15,7 @@
 #include "content/public/renderer/content_renderer_client.h"
 #include "content/public/renderer/render_view.h"
 #include "common/render_messages_ewk.h"
+#include "common/hit_test_params.h"
 #include "third_party/WebKit/public/platform/WebCString.h"
 #include "third_party/WebKit/public/platform/WebData.h"
 #include "third_party/WebKit/public/platform/WebPoint.h"
@@ -85,7 +86,7 @@ bool GetGRBAValuesFromString(const std::string& input, int* r, int* g, int* b, i
   return parsing_status;
 }
 
-void PopulateEwkHitTestData(const blink::WebHitTestResult& web_hit_test, _Ewk_Hit_Test* ewk_hit_test)
+void PopulateEwkHitTestData(const blink::WebHitTestResult& web_hit_test, _Ewk_Hit_Test* ewk_hit_test, Hit_Test_Params* params)
 {
   DCHECK(ewk_hit_test);
   ewk_hit_test->imageURI = web_hit_test.absoluteImageURL().string().utf8();
@@ -95,6 +96,13 @@ void PopulateEwkHitTestData(const blink::WebHitTestResult& web_hit_test, _Ewk_Hi
   ewk_hit_test->linkTitle = web_hit_test.titleDisplayString().utf8();
   ewk_hit_test->isEditable = web_hit_test.isContentEditable();
 
+  params->imageURI = web_hit_test.absoluteImageURL().string().utf8();
+  params->linkURI = web_hit_test.absoluteLinkURL().string().utf8();
+  params->mediaURI = web_hit_test.absoluteMediaURL().string().utf8();
+  params->linkLabel = web_hit_test.textContent().utf8();
+  params->linkTitle = web_hit_test.titleDisplayString().utf8();
+  params->isEditable = web_hit_test.isContentEditable();
+
   int context = TW_HIT_TEST_RESULT_CONTEXT_DOCUMENT;
   if (!web_hit_test.absoluteLinkURL().isEmpty())
     context |= TW_HIT_TEST_RESULT_CONTEXT_LINK;
@@ -112,9 +120,13 @@ void PopulateEwkHitTestData(const blink::WebHitTestResult& web_hit_test, _Ewk_Hi
   ewk_hit_test->context = static_cast<tizen_webview::Hit_Test_Result_Context>(context);
   ewk_hit_test->nodeData.attributeHash = 0;
 
+  params->context = static_cast<tizen_webview::Hit_Test_Result_Context>(context);
+
   if (ewk_hit_test->mode & TW_HIT_TEST_MODE_NODE_DATA) {
     ewk_hit_test->nodeData.tagName = web_hit_test.node().nodeName().utf8();
     ewk_hit_test->nodeData.nodeValue = web_hit_test.node().nodeValue().utf8();
+    params->nodeData.tagName = web_hit_test.node().nodeName().utf8();
+    params->nodeData.nodeValue = web_hit_test.node().nodeValue().utf8();
   }
 
   if ((ewk_hit_test->mode & TW_HIT_TEST_MODE_IMAGE_DATA) &&
@@ -122,19 +134,27 @@ void PopulateEwkHitTestData(const blink::WebHitTestResult& web_hit_test, _Ewk_Hi
     blink::WebElement hit_element = web_hit_test.node().toConst<blink::WebElement>();
     ewk_hit_test->imageData.imageBitmap = hit_element.imageContents().getSkBitmap();
     ewk_hit_test->imageData.fileNameExtension = hit_element.imageFilenameExtension().utf8();
+
+    params->imageData.imageBitmap = hit_element.imageContents().getSkBitmap();
+    params->imageData.fileNameExtension = hit_element.imageFilenameExtension().utf8();
   }
 }
 
 void PopulateNodeAttributesMapFromHitTest(const blink::WebHitTestResult& web_hit_test,
-                                          NodeAttributesMap* attributes)
+                                          NodeAttributesMap* attributes,
+                                          Hit_Test_Params* params)
 {
-  if (!attributes || !web_hit_test.node().isElementNode())
+  DCHECK(attributes && params);
+
+  if (!web_hit_test.node().isElementNode())
     return;
 
   blink::WebElement hit_element = web_hit_test.node().toConst<blink::WebElement>();
   for (unsigned int i = 0; i < hit_element.attributeCount(); i++) {
     attributes->insert(std::pair<std::string, std::string>(
         hit_element.attributeLocalName(i).utf8(), hit_element.attributeValue(i).utf8()));
+    params->nodeData.attributes.insert(std::pair<std::string, std::string>(
+        hit_element.attributeLocalName(i).utf8(), hit_element.attributeValue(i).utf8()));
   }
 }
 
@@ -302,8 +322,9 @@ void RenderViewObserverEfl::OnDoHitTest(int view_x, int view_y, tizen_webview::H
 {
   _Ewk_Hit_Test hit_test_result;
   NodeAttributesMap attributes;
+  Hit_Test_Params params;
 
-  if (DoHitTest(view_x, view_y, mode, &hit_test_result, &attributes)) {
+  if (DoHitTest(view_x, view_y, mode, &hit_test_result, &attributes, &params)) {
     Send(new EwkViewHostMsg_HitTestReply(routing_id(), hit_test_result, attributes));
   }
 }
@@ -312,16 +333,18 @@ void RenderViewObserverEfl::OnDoHitTestAsync(int view_x, int view_y, tizen_webvi
 {
   _Ewk_Hit_Test hit_test_result;
   NodeAttributesMap attributes;
+  Hit_Test_Params params;
 
-  if (DoHitTest(view_x, view_y, mode, &hit_test_result, &attributes)) {
-    Send(new EwkViewHostMsg_HitTestAsyncReply(routing_id(), hit_test_result, attributes, request_id));
+  if (DoHitTest(view_x, view_y, mode, &hit_test_result, &attributes, &params)) {
+    Send(new EwkViewHostMsg_HitTestAsyncReply(routing_id(), hit_test_result, attributes, params, request_id));
   }
 }
 
-bool RenderViewObserverEfl::DoHitTest(int view_x, int view_y, tizen_webview::Hit_Test_Mode mode, _Ewk_Hit_Test* hit_test_result, NodeAttributesMap* attributes)
+bool RenderViewObserverEfl::DoHitTest(int view_x, int view_y, tizen_webview::Hit_Test_Mode mode, _Ewk_Hit_Test* hit_test_result, NodeAttributesMap* attributes, Hit_Test_Params* params)
 {
   DCHECK(hit_test_result);
   DCHECK(attributes);
+  DCHECK(params);
 
   if (!render_view() || !render_view()->GetWebView())
     return false;
@@ -334,10 +357,11 @@ bool RenderViewObserverEfl::DoHitTest(int view_x, int view_y, tizen_webview::Hit
     return false;
 
   hit_test_result->mode = mode;
+  params->mode = mode;
 
-  PopulateEwkHitTestData(web_hit_test_result, hit_test_result);
+  PopulateEwkHitTestData(web_hit_test_result, hit_test_result, params);
   if (hit_test_result->mode & TW_HIT_TEST_MODE_NODE_DATA)
-    PopulateNodeAttributesMapFromHitTest(web_hit_test_result, attributes);
+    PopulateNodeAttributesMapFromHitTest(web_hit_test_result, attributes, params);
 
   return true;
 }
index f242582..1b7053a 100644 (file)
@@ -37,6 +37,7 @@ class Settings;
 }
 
 class EwkViewMsg_LoadData_Params;
+class Hit_Test_Params;
 
 class RenderViewObserverEfl: public content::RenderViewObserver {
  public:
@@ -72,7 +73,7 @@ class RenderViewObserverEfl: public content::RenderViewObserver {
   void OnGetSelectionStyle();
   void OnDoHitTest(int x, int y, tizen_webview::Hit_Test_Mode mode);
   void OnDoHitTestAsync(int view_x, int view_y, tizen_webview::Hit_Test_Mode mode, int64_t request_id);
-  bool DoHitTest(int view_x, int view_y, tizen_webview::Hit_Test_Mode mode, _Ewk_Hit_Test* hit_test_result, NodeAttributesMap* attributes);
+  bool DoHitTest(int view_x, int view_y, tizen_webview::Hit_Test_Mode mode, _Ewk_Hit_Test* hit_test_result, NodeAttributesMap* attributes, Hit_Test_Params* params);
   void OnPrintToPdf(int width, int height, const base::FilePath& filename);
   void OnGetMHTMLData(int callback_id);
   void OnSetDrawsTransparentBackground(bool enabled);
index 1d0b396..e5a5fa3 100644 (file)
@@ -23,6 +23,10 @@ Hit_Test::Hit_Test(const Hit_Test_Impl& impl_)
     : impl (new _Ewk_Hit_Test(impl_)) {
 }
 
+Hit_Test::Hit_Test(const Hit_Test_Params& params)
+    : impl (new _Ewk_Hit_Test(params)) {
+}
+
 Hit_Test::~Hit_Test() {
   delete impl;
 }
index 7bdb5d9..cd07418 100644 (file)
@@ -9,6 +9,8 @@
 #include <eina_hash.h>
 #include <cstddef>   // Provides size_t
 
+#include "common/hit_test_params.h"
+
 struct _Ewk_Hit_Test;
 class EWebView;
 
@@ -57,6 +59,7 @@ class Hit_Test {
  public:
   Hit_Test();
   Hit_Test(const Hit_Test& other);
+  Hit_Test(const Hit_Test_Params& params);
   ~Hit_Test();
   Hit_Test& operator=(const Hit_Test& other);