[M108 Migration] Bringup Link Effect feature 75/287975/7
authorBakka Uday Kiran <b.kiran@samsung.com>
Wed, 8 Feb 2023 10:31:31 +0000 (16:01 +0530)
committerDae-Hyun Ko <dhyuna.ko@samsung.com>
Fri, 10 Feb 2023 23:52:48 +0000 (23:52 +0000)
Link effect feature produces sound effect when user taps
on elements. The functionality is enabled on few elements
that satisfy certain contraints. This check is done at
blink side on GestureTap event and notifies
RenderFrameObserver to play the sound effect using tizen
haptic feedback library on mobile.

Reference: https://review.tizen.org/gerrit/c/279964

Change-Id: I349a479817405b84fc4c2552b208a304a535ad10
Signed-off-by: Bakka Uday Kiran <b.kiran@samsung.com>
24 files changed:
content/public/renderer/render_frame_observer.h
content/renderer/render_frame_impl.cc
content/renderer/render_frame_impl.h
third_party/blink/public/common/web_preferences/web_preferences.h
third_party/blink/public/common/web_preferences/web_preferences_mojom_traits.h
third_party/blink/public/mojom/webpreferences/web_preferences.mojom
third_party/blink/public/web/web_local_frame_client.h
third_party/blink/public/web/web_settings.h
third_party/blink/renderer/core/exported/web_settings_impl.cc
third_party/blink/renderer/core/exported/web_settings_impl.h
third_party/blink/renderer/core/exported/web_view_impl.cc
third_party/blink/renderer/core/frame/settings.json5
third_party/blink/renderer/core/frame/web_frame_widget_impl.cc
third_party/blink/renderer/core/layout/hit_test_result.cc
third_party/blink/renderer/core/layout/hit_test_result.h
tizen_src/ewk/efl_integration/browser/web_view_browser_message_filter.cc
tizen_src/ewk/efl_integration/common/render_messages_ewk.h
tizen_src/ewk/efl_integration/common/web_preferences_efl.h
tizen_src/ewk/efl_integration/private/ewk_settings_private.h
tizen_src/ewk/efl_integration/public/ewk_settings.cc
tizen_src/ewk/efl_integration/renderer/render_frame_observer_efl.cc
tizen_src/ewk/efl_integration/renderer/render_frame_observer_efl.h
tizen_src/ewk/efl_integration/web_contents_observer_efl.cc
tizen_src/ewk/efl_integration/web_contents_observer_efl.h

index 0af40eb..98f37cd 100644 (file)
@@ -125,6 +125,9 @@ class CONTENT_EXPORT RenderFrameObserver : public IPC::Listener,
   // being created occurs).
   virtual void DidCreateNewDocument() {}
   virtual void DidCreateDocumentElement() {}
+#if BUILDFLAG(IS_EFL)
+  virtual void PlayLinkEffect() {}
+#endif
   // TODO(dgozman): replace next two methods with DidFinishNavigation.
   // DidCommitProvisionalLoad is only called for new-document navigations.
   // Use DidFinishSameDocumentNavigation for same-document navigations.
index e70d20b..576cdfa 100644 (file)
@@ -3893,6 +3893,13 @@ void RenderFrameImpl::DidDispatchDOMContentLoadedEvent() {
   UpdateEncoding(frame_, frame_->View()->PageEncoding().Utf8());
 }
 
+#if BUILDFLAG(IS_EFL)
+void RenderFrameImpl::PlayLinkEffect() {
+  for (auto& observer : observers_)
+    observer.PlayLinkEffect();
+}
+#endif
+
 void RenderFrameImpl::RunScriptsAtDocumentReady() {
   DCHECK(initialized_);
   GetContentClient()->renderer()->RunScriptsAtDocumentEnd(this);
index 0e1296d..762a6f2 100644 (file)
@@ -540,6 +540,9 @@ class CONTENT_EXPORT RenderFrameImpl
       blink::WebDocumentLoader* document_loader) override;
   void DidClearWindowObject() override;
   void DidCreateDocumentElement() override;
+#if BUILDFLAG(IS_EFL)
+  void PlayLinkEffect() override;
+#endif
   void RunScriptsAtDocumentElementAvailable() override;
   void DidReceiveTitle(const blink::WebString& title) override;
   void DidDispatchDOMContentLoadedEvent() override;
index 651f9e7..c141ba7 100644 (file)
@@ -208,6 +208,7 @@ struct BLINK_COMMON_EXPORT WebPreferences {
 
 #if BUILDFLAG(IS_EFL)
   float font_scale_factor;
+  bool link_effect_enabled = false;
 #endif
 
   bool double_tap_to_zoom_enabled;
index 2b741fd..dafe321 100644 (file)
@@ -525,6 +525,12 @@ struct BLINK_COMMON_EXPORT StructTraits<blink::mojom::WebPreferencesDataView,
     return r.text_autosizing_enabled;
   }
 
+#if BUILDFLAG(IS_EFL)
+  static bool link_effect_enabled(const blink::web_pref::WebPreferences& r) {
+    return r.link_effect_enabled;
+  }
+#endif
+
   static const GURL& web_app_scope(const ::blink::web_pref::WebPreferences& r) {
     return r.web_app_scope;
   }
index a7a39da..14fa99b 100644 (file)
@@ -261,6 +261,9 @@ struct WebPreferences {
 
   bool text_autosizing_enabled;
 
+  [EnableIf=is_efl]
+  bool link_effect_enabled;
+
   // Representation of the Web App Manifest scope if any.
   url.mojom.Url web_app_scope;
 
index 149ca59..415589e 100644 (file)
@@ -377,6 +377,10 @@ class BLINK_EXPORT WebLocalFrameClient {
   // This method may not invalidate the frame, nor execute JavaScript code.
   virtual void DidCreateDocumentElement() {}
 
+#if BUILDFLAG(IS_EFL)
+  virtual void PlayLinkEffect() {}
+#endif
+
   // Like |didCreateDocumentElement|, except this method may run JavaScript
   // code (and possibly invalidate the frame).
   virtual void RunScriptsAtDocumentElementAvailable() {}
index fe65679..1513d89 100644 (file)
@@ -281,6 +281,11 @@ class WebSettings {
   virtual bool TizenCompatibilityModeEnabled() const = 0;
 #endif
 
+#if BUILDFLAG(IS_EFL)
+  virtual void SetLinkEffectEnabled(bool) = 0;
+  virtual bool LinkEffectEnabled() const = 0;
+#endif
+
  protected:
   ~WebSettings() = default;
 };
index 3e280f5..d9c8252 100644 (file)
@@ -778,12 +778,20 @@ void WebSettingsImpl::SetWebXRImmersiveArAllowed(
 }
 
 #if BUILDFLAG(IS_EFL)
+void WebSettingsImpl::SetLinkEffectEnabled(bool link_effect_enabled) {
+  settings_->SetLinkEffectEnabled(link_effect_enabled);
+}
+
 void WebSettingsImpl::SetTizenVersion(unsigned major,
                                       unsigned minor,
                                       unsigned release) {
   settings_->SetTizenVersion(major, minor, release);
 }
 
+bool WebSettingsImpl::LinkEffectEnabled() const {
+  return settings_->GetLinkEffectEnabled();
+}
+
 bool WebSettingsImpl::TizenCompatibilityModeEnabled() const {
   return settings_->TizenCompatibilityModeEnabled();
 }
index 25e4c72..f5dd42e 100644 (file)
@@ -227,6 +227,8 @@ class CORE_EXPORT WebSettingsImpl final : public WebSettings {
 
 #if BUILDFLAG(IS_EFL)
   void SetTizenVersion(unsigned, unsigned, unsigned) override;
+  void SetLinkEffectEnabled(bool) override;
+  bool LinkEffectEnabled() const override;
   bool TizenCompatibilityModeEnabled() const override;
 #endif
 
index 0a7d9aa..a27515a 100644 (file)
 #include "third_party/blink/renderer/core/dom/static_node_list.h"
 #endif
 
+#if BUILDFLAG(IS_TIZEN)
+#include "tizen/system_info.h"
+#endif
+
 // Get rid of WTF's pow define so we can use std::pow.
 #undef pow
 #include <cmath>  // for std::pow
@@ -1665,6 +1669,11 @@ void WebView::ApplyWebPreferences(const web_pref::WebPreferences& prefs,
                             prefs.tizen_version_release);
 #endif
 
+#if BUILDFLAG(IS_TIZEN)
+  if (IsMobileProfile())
+    settings->SetLinkEffectEnabled(true);
+#endif
+
 #if BUILDFLAG(IS_ANDROID)
   settings->SetAllowCustomScrollbarInMainFrame(false);
   settings->SetAccessibilityFontScaleFactor(prefs.font_scale_factor);
index 63616e5..a80dcbe 100644 (file)
     },
 
     {
+      name: "linkEffectEnabled",
+      initial: false,
+    },
+
+    {
       name: "presentationRequiresUserGesture",
       initial: true,
     },
index f7570da..a613475 100644 (file)
@@ -998,6 +998,14 @@ WebInputEventResult WebFrameWidgetImpl::HandleGestureEvent(
 
   switch (scaled_event.GetType()) {
     case WebInputEvent::Type::kGestureTap: {
+#if BUILDFLAG(IS_EFL)
+      if (web_view->SettingsImpl()->LinkEffectEnabled()) {
+        HitTestResult result = targeted_event.GetHitTestResult();
+        result.SetToShadowHostIfInRestrictedShadowRoot();
+        if (result.CanPlayLinkEffect())
+          FocusedWebLocalFrameInWidget()->Client()->PlayLinkEffect();
+      }
+#endif
       {
         ContextMenuAllowedScope scope;
         event_result =
index 72f6ece..4c59df3 100644 (file)
@@ -431,6 +431,47 @@ KURL HitTestResult::AbsoluteImageURL(const Node* node) {
       StripLeadingAndTrailingHTMLSpaces(url_string));
 }
 
+#if BUILDFLAG(IS_EFL)
+bool HitTestResult::CanPlayLinkEffect() const {
+  for (Node* node = inner_node_.Get(); node; node = node->parentNode()) {
+    auto* html_element = DynamicTo<HTMLElement>(node);
+
+    if (IsRichlyEditable(*node))
+      return false;
+
+    if (node->IsElementNode() && html_element &&
+        html_element->IsFormControlElement() &&
+        html_element->IsDisabledFormControl()) {
+      return false;
+    }
+
+    if (node->GetLayoutObject() && node->GetLayoutObject()->IsDocumentElement())
+      return false;
+
+    if (node->HasTagName(html_names::kBodyTag))
+      continue;
+
+    if ((node->HasTagName(html_names::kATag) &&
+         html_element->hasAttribute(html_names::kHrefAttr)) ||
+        (node->HasTagName(html_names::kAreaTag) &&
+         html_element->hasAttribute(html_names::kHrefAttr)) ||
+        (node->HasTagName(html_names::kSummaryTag) &&
+         html_element->SupportsFocus()) ||
+        node->HasTagName(html_names::kButtonTag) ||
+        node->HasTagName(html_names::kInputTag) ||
+        node->HasTagName(html_names::kSelectTag) ||
+        node->HasEventListeners(event_type_names::kClick) ||
+        node->HasEventListeners(event_type_names::kMousedown) ||
+        node->HasEventListeners(event_type_names::kMouseup) ||
+        node->HasEventListeners(event_type_names::kMouseover)) {
+      return true;
+    }
+  }
+
+  return false;
+}
+#endif
+
 KURL HitTestResult::AbsoluteImageURL() const {
   return AbsoluteImageURL(InnerNodeOrImageMapImage());
 }
index 37e272f..31b2c4e 100644 (file)
@@ -192,6 +192,9 @@ class CORE_EXPORT HitTestResult {
                                                         const cc::Region&);
 
   void Append(const HitTestResult&);
+#if BUILDFLAG(IS_EFL)
+  bool CanPlayLinkEffect() const;
+#endif
 
   bool HasListBasedResult() const {
     return GetHitTestRequest().ListBased() && InnerNode();
index 11c52d6..f9d2d61 100644 (file)
@@ -5,7 +5,6 @@
 #include "browser/web_view_browser_message_filter.h"
 
 #include "base/cxx17_backports.h"
-#include "browser/sound_effect.h"
 #include "common/hit_test_params.h"
 #include "common/render_messages_ewk.h"
 #include "common/web_contents_utils.h"
@@ -86,8 +85,6 @@ class WebViewBrowserMessageFilterPrivate
     if (!web_view_)
       return;
 
-    if (is_link && web_view_->GetSettings()->getLinkEffectEnabled())
-      sound_effect::playLinkEffect();
     web_view_->HandleTapGestureForSelection(is_content_editable);
   }
 
index e04c7f0..ea7ab84 100644 (file)
@@ -38,6 +38,7 @@ IPC_STRUCT_TRAITS_END()
 IPC_STRUCT_TRAITS_BEGIN(WebPreferencesEfl)
   IPC_STRUCT_TRAITS_MEMBER(shrinks_viewport_content_to_fit)
   IPC_STRUCT_TRAITS_MEMBER(javascript_can_open_windows_automatically_ewk)
+  IPC_STRUCT_TRAITS_MEMBER(link_effect_enabled)
 IPC_STRUCT_TRAITS_END()
 
 IPC_STRUCT_TRAITS_BEGIN(Hit_Test_Params::Node_Data)
@@ -203,6 +204,8 @@ IPC_MESSAGE_ROUTED2(EwkHostMsg_HandleTapGestureWithContext,
                     bool /* is_link */,
                     bool /* is_editable_content */)
 
+IPC_MESSAGE_ROUTED0(EwkHostMsg_PlayLinkEffect)
+
 IPC_MESSAGE_ROUTED2(EwkHostMsg_PlainTextGetContents,
                     std::string, /* contentText */
                     int /* callback id */)
index 8c87884..f9c5bda 100644 (file)
@@ -13,6 +13,7 @@ struct WebPreferencesEfl {
   bool shrinks_viewport_content_to_fit =
       IsMobileProfile() || IsWearableProfile() ? true : false;
   bool javascript_can_open_windows_automatically_ewk = true;
+  bool link_effect_enabled = true;
 };
 
 #endif // WEB_PREFERENCES_EFL_H
index 924e79a..863df9a 100644 (file)
@@ -44,8 +44,7 @@ class Ewk_Settings {
          m_zoomEnabled(true),
          m_openPanelEnabled(true),
          m_allowRestrictedURL(true),
-         m_URLBarHide(false),
-         m_linkEffectEnabled(true) {}
+         m_URLBarHide(false) {}
 
    const char* defaultTextEncoding() const {
      return m_preferences.default_encoding.c_str();
@@ -112,8 +111,6 @@ class Ewk_Settings {
     bool getAllowRestrictedURLEnabled() const { return m_allowRestrictedURL; }
     void setURLBarHideEnabled(bool enable) { m_URLBarHide = enable; }
     bool getURLBarHideEnabled() const { return m_URLBarHide; }
-    void setLinkEffectEnabled(bool enable) { m_linkEffectEnabled = enable; }
-    bool getLinkEffectEnabled() const { return m_linkEffectEnabled; }
 
   private:
    WebPreferences m_preferences;
@@ -148,7 +145,6 @@ class Ewk_Settings {
    bool m_openPanelEnabled;
    bool m_allowRestrictedURL;
    bool m_URLBarHide;
-   bool m_linkEffectEnabled;
 };
 
 #endif // ewk_settings_private_h
index f42cdd4..73141a1 100644 (file)
@@ -308,17 +308,18 @@ Eina_Bool ewk_settings_link_magnifier_enabled_get(const Ewk_Settings *settings)
   return webview->GetLinkMagnifierEnabled();
 }
 
-Eina_Bool ewk_settings_link_effect_enabled_set(Ewk_Settings* settings, Eina_Bool linkEffectEnabled)
-{
+Eina_Bool ewk_settings_link_effect_enabled_set(Ewk_Settings* settings,
+                                               Eina_Bool enable) {
   EINA_SAFETY_ON_NULL_RETURN_VAL(settings, false);
-  settings->setLinkEffectEnabled(linkEffectEnabled);
+  settings->getPreferencesEfl().link_effect_enabled = enable;
+  ewkUpdateWebkitPreferences(settings->getEvasObject());
   return true;
 }
 
 Eina_Bool ewk_settings_link_effect_enabled_get(const Ewk_Settings* settings)
 {
   EINA_SAFETY_ON_NULL_RETURN_VAL(settings, false);
-  return settings->getLinkEffectEnabled();
+  return settings->getPreferencesEfl().link_effect_enabled;
 }
 
 Eina_Bool ewk_settings_uses_encoding_detector_set(Ewk_Settings* settings, Eina_Bool use)
index 4c79681..3aa50c5 100644 (file)
@@ -215,6 +215,10 @@ void RenderFrameObserverEfl::DidCreateDocumentElement() {
   Send(new EwkHostMsg_DidCreateDocumentElement(render_frame()->GetRoutingID()));
 }
 
+void RenderFrameObserverEfl::PlayLinkEffect() {
+  Send(new EwkHostMsg_PlayLinkEffect(render_frame()->GetRoutingID()));
+}
+
 void RenderFrameObserverEfl::DidCreateScriptContext(
     v8::Local<v8::Context> context,
     int world_id) {
index d9cb6b9..6d7d84c 100644 (file)
@@ -53,6 +53,7 @@ class RenderFrameObserverEfl : public RenderFrameObserver {
   void WillReleaseScriptContext(v8::Handle<v8::Context> context,
                                 int world_id) override;
   void DidCreateDocumentElement() override;
+  void PlayLinkEffect() override;
 
  private:
   void OnSelectPopupMenuItems(bool canceled,
index bca966f..55f54ec 100644 (file)
@@ -7,6 +7,7 @@
 #include "base/task/bind_post_task.h"
 #include "browser/favicon/favicon_database.h"
 #include "browser/favicon/favicon_downloader.h"
+#include "browser/sound_effect.h"
 #include "browser_context_efl.h"
 #include "common/print_pages_params.h"
 #include "common/render_messages_ewk.h"
@@ -230,6 +231,7 @@ bool WebContentsObserverEfl::OnMessageReceived(
     IPC_MESSAGE_HANDLER(EwkHostMsg_DidNotAllowScript, OnDidNotAllowScript)
     IPC_MESSAGE_HANDLER(EwkHostMsg_DidCreateDocumentElement,
                         OnDidCreateDocumentElement)
+    IPC_MESSAGE_HANDLER(EwkHostMsg_PlayLinkEffect, OnPlayLinkEffect)
     IPC_MESSAGE_HANDLER(EwkHostMsg_DidPrintPagesToPdf,
                         OnPrintedMetafileReceived)
     IPC_MESSAGE_HANDLER(EwkHostMsg_WrtMessage, OnWrtPluginMessage)
@@ -265,6 +267,11 @@ void WebContentsObserverEfl::OnDidCreateDocumentElement() {
     SetContentSecurityPolicy(pending_content_security_policy_->policy, type);
 }
 
+void WebContentsObserverEfl::OnPlayLinkEffect() {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  sound_effect::playLinkEffect();
+}
+
 void WebContentsObserverEfl::OnPrintedMetafileReceived(
     const DidPrintPagesParams& params) {
 #if !defined(EWK_BRINGUP)  // FIXME: m85 bringup
index 6dac0d7..3e54d14 100644 (file)
@@ -76,6 +76,7 @@ class WebContentsObserverEfl : public WebContentsObserver, public IPC::Sender {
   void OnDidChangeScrollOffset(int scroll_x, int scroll_y);
   void OnFormSubmit(const GURL& url);
   void OnDidNotAllowScript();
+  void OnPlayLinkEffect();
   void OnWrtPluginMessage(const Ewk_Wrt_Message_Data& data);
   void OnWrtPluginSyncMessage(const Ewk_Wrt_Message_Data& data,
                               IPC::Message* reply);