[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 5a50360ec13c6e1d85c026661bab9ebd50b50da0..2a9fcfc3ddcbc121da6318c2b974cd68b7bdbae0 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 7fe76c35fd74f27e9d70edd48e0d0584035cce7a..219a7e05d6b2d6d688dd233cbbaa2bbc0d5e145a 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 ca3ed44986a268ba3307591016f4c1f9006a7a68..b2ed7f299f1b0e81c2eeb79fa4edb308f0b120be 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 1d0d71deb1acade58e4d34a4f0fe2d18dcdee765..5f72ea08eeeaffdf0c287f83f2533deee4190b80 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 cb440cc0b5a97c1f3ebcc1d7d284162e1f36c881..c9ad53b7eaefc7ac292c16b76ecea2087160ab64 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 11c7b61b89656e54973fc35c86c6e8f94008fc40..1e577763b2ca8e8c07ddff6c87cfcabb75fc18fe 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 62ddad12409e307214994e757bf04c1335d62727..4f2d63d83083820d46d2dfba1500763ebf9f03cc 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 244f45d3b3690b2cec3c298b93987b3e6f8c996c..a283704c53421feb8c03b310443a639315540879 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 5bcf27a4d0c6b5268f16cb1cba70ca6fbdeabcd4..81b72b098e9d7697f3b6f0907f9a4fca2646bb14 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 35eab4c08b495b5293073d5eca733f7f91add795..99f1772d80b450250c66e2aeeb07882c972c6037 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)) {