[M108 Migration][VD] Implement mixed contents EWK interfaces 80/289680/5
authorjingjieli <jingjie.li@samsung.com>
Mon, 13 Mar 2023 09:13:31 +0000 (17:13 +0800)
committerBot Blink <blinkbot@samsung.com>
Mon, 20 Mar 2023 02:57:39 +0000 (02:57 +0000)
1. When the page was loaded over https, but attemped to connect to
   the insecure http resource. The callback will be invoked to ask
   browser to confirm it.
2. Add new EWK interfaces:
   Send "did,block,insecure,content" to notify browser.
   ewk_settings_mixed_contents_reply_set to set "allow/deny" to blink
3. Implement ewk_settings_default_mixed_contents_policy_set

Refrences:
https://review.tizen.org/gerrit/#/c/279551/
https://review.tizen.org/gerrit/#/c/289527/
https://review.tizen.org/gerrit/#/c/289413/

Change-Id: Ic512e076c71a9909ac91bb67add2a3606d0c9d8a
Signed-off-by: jingjieli <jingjie.li@samsung.com>
15 files changed:
content/browser/web_contents/web_contents_impl.cc
content/browser/web_contents/web_contents_impl.h [changed mode: 0755->0644]
content/public/browser/web_contents.h [changed mode: 0755->0644]
content/public/browser/web_contents_user_data.h
tizen_src/ewk/efl_integration/BUILD.gn [changed mode: 0755->0644]
tizen_src/ewk/efl_integration/browser/mixed_content_observer.cc [new file with mode: 0644]
tizen_src/ewk/efl_integration/browser/mixed_content_observer.h [new file with mode: 0644]
tizen_src/ewk/efl_integration/common/render_messages_ewk.h
tizen_src/ewk/efl_integration/content_browser_client_efl.cc
tizen_src/ewk/efl_integration/eweb_view.cc
tizen_src/ewk/efl_integration/eweb_view_callbacks.h
tizen_src/ewk/efl_integration/public/ewk_settings.cc
tizen_src/ewk/efl_integration/renderer/content_settings_client_efl.cc
tizen_src/ewk/efl_integration/renderer/content_settings_client_efl.h
tizen_src/ewk/efl_integration/web_contents_delegate_efl.cc

index 5a50360..2a9fcfc 100644 (file)
@@ -373,6 +373,40 @@ void RecordMaxFrameCountUMA(size_t max_frame_count) {
                              max_frame_count);
 }
 
+std::vector<RenderFrameHost*> GetAllFramesImpl(FrameTree& frame_tree,
+                                               bool include_pending) {
+  std::vector<RenderFrameHost*> frame_hosts;
+  for (FrameTreeNode* node : frame_tree.Nodes()) {
+    frame_hosts.push_back(node->current_frame_host());
+    if (include_pending) {
+      RenderFrameHostImpl* pending_frame_host =
+          node->render_manager()->speculative_frame_host();
+      if (pending_frame_host)
+        frame_hosts.push_back(pending_frame_host);
+    }
+  }
+  return frame_hosts;
+}
+
+int SendToAllFramesImpl(FrameTree& frame_tree,
+                        bool include_pending,
+                        IPC::Message* message) {
+  int number_of_messages = 0;
+  std::vector<RenderFrameHost*> frame_hosts =
+      GetAllFramesImpl(frame_tree, include_pending);
+  for (RenderFrameHost* rfh : frame_hosts) {
+    if (!rfh->IsRenderFrameLive())
+      continue;
+
+    ++number_of_messages;
+    IPC::Message* message_copy = new IPC::Message(*message);
+    message_copy->set_routing_id(rfh->GetRoutingID());
+    rfh->Send(message_copy);
+  }
+  delete message;
+  return number_of_messages;
+}
+
 // Returns the set of all WebContentses that are reachable from |web_contents|
 // by applying some combination of
 // WebContents::GetFirstWebContentsInLiveOriginalOpenerChain() and
@@ -1501,6 +1535,27 @@ void WebContentsImpl::ForEachFrameTree(
   }
 }
 
+std::vector<RenderFrameHost*> WebContentsImpl::GetAllFrames() {
+  return GetAllFramesImpl(primary_frame_tree_, /*include_pending=*/false);
+}
+
+std::vector<RenderFrameHost*> WebContentsImpl::GetAllFramesIncludingPending() {
+  return GetAllFramesImpl(primary_frame_tree_, /*include_pending=*/true);
+}
+
+int WebContentsImpl::SendToAllFrames(IPC::Message* message) {
+  OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::SendToAllFrames");
+  return SendToAllFramesImpl(primary_frame_tree_, /*include_pending=*/false,
+                             message);
+}
+
+int WebContentsImpl::SendToAllFramesIncludingPending(IPC::Message* message) {
+  OPTIONAL_TRACE_EVENT0("content",
+                        "WebContentsImpl::SentToAllFramesIncludingPending");
+  return SendToAllFramesImpl(primary_frame_tree_, /*include_pending=*/true,
+                             message);
+}
+
 std::vector<FrameTree*> WebContentsImpl::GetOutermostFrameTrees() {
   // If the WebContentsImpl is being destroyed, then we should not
   // perform the tree traversal.
old mode 100755 (executable)
new mode 100644 (file)
index 1c2f209..e84c8aa
@@ -1315,6 +1315,12 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
   // WebContentsDelegate.
   void SystemDragEnded(RenderWidgetHost* source_rwh);
 
+  // They are similar to functions GetAllFrames() and SendToAllFrames() in
+  // WebContents interface, but also include pendings frames. See bug:
+  // http://crbug.com/1087806
+  std::vector<RenderFrameHost*> GetAllFramesIncludingPending();
+  int SendToAllFramesIncludingPending(IPC::Message* message);
+
   // These are the content internal equivalents of
   // |WebContents::ForEachRenderFrameHost| whose comment can be referred to
   // for details. Content internals can also access speculative
@@ -1892,6 +1898,9 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
   // trees based on MPArch.
   void ForEachFrameTree(FrameTreeIterationCallback on_frame_tree);
 
+  std::vector<RenderFrameHost*> GetAllFrames();
+  int SendToAllFrames(IPC::Message* message);
+
   // Returns the primary frame tree, followed by any other outermost frame trees
   // in this WebContents. Outermost frame trees include, for example,
   // prerendering frame trees, and do not include, for example, fenced frames or
old mode 100755 (executable)
new mode 100644 (file)
index bbb8bca..de2662a
@@ -425,6 +425,16 @@ class WebContents : public PageNavigator,
   virtual RenderFrameHost* UnsafeFindFrameByFrameTreeNodeId(
       int frame_tree_node_id) = 0;
 
+  // TODO(1208438): Migrate to |ForEachRenderFrameHost|.
+  // Returns a vector of all RenderFrameHosts in the currently active view in
+  // breadth-first traversal order.
+  virtual std::vector<RenderFrameHost*> GetAllFrames() = 0;
+
+  // TODO(1208438): Migrate to |ForEachRenderFrameHost|.
+  // Sends the given IPC to all live frames in this WebContents and returns the
+  // number of sent messages (i.e. the number of processed frames).
+  virtual int SendToAllFrames(IPC::Message* message) = 0;
+
   // Calls |on_frame| for every RenderFrameHost in this WebContents. Note that
   // this includes RenderFrameHosts that are not descended from the primary main
   // frame (e.g. bfcached pages and prerendered pages). The order of traversal
index 7fe76c3..219a7e0 100644 (file)
@@ -47,6 +47,7 @@ namespace content {
 template <typename T>
 class WebContentsUserData : public base::SupportsUserData::Data {
  public:
+  WebContentsUserData() {}
   explicit WebContentsUserData(WebContents& web_contents)
       : web_contents_(&web_contents) {}
 
old mode 100755 (executable)
new mode 100644 (file)
index 06f3a8f..b71db9f
@@ -665,6 +665,8 @@ shared_library("chromium-ewk") {
 
   if (tizen_product_tv) {
     sources += [
+      "browser/mixed_content_observer.cc",
+      "browser/mixed_content_observer.h",
       "common/application_type.cc",
       "common/application_type.h",
       "wrt/hbbtv_dynamicplugin.cc",
diff --git a/tizen_src/ewk/efl_integration/browser/mixed_content_observer.cc b/tizen_src/ewk/efl_integration/browser/mixed_content_observer.cc
new file mode 100644 (file)
index 0000000..df75229
--- /dev/null
@@ -0,0 +1,48 @@
+// Copyright (c) 2019 Samsung Electronics. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "mixed_content_observer.h"
+
+#include "base/logging.h"
+#include "common/render_messages_ewk.h"
+#include "common/web_contents_utils.h"
+#include "eweb_view.h"
+#include "ipc/ipc_message.h"
+
+using web_contents_utils::WebViewFromWebContents;
+
+MixedContentObserver::MixedContentObserver(content::WebContents* web_contents)
+    : content::WebContentsObserver(web_contents) {}
+
+bool MixedContentObserver::OnMessageReceived(
+    const IPC::Message& message,
+    content::RenderFrameHost* render_frame_host) {
+  bool handled = true;
+  IPC_BEGIN_MESSAGE_MAP(MixedContentObserver, message)
+  IPC_MESSAGE_HANDLER(EwkHostMsg_DidBlockInsecureContent,
+                      OnDidBlockInsecureContent)
+  IPC_MESSAGE_UNHANDLED(handled = false)
+  IPC_END_MESSAGE_MAP()
+
+  return handled;
+}
+
+void MixedContentObserver::OnDidBlockInsecureContent() {
+  EWebView* web_view = WebViewFromWebContents(web_contents());
+  if (web_view) {
+    LOG(INFO) << "OnDidBlockInsecureContent callback";
+    web_view->SmartCallback<EWebViewCallbacks::DidBlockInsecureContent>()
+        .call();
+  }
+}
+
+bool MixedContentObserver::MixedContentReply(bool allow) {
+  if (allow) {
+    web_contents()->SendToAllFrames(
+        new EwkMsg_SetAllowInsecureContent(MSG_ROUTING_NONE, true));
+  }
+  return true;
+}
+
+WEB_CONTENTS_USER_DATA_KEY_IMPL(MixedContentObserver);
\ No newline at end of file
diff --git a/tizen_src/ewk/efl_integration/browser/mixed_content_observer.h b/tizen_src/ewk/efl_integration/browser/mixed_content_observer.h
new file mode 100644 (file)
index 0000000..fcb1a4f
--- /dev/null
@@ -0,0 +1,38 @@
+// Copyright 2019 Samsung Electronics. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef TIZEN_SRC_EWK_EFL_INTEGRATION_MIXED_CONTENT_OBSERVER_H
+#define TIZEN_SRC_EWK_EFL_INTEGRATION_MIXED_CONTENT_OBSERVER_H
+
+#include "content/public/browser/web_contents_observer.h"
+#include "content/public/browser/web_contents_user_data.h"
+
+namespace content {
+class WebContents;
+class RenderFrameHost;
+}  // namespace content
+
+class MixedContentObserver
+    : public content::WebContentsUserData<MixedContentObserver>,
+      public content::WebContentsObserver {
+ public:
+  ~MixedContentObserver() override {}
+  bool MixedContentReply(bool allow);
+
+  // content::WebContentsObserver implementation.
+  bool OnMessageReceived(const IPC::Message& message,
+                         content::RenderFrameHost* render_frame_host) override;
+
+ private:
+  explicit MixedContentObserver(content::WebContents* web_contents);
+  friend class content::WebContentsUserData<MixedContentObserver>;
+
+  void OnDidBlockInsecureContent();
+
+  // DISALLOW_COPY_AND_ASSIGN(MixedContentObserver);
+
+  WEB_CONTENTS_USER_DATA_KEY_DECL();
+};
+
+#endif  // TIZEN_SRC_EWK_EFL_INTEGRATION_MIXED_CONTENT_OBSERVER_H
\ No newline at end of file
index ca3ed44..b2ed7f2 100644 (file)
@@ -262,4 +262,10 @@ IPC_MESSAGE_CONTROL1(HbbtvMsg_RegisterURLSchemesAsCORSEnabled,
                      std::string /* scheme */)
 
 IPC_MESSAGE_CONTROL1(EwkViewMsg_SetTimeOffset, double /* time offset */)
+// Sent when the renderer was prevented from displaying insecure content in
+// a secure page by a security policy.  The page may appear incomplete.
+IPC_MESSAGE_ROUTED0(EwkHostMsg_DidBlockInsecureContent)
+
+// Sent in response to FrameHostMsg_DidBlockDisplayingInsecureContent.
+IPC_MESSAGE_ROUTED1(EwkMsg_SetAllowInsecureContent, bool /* allowed */)
 #endif
index 1d0d71d..5f72ea0 100644 (file)
@@ -442,7 +442,9 @@ void ContentBrowserClientEfl::OverrideWebkitPrefs(
   // because some content providers such as YouTube use plain http requests
   // to retrieve media data chunks while running in a https page. This pref
   // should be disabled once all the content providers are no longer doing that.
+#if !BUILDFLAG(IS_TIZEN_TV)
   prefs->allow_running_insecure_content = true;
+#endif
 }
 
 void ContentBrowserClientEfl::RenderProcessWillLaunch(
index cb440cc..c9ad53b 100644 (file)
 #include "common/application_type.h"
 #include "devtools_port_manager.h"
 #include "public/ewk_media_downloadable_font_info.h"
+#include "browser/mixed_content_observer.h"
 #endif // OS_TIZEN_TV_PRODUCT
 
 #if defined(TIZEN_PEPPER_EXTENSIONS)
@@ -3330,3 +3331,11 @@ bool EWebView::GetAtkStatus() {
 }
 /* LCOV_EXCL_STOP */
 #endif
+
+#if BUILDFLAG(IS_TIZEN_TV)
+bool EWebView::SetMixedContents(bool allow) {
+  MixedContentObserver* mixed_content_observer =
+      MixedContentObserver::FromWebContents(web_contents_.get());
+  return mixed_content_observer->MixedContentReply(allow);
+}
+#endif
index 11c7b61..1e57776 100644 (file)
@@ -156,6 +156,7 @@ enum CallbackType {
   HoverOutLink,
   LoginFormSubmitted,
   LoginFields,
+  DidBlockInsecureContent,
 #endif
   URIChanged,
   DidNotAllowScript,
@@ -332,6 +333,9 @@ DECLARE_EWK_VIEW_CALLBACK(LoginFormSubmitted,
 DECLARE_EWK_VIEW_CALLBACK(LoginFields,
                           "login,field,identified",
                           _Ewk_Form_Info*);
+DECLARE_EWK_VIEW_CALLBACK(DidBlockInsecureContent,
+                          "did,block,insecure,content",
+                          void);
 #endif
 
 DECLARE_EWK_VIEW_CALLBACK(ContentsSizeChanged, "contents,size,changed", void);
index 62ddad1..4f2d63d 100644 (file)
@@ -690,7 +690,13 @@ Eina_Bool ewk_settings_scan_malware_enabled_get(const Ewk_Settings* settings)
 
 void ewk_settings_default_mixed_contents_policy_set(Ewk_Settings* settings, Eina_Bool enable)
 {
+#if BUILDFLAG(IS_TIZEN_TV)
+  EINA_SAFETY_ON_NULL_RETURN(settings);
+  settings->getPreferences().allow_running_insecure_content = enable;
+  ewkUpdateWebkitPreferences(settings->getEvasObject());
+#else
   LOG_EWK_API_MOCKUP();
+#endif
 }
 
 void ewk_settings_disable_webgl_set(Ewk_Settings* settings, Eina_Bool disable)
@@ -806,7 +812,16 @@ void ewk_settings_disclose_set_cookie_headers_enabled(Ewk_Settings* settings, Ei
 
 Eina_Bool ewk_settings_mixed_contents_set(const Ewk_Settings* settings, Eina_Bool allow)
 {
+#if BUILDFLAG(IS_TIZEN_TV)
+  EINA_SAFETY_ON_NULL_RETURN_VAL(settings, EINA_FALSE);
+  LOG(INFO)<<"Set mixed contents: " << (bool)allow;
+  EWK_VIEW_IMPL_GET_OR_RETURN(
+    const_cast<Ewk_Settings*>(settings)->getEvasObject(), webview, EINA_FALSE);
+  return webview->SetMixedContents(allow);
+#else
+  LOG_EWK_API_MOCKUP("Only for Tizen TV");
   return EINA_FALSE;
+#endif
 }
 
 Eina_Bool ewk_settings_do_not_track_set(Ewk_Settings* settings, Eina_Bool enabled)
index 244f45d..a283704 100644 (file)
@@ -8,11 +8,28 @@
 #include "content/public/renderer/render_frame.h"
 #include "third_party/blink/public/web/web_local_frame.h"
 
+#if BUILDFLAG(IS_TIZEN_TV)
+#include "common/application_type.h"
+#endif
+
 namespace content {
 
 ContentSettingsClientEfl::ContentSettingsClientEfl(RenderFrame* render_frame)
+#if !BUILDFLAG(IS_TIZEN_TV)
     : RenderFrameObserver(render_frame) {
+#else
+    : RenderFrameObserver(render_frame),
+      RenderFrameObserverTracker<ContentSettingsClientEfl>(render_frame),
+      mixed_content_state_(false),
+      allow_insecure_content_(false) {
+#endif
   render_frame->GetWebFrame()->SetContentSettingsClient(this);
+#if BUILDFLAG(IS_TIZEN_TV)
+  // get allow_insecure_content_ from parent frame
+  parent_client_ = GetParentClient(render_frame);
+  GetAllowInsecureContent(parent_client_);
+  GetMixedContentState(parent_client_);
+#endif
 }
 
 ContentSettingsClientEfl::~ContentSettingsClientEfl() {}
@@ -25,4 +42,78 @@ void ContentSettingsClientEfl::OnDestruct() {
   delete this;
 }
 
+#if BUILDFLAG(IS_TIZEN_TV)
+bool ContentSettingsClientEfl::OnMessageReceived(const IPC::Message& message) {
+  bool handled = true;
+  IPC_BEGIN_MESSAGE_MAP(ContentSettingsClientEfl, message)
+  IPC_MESSAGE_HANDLER(EwkMsg_SetAllowInsecureContent, OnSetAllowInsecureContent)
+  IPC_MESSAGE_UNHANDLED(handled = false)
+  IPC_END_MESSAGE_MAP()
+  return handled;
+}
+
+bool ContentSettingsClientEfl::AllowInsecureContent(bool allowed_per_settings) {
+  if (allowed_per_settings)
+    return true;
+
+  if (GetMixedContentState(parent_client_))
+    return allow_insecure_content_;
+  Send(new EwkHostMsg_DidBlockInsecureContent(routing_id()));
+  SetMixedContentState(parent_client_, true);
+  return false;
+}
+
+bool ContentSettingsClientEfl::AllowRunningInsecureContent(
+    bool allowed_per_settings,
+    const blink::WebURL& resource_url) {
+  if (IsWebBrowser()) {
+    // For floating video window feature
+    std::string str_url = resource_url.GetString().Utf8().data();
+    if (!str_url.compare(0, 16, "http://127.0.0.1") ||
+        !str_url.compare(0, 16, "http://localhost"))
+      return true;
+  }
+  return AllowInsecureContent(allowed_per_settings);
+}
+
+inline ContentSettingsClientEfl* ContentSettingsClientEfl::GetParentClient(
+    RenderFrame* render_frame) {
+  RenderFrame* main_frame = NULL;
+  ContentSettingsClientEfl* parent_client = NULL;
+  if (render_frame)
+    main_frame = render_frame->GetMainRenderFrame();
+  if (main_frame)
+    parent_client = ContentSettingsClientEfl::Get(main_frame);
+
+  return parent_client;
+}
+
+void ContentSettingsClientEfl::OnSetAllowInsecureContent(bool allow) {
+  allow_insecure_content_ = allow;
+}
+
+inline bool ContentSettingsClientEfl::GetAllowInsecureContent(
+    const ContentSettingsClientEfl* client) {
+  if (client)
+    allow_insecure_content_ = client->allow_insecure_content_;
+
+  return allow_insecure_content_;
+}
+
+void ContentSettingsClientEfl::SetMixedContentState(
+    ContentSettingsClientEfl* client,
+    bool state) {
+  if (client)
+    client->mixed_content_state_ = state;
+  mixed_content_state_ = state;
+}
+
+inline bool ContentSettingsClientEfl::GetMixedContentState(
+    const ContentSettingsClientEfl* client) {
+  if (client)
+    mixed_content_state_ = client->mixed_content_state_;
+
+  return mixed_content_state_;
+}
+#endif
 }  // namespace content
index 5bcf27a..81b72b0 100644 (file)
@@ -8,10 +8,18 @@
 #include "content/public/renderer/render_frame_observer.h"
 #include "third_party/blink/public/platform/web_content_settings_client.h"
 
+#if BUILDFLAG(IS_TIZEN_TV)
+#include "content/public/renderer/render_frame_observer_tracker.h"
+#endif
+
 namespace content {
 
-class ContentSettingsClientEfl : public RenderFrameObserver,
-                                 public blink::WebContentSettingsClient {
+class ContentSettingsClientEfl
+    : public RenderFrameObserver,
+#if BUILDFLAG(IS_TIZEN_TV)
+      public RenderFrameObserverTracker<ContentSettingsClientEfl>,
+#endif
+      public blink::WebContentSettingsClient {
  public:
   explicit ContentSettingsClientEfl(RenderFrame* render_view);
   ~ContentSettingsClientEfl() override;
@@ -24,6 +32,27 @@ class ContentSettingsClientEfl : public RenderFrameObserver,
 
   // blink::WebContentSettingsClient implementation.
   void DidNotAllowScript() override;
+
+#if BUILDFLAG(IS_TIZEN_TV)
+  // blink::WebContentSettingsClient implementation.
+  bool AllowRunningInsecureContent(bool allowed_per_settings,
+                                   const blink::WebURL& url) override;
+  bool OnMessageReceived(const IPC::Message& message) override;
+#endif
+ private:
+#if BUILDFLAG(IS_TIZEN_TV)
+  bool AllowInsecureContent(bool allowed_per_settings);
+  void OnSetAllowInsecureContent(bool allow);
+  ContentSettingsClientEfl* GetParentClient(RenderFrame* render_frame);
+  bool GetAllowInsecureContent(const ContentSettingsClientEfl* client);
+  void SetMixedContentState(ContentSettingsClientEfl* client, bool state);
+  bool GetMixedContentState(const ContentSettingsClientEfl* client);
+
+  // Insecure content may be permitted for the duration of this render view.
+  ContentSettingsClientEfl* parent_client_;
+  bool mixed_content_state_;
+  bool allow_insecure_content_;
+#endif
 };
 
 }  // namespace content
index 35eab4c..99f1772 100644 (file)
@@ -77,7 +77,9 @@ using autofill::AutofillClientEfl;
 using autofill::ContentAutofillDriverFactory;
 using password_manager::PasswordManagerClientEfl;
 #endif
-
+#if BUILDFLAG(IS_TIZEN_TV)
+#include "browser/mixed_content_observer.h"
+#endif
 using std::u16string;
 using namespace ui;
 
@@ -129,6 +131,9 @@ WebContentsDelegateEfl::WebContentsDelegateEfl(EWebView* view)
     : web_view_(view),
       web_contents_(view->web_contents()),
       contents_observer_(std::make_unique<WebContentsObserverEfl>(view, this)) {
+#if BUILDFLAG(IS_TIZEN_TV)
+  MixedContentObserver::CreateForWebContents(&web_contents_);
+#endif
 #if defined(TIZEN_AUTOFILL)
   if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
           autofill::switches::kDisableAutofill)) {