[M120 Migration][VD] Support EWK Scroll API for TV WebBrowser
[platform/framework/web/chromium-efl.git] / tizen_src / ewk / efl_integration / eweb_view.cc
index 363fc93..ce6088c 100644 (file)
@@ -8,21 +8,22 @@
 #include <Eina.h>
 #include <Elementary.h>
 
-#include "base/bind.h"
 #include "base/command_line.h"
-#include "base/files/file_path.h"
+#include "base/files/file_util.h"
+#include "base/functional/bind.h"
 #include "base/json/json_string_value_serializer.h"
 #include "base/logging.h"
 #include "base/pickle.h"
+#include "base/strings/escape.h"
 #include "base/strings/utf_string_conversions.h"
+#include "base/task/thread_pool.h"
 #include "browser/javascript_dialog_manager_efl.h"
 #include "browser/javascript_interface/gin_native_bridge_dispatcher_host.h"
 #include "browser/navigation_policy_handler_efl.h"
-#include "browser/quota_permission_context_efl.h"
-#include "browser/selectpicker/popup_menu_item.h"
-#include "browser/selectpicker/popup_menu_item_private.h"
+#include "browser/scoped_allow_wait_for_legacy_web_view_api.h"
+#include "browser/select_picker/select_picker_mobile.h"
+#include "browser/select_picker/select_picker_tv.h"
 #include "browser/web_view_browser_message_filter.h"
-#include "browser/web_view_evas_handler.h"
 #include "browser_context_efl.h"
 #include "common/content_client_efl.h"
 #include "common/render_messages_ewk.h"
 #include "content/public/browser/host_zoom_map.h"
 #include "content/public/browser/navigation_controller.h"
 #include "content/public/browser/navigation_entry.h"
+#include "content/public/browser/navigation_handle.h"
 #include "content/public/common/content_client.h"
 #include "content/public/common/content_switches.h"
+#include "content/public/common/mhtml_generation_params.h"
 #include "content/public/common/user_agent.h"
+#include "net/base/filename_util.h"
 #include "permission_popup_manager.cc"
+#include "private/ewk_app_control_private.h"
 #include "private/ewk_back_forward_list_private.h"
 #include "private/ewk_context_private.h"
 #include "private/ewk_frame_private.h"
 #include "private/ewk_policy_decision_private.h"
 #include "private/ewk_quota_permission_request_private.h"
 #include "private/ewk_settings_private.h"
-#include "private/ewk_text_style_private.h"
 #include "private/webview_delegate_ewk.h"
 #include "public/ewk_hit_test_internal.h"
+#include "services/network/public/cpp/features.h"
 #include "services/network/public/cpp/resource_request_body.h"
+#include "services/network/public/mojom/network_context.mojom.h"
 #include "skia/ext/platform_canvas.h"
 #include "third_party/blink/public/common/page/page_zoom.h"
 #include "third_party/blink/public/platform/web_string.h"
 #include "ui/aura/test/test_focus_client.h"
 #include "ui/aura/test/test_window_parenting_client.h"
 #include "ui/aura/window.h"
+#include "ui/base/clipboard/clipboard_helper_efl.h"
 #include "ui/base/l10n/l10n_util.h"
+#include "ui/compositor/compositor_observer_efl.h"
 #include "ui/display/screen.h"
 #include "ui/events/event_switches.h"
 #include "ui/gfx/geometry/dip_util.h"
 #include "ui/gfx/geometry/vector2d_f.h"
+#include "ui/ozone/platform/efl/efl_event_handler.h"
 #include "ui/platform_window/platform_window_init_properties.h"
 #include "web_contents_delegate_efl.h"
-#include "web_contents_efl_delegate_ewk.h"
+#include "webview_delegate_efl.h"
 
 #include <iostream>
 
+#if defined(TIZEN_ATK_SUPPORT)
+#include "content/browser/accessibility/browser_accessibility_state_impl.h"
+#include "eweb_accessibility.h"
+#include "eweb_accessibility_util.h"
+#endif
+
+#if defined(TIZEN_AUTOFILL_FW)
+#include "browser/autofill/autofill_request_manager.h"
+#include "components/autofill/core/common/autofill_switches.h"
+#endif
+
+#if BUILDFLAG(IS_TIZEN_TV)
+#include "browser/mixed_content_observer.h"
+#include "common/application_type.h"
+#include "devtools_port_manager.h"
+#include "private/ewk_file_chooser_request_private.h"
+#include "public/ewk_media_downloadable_font_info.h"
+#include "public/ewk_media_parental_rating_info.h"
+#include "public/ewk_media_playback_info_product.h"
+#include "public/ewk_media_subtitle_info_product.h"
+#include "public/ewk_user_media_internal.h"
+#include "third_party/blink/public/platform/web_media_player.h"
+#endif
+
+#if defined(TIZEN_PEPPER_EXTENSIONS)
+#include "efl/window_factory.h"
+#include "ewk/efl_integration/ewk_privilege_checker.h"
+#endif  // defined(TIZEN_PEPPER_EXTENSIONS)
+
+#if defined(USE_WAYLAND) && defined(TIZEN_PEPPER_EXTENSIONS)
+#include <Ecore_Wayland.h>
+#endif  // defined(USE_WAYLAND)
+
+#if defined(TIZEN_TBM_SUPPORT)
+#include "ui/compositor/compositor.h"
+#endif
+
 using namespace content;
 using web_contents_utils::WebViewFromWebContents;
 
 namespace {
 
+const int kTitleLengthMax = 80;
+const base::FilePath::CharType kMHTMLFileNameExtension[] =
+    FILE_PATH_LITERAL(".mhtml");
+const base::FilePath::CharType kMHTMLExtension[] = FILE_PATH_LITERAL("mhtml");
+const base::FilePath::CharType kDefaultFileName[] =
+    FILE_PATH_LITERAL("saved_page");
+const char kReplaceChars[] = " ";
+const char kReplaceWith[] = "_";
+
 static const char* kRendererCrashedHTMLMessage =
     "<html><body><h1>Renderer process has crashed!</h1></body></html>";
 
+// "visible,content,changed" is an email-app specific signal which informs
+// that the web view is only partially visible.
+static const char* kVisibleContentChangedSignalName = "visible,content,changed";
+
+// email-app specific signal which informs that custom scrolling is started.
+const char* kCustomScrollBeginSignalName = "custom,scroll,begin";
+
+// email-app specific signal which informs that custom scrolling is finished.
+const char* kCustomScrollEndSignalName = "custom,scroll,end";
+
+const float kDelayShowContextMenuTime = 0.2f;
+
 inline void SetDefaultStringIfNull(const char*& variable,
                                    const char* default_string) {
   if (!variable) {
@@ -100,10 +167,88 @@ void GetEinaRectFromGfxRect(const gfx::Rect& gfx_rect,
   eina_rect->h = gfx_rect.height();
 }
 
+#if BUILDFLAG(IS_TIZEN)
+static Eina_Bool RotateWindowCb(void* data, int type, void* event) {
+  auto wv = static_cast<EWebView*>(data);
+#if defined(TIZEN_TBM_SUPPORT)
+  if (wv->rwhva() && wv->rwhva()->GetCompositor() &&
+      wv->rwhva()->GetCompositor()->use_tbm_surface_for_offscreen_rendering()) {
+    Ecore_Wl2_Event_Window_Rotation* rotateEvent =
+        static_cast<Ecore_Wl2_Event_Window_Rotation*>(event);
+    if (rotateEvent != nullptr) {
+      LOG(INFO) << "For NUI app, new ori " << rotateEvent->angle;
+      wv->SetOrientation(rotateEvent->angle);
+    }
+    return ECORE_CALLBACK_PASS_ON;
+  }
+#endif
+  LOG(INFO) << "New ori "
+            << ecore_evas_rotation_get(
+                   ecore_evas_ecore_evas_get(wv->GetEvas()));
+  wv->SetOrientation(
+      ecore_evas_rotation_get(ecore_evas_ecore_evas_get(wv->GetEvas())));
+  return ECORE_CALLBACK_PASS_ON;
+}
+#endif
+
 static content::WebContents* NullCreateWebContents(void*) {
   return NULL;
 }
 
+base::FilePath GenerateMHTMLFilePath(const GURL& url,
+                                     const std::string& title,
+                                     const std::string& base_path) {
+  base::FilePath file_path(base_path);
+
+  if (base::DirectoryExists(file_path)) {
+    std::string title_part(title.substr(0, kTitleLengthMax));
+    base::ReplaceChars(title_part, kReplaceChars, kReplaceWith, &title_part);
+    base::FilePath file_name =
+        net::GenerateFileName(url, std::string(), std::string(), title_part,
+                              std::string(), kDefaultFileName);
+    DCHECK(!file_name.empty());
+    file_path = file_path.Append(file_name);
+  }
+
+  if (file_path.Extension().empty())
+    file_path = file_path.AddExtension(kMHTMLExtension);
+  else if (!file_path.MatchesExtension(kMHTMLFileNameExtension))
+    file_path = file_path.ReplaceExtension(kMHTMLExtension);
+
+  if (!base::PathExists(file_path))
+    return file_path;
+
+  int uniquifier = base::GetUniquePathNumber(file_path);
+  if (uniquifier > 0) {
+    return file_path.InsertBeforeExtensionASCII(
+        base::StringPrintf(" (%d)", uniquifier));
+  }
+
+  return base::FilePath();
+}
+
+SelectPickerBase* CreateSelectPicker(
+    EWebView* web_view,
+    int selected_index,
+    std::vector<blink::mojom::MenuItemPtr> items,
+    bool is_multiple_selection,
+    const gfx::Rect& bounds) {
+  SelectPickerBase* picker;
+  if (IsTvProfile()) {
+    picker =
+        new SelectPickerTv(web_view, selected_index, is_multiple_selection);
+  } else {
+    picker =
+        new SelectPickerMobile(web_view, selected_index, is_multiple_selection);
+  }
+  // Create two separate Elm_Genlist_Item_Class classes, because EFL cannot swap
+  // item_style at runtime.
+  picker->InitializeItemClass();
+  picker->InitializeGroupClass();
+  picker->Init(std::move(items), bounds);
+  return picker;
+}
+
 }  // namespace
 
 class WebViewAsyncRequestHitTestDataCallback {
@@ -140,7 +285,7 @@ class WebViewAsyncRequestHitTestDataUserCallback
 
   void Run(_Ewk_Hit_Test* hit_test, EWebView* web_view) override {
     DCHECK(callback_);
-    callback_(web_view->evas_object(), GetX(), GetY(), GetMode(), hit_test,
+    callback_(web_view->ewk_view(), GetX(), GetY(), GetMode(), hit_test,
               user_data_);
   }
 
@@ -149,40 +294,69 @@ class WebViewAsyncRequestHitTestDataUserCallback
   void* user_data_;
 };
 
+#if defined(TIZEN_ATK_SUPPORT)
+class EWebAccessibilityObserver : public EWebAccessibility::Observer {
+ public:
+  explicit EWebAccessibilityObserver(EWebView* webview) : webview_(webview) {}
+  virtual ~EWebAccessibilityObserver() {}
+
+  // EWebAccessibility::Observer implementation
+  void OnSpatialNavigationStatusChanged(Eina_Bool enable) override {
+    webview_->UpdateSpatialNavigationStatus(enable);
+  }
+
+  void OnAccessibilityStatusChanged(Eina_Bool enable) override {
+    webview_->UpdateAccessibilityStatus(enable);
+  }
+
+ private:
+  EWebView* webview_;
+};
+#endif
+
 int EWebView::find_request_id_counter_ = 0;
-content::WebContentsEflDelegate::WebContentsCreateCallback
+content::WebViewDelegate::WebContentsCreateCallback
     EWebView::create_new_window_web_contents_cb_ =
         base::BindRepeating(&NullCreateWebContents);
 
-EWebView* EWebView::FromEvasObject(Evas_Object* eo) {
-  return WebViewDelegateEwk::GetInstance().GetWebViewFromEvasObject(eo);
+EWebView* EWebView::FromEwkView(Evas_Object* ewk_view) {
+  return WebViewDelegateEwk::GetInstance().GetEWebViewFromEwkView(ewk_view);
 }
 
-#if !defined(USE_AURA)
-RenderWidgetHostViewEfl* EWebView::rwhv() const {
-  return static_cast<RenderWidgetHostViewEfl*>(
-      web_contents_->GetRenderWidgetHostView());
+void EWebView::VisibleContentChangedCallback(void* user_data,
+                                             Evas_Object* /*object*/,
+                                             void* event_info) {
+  auto view = static_cast<EWebView*>(user_data);
+  if (!view->GetSelectionController()) {
+    return;
+  }
+  auto rect = static_cast<Eina_Rectangle*>(event_info);
+  view->GetSelectionController()->SetCustomVisibleViewRect(
+      gfx::Rect(rect->x, rect->y, rect->w, rect->h));
 }
-#endif
 
-void EWebView::OnViewFocusIn(void* data, Evas*, Evas_Object*, void*) {
-  auto view = static_cast<EWebView*>(data);
-  view->SetFocus(EINA_TRUE);
+void EWebView::OnCustomScrollBeginCallback(void* user_data,
+                                           Evas_Object* /*object*/,
+                                           void* /*event_info*/) {
+  auto* view = static_cast<EWebView*>(user_data);
+  if (auto* selection_controller = view->GetSelectionController())
+    selection_controller->SetControlsTemporarilyHidden(true,true);
 }
 
-void EWebView::OnViewFocusOut(void* data, Evas*, Evas_Object*, void*) {
-  auto view = static_cast<EWebView*>(data);
-  view->SetFocus(EINA_FALSE);
+void EWebView::OnCustomScrollEndCallback(void* user_data,
+                                         Evas_Object* /*object*/,
+                                         void* /*event_info*/) {
+  auto* view = static_cast<EWebView*>(user_data);
+  if (auto* selection_controller = view->GetSelectionController())
+    selection_controller->SetControlsTemporarilyHidden(false,true);
 }
 
-EWebView::EWebView(Ewk_Context* context, Evas_Object* object)
+EWebView::EWebView(Ewk_Context* context, Evas_Object* ewk_view)
     : context_(context),
-      evas_object_(object),
-      native_view_(object),
-      touch_events_enabled_(false),
+      ewk_view_(ewk_view),
+      efl_main_layout_(ewk_view),
       mouse_events_enabled_(false),
       text_zoom_factor_(1.0),
-      formIsNavigating_(false),
       current_find_request_id_(find_request_id_counter_++),
       progress_(0.0),
       hit_test_completion_(base::WaitableEvent::ResetPolicy::AUTOMATIC,
@@ -190,12 +364,28 @@ EWebView::EWebView(Ewk_Context* context, Evas_Object* object)
       page_scale_factor_(1.0),
       x_delta_(0.0),
       y_delta_(0.0),
+#if BUILDFLAG(IS_TIZEN_TV)
+      is_processing_edge_scroll_(false),
+      use_early_rwi_(false),
+      rwi_info_showed_(false),
+#endif
+#if defined(TIZEN_PEPPER_EXTENSIONS)
+      render_frame_id_{0, 0},
+#endif
       is_initialized_(false) {
- if (evas_object_) {
-    evas_object_event_callback_add(evas_object_, EVAS_CALLBACK_FOCUS_IN,
-                                   OnViewFocusIn, this);
-    evas_object_event_callback_add(evas_object_, EVAS_CALLBACK_FOCUS_OUT,
-                                   OnViewFocusOut, this);
+  LOG(INFO) << "EWebView: " << this;
+  if (ewk_view_) {
+    evas_object_smart_callback_add(ewk_view_, kVisibleContentChangedSignalName,
+                                   VisibleContentChangedCallback, this);
+
+    evas_object_smart_callback_add(ewk_view_, kCustomScrollBeginSignalName,
+                                   OnCustomScrollBeginCallback, this);
+    evas_object_smart_callback_add(ewk_view_, kCustomScrollEndSignalName,
+                                   OnCustomScrollEndCallback, this);
+#if BUILDFLAG(IS_TIZEN)
+    window_rotate_handler_ = ecore_event_handler_add(
+      ECORE_WL2_EVENT_WINDOW_ROTATE, RotateWindowCb, this);
+#endif
   }
 }
 
@@ -206,15 +396,24 @@ void EWebView::Initialize() {
 
   InitializeContent();
 
-  evas_event_handler_ = new WebViewEvasEventHandler(this);
-
   scroll_detector_.reset(new ScrollDetector(this));
 
+#if defined(TIZEN_PEPPER_EXTENSIONS)
+  InitializePepperExtensionSystem();
+#endif
   DCHECK(web_contents_->GetRenderViewHost());
   // Settings (content::WebPreferences) will be initalized by
   // RenderViewHostImpl::ComputeWebkitPrefs() based on command line switches.
-  settings_.reset(new Ewk_Settings(evas_object_,
-                                   web_contents_->GetOrCreateWebPreferences()));
+  settings_.reset(
+      new Ewk_Settings(ewk_view_, web_contents_->GetOrCreateWebPreferences()));
+#if defined(TIZEN_ATK_SUPPORT)
+  std::unique_ptr<EWebAccessibilityObserver> observer(
+      new EWebAccessibilityObserver(this));
+  eweb_accessibility_.reset(new EWebAccessibility(
+      ewk_view_, web_contents_.get(), std::move(observer)));
+  lazy_initialize_atk_ = true;
+#endif
+
   base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess();
   if (cmdline->HasSwitch(switches::kTouchEventFeatureDetection)) {
     SetTouchEventsEnabled(
@@ -230,35 +429,45 @@ void EWebView::Initialize() {
       blink::UserAgentOverride::UserAgentOnly(user_agent),
       false /* override_in_new_tabs */);
 
-  popupMenuItems_ = 0;
-  popupPicker_ = 0;
-
-  formNavigation_.count = 1;
-  formNavigation_.position = 0;
-  formNavigation_.prevState = false;
-  formNavigation_.nextState = false;
-
-  // allow this object and its children to get a focus
-  elm_object_tree_focus_allow_set(native_view_, EINA_TRUE);
+  elm_object_tree_focus_allow_set(efl_main_layout_, EINA_TRUE);
   is_initialized_ = true;
+  evas_object_event_callback_add(efl_main_layout_, EVAS_CALLBACK_RESIZE,
+                                 EWebView::NativeViewResize, this);
 
   auto cbce = static_cast<ContentBrowserClientEfl*>(
       content::GetContentClientExport()->browser());
   // Initialize accept languages
   SyncAcceptLanguages(cbce->GetAcceptLangs(nullptr));
-  accept_langs_changed_callback_ =
-      base::BindOnce(&EWebView::SyncAcceptLanguages, base::Unretained(this));
-  cbce->AddAcceptLangsChangedCallback(
-      std::move(accept_langs_changed_callback_));
+  accept_langs_changed_callback_ = base::BindRepeating(
+      &EWebView::SyncAcceptLanguages, base::Unretained(this));
+  cbce->AddAcceptLangsChangedCallback(accept_langs_changed_callback_);
+
+  // If EWebView is created by window.open, RenderView is already created
+  // before initializing WebContents. So we should manually invoke
+  // EWebView::RenderViewReady here.
+  if (web_contents_->GetPrimaryMainFrame() &&
+      web_contents_->GetPrimaryMainFrame()->IsRenderFrameLive()) {
+    RenderViewReady();
+  }
 }
 
 EWebView::~EWebView() {
+  LOG(INFO) << "EWebView: " << this;
+  weak_factory_.InvalidateWeakPtrs();
   auto cbce = static_cast<ContentBrowserClientEfl*>(
       content::GetContentClientExport()->browser());
-#if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
-  cbce->RemoveAcceptLangsChangedCallback(
-      std::move(accept_langs_changed_callback_));
+  cbce->RemoveAcceptLangsChangedCallback(accept_langs_changed_callback_);
+#if defined(TIZEN_PEPPER_EXTENSIONS)
+  UnregisterPepperExtensionDelegate();
+#endif
+
+  evas_object_event_callback_del(efl_main_layout_, EVAS_CALLBACK_RESIZE,
+                                 EWebView::NativeViewResize);
+#if defined(USE_WAYLAND)
+  if (GetSettings()->getClipboardEnabled())
+    ClipboardHelperEfl::GetInstance()->MaybeInvalidateActiveWebview(this);
 #endif
+
   std::map<int64_t, WebViewAsyncRequestHitTestDataCallback*>::iterator
       hit_test_callback_iterator;
   for (hit_test_callback_iterator = hit_test_callback_.begin();
@@ -277,20 +486,25 @@ EWebView::~EWebView() {
     return;
   }
 
-  context_menu_.reset();
-  mhtml_callback_map_.Clear();
-
-  ReleasePopupMenuList();
+#if defined(TIZEN_ATK_SUPPORT)
+  eweb_accessibility_.reset();
+#endif
 
-  if (popupPicker_)
-    popup_picker_del(popupPicker_);
+#if defined(TIZEN_AUTOFILL_FW)
+  if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
+          autofill::switches::kDisableAutofill)) {
+    autofill::AutofillRequestManager::GetInstance()->RemoveRequest(ewk_view());
+  }
+#endif
 
-  formNavigation_.count = 1;
-  formNavigation_.position = 0;
-  formNavigation_.prevState = false;
-  formNavigation_.nextState = false;
+  select_picker_.reset();
+  context_menu_.reset();
+  mhtml_callback_map_.Clear();
+#if BUILDFLAG(IS_TIZEN_TV)
+  is_video_playing_callback_map_.Clear();
+#endif
 
-  //  evas_object_del(evas_object());
+  compositor_observer_.reset();
 
   // Release manually those scoped pointers to
   // make sure they are released in correct order
@@ -301,36 +515,23 @@ EWebView::~EWebView() {
   // because WebContents depends on BrowserContext which
   // is deleted along with EwkContext.
   CHECK(!web_contents_);
-  if (old_context_.get()) {
-    Ewk_Context::Delete(context_.get());
-    context_ = old_context_;
-    old_context_ = nullptr;
-  }
 
   permission_popup_manager_.reset();
 
-  if (context_->GetImpl()->browser_context()->IsOffTheRecord())
-    Ewk_Context::Delete(context_.get());
   gin_native_bridge_dispatcher_host_.reset();
 
-  if (evas_object_) {
-    evas_object_event_callback_del(evas_object_, EVAS_CALLBACK_FOCUS_IN,
-                                   OnViewFocusIn);
-    evas_object_event_callback_del(evas_object_, EVAS_CALLBACK_FOCUS_OUT,
-                                   OnViewFocusOut);
-  }
-}
-
-void EWebView::ReleasePopupMenuList() {
-  if (!popupMenuItems_)
-    return;
-
-  void* dummyItem;
-  EINA_LIST_FREE(popupMenuItems_, dummyItem) {
-    delete static_cast<Popup_Menu_Item*>(dummyItem);
+  if (ewk_view_) {
+    evas_object_smart_callback_del(ewk_view_, kVisibleContentChangedSignalName,
+                                   VisibleContentChangedCallback);
+    evas_object_smart_callback_del(ewk_view_, kCustomScrollBeginSignalName,
+                                   OnCustomScrollBeginCallback);
+    evas_object_smart_callback_del(ewk_view_, kCustomScrollEndSignalName,
+                                   OnCustomScrollEndCallback);
+#if BUILDFLAG(IS_TIZEN)
+    if (window_rotate_handler_)
+      ecore_event_handler_del(window_rotate_handler_);
+#endif
   }
-
-  popupMenuItems_ = 0;
 }
 
 content::RenderWidgetHostViewAura* EWebView::rwhva() const {
@@ -343,19 +544,56 @@ content::WebContentsViewAura* EWebView::wcva() const {
   return static_cast<WebContentsViewAura*>(wc->GetView());
 }
 
+void EWebView::NativeViewResize(void* data,
+                                Evas* e,
+                                Evas_Object* obj,
+                                void* event_info) {
+  auto thiz = static_cast<EWebView*>(data);
+  if (!thiz->context_menu_)
+    return;
+  int x, y, width, height;
+  evas_object_geometry_get(obj, &x, &y, &width, &height);
+  thiz->context_menu_->Resize(gfx::Rect(x, y, width, height));
+}
+
 void EWebView::ResetContextMenuController() {
   return context_menu_.reset();
 }
 
+#if BUILDFLAG(IS_TIZEN_TV)
+void EWebView::RunPendingSetFocus(Eina_Bool focus) {
+  SetFocusInternal(focus);
+}
+
+void EWebView::SetFocusInternal(Eina_Bool focus) {
+  if (!rwhva() || !rwhva()->offscreen_helper() || (HasFocus() == focus))
+    return;
+  rwhva()->offscreen_helper()->Focus(focus);
+}
+#endif
+
 void EWebView::SetFocus(Eina_Bool focus) {
-  if (!web_contents_ || !rwhva() || (HasFocus() == focus))
+  if (!web_contents_)
     return;
 
+#if BUILDFLAG(IS_TIZEN_TV)
+  if (web_contents_->GetPrimaryMainFrame()->IsRenderFrameLive()) {
+    SetFocusInternal(focus);
+
+    if (pending_setfocus_closure_)
+      pending_setfocus_closure_.Reset();
+  } else {
+    LOG(ERROR) << "SEND DELAY SET FOCUS BIND";
+    pending_setfocus_closure_ = base::BindOnce(&EWebView::RunPendingSetFocus,
+                                               base::Unretained(this), focus);
+  }
+#else
   rwhva()->offscreen_helper()->Focus(focus);
+#endif
 }
 
 Eina_Bool EWebView::HasFocus() const {
-  if (!rwhva())
+  if (!rwhva() || !rwhva()->offscreen_helper())
     return EINA_FALSE;
 
   return rwhva()->offscreen_helper()->HasFocus() ? EINA_TRUE : EINA_FALSE;
@@ -397,7 +635,10 @@ bool EWebView::SetPageVisibility(
 }
 
 bool EWebView::CreateNewWindow(
-    content::WebContentsEflDelegate::WebContentsCreateCallback cb) {
+    content::WebViewDelegate::WebContentsCreateCallback cb) {
+#if BUILDFLAG(IS_TIZEN_TV)
+  LOG(INFO) << __FUNCTION__;
+#endif
   create_new_window_web_contents_cb_ = cb;
   Evas_Object* new_object = NULL;
   SmartCallback<EWebViewCallbacks::CreateNewWindow>().call(&new_object);
@@ -409,11 +650,11 @@ bool EWebView::CreateNewWindow(
 // static
 Evas_Object* EWebView::GetHostWindowDelegate(const content::WebContents* wc) {
   EWebView* thiz = WebViewFromWebContents(wc);
-  DCHECK(thiz->evas_object_);
-  Evas_Object* parent = evas_object_above_get(thiz->evas_object_);
+  DCHECK(thiz->ewk_view_);
+  Evas_Object* parent = evas_object_above_get(thiz->ewk_view_);
   if (!parent) {
     LOG(WARNING) << "Could not find and visual parents for EWK smart object!.";
-    return thiz->evas_object_;
+    return thiz->ewk_view_;
   }
 
   if (elm_object_widget_check(parent)) {
@@ -424,16 +665,31 @@ Evas_Object* EWebView::GetHostWindowDelegate(const content::WebContents* wc) {
   }
 
   LOG(WARNING) << "Could not find elementary parent for WebView object!";
-  return thiz->evas_object_;
+  return thiz->ewk_view_;
 }
 
 Evas_Object* EWebView::GetElmWindow() const {
-  Evas_Object* parent = elm_object_parent_widget_get(evas_object_);
+  Evas_Object* parent = elm_object_parent_widget_get(ewk_view_);
   return parent ? elm_object_top_widget_get(parent) : nullptr;
 }
 
-void EWebView::SetURL(const GURL& url) {
+void EWebView::SetURL(const GURL& url, bool from_api) {
   NavigationController::LoadURLParams params(url);
+
+  if (from_api) {
+    params.transition_type = ui::PageTransitionFromInt(
+        ui::PAGE_TRANSITION_LINK | ui::PAGE_TRANSITION_FROM_API);
+  }
+
+#if BUILDFLAG(IS_TIZEN_TV)
+  if (use_early_rwi_) {
+    LOG(INFO) << "[FAST RWI] SetURL Replace [" << url.spec()
+              << "] to [about:blank]";
+    rwi_gurl_ = url;
+    params.url = GURL("about:blank");
+  }
+#endif
+
   params.override_user_agent = NavigationController::UA_OVERRIDE_TRUE;
   web_contents_->GetController().LoadURLWithParams(params);
 }
@@ -471,6 +727,11 @@ Eina_Bool EWebView::GoBack() {
   if (!web_contents_->GetController().CanGoBack())
     return EINA_FALSE;
 
+#if defined(TIZEN_AUTOFILL_FW)
+  if (web_contents_delegate_)
+    web_contents_delegate_->ResetLastInteractedElements();
+#endif
+
   web_contents_->GetController().GoBack();
   return EINA_TRUE;
 }
@@ -489,45 +750,55 @@ void EWebView::Stop() {
 }
 
 void EWebView::Suspend() {
+#if BUILDFLAG(IS_TIZEN)
   CHECK(web_contents_);
+  if (IsMobileProfile() && web_contents_->IsFullscreen())
+    web_contents_->ExitFullscreen(true);
   RenderViewHost* rvh = web_contents_->GetRenderViewHost();
   RenderFrameHost* rfh = web_contents_->GetPrimaryMainFrame();
   CHECK(rvh);
   CHECK(rfh);
-#if !defined(EWK_BRINGUP)  // FIXME: m69 bringup
-  rfh->BlockRequestsForFrame();
-#endif
-#if 0
-  content::BrowserThread::PostTask(
-      content::BrowserThread::IO, FROM_HERE,
-      base::BindOnce(&content::ResourceDispatcherHost::BlockRequestsForFrameFromUI,
-                 rfh));
-
-  if (rvh)
-    rvh->Send(new EwkViewMsg_SuspendScheduledTask(rvh->GetRoutingID()));
+  if (rvh->IsRenderViewLive()) {
+    RenderWidgetHostImpl* rwhi = static_cast<RenderWidgetHostImpl*>(rvh->GetWidget());
+    rwhi->PauseScheduledTasks();
+  }
 #endif
 }
 
 void EWebView::Resume() {
+#if BUILDFLAG(IS_TIZEN)
   CHECK(web_contents_);
   RenderViewHost* rvh = web_contents_->GetRenderViewHost();
   RenderFrameHost* rfh = web_contents_->GetPrimaryMainFrame();
   CHECK(rvh);
   CHECK(rfh);
-#if !defined(EWK_BRINGUP)  // FIXME: m69 bringup
-  rfh->ResumeBlockedRequestsForFrame();
+  if (rvh->IsRenderViewLive() && rwhva())
+    rwhva()->host()->UnPauseScheduledTasks();
 #endif
-#if 0
-  content::BrowserThread::PostTask(
-      content::BrowserThread::IO, FROM_HERE,
-      base::BindOnce(
-          &content::ResourceDispatcherHost::ResumeBlockedRequestsForFrameFromUI,
-          rfh));
+}
 
-  if (rvh)
-    rvh->Send(new EwkViewMsg_ResumeScheduledTasks(rvh->GetRoutingID()));
-#endif
+#if BUILDFLAG(IS_TIZEN_TV)
+void EWebView::SetFloatVideoWindowState(bool enabled) {
+  RenderWidgetHostImpl* rwhi = static_cast<RenderWidgetHostImpl*>(
+      web_contents_->GetRenderViewHost()->GetWidget());
+
+    rwhi->SetFloatVideoWindowState(enabled);
+}
+
+void EWebView::SuspendNetworkLoading() {
+  RenderWidgetHostImpl* rwhi = static_cast<RenderWidgetHostImpl*>(
+      web_contents_->GetRenderViewHost()->GetWidget());
+
+  rwhi->SuspendNetworkLoading();
+}
+
+void EWebView::ResumeNetworkLoading() {
+  RenderWidgetHostImpl* rwhi = static_cast<RenderWidgetHostImpl*>(
+      web_contents_->GetRenderViewHost()->GetWidget());
+
+  rwhi->ResumeNetworkLoading();
 }
+#endif // IS_TIZEN_TV
 
 double EWebView::GetTextZoomFactor() const {
   if (text_zoom_factor_ < 0.0)
@@ -563,51 +834,57 @@ void EWebView::SetPageZoomFactor(double page_zoom_factor) {
 void EWebView::ExecuteEditCommand(const char* command, const char* value) {
   EINA_SAFETY_ON_NULL_RETURN(command);
 
-  value = (value == NULL) ? "" : value;
+  absl::optional<std::u16string> optional_value;
+  if (value)
+    optional_value = absl::make_optional(base::ASCIIToUTF16(value));
 
-  RenderWidgetHostImpl* rwhi = static_cast<RenderWidgetHostImpl*>(
-      web_contents_->GetRenderViewHost()->GetWidget());
+  WebContentsImpl* wc = static_cast<WebContentsImpl*>(web_contents_.get());
+  if (!wc || !wc->GetFocusedFrameWidgetInputHandler())
+    return;
 
-#if !defined(EWK_BRINGUP)  // FIXME: m67 bringup
-  // This is moved to mojo in upstream. Change it.
-  // https://chromium-review.googlesource.com/c/chromium/src/+/541036
-  rwhi->ExecuteEditCommand(command, value);
-#endif
+  wc->GetFocusedFrameWidgetInputHandler()->ExecuteEditCommand(
+      std::string(command), optional_value);
+}
 
-  // This is workaround for rich text toolbar buttons in email application
-  if (!strcmp(command, "InsertOrderedList") ||
-      !strcmp(command, "InsertUnorderedList") ||
-      !strcmp(command, "AlignCenter") || !strcmp(command, "AlignJustified") ||
-      !strcmp(command, "AlignLeft") || !strcmp(command, "AlignRight")) {
-    QuerySelectionStyle();
+#if BUILDFLAG(IS_TIZEN)
+void EWebView::EnterDragState() {
+  if (IsMobileProfile()) {
+    if (RenderViewHost* render_view_host = web_contents_->GetRenderViewHost())
+      web_contents_->EnterDragState(render_view_host);
   }
 }
+#endif
 
 void EWebView::SetOrientation(int orientation) {
+  LOG(INFO) << "New ori " << orientation << " GetOrientation "
+            << GetOrientation();
   if (GetOrientation() == orientation)
     return;
+  SetRotationChanged(true);
 
   if (orientation == 0 || orientation == 90 || orientation == 180 ||
       orientation == 270) {
 #if !defined(USE_AURA)
     GetWebContentsViewEfl()->SetOrientation(orientation);
+#else
+#if BUILDFLAG(IS_TIZEN)
+    TRACE_EVENT2("viz", "EWebView::SetOrientation", "orientation", orientation,
+                 "this", (void*)this);
+    wcva()->SetOrientation(orientation);
+#endif
 #endif
     int width = 0;
     int height = 0;
     const Ecore_Evas* ee =
-        ecore_evas_ecore_evas_get(evas_object_evas_get(evas_object_));
+        ecore_evas_ecore_evas_get(evas_object_evas_get(ewk_view_));
     ecore_evas_screen_geometry_get(ee, nullptr, nullptr, &width, &height);
     if (orientation == 90 || orientation == 270)
       std::swap(width, height);
 
-    if (context_menu_)
-      context_menu_->SetPopupSize(width, height);
     if (popup_controller_)
       popup_controller_->SetPopupSize(width, height);
     if (JavaScriptDialogManagerEfl* dialogMG = GetJavaScriptDialogManagerEfl())
       dialogMG->SetPopupSize(width, height);
-    if (popupPicker_)
-      popup_picker_resize(popupPicker_, width, height);
   }
 }
 
@@ -615,17 +892,24 @@ int EWebView::GetOrientation() {
 #if !defined(USE_AURA)
   return GetWebContentsViewEfl()->GetOrientation();
 #else
+#if BUILDFLAG(IS_TIZEN)
+  return wcva()->GetOrientation();
+#else
   return 0;
 #endif
+#endif
 }
 
 void EWebView::Show() {
-  evas_object_show(native_view_);
+  evas_object_show(efl_main_layout_);
   web_contents_->WasShown();
 }
 
 void EWebView::Hide() {
-  evas_object_hide(native_view_);
+  LOG(INFO) << "EWebView: " << this;
+  evas_object_hide(efl_main_layout_);
+  if (!web_contents_)
+    return;
   web_contents_->WasHidden();
 }
 
@@ -640,7 +924,7 @@ void EWebView::InvokeAuthCallback(LoginDelegateEfl* login_delegate,
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 
   auth_challenge_.reset(new _Ewk_Auth_Challenge(login_delegate, url, realm));
-  authentication_cb_.Run(evas_object_, auth_challenge_.get());
+  authentication_cb_.Run(ewk_view_, auth_challenge_.get());
 
   if (!auth_challenge_->is_decided && !auth_challenge_->is_suspended) {
     auth_challenge_->is_decided = true;
@@ -695,50 +979,58 @@ void EWebView::InvokePolicyNavigationCallback(
 void EWebView::HandleTouchEvents(Ewk_Touch_Event_Type type,
                                  const Eina_List* points,
                                  const Evas_Modifier* modifiers) {
-#if !defined(USE_AURA)
   const Eina_List* l;
   void* data;
+
+  if (GetSettings()->touchFocusEnabled() &&
+      (type == EWK_TOUCH_START && eina_list_count(points) == 1)) {
+    SetFocus(EINA_TRUE);
+  }
+
   EINA_LIST_FOREACH(points, l, data) {
     const Ewk_Touch_Point* point = static_cast<Ewk_Touch_Point*>(data);
     if (point->state == EVAS_TOUCH_POINT_STILL) {
       // Chromium doesn't expect (and doesn't like) these events.
       continue;
     }
-    if (rwhv()) {
+    if (rwhva()) {
       Evas_Coord_Point pt;
       pt.x = point->x;
       pt.y = point->y;
+
+      int delta_y = 0;
+      evas_object_geometry_get(ewk_view(), nullptr, &delta_y, nullptr, nullptr);
       ui::TouchEvent touch_event =
-          MakeTouchEvent(pt, point->state, point->id, evas_object());
-      rwhv()->HandleTouchEvent(&touch_event);
+          ui::MakeTouchEvent(pt, point->state, point->id, 0, delta_y);
+      rwhva()->OnTouchEvent(&touch_event);
     }
   }
-#endif
 }
 
 bool EWebView::TouchEventsEnabled() const {
-  return touch_events_enabled_;
+  return rwhva()->offscreen_helper()->TouchEventsEnabled();
 }
 
 // TODO: Touch events use the same mouse events in EFL API.
 // Figure out how to distinguish touch and mouse events on touch&mice devices.
 // Currently mouse and touch support is mutually exclusive.
 void EWebView::SetTouchEventsEnabled(bool enabled) {
-  if (touch_events_enabled_ == enabled)
+  if (!rwhva() || !rwhva()->offscreen_helper()) {
+    LOG(WARNING) << "RWHV is not created yet!";
     return;
+  }
 
-  touch_events_enabled_ = enabled;
-#if !defined(USE_AURA)
-  GetWebContentsViewEfl()->SetTouchEventsEnabled(enabled);
-#endif
-#if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
-  // there is no flag touch_enabled in web preferences
-  GetSettings()->getPreferences().touch_enabled = enabled;
+  if (rwhva()->offscreen_helper()->TouchEventsEnabled() == enabled)
+    return;
+
+  rwhva()->offscreen_helper()->SetTouchEventsEnabled(enabled);
+
+  GetSettings()->getPreferences().touch_event_feature_detection_enabled =
+      enabled;
   GetSettings()->getPreferences().double_tap_to_zoom_enabled = enabled;
   GetSettings()->getPreferences().editing_behavior =
-      enabled ? content::EDITING_BEHAVIOR_ANDROID
-              : content::EDITING_BEHAVIOR_UNIX;
-#endif
+      enabled ? blink::mojom::EditingBehavior::kEditingAndroidBehavior
+              : blink::mojom::EditingBehavior::kEditingUnixBehavior,
   UpdateWebKitPreferences();
 }
 
@@ -747,13 +1039,41 @@ bool EWebView::MouseEventsEnabled() const {
 }
 
 void EWebView::SetMouseEventsEnabled(bool enabled) {
+  if (!rwhva() || !rwhva()->offscreen_helper()) {
+    LOG(WARNING) << "RWHV is not created yet!";
+    return;
+  }
+
   if (mouse_events_enabled_ == enabled)
     return;
 
   mouse_events_enabled_ = enabled;
-#if !defined(USE_AURA)
-  GetWebContentsViewEfl()->SetTouchEventsEnabled(!enabled);
-#endif
+  rwhva()->offscreen_helper()->SetTouchEventsEnabled(!enabled);
+}
+
+bool EWebView::SetKeyEventsEnabled(bool enabled) {
+  if (!rwhva() || !rwhva()->aura_efl_helper()) {
+    LOG(WARNING) << "RWHV is not created yet!";
+    return false;
+  }
+
+  if (key_events_enabled_ == enabled)
+    return true;
+
+  key_events_enabled_ = enabled;
+  rwhva()->aura_efl_helper()->SetKeyEventsEnabled(enabled);
+  return true;
+}
+
+void EWebView::SendKeyEvent(Evas_Object* ewk_view,
+                            void* key_event,
+                            bool is_press) {
+  if (!rwhva() || !rwhva()->aura_efl_helper()) {
+    LOG(WARNING) << "RWHV is not created yet!";
+    return;
+  }
+
+  rwhva()->aura_efl_helper()->SendKeyEvent(ewk_view, key_event, is_press);
 }
 
 namespace {
@@ -817,7 +1137,7 @@ bool EWebView::ExecuteJavaScript(const char* script,
   base::UTF8ToUTF16(script, strlen(script), &js_script);
   if (callback) {
     JavaScriptCallbackDetails* script_callback_data =
-        new JavaScriptCallbackDetails(callback, userdata, evas_object_);
+        new JavaScriptCallbackDetails(callback, userdata, ewk_view_);
     RenderFrameHost::JavaScriptResultCallback js_callback =
         base::BindOnce(&JavaScriptComplete, base::Owned(script_callback_data));
     // In M47, it isn't possible anymore to execute javascript in the generic
@@ -861,39 +1181,18 @@ bool EWebView::SetUserAgentAppName(const char* application_name) {
   return true;
 }
 
+#if BUILDFLAG(IS_TIZEN)
 bool EWebView::SetPrivateBrowsing(bool incognito) {
   if (context_->GetImpl()->browser_context()->IsOffTheRecord() == incognito)
     return false;
-
-  GURL url = web_contents_->GetVisibleURL();
-  if (old_context_.get()) {
-    DCHECK(!incognito);
-    web_contents_.reset();
-    web_contents_delegate_.reset();
-    Ewk_Context::Delete(context_.get());
-    context_ = old_context_;
-    old_context_ = nullptr;
-  } else {
-    if (incognito) {
-      old_context_ = context_;
-    }
-    context_ = Ewk_Context::Create(incognito);
-  }
-
-  InitializeContent();
-  SetURL(url);
+  context_->GetImpl()->browser_context()->SetOffTheRecord(incognito);
   return true;
 }
 
 bool EWebView::GetPrivateBrowsing() const {
   return context_->GetImpl()->browser_context()->IsOffTheRecord();
 }
-
-void EWebView::set_magnifier(bool status) {
-#if !defined(USE_AURA)
-  rwhv()->set_magnifier(status);
 #endif
-}
 
 const char* EWebView::GetUserAgent() const {
   std::string user_agent =
@@ -974,12 +1273,21 @@ void EWebView::LoadPlainTextString(const char* plain_text) {
   LoadData(plain_text, std::string::npos, "text/plain", NULL, NULL, NULL);
 }
 
+void EWebView::LoadHTMLStringOverridingCurrentEntry(
+    const char* html,
+    const char* base_uri,
+    const char* unreachable_url) {
+  LoadData(html, std::string::npos, NULL, NULL, base_uri, unreachable_url,
+           true);
+}
+
 void EWebView::LoadData(const char* data,
                         size_t size,
                         const char* mime_type,
                         const char* encoding,
                         const char* base_uri,
-                        const char* unreachable_uri) {
+                        const char* unreachable_uri,
+                        bool should_replace_current_entry) {
   SetDefaultStringIfNull(mime_type, "text/html");
   SetDefaultStringIfNull(encoding, "utf-8");
   SetDefaultStringIfNull(base_uri, "about:blank");  // Webkit2 compatible
@@ -995,7 +1303,10 @@ void EWebView::LoadData(const char* data,
   url_str.append(";charset=");
   url_str.append(encoding);
   url_str.append(",");
-  url_str.append(str_data);
+
+  // GURL constructor performs canonicalization of url string, but this is not
+  // enough for correctly escaping contents of "data:" url.
+  url_str.append(base::EscapeUrlEncodedData(str_data, false));
 
   NavigationController::LoadURLParams data_params(GURL(url_str.c_str()));
 
@@ -1003,7 +1314,7 @@ void EWebView::LoadData(const char* data,
   data_params.virtual_url_for_data_url = GURL(unreachable_uri);
 
   data_params.load_type = NavigationController::LOAD_TYPE_DATA;
-  data_params.should_replace_current_entry = false;
+  data_params.should_replace_current_entry = should_replace_current_entry;
   data_params.override_user_agent = NavigationController::UA_OVERRIDE_TRUE;
   web_contents_->GetController().LoadURLWithParams(data_params);
 }
@@ -1017,241 +1328,194 @@ void EWebView::InvokeLoadError(const GURL& url,
   SmartCallback<EWebViewCallbacks::LoadError>().call(&err);
 }
 
-void EWebView::ShowPopupMenu(const std::vector<blink::MenuItemInfo>& items,
-                             int selectedIndex,
-                             bool multiple) {
-  // Request form navigation information as early as possible,
-  // given that is renderer will ping-back with actual requested data.
-  RenderFrameHostImpl* render_frame_host =
-      static_cast<RenderFrameHostImpl*>(web_contents_->GetPrimaryMainFrame());
-  if (render_frame_host)
-    render_frame_host->Send(new EwkFrameMsg_RequestSelectCollectionInformation(
-        render_frame_host->GetRoutingID()));
-
-  Eina_List* popupItems = 0;
-  const size_t size = items.size();
-  for (size_t i = 0; i < size; ++i) {
-    popupItems = eina_list_append(popupItems, new Popup_Menu_Item(items[i]));
-  }
-
-  ReleasePopupMenuList();
-  popupMenuItems_ = popupItems;
-
-  if (popupPicker_ && FormIsNavigating()) {
-    popupPicker_->multiSelect = multiple;
-    PopupMenuUpdate(popupMenuItems_, selectedIndex);
-    SetFormIsNavigating(false);
-    return;
-  }
-
-  if (popupPicker_)
-    popup_picker_del(popupPicker_);
-  popupPicker_ = 0;
-
-  if (multiple)
-    popupPicker_ =
-        popup_picker_new(this, evas_object(), popupMenuItems_, 0, multiple);
-  else
-    popupPicker_ = popup_picker_new(this, evas_object(), popupMenuItems_,
-                                    selectedIndex, multiple);
-
-  popup_picker_buttons_update(popupPicker_, formNavigation_.position,
-                              formNavigation_.count, false);
-}
-
-Eina_Bool EWebView::HidePopupMenu() {
-  if (!popupPicker_)
-    return false;
-
-  if (FormIsNavigating())
-    return true;
-
-  popup_picker_del(popupPicker_);
-  popupPicker_ = 0;
-  return true;
+void EWebView::SetViewLoadErrorPageCallback(
+    Ewk_View_Error_Page_Load_Callback callback,
+    void* user_data) {
+  load_error_page_cb_.Set(callback, user_data);
 }
 
-void EWebView::UpdateFormNavigation(int formElementCount,
-                                    int currentNodeIndex,
-                                    bool prevState,
-                                    bool nextState) {
-  formNavigation_.count = formElementCount;
-  formNavigation_.position = currentNodeIndex;
-  formNavigation_.prevState = prevState;
-  formNavigation_.nextState = nextState;
-}
+// Remove below code while ewk_error_cancellation_get has been implemented.
+const char* EWebView::InvokeViewLoadErrorPageCallback(const GURL& url,
+                                                      int error_code,
+                                                      bool is_cancellation) {
+  std::unique_ptr<_Ewk_Error> err(new _Ewk_Error(
+      error_code, is_cancellation, url.possibly_invalid_spec().c_str()));
+  _Ewk_Error_Page error_page;
 
-bool EWebView::IsSelectPickerShown() const {
-  return (popupPicker_ != NULL);
-}
+  LOG(INFO) << "EWebView::InvokeLoadErrorPageCallback url: "
+            << url.spec().c_str() << ", error_code: " << error_code;
 
-void EWebView::CloseSelectPicker() {
-  listClosed(popupPicker_, 0, 0, 0);
+  load_error_page_cb_.Run(ewk_view_, err.get(), &error_page);
+  return error_page.content;
 }
 
-void EWebView::SetFormIsNavigating(bool formIsNavigating) {
-  formIsNavigating_ = formIsNavigating;
+bool EWebView::IsLoadErrorPageCallbackSet() const {
+  return load_error_page_cb_.IsCallbackSet();
 }
+void EWebView::HandlePopupMenu(std::vector<blink::mojom::MenuItemPtr> items,
+                               int selectedIndex,
+                               bool multiple,
+                               const gfx::Rect& bounds) {
+  if (!select_picker_) {
+    select_picker_.reset(CreateSelectPicker(
+        this, selectedIndex, std::move(items), multiple, bounds));
 
-Eina_Bool EWebView::PopupMenuUpdate(Eina_List* items, int selectedIndex) {
-  if (!popupPicker_)
-    return false;
+    // Picker has been shown on top of webview and the page content gets
+    // partially overlapped. Decrease viewport while showing picker.
+    AdjustViewPortHeightToPopupMenu(true /* is_popup_menu_visible */);
+#if BUILDFLAG(IS_TIZEN_TV)
+    SmartCallback<EWebViewCallbacks::PopupMenuShow>().call();
+#endif
+  } else {
+    select_picker_->UpdatePickerData(selectedIndex, std::move(items), multiple);
+  }
 
-  popup_picker_update(evas_object(), popupPicker_, items, selectedIndex);
-  popup_picker_buttons_update(popupPicker_, formNavigation_.position,
-                              formNavigation_.count, false);
-  return true;
+  select_picker_->Show();
 }
 
-void EWebView::FormNavigate(bool direction) {
-  RenderFrameHostImpl* render_frame_host =
-      static_cast<RenderFrameHostImpl*>(web_contents_->GetPrimaryMainFrame());
-  if (!render_frame_host)
+void EWebView::HidePopupMenu() {
+  if (!select_picker_)
     return;
 
-  popup_picker_buttons_update(popupPicker_, formNavigation_.position,
-                              formNavigation_.count, true);
-
-  if ((direction && formNavigation_.nextState) ||
-      (!direction && formNavigation_.prevState))
-    SetFormIsNavigating(true);
-
-  listClosed(popupPicker_, 0, 0, 0);
-  render_frame_host->Send(new EwkFrameMsg_MoveToNextOrPreviousSelectElement(
-      render_frame_host->GetRoutingID(), direction));
-}
-
-Eina_Bool EWebView::DidSelectPopupMenuItem(int selectedIndex) {
-  RenderFrameHostImpl* render_frame_host =
-      static_cast<RenderFrameHostImpl*>(web_contents_->GetPrimaryMainFrame());
-  if (!render_frame_host)
-    return false;
-
-  if (!popupMenuItems_)
-    return false;
-
-  // When user select empty space then no index is selected, so selectedIndex
-  // value is -1
-  // In that case we should call valueChanged() with -1 index.That in turn call
-  // popupDidHide()
-  // in didChangeSelectedIndex() for reseting the value of m_popupIsVisible in
-  // RenderMenuList.
-  if (selectedIndex != -1 &&
-      selectedIndex >= (int)eina_list_count(popupMenuItems_))
-    return false;
-
-  // In order to reuse RenderFrameHostImpl::DidSelectPopupMenuItems() method in
-  // Android,
-  // put selectedIndex into std::vector<int>.
-  std::vector<int> selectedIndices;
-  selectedIndices.push_back(selectedIndex);
-#if !defined(EWK_BRINGUP)  // FIXME: m67 bringup
-  render_frame_host->DidSelectPopupMenuItems(selectedIndices);
+  AdjustViewPortHeightToPopupMenu(false /* is_popup_menu_visible */);
+#if BUILDFLAG(IS_TIZEN_TV)
+  SmartCallback<EWebViewCallbacks::PopupMenuHide>().call();
 #endif
-  return true;
+  select_picker_.reset();
 }
 
-Eina_Bool EWebView::DidMultipleSelectPopupMenuItem(
-    std::vector<int>& selectedIndices) {
-  RenderFrameHostImpl* render_frame_host =
-      static_cast<RenderFrameHostImpl*>(web_contents_->GetPrimaryMainFrame());
-  if (!render_frame_host)
-    return false;
-
-  if (!popupMenuItems_)
-    return false;
-#if !defined(EWK_BRINGUP)  // FIXME: m67 bringup
-  render_frame_host->DidSelectPopupMenuItems(selectedIndices);
-#endif
-  return true;
+void EWebView::DidSelectPopupMenuItems(std::vector<int>& indices) {
+  wcva()->wcva_helper()->DidSelectPopupMenuItems(indices);
 }
 
-Eina_Bool EWebView::PopupMenuClose() {
-// DJKim : FIXME
-#if 0
-  if (!impl->popupMenuProxy)
-    return false;
-
-  impl->popupMenuProxy = 0;
-#endif
-  HidePopupMenu();
-
-  if (!popupMenuItems_)
-    return false;
-
-  void* item;
-  EINA_LIST_FREE(popupMenuItems_, item)
-  delete static_cast<Popup_Menu_Item*>(item);
-  popupMenuItems_ = 0;
-
-  RenderFrameHostImpl* render_frame_host =
-      static_cast<RenderFrameHostImpl*>(web_contents_->GetPrimaryMainFrame());
-  if (!render_frame_host)
-    return false;
-#if !defined(EWK_BRINGUP)  // FIXME: m67 bringup
-  render_frame_host->DidCancelPopupMenu();
-#endif
-  return true;
+void EWebView::DidCancelPopupMenu() {
+  wcva()->wcva_helper()->DidCancelPopupMenu();
 }
 
 void EWebView::HandleLongPressGesture(
     const content::ContextMenuParams& params) {
-#if !defined(USE_AURA)
   // This menu is created in renderer process and it does not now anything about
   // view scaling factor and it has another calling sequence, so coordinates is
   // not updated.
+  if (settings_ && !settings_->getPreferences().long_press_enabled)
+    return;
+
   content::ContextMenuParams convertedParams = params;
   gfx::Point convertedPoint =
-      rwhv()->ConvertPointInViewPix(gfx::Point(params.x, params.y));
+      rwhva()->offscreen_helper()->ConvertPointInViewPix(
+          gfx::Point(params.x, params.y));
   convertedParams.x = convertedPoint.x();
   convertedParams.y = convertedPoint.y();
 
   Evas_Coord x, y;
-  evas_object_geometry_get(evas_object(), &x, &y, 0, 0);
+  evas_object_geometry_get(ewk_view(), &x, &y, 0, 0);
   convertedParams.x += x;
   convertedParams.y += y;
 
+  bool show_context_menu_now = true;
   if (GetSelectionController() && GetSelectionController()->GetLongPressed()) {
-    bool show_context_menu_now =
-        !GetSelectionController()->HandleLongPressEvent(convertedPoint,
-                                                        convertedParams);
-    if (show_context_menu_now)
-      ShowContextMenuInternal(convertedParams);
+    show_context_menu_now = !GetSelectionController()->HandleLongPressEvent(
+        convertedPoint, convertedParams);
+  }
+  if (show_context_menu_now) {
+    ShowContextMenuInternal(convertedParams);
   }
-#endif
 }
 
 void EWebView::ShowContextMenu(const content::ContextMenuParams& params) {
-#if !defined(USE_AURA)
+  if (!rwhva())
+    return;
+
   // This menu is created in renderer process and it does not now anything about
   // view scaling factor and it has another calling sequence, so coordinates is
   // not updated.
   content::ContextMenuParams convertedParams = params;
   gfx::Point convertedPoint =
-      rwhv()->ConvertPointInViewPix(gfx::Point(params.x, params.y));
+      rwhva()->offscreen_helper()->ConvertPointInViewPix(
+          gfx::Point(params.x, params.y));
   convertedParams.x = convertedPoint.x();
   convertedParams.y = convertedPoint.y();
 
   Evas_Coord x, y;
-  evas_object_geometry_get(evas_object(), &x, &y, 0, 0);
+  evas_object_geometry_get(ewk_view(), &x, &y, 0, 0);
   convertedParams.x += x;
   convertedParams.y += y;
 
   context_menu_position_ = gfx::Point(convertedParams.x, convertedParams.y);
 
   ShowContextMenuInternal(convertedParams);
-#endif
 }
 
 void EWebView::ShowContextMenuInternal(
     const content::ContextMenuParams& params) {
-  context_menu_.reset(
+  // We don't want to show 'cut' or 'copy' for inputs of type 'password' in
+  // selection context menu, but params.input_field_type might not be set
+  // correctly, because in some cases params is received from SelectionBoxEfl,
+  // not from FrameHostMsg_ContextMenu message. In SelectionBoxEfl
+  // ContextMenuParams is constructed on our side with limited information and
+  // input_field_type is not set.
+  //
+  // To work around this, we query for input type and set it separately. In
+  // response to EwkViewMsg_QueryInputType we run ::UpdateContextMenu with
+  // information about input's type.
+  //
+  // FIXME: the way we get ContextMenuParams for context menu is flawed in some
+  //        cases. This should be fixed by restructuring context menu code.
+  //        Context menu creation should be unified to always have
+  //        ContextMenuParams received from FrameHostMsg_ContextMenu.
+  //        Tracked at: http://suprem.sec.samsung.net/jira/browse/TWF-1640
+  if (params.is_editable) {
+    saved_context_menu_params_ = params;
+    if (rwhva())
+      rwhva()->host()->QueryInputType();
+  } else {
+    UpdateContextMenuWithParams(params);
+  }
+}
+
+void EWebView::UpdateContextMenu(bool is_password_input) {
+  if (is_password_input) {
+    saved_context_menu_params_.form_control_type =
+        blink::mojom::FormControlType::kInputPassword;
+  }
+  UpdateContextMenuWithParams(saved_context_menu_params_);
+}
+
+void EWebView::UpdateContextMenuWithParams(
+    const content::ContextMenuParams& params) {
+  context_menu_.reset(
       new content::ContextMenuControllerEfl(this, *web_contents_.get()));
-  if (!context_menu_->PopulateAndShowContextMenu(params)) {
-    context_menu_.reset();
-    if (GetSelectionController())
-      GetSelectionController()->HideHandles();
+
+  if (IsMobileProfile()) {
+    if (delayed_show_context_menu_timer_) {
+      ecore_timer_del(delayed_show_context_menu_timer_);
+      delayed_show_context_menu_timer_ = nullptr;
+    }
+    saved_context_menu_params_ = params;
+    delayed_show_context_menu_timer_ = ecore_timer_add(
+        kDelayShowContextMenuTime, DelayedPopulateAndShowContextMenu, this);
+  } else {
+    if (!context_menu_->PopulateAndShowContextMenu(params)) {
+      context_menu_.reset();
+      if (GetSelectionController())
+        GetSelectionController()->HideHandles();
+    }
+  }
+}
+
+Eina_Bool EWebView::DelayedPopulateAndShowContextMenu(void* data) {
+  if (IsMobileProfile()) {
+    EWebView* view = static_cast<EWebView*>(data);
+    if (view) {
+      if (view->context_menu_ &&
+          !(view->context_menu_->PopulateAndShowContextMenu(
+              view->saved_context_menu_params_))) {
+        view->context_menu_.reset();
+      }
+      view->delayed_show_context_menu_timer_ = nullptr;
+    }
   }
+  return ECORE_CALLBACK_CANCEL;
 }
 
 void EWebView::CancelContextMenu(int request_id) {
@@ -1286,6 +1550,39 @@ void EWebView::SetScale(double scale_factor) {
       scale_factor);
 }
 
+void EWebView::ScrollFocusedNodeIntoView() {
+  if (RenderViewHost* render_view_host = web_contents_->GetRenderViewHost()) {
+    if (auto& broadcast = static_cast<RenderViewHostImpl*>(render_view_host)
+                              ->GetAssociatedPageBroadcast())
+      broadcast->ScrollFocusedNodeIntoView();
+  }
+}
+
+void EWebView::AdjustViewPortHeightToPopupMenu(bool is_popup_menu_visible) {
+  if (!rwhva() || !IsMobileProfile() ||
+      settings_->getPreferences().TizenCompatibilityModeEnabled()) {
+    return;
+  }
+
+  int picker_height = select_picker_->GetGeometryDIP().height();
+  gfx::Rect screen_rect =
+      display::Screen::GetScreen()->GetPrimaryDisplay().bounds();
+  gfx::Rect view_rect = rwhva()->offscreen_helper()->GetViewBounds();
+  int bottom_height =
+      screen_rect.height() - (view_rect.y() + view_rect.height());
+
+  rwhva()->offscreen_helper()->SetCustomViewportSize(
+      is_popup_menu_visible
+          ? gfx::Size(view_rect.width(),
+                      view_rect.height() - picker_height + bottom_height)
+          : gfx::Size());
+}
+
+void EWebView::SetScaleChangedCallback(Ewk_View_Scale_Changed_Callback callback,
+                                       void* user_data) {
+  scale_changed_cb_.Set(callback, user_data);
+}
+
 bool EWebView::GetScrollPosition(int* x, int* y) const {
   if (!rwhva()) {
     LOG(ERROR) << "rwhva() returns nullptr";
@@ -1341,15 +1638,13 @@ void EWebView::ChangeScroll(int& x, int& y) {
 }
 
 void EWebView::SetScroll(int x, int y) {
-  RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
-  if (!render_view_host)
-    return;
-
-  ChangeScroll(x, y);
-#if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
-  render_view_host->Send(
-      new EwkViewMsg_SetScroll(render_view_host->GetRoutingID(), x, y));
-#endif
+  if (auto* render_view_host = web_contents_->GetRenderViewHost()) {
+    if (auto& broadcast = static_cast<RenderViewHostImpl*>(render_view_host)
+                              ->GetAssociatedPageBroadcast()) {
+      ChangeScroll(x, y);
+      broadcast->SetScrollOffset(x, y);
+    }
+  }
 }
 
 void EWebView::UseSettingsFont() {
@@ -1402,30 +1697,8 @@ void EWebView::GetScrollSize(int* width, int* height) {
 }
 
 void EWebView::MoveCaret(const gfx::Point& point) {
-#if !defined(USE_AURA)
-  if (rwhv())
-    rwhv()->MoveCaret(point);
-#endif
-}
-
-void EWebView::QuerySelectionStyle() {
-#if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
-  if (GetSettings()->textStyleStateState()) {
-    RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
-    render_view_host->Send(
-        new EwkViewMsg_GetSelectionStyle(render_view_host->GetRoutingID()));
-  }
-#endif
-}
-
-void EWebView::OnQuerySelectionStyleReply(const SelectionStylePrams& params) {
-  gfx::Rect left_rect, right_rect;
-  if (GetSelectionController()) {
-    GetSelectionController()->GetSelectionBounds(&left_rect, &right_rect);
-    _Ewk_Text_Style style_data(params, left_rect.origin(),
-                               right_rect.bottom_right());
-    SmartCallback<EWebViewCallbacks::TextStyleState>().call(&style_data);
-  }
+  if (rwhva())
+    rwhva()->offscreen_helper()->MoveCaret(point);
 }
 
 SelectionControllerEfl* EWebView::GetSelectionController() const {
@@ -1435,16 +1708,12 @@ SelectionControllerEfl* EWebView::GetSelectionController() const {
   return view ? view->offscreen_helper()->GetSelectionController() : 0;
 }
 
-void EWebView::SelectLinkText(const gfx::Point& touch_point) {
-#if !defined(EWK_BRINGUP)  // FIXME: m67 bringup
-  float device_scale_factor =
-      display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
-  RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
-  render_view_host->Send(new ViewMsg_SelectLinkText(
-      render_view_host->GetRoutingID(),
-      gfx::Point(touch_point.x() / device_scale_factor,
-                 touch_point.y() / device_scale_factor)));
-#endif
+void EWebView::SelectFocusedLink() {
+  if (!rwhva()) {
+    return;
+  }
+
+  rwhva()->host()->SelectFocusedLink();
 }
 
 bool EWebView::GetSelectionRange(Eina_Rectangle* left_rect,
@@ -1461,13 +1730,17 @@ bool EWebView::GetSelectionRange(Eina_Rectangle* left_rect,
   return false;
 }
 
+void EWebView::OnSelectionRectReceived(const gfx::Rect& selection_rect) const {
+  if (context_menu_)
+    context_menu_->OnSelectionRectReceived(selection_rect);
+}
+
 Eina_Bool EWebView::ClearSelection() {
   if (!rwhva())
     return EINA_FALSE;
 
   ResetContextMenuController();
-  rwhva()->offscreen_helper()->SelectionChanged(std::u16string(), 0,
-                                                gfx::Range());
+  rwhva()->SelectionChanged(std::u16string(), 0, gfx::Range());
 
   if (GetSelectionController())
     return GetSelectionController()->ClearSelectionViaEWebView();
@@ -1565,7 +1838,6 @@ _Ewk_Hit_Test* EWebView::RequestHitTestDataAtBlinkCoords(
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 
   RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
-  DCHECK(render_view_host);
 
   if (render_view_host) {
     // We wait on UI thread till hit test data is updated.
@@ -1577,22 +1849,24 @@ _Ewk_Hit_Test* EWebView::RequestHitTestDataAtBlinkCoords(
     return new _Ewk_Hit_Test(hit_test_params_);
   }
 
-  return NULL;
+  return nullptr;
 }
 
 void EWebView::EvasToBlinkCords(int x, int y, int* view_x, int* view_y) {
   DCHECK(display::Screen::GetScreen());
-  Evas_Coord tmpX, tmpY;
-  evas_object_geometry_get(evas_object_, &tmpX, &tmpY, NULL, NULL);
+  if (!rwhva())
+    return;
+
+  gfx::Rect view_bounds = rwhva()->offscreen_helper()->GetViewBoundsInPix();
 
   if (view_x) {
-    *view_x = x - tmpX;
+    *view_x = x - view_bounds.x();
     *view_x /=
         display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
   }
 
   if (view_y) {
-    *view_y = y - tmpY;
+    *view_y = y - view_bounds.y();
     *view_y /=
         display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
   }
@@ -1608,21 +1882,50 @@ void EWebView::OnCopyFromBackingStore(bool success, const SkBitmap& bitmap) {}
 
 void EWebView::OnFocusIn() {
   SmartCallback<EWebViewCallbacks::FocusIn>().call();
+#if defined(USE_WAYLAND)
+  if (!rwhva() || !rwhva()->offscreen_helper())
+    return;
+  if (GetSettings()->getClipboardEnabled()) {
+    ClipboardHelperEfl::GetInstance()->OnWebviewFocusIn(
+        this, rwhva()->offscreen_helper()->content_image_elm_host(),
+        rwhva()->offscreen_helper()->IsFocusedNodeContentEditable(),
+        base::BindRepeating(&EWebView::ExecuteEditCommand,
+                            base::Unretained(this)));
+  }
+#endif
 }
 
 void EWebView::OnFocusOut() {
+#if defined(TIZEN_ATK_SUPPORT)
+  if (IsMobileProfile())
+    eweb_accessibility_->OnFocusOut();
+#endif
   SmartCallback<EWebViewCallbacks::FocusOut>().call();
+#if defined(USE_WAYLAND)
+  if (GetSettings()->getClipboardEnabled())
+    ClipboardHelperEfl::GetInstance()->MaybeInvalidateActiveWebview(this);
+#endif
 }
 
-void EWebView::RenderViewCreated(RenderViewHost* render_view_host) {
-  SendDelayedMessages(render_view_host);
-  UpdateWebkitPreferencesEfl(render_view_host);
+void EWebView::RenderViewReady() {
   if (rwhva()) {
     rwhva()->offscreen_helper()->SetFocusInOutCallbacks(
         base::BindRepeating(&EWebView::OnFocusIn, base::Unretained(this)),
         base::BindRepeating(&EWebView::OnFocusOut, base::Unretained(this)));
   }
 
+#if defined(TIZEN_VIDEO_HOLE)
+  if (rwhva() && pending_video_hole_setting_) {
+    EnableVideoHoleSupportInternal();
+    pending_video_hole_setting_ = false;
+  }
+#endif
+
+  RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
+
+  SendDelayedMessages(render_view_host);
+  UpdateWebkitPreferencesEfl(render_view_host);
+
   if (render_view_host) {
     WebContents* content = WebContents::FromRenderViewHost(render_view_host);
     if (content) {
@@ -1633,26 +1936,20 @@ void EWebView::RenderViewCreated(RenderViewHost* render_view_host) {
   }
 }
 
-void EWebView::SetOverrideEncoding(const std::string& encoding) {
-// EWK_BRINGUP definition should be removed.
-#if !defined(EWK_BRINGUP)  // FIXME: m67 bringup
-  web_contents_->SetOverrideEncoding(encoding);
-#endif  // !defined(EWK_BRINGUP)
-}
-
 void EWebView::SetQuotaPermissionRequestCallback(
     Ewk_Quota_Permission_Request_Callback callback,
     void* user_data) {
   quota_request_callback_.Set(callback, user_data);
 }
 
+#if !defined(EWK_BRINGUP)  // FIXME: m114 bringup
 void EWebView::InvokeQuotaPermissionRequest(
     _Ewk_Quota_Permission_Request* request,
     content::QuotaPermissionContext::PermissionCallback cb) {
   quota_permission_request_map_[request] = std::move(cb);
-  request->setView(evas_object());
+  request->setView(ewk_view());
   if (quota_request_callback_.IsCallbackSet())
-    quota_request_callback_.Run(evas_object(), request);
+    quota_request_callback_.Run(ewk_view(), request);
   else
     QuotaRequestCancel(request);
 }
@@ -1682,6 +1979,7 @@ void EWebView::QuotaRequestCancel(
   quota_permission_request_map_.erase(request);
   delete request;
 }
+#endif
 
 bool EWebView::GetLinkMagnifierEnabled() const {
 #if !defined(EWK_BRINGUP)  // FIXME: m71 bringup
@@ -1850,7 +2148,7 @@ bool EWebView::IsNotificationPermissionCallbackSet() const {
 bool EWebView::InvokeNotificationPermissionCallback(
     Ewk_Notification_Permission_Request* request) {
   Eina_Bool ret = EINA_FALSE;
-  notification_permission_callback_.Run(evas_object_, request, &ret);
+  notification_permission_callback_.Run(ewk_view_, request, &ret);
   return ret;
 }
 
@@ -1865,24 +2163,20 @@ int EWebView::SetEwkViewPlainTextGetCallback(
 
 bool EWebView::PlainTextGet(Ewk_View_Plain_Text_Get_Callback callback,
                             void* user_data) {
-  RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
-  if (!render_view_host)
+  auto* render_frame_host = web_contents_->GetPrimaryMainFrame();
+  if (!render_frame_host)
     return false;
-#if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
-  int plain_text_get_callback_id =
-      SetEwkViewPlainTextGetCallback(callback, user_data);
-  return render_view_host->Send(new EwkViewMsg_PlainTextGet(
-      render_view_host->GetRoutingID(), plain_text_get_callback_id));
-#else
-  return false;
-#endif
+
+  auto callback_id = SetEwkViewPlainTextGetCallback(callback, user_data);
+  return render_frame_host->Send(new EwkFrameMsg_GetPlainText(
+      render_frame_host->GetRoutingID(), callback_id));
 }
 
 void EWebView::InvokePlainTextGetCallback(const std::string& content_text,
                                           int plain_text_get_callback_id) {
   EwkViewPlainTextGetCallback* view_plain_text_callback_invoke_ptr =
       plain_text_get_callback_map_.Lookup(plain_text_get_callback_id);
-  view_plain_text_callback_invoke_ptr->Run(evas_object(), content_text.c_str());
+  view_plain_text_callback_invoke_ptr->Run(ewk_view(), content_text.c_str());
   plain_text_get_callback_map_.Remove(plain_text_get_callback_id);
 }
 
@@ -1895,7 +2189,7 @@ void EWebView::SetViewGeolocationPermissionCallback(
 bool EWebView::InvokeViewGeolocationPermissionCallback(
     _Ewk_Geolocation_Permission_Request* permission_context,
     Eina_Bool* callback_result) {
-  return geolocation_permission_cb_.Run(evas_object_, permission_context,
+  return geolocation_permission_cb_.Run(ewk_view_, permission_context,
                                         callback_result);
 }
 
@@ -1908,10 +2202,22 @@ void EWebView::SetViewUserMediaPermissionCallback(
 bool EWebView::InvokeViewUserMediaPermissionCallback(
     _Ewk_User_Media_Permission_Request* permission_context,
     Eina_Bool* callback_result) {
-  return user_media_permission_cb_.Run(evas_object_, permission_context,
+  return user_media_permission_cb_.Run(ewk_view_, permission_context,
                                        callback_result);
 }
 
+void EWebView::SetViewUserMediaPermissionQueryCallback(
+    Ewk_View_User_Media_Permission_Query_Callback callback,
+    void* user_data) {
+  user_media_permission_query_cb_.Set(callback, user_data);
+}
+
+Ewk_User_Media_Permission_Query_Result
+EWebView::InvokeViewUserMediaPermissionQueryCallback(
+    _Ewk_User_Media_Permission_Query* permission_context) {
+  return user_media_permission_query_cb_.Run(ewk_view_, permission_context);
+}
+
 void EWebView::SetViewUnfocusAllowCallback(
     Ewk_View_Unfocus_Allow_Callback callback,
     void* user_data) {
@@ -1920,7 +2226,7 @@ void EWebView::SetViewUnfocusAllowCallback(
 
 bool EWebView::InvokeViewUnfocusAllowCallback(Ewk_Unfocus_Direction direction,
                                               Eina_Bool* callback_result) {
-  return unfocus_allow_cb_.Run(evas_object_, direction, callback_result);
+  return unfocus_allow_cb_.Run(ewk_view_, direction, callback_result);
 }
 
 void EWebView::StopFinding() {
@@ -1941,16 +2247,10 @@ const char* EWebView::GetTitle() {
 }
 
 bool EWebView::SaveAsPdf(int width, int height, const std::string& filename) {
-  RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
-  if (!render_view_host)
+  if (!rwhva())
     return false;
-#if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
-  return render_view_host->Send(
-      new EwkViewMsg_PrintToPdf(render_view_host->GetRoutingID(), width, height,
-                                base::FilePath(filename)));
-#else
-  return false;
-#endif
+  rwhva()->host()->PrintToPdf(width, height, base::FilePath(filename));
+  return true;
 }
 
 bool EWebView::GetMHTMLData(Ewk_View_MHTML_Data_Get_Callback callback,
@@ -1959,9 +2259,9 @@ bool EWebView::GetMHTMLData(Ewk_View_MHTML_Data_Get_Callback callback,
   if (!render_view_host)
     return false;
 
+#if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
   MHTMLCallbackDetails* callback_details = new MHTMLCallbackDetails;
   callback_details->Set(callback, user_data);
-#if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
   int mhtml_callback_id = mhtml_callback_map_.Add(callback_details);
   return render_view_host->Send(new EwkViewMsg_GetMHTMLData(
       render_view_host->GetRoutingID(), mhtml_callback_id));
@@ -1974,10 +2274,79 @@ void EWebView::OnMHTMLContentGet(const std::string& mhtml_content,
                                  int callback_id) {
   MHTMLCallbackDetails* callback_details =
       mhtml_callback_map_.Lookup(callback_id);
-  callback_details->Run(evas_object(), mhtml_content.c_str());
+  callback_details->Run(ewk_view(), mhtml_content.c_str());
   mhtml_callback_map_.Remove(callback_id);
 }
 
+bool EWebView::SavePageAsMHTML(const std::string& path,
+                               Ewk_View_Save_Page_Callback callback,
+                               void* user_data) {
+  if (!web_contents_)
+    return false;
+
+  GURL url(web_contents_->GetLastCommittedURL());
+  std::u16string title(web_contents_->GetTitle());
+
+  // Post function that has file access to blocking task runner.
+  base::ThreadPool::PostTaskAndReplyWithResult(
+      FROM_HERE,
+      {base::MayBlock(), base::TaskPriority::BEST_EFFORT,
+       base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN},
+      base::BindOnce(&GenerateMHTMLFilePath, url, base::UTF16ToUTF8(title),
+                     path),
+      base::BindOnce(&EWebView::GenerateMHTML, base::Unretained(this), callback,
+                     user_data));
+  return true;
+}
+
+void EWebView::GenerateMHTML(Ewk_View_Save_Page_Callback callback,
+                             void* user_data,
+                             const base::FilePath& file_path) {
+  if (file_path.empty()) {
+    LOG(ERROR) << "Generating file path was failed";
+    callback(ewk_view_, nullptr, user_data);
+    return;
+  }
+
+  MHTMLGenerationParams params(file_path);
+  web_contents_->GenerateMHTML(
+      params, base::BindOnce(&EWebView::MHTMLGenerated, base::Unretained(this),
+                             callback, user_data, file_path));
+}
+
+void EWebView::MHTMLGenerated(Ewk_View_Save_Page_Callback callback,
+                              void* user_data,
+                              const base::FilePath& file_path,
+                              int64_t file_size) {
+  callback(ewk_view_, file_size > 0 ? file_path.value().c_str() : nullptr,
+           user_data);
+}
+
+bool EWebView::GetBackgroundColor(
+    Ewk_View_Background_Color_Get_Callback callback,
+    void* user_data) {
+  if (!rwhva())
+    return false;
+  BackgroundColorGetCallback* cb =
+      new BackgroundColorGetCallback(callback, user_data);
+  int callback_id = background_color_get_callback_map_.Add(cb);
+
+  rwhva()->host()->RequestBackgroundColor(callback_id);
+  return true;
+}
+
+void EWebView::OnGetBackgroundColor(int callback_id, SkColor bg_color) {
+  BackgroundColorGetCallback* cb =
+      background_color_get_callback_map_.Lookup(callback_id);
+
+  if (!cb)
+    return;
+
+  cb->Run(ewk_view(), SkColorGetR(bg_color), SkColorGetG(bg_color),
+          SkColorGetB(bg_color), SkColorGetA(bg_color));
+  background_color_get_callback_map_.Remove(callback_id);
+}
+
 bool EWebView::IsFullscreen() {
   return web_contents_delegate_->IsFullscreenForTabOrPending(
       web_contents_.get());
@@ -1996,6 +2365,9 @@ void EWebView::DidChangePageScaleFactor(double scale_factor) {
   page_scale_factor_ = scale_factor;
   wcva()->wcva_helper()->SetPageScaleFactor(scale_factor);
   SetScaledContentsSize();
+
+  // Notify app about the scale change.
+  scale_changed_cb_.Run(ewk_view_, scale_factor);
 }
 
 inline JavaScriptDialogManagerEfl* EWebView::GetJavaScriptDialogManagerEfl() {
@@ -2040,20 +2412,77 @@ void EWebView::JavaScriptPromptReply(const char* result) {
 }
 
 void EWebView::GetPageScaleRange(double* min_scale, double* max_scale) {
-  auto prefs = web_contents_->GetOrCreateWebPreferences();
+  auto& prefs = web_contents_->GetOrCreateWebPreferences();
   if (min_scale)
     *min_scale = prefs.default_minimum_page_scale_factor;
   if (max_scale)
     *max_scale = prefs.default_maximum_page_scale_factor;
 }
 
-void EWebView::SetDrawsTransparentBackground(bool enabled) {
+content::WebContentsViewAura* EWebView::GetWebContentsViewAura() const {
+  WebContentsImpl* wc = static_cast<WebContentsImpl*>(web_contents_.get());
+  return static_cast<WebContentsViewAura*>(wc->GetView());
+}
+
+bool EWebView::SetDrawsTransparentBackground(bool enabled) {
+#if BUILDFLAG(IS_TIZEN)
   RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
-  if (!render_view_host)
-    return;
-#if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
-  render_view_host->Send(new EwkViewMsg_SetDrawsTransparentBackground(
-      render_view_host->GetRoutingID(), enabled));
+  if (!render_view_host || !rwhva())
+    return false;
+
+  if (!rwhva()->offscreen_helper())
+    return false;
+  elm_object_style_set(rwhva()->offscreen_helper()->content_image_elm_host(),
+                       enabled ? "transparent" : "default");
+  evas_object_image_alpha_set(rwhva()->offscreen_helper()->content_image(),
+                              enabled);
+  GetWebContentsViewAura()->SetBackgroundColor(enabled ? SK_ColorTRANSPARENT
+                                                       : SK_ColorWHITE);
+  static_cast<RenderViewHostImpl*>(render_view_host)
+      ->GetWidget()
+      ->GetAssociatedFrameWidget()
+      ->SetDrawsTransparentBackground(enabled);
+  rwhva()->SetBackgroundColor(enabled ? SK_ColorTRANSPARENT : SK_ColorWHITE);
+  return true;
+#else
+  return false;
+#endif
+}
+
+bool EWebView::GetDrawsTransparentBackground() {
+#if BUILDFLAG(IS_TIZEN)
+  return GetWebContentsViewAura()->GetBackgroundColor() == SK_ColorTRANSPARENT;
+#else
+  return false;
+#endif
+}
+
+bool EWebView::SetBackgroundColor(int red, int green, int blue, int alpha) {
+#if BUILDFLAG(IS_TIZEN)
+  if (!alpha)
+    return SetDrawsTransparentBackground(true);
+
+  RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
+  if (!render_view_host || !rwhva())
+    return false;
+
+  if (!rwhva()->offscreen_helper())
+    return false;
+  elm_object_style_set(rwhva()->offscreen_helper()->content_image_elm_host(),
+                       alpha < 255 ? "transparent" : "default");
+  evas_object_image_alpha_set(rwhva()->offscreen_helper()->content_image(),
+                              alpha < 255);
+  GetWebContentsViewAura()->SetBackgroundColor(
+      SkColorSetARGB(alpha, red, green, blue));
+  static_cast<RenderViewHostImpl*>(render_view_host)
+      ->GetWidget()
+      ->GetAssociatedFrameWidget()
+      ->SetBackgroundColor(red, green, blue, alpha);
+  rwhva()->SetBackgroundColor(SkColorSetARGB(alpha, red, green, blue));
+
+  return true;
+#else
+  return false;
 #endif
 }
 
@@ -2075,7 +2504,13 @@ void EWebView::GetSessionData(const char** data, unsigned* length) const {
     serializedEntry.WriteToPickle(MAX_SESSION_ENTRY_SIZE, &sessionPickle);
   }
 
-  *data = static_cast<char*>(malloc(sizeof(char) * sessionPickle.size()));
+  if (sessionPickle.size() <= 0 ||
+      !(*data =
+            static_cast<char*>(malloc(sizeof(char) * sessionPickle.size())))) {
+    LOG(ERROR) << "Failed to get session data";
+    *length = 0;
+    return;
+  }
   memcpy(const_cast<char*>(*data), sessionPickle.data(), sessionPickle.size());
   *length = sessionPickle.size();
 }
@@ -2116,12 +2551,8 @@ bool EWebView::RestoreFromSessionData(const char* data, unsigned length) {
   if (currentEntry >= static_cast<int>(scopedEntries.size()))
     currentEntry = scopedEntries.size() - 1;
 
-#if !defined(EWK_BRINGUP)  // FIXME: m67 bringup
-  // FIXME: EWK_BRINGUP definition should be removed.
-  navigationController.Restore(
-      currentEntry, NavigationController::RESTORE_LAST_SESSION_EXITED_CLEANLY,
-      &scopedEntries);
-#endif  // !defined(EWK_BRINGUP)
+  navigationController.Restore(currentEntry, RestoreType::kRestored,
+                               &scopedEntries);
   return true;
 }
 
@@ -2144,28 +2575,20 @@ bool EWebView::IsDragging() const {
   return wcva()->wcva_helper()->IsDragging();
 }
 
-void EWebView::ShowFileChooser(content::RenderFrameHost* render_frame_host,
-                               const blink::mojom::FileChooserParams& params) {
+void EWebView::ShowFileChooser(
+    scoped_refptr<content::FileSelectListener> listener,
+    const blink::mojom::FileChooserParams& params) {
+#if BUILDFLAG(IS_TIZEN_TV)
+  LOG(INFO) << "File chooser request callback.";
+  file_chooser_request_.reset(new _Ewk_File_Chooser_Request(
+      std::move(listener), params.accept_types, params.mode));
+  SmartCallback<EWebViewCallbacks::FileChooserRequest>().call(
+      file_chooser_request_.get());
+#else
   if (!IsMobileProfile() && !IsWearableProfile())
     return;
-
-#if !defined(EWK_BRINGUP)  // FIXME: m71 bringup
-  if (params.capture) {
-    const std::string capture_types[] = {"video/*", "audio/*", "image/*"};
-    unsigned int capture_types_num =
-        sizeof(capture_types) / sizeof(*capture_types);
-    for (unsigned int i = 0; i < capture_types_num; ++i) {
-      for (unsigned int j = 0; j < params.accept_types.size(); ++j) {
-        if (UTF16ToUTF8(params.accept_types[j]) == capture_types[i]) {
-          filechooser_mode_ = params.mode;
-          LaunchCamera(params.accept_types[j]);
-          return;
-        }
-      }
-    }
-  }
   file_chooser_.reset(
-      new content::FileChooserControllerEfl(render_frame_host, &params));
+      new content::FileChooserControllerEfl(std::move(listener), params));
   file_chooser_->Open();
 #endif
 }
@@ -2196,7 +2619,7 @@ void EWebView::ShowContentsDetectedPopup(const char* message) {
 }
 
 void EWebView::RequestColorPicker(int r, int g, int b, int a) {
-  input_picker_.reset(new InputPicker(this));
+  input_picker_.reset(new InputPicker(this, web_contents_.get(), ewk_view()));
   input_picker_->ShowColorPicker(r, g, b, a);
 }
 
@@ -2210,8 +2633,8 @@ bool EWebView::SetColorPickerColor(int r, int g, int b, int a) {
 void EWebView::InputPickerShow(ui::TextInputType input_type,
                                double input_value,
                                content::DateTimeChooserEfl* date_time_chooser) {
-  input_picker_.reset(new InputPicker(this));
-  date_time_chooser_ = date_time_chooser;
+  input_picker_.reset(new InputPicker(this, web_contents_.get(), ewk_view(),
+                                      date_time_chooser));
   input_picker_->ShowDatePicker(input_type, input_value);
 }
 
@@ -2239,10 +2662,30 @@ std::string EWebView::GetPlatformLocale() {
 }
 
 int EWebView::StartInspectorServer(int port) {
+#if BUILDFLAG(IS_TIZEN_TV)
+  if (IsTIZENWRT()) {
+    use_early_rwi_ = false;
+    rwi_info_showed_ = false;
+  }
+  if (!context_->GetImpl()->GetInspectorServerState()) {
+    int validPort = 0;
+    if (!devtools_http_handler::DevToolsPortManager::GetInstance()
+             ->GetValidPort(validPort))
+      return 0;
+
+    port = validPort;
+  }
+#endif
   return context_->InspectorServerStart(port);
 }
 
 bool EWebView::StopInspectorServer() {
+#if BUILDFLAG(IS_TIZEN_TV)
+  if (IsTIZENWRT()) {
+    use_early_rwi_ = false;
+    rwi_info_showed_ = false;
+  }
+#endif
   return context_->InspectorServerStop();
 }
 
@@ -2259,16 +2702,108 @@ void EWebView::InvokeWebProcessCrashedCallback() {
 void EWebView::SyncAcceptLanguages(const std::string& accept_languages) {
   web_contents_->GetMutableRendererPrefs()->accept_languages = accept_languages;
   web_contents_->SyncRendererPrefs();
+  BrowserContext* browser_context = web_contents_->GetBrowserContext();
+  if (!browser_context)
+    return;
+
+  auto* storage_partition = browser_context->GetDefaultStoragePartition();
+  if (!storage_partition)
+    return;
+
+  if (auto* network_context = storage_partition->GetNetworkContext())
+    network_context->SetAcceptLanguage(accept_languages);
+}
+
+#if BUILDFLAG(IS_TIZEN_TV)
+bool EWebView::EdgeScrollBy(int delta_x, int delta_y) {
+  if ((delta_x == 0 && delta_y == 0) || is_processing_edge_scroll_)
+    return false;
+
+  RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
+  if (!render_view_host)
+    return false;
+
+  if (!rwhva())
+    return false;
+
+  gfx::Point offset = gfx::Point(delta_x, delta_y);
+  gfx::Point mouse_position;
+  GetMousePosition(mouse_position);
+  is_processing_edge_scroll_ = true;
+
+  static_cast<RenderViewHostImpl*>(render_view_host)
+      ->GetWidget()
+      ->GetAssociatedFrameWidget()
+      ->EdgeScrollBy(offset, mouse_position);
+  return true;
+}
+
+void EWebView::GetMousePosition(gfx::Point& mouse_position) {
+  int mouse_x, mouse_y;
+  evas_pointer_output_xy_get(GetEvas(), &mouse_x, &mouse_y);
+  Evas_Coord x, y, width, height;
+  evas_object_geometry_get(ewk_view(), &x, &y, &width, &height);
+
+  if (mouse_y < y)
+    mouse_y = y + 1;
+  else if (mouse_y > y + height)
+    mouse_y = y + height - 1;
+  if (mouse_x < x)
+    mouse_x = x + 1;
+  else if (mouse_x > x + width)
+    mouse_x = x + width - 1;
+
+  mouse_x -= x;
+  mouse_y -= y;
+
+  mouse_x /=
+      display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
+  mouse_y /=
+      display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
+
+  mouse_position.set_x(mouse_x);
+  mouse_position.set_y(mouse_y);
 }
 
+void EWebView::InvokeEdgeScrollByCallback(const gfx::Point& offset,
+                                          bool handled) {
+  is_processing_edge_scroll_ = false;
+
+  if (offset.x() < 0)
+    SmartCallback<EWebViewCallbacks::EdgeScrollLeft>().call(&handled);
+  else if (offset.x() > 0)
+    SmartCallback<EWebViewCallbacks::EdgeScrollRight>().call(&handled);
+
+  if (offset.y() < 0)
+    SmartCallback<EWebViewCallbacks::EdgeScrollTop>().call(&handled);
+  else if (offset.y() > 0)
+    SmartCallback<EWebViewCallbacks::EdgeScrollBottom>().call(&handled);
+}
+#endif
+
+#if BUILDFLAG(IS_TIZEN_TV)
+void EWebView::InvokeScrollbarThumbFocusChangedCallback(
+    Ewk_Scrollbar_Orientation orientation,
+    bool focused) {
+  Ewk_Scrollbar_Data data;
+  data.orientation = orientation;
+  data.focused = focused;
+  SmartCallback<EWebViewCallbacks::DidChagneScrollbarsThumbFocus>().call(&data);
+}
+#endif
+
 void EWebView::HandleRendererProcessCrash() {
-  base::ThreadPool::PostTask(
-      FROM_HERE, {BrowserThread::UI},
+  content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
       base::BindOnce(&EWebView::InvokeWebProcessCrashedCallback,
                      base::Unretained(this)));
 }
 
 void EWebView::InitializeContent() {
+  LOG(INFO) << "eweb_view.cc  InitializeContent" ;
+#if BUILDFLAG(IS_TIZEN_TV)
+  // When initialize content init inspector server
+  InitInspectorServer();
+#endif
   WebContents* new_contents = create_new_window_web_contents_cb_.Run(this);
   if (!new_contents) {
     WebContents::CreateParams params(context_->browser_context());
@@ -2318,34 +2853,70 @@ void EWebView::InitializeContent() {
           << "Aborting execution ...";
     }
   }
+
   web_contents_delegate_.reset(new WebContentsDelegateEfl(this));
   web_contents_->SetDelegate(web_contents_delegate_.get());
+
+  // EWebView's delegate. Calls to WebContentsImplEfl and
+  // WebContentsViewAuraHelperEfl are delegated to this class.
+  // For more details, refer commit message of patch 301647.
+  webview_delegate_.reset(new WebViewDelegateEfl(this));
   WebContentsImplEfl* wc_efl =
       static_cast<WebContentsImplEfl*>(web_contents_.get());
-  wc_efl->SetEflDelegate(new WebContentsEflDelegateEwk(this));
-  wcva()->wcva_helper()->SetEflDelegate(wc_efl->GetEflDelegate());
+  wc_efl->SetWebviewDelegate(webview_delegate_.get());
+  wcva()->wcva_helper()->SetWebviewDelegate(webview_delegate_.get());
 
-  back_forward_list_.reset(
-      new _Ewk_Back_Forward_List(web_contents_->GetController()));
+  back_forward_list_.reset(new _Ewk_Back_Forward_List(web_contents_.get()));
 
-  permission_popup_manager_.reset(new PermissionPopupManager(evas_object_));
+  permission_popup_manager_.reset(new PermissionPopupManager(ewk_view_));
   gin_native_bridge_dispatcher_host_.reset(
       new content::GinNativeBridgeDispatcherHost(web_contents_.get()));
 
-  native_view_ =
-      static_cast<WebContentsImplEfl*>(web_contents_.get())->GetEflNativeView();
-  evas_object_smart_member_add(native_view_, evas_object_);
-  static_cast<WebContentsImpl*>(web_contents_.get())
-      ->set_ewk_view(evas_object_);
+  efl_main_layout_ =
+      static_cast<WebContentsImplEfl*>(web_contents_.get())->GetEflMainLayout();
+  evas_object_smart_member_add(efl_main_layout_, ewk_view_);
+  static_cast<WebContentsImpl*>(web_contents_.get())->set_ewk_view(ewk_view_);
   InitializeWindowTreeHost();
 }
 
+#if BUILDFLAG(IS_TIZEN_TV)
+void EWebView::OnDialogClosed() {
+  if (!use_early_rwi_)
+    return;
+
+  use_early_rwi_ = false;
+  LOG(INFO) << "[FAST RWI] SetURL Restore [" << rwi_gurl_.spec()
+            << "] from [about:blank]";
+  SetURL(rwi_gurl_);
+  rwi_gurl_ = GURL();
+  rwi_info_showed_ = true;
+}
+
+void EWebView::InitInspectorServer() {
+  if (devtools_http_handler::DevToolsPortManager::GetInstance()
+          ->ProcessCompare()) {
+    int res = StartInspectorServer(0);
+    if (res) {
+      LOG(INFO) << "InitInspectorServer SetPort";
+      devtools_http_handler::DevToolsPortManager::GetInstance()->SetPort(res);
+    }
+  }
+}
+#endif
+
+#if defined(TIZEN_TBM_SUPPORT)
+void EWebView::SetOffscreenRendering(bool enable) {
+  if (host_)
+    host_->compositor()->SetUseTbmSuraceForOffscreenRendering(enable);
+}
+#endif
+
 void EWebView::InitializeWindowTreeHost() {
   CHECK(aura::Env::GetInstance());
 
   int x, y, width, height;
   Ecore_Evas* ee =
-      ecore_evas_ecore_evas_get(evas_object_evas_get(native_view_));
+      ecore_evas_ecore_evas_get(evas_object_evas_get(efl_main_layout_));
   ecore_evas_geometry_get(ee, &x, &y, &width, &height);
 
   gfx::Rect bounds(x, y, width, height);
@@ -2360,6 +2931,8 @@ void EWebView::InitializeWindowTreeHost() {
       std::make_unique<aura::test::TestFocusClient>(host_->window());
   window_parenting_client_ =
       std::make_unique<aura::test::TestWindowParentingClient>(host_->window());
+  compositor_observer_ = std::make_unique<ui::CompositorObserverEfl>(
+      host_->compositor(), web_contents_.get());
 
   aura::Window* content = web_contents_->GetNativeView();
   aura::Window* parent = host_->window();
@@ -2373,71 +2946,6 @@ void EWebView::InitializeWindowTreeHost() {
     host_view->SetSize(bounds.size());
 }
 
-#if BUILDFLAG(IS_TIZEN) && !defined(EWK_BRINGUP)
-void EWebView::cameraResultCb(service_h request,
-                              service_h reply,
-                              service_result_e result,
-                              void* data) {
-  if (!IsMobileProfile() && !IsWearableProfile())
-    return;
-
-  EWebView* webview = static_cast<EWebView*>(data);
-  RenderViewHost* render_view_host =
-      webview->web_contents_->GetRenderViewHost();
-  if (result == SERVICE_RESULT_SUCCEEDED) {
-    int ret = -1;
-    char** filesarray;
-    int number;
-    ret = service_get_extra_data_array(reply, SERVICE_DATA_SELECTED,
-                                       &filesarray, &number);
-    if (filesarray) {
-      for (int i = 0; i < number; i++) {
-        std::vector<ui::SelectedFileInfo> files;
-        if (!render_view_host) {
-          return;
-        }
-        if (filesarray[i]) {
-          GURL url(filesarray[i]);
-          if (!url.is_valid()) {
-            base::FilePath path(url.SchemeIsFile() ? url.path()
-                                                   : filesarray[i]);
-            files.push_back(ui::SelectedFileInfo(path, base::FilePath()));
-          }
-        }
-        render_view_host->FilesSelectedInChooser(files,
-                                                 webview->filechooser_mode_);
-      }
-    }
-  } else {
-    std::vector<ui::SelectedFileInfo> files;
-    if (render_view_host) {
-      render_view_host->FilesSelectedInChooser(files,
-                                               webview->filechooser_mode_);
-    }
-  }
-}
-
-bool EWebView::LaunchCamera(std::u16string mimetype) {
-  service_h svcHandle = 0;
-  if (service_create(&svcHandle) < 0 || !svcHandle) {
-    LOG(ERROR) << __FUNCTION__ << " Service Creation Failed ";
-    return false;
-  }
-  service_set_operation(svcHandle, SERVICE_OPERATION_CREATE_CONTENT);
-  service_set_mime(svcHandle, UTF16ToUTF8(mimetype).c_str());
-  service_add_extra_data(svcHandle, "CALLER", "Browser");
-
-  int ret = service_send_launch_request(svcHandle, cameraResultCb, this);
-  if (ret != SERVICE_ERROR_NONE) {
-    LOG(ERROR) << __FUNCTION__ << " Service Launch Failed ";
-    service_destroy(svcHandle);
-    return false;
-  }
-  service_destroy(svcHandle);
-  return true;
-}
-#endif
-
 void EWebView::UrlRequestSet(
     const char* url,
     content::NavigationController::LoadURLType loadtype,
@@ -2475,8 +2983,30 @@ void EWebView::UrlRequestSet(
   web_contents_->GetController().LoadURLWithParams(params);
 }
 
+#if defined(TIZEN_VIDEO_HOLE)
+void EWebView::EnableVideoHoleSupport() {
+  if (!web_contents_->GetPrimaryMainFrame() ||
+      !web_contents_->GetPrimaryMainFrame()->IsRenderFrameLive() || !rwhva()) {
+    pending_video_hole_setting_ = true;
+    return;
+  }
+
+  EnableVideoHoleSupportInternal();
+}
+
+void EWebView::EnableVideoHoleSupportInternal() {
+  if (settings_->getPreferences().video_hole_enabled)
+    return;
+
+  settings_->getPreferences().video_hole_enabled = true;
+  WebContentsImpl* wc = static_cast<WebContentsImpl*>(web_contents_.get());
+  if (wc)
+    wc->EnableVideoHole();
+}
+#endif
+
 bool EWebView::HandleShow() {
-  if (!native_view_)
+  if (!efl_main_layout_)
     return false;
 
   Show();
@@ -2484,7 +3014,7 @@ bool EWebView::HandleShow() {
 }
 
 bool EWebView::HandleHide() {
-  if (!native_view_)
+  if (!efl_main_layout_)
     return false;
 
   Hide();
@@ -2492,16 +3022,46 @@ bool EWebView::HandleHide() {
 }
 
 bool EWebView::HandleMove(int x, int y) {
-  if (!native_view_)
+  if (!efl_main_layout_)
     return false;
-  evas_object_move(native_view_, x, y);
+  evas_object_move(efl_main_layout_, x, y);
+  LOG(INFO) << "Move x " << x << " y " << y;
+#if defined(TIZEN_VIDEO_HOLE)
+  if (rwhva())
+    rwhva()->DidMoveWebView();
+#endif
+
+  if (context_menu_)
+    context_menu_->Move(x, y);
+
   return true;
 }
 
 bool EWebView::HandleResize(int width, int height) {
-  if (!native_view_)
+  if (!efl_main_layout_)
     return false;
-  evas_object_resize(native_view_, width, height);
+  evas_object_resize(efl_main_layout_, width, height);
+
+#if defined(TIZEN_VIDEO_HOLE)
+  LOG(INFO) << __func__ << " new size " << width << "*" << height;
+  if (rwhva())
+    rwhva()->DidMoveWebView();
+#endif
+
+  if (select_picker_) {
+    AdjustViewPortHeightToPopupMenu(true /* is_popup_menu_visible */);
+    ScrollFocusedNodeIntoView();
+  }
+
+#if defined(USE_AURA) && BUILDFLAG(IS_TIZEN_TV)
+  if (host_) {
+    int x, y;
+    evas_object_geometry_get(efl_main_layout_, &x, &y, nullptr, nullptr);
+    gfx::Rect bounds(x, y, width, height);
+    host_->SetBoundsInPixels(bounds);
+  }
+#endif
+
   return true;
 }
 
@@ -2536,17 +3096,43 @@ void EWebView::HandleZoomGesture(blink::WebGestureEvent& event) {
   }
 }
 
+bool EWebView::GetHorizontalPanningHold() const {
+  if (!rwhva())
+    return false;
+  return rwhva()->offscreen_helper()->GetHorizontalPanningHold();
+}
+
+void EWebView::SetHorizontalPanningHold(bool hold) {
+  if (rwhva())
+    rwhva()->offscreen_helper()->SetHorizontalPanningHold(hold);
+}
+
+bool EWebView::GetVerticalPanningHold() const {
+  if (!rwhva())
+    return false;
+  return rwhva()->offscreen_helper()->GetVerticalPanningHold();
+}
+
+void EWebView::SetVerticalPanningHold(bool hold) {
+  if (rwhva())
+    rwhva()->offscreen_helper()->SetVerticalPanningHold(hold);
+}
+
 void EWebView::SendDelayedMessages(RenderViewHost* render_view_host) {
   DCHECK(render_view_host);
 
   if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
-    base::ThreadPool::PostTask(
-        FROM_HERE, {BrowserThread::UI},
+    content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
         base::BindOnce(&EWebView::SendDelayedMessages, base::Unretained(this),
                        render_view_host));
     return;
   }
 
+#if BUILDFLAG(IS_TIZEN_TV)
+  if (pending_setfocus_closure_)
+    std::move(pending_setfocus_closure_).Run();
+#endif
+
   for (auto iter = delayed_messages_.begin(); iter != delayed_messages_.end();
        ++iter) {
     IPC::Message* message = *iter;
@@ -2563,6 +3149,47 @@ void EWebView::ClosePage() {
   web_contents_->ClosePage();
 }
 
+bool EWebView::SetMainFrameScrollbarVisible(bool visible) {
+  if (web_contents_->GetPrimaryMainFrame()->IsRenderFrameLive() && rwhva())
+    rwhva()->host()->SetMainFrameScrollbarVisible(visible);
+  return true;
+}
+
+bool EWebView::GetMainFrameScrollbarVisible(
+    Ewk_View_Main_Frame_Scrollbar_Visible_Get_Callback callback,
+    void* user_data) {
+  if (!rwhva())
+    return false;
+
+  MainFrameScrollbarVisibleGetCallback* callback_ptr =
+      new MainFrameScrollbarVisibleGetCallback;
+  callback_ptr->Set(callback, user_data);
+  int callback_id =
+      main_frame_scrollbar_visible_callback_map_.Add(callback_ptr);
+  rwhva()->host()->RequestMainFrameScrollbarVisible(callback_id);
+  return true;
+}
+
+void EWebView::InvokeMainFrameScrollbarVisibleCallback(int callback_id,
+                                                       bool visible) {
+  if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
+    content::GetUIThreadTaskRunner({})->PostTask(
+        FROM_HERE,
+        base::BindOnce(&EWebView::InvokeMainFrameScrollbarVisibleCallback,
+                       base::Unretained(this), visible, callback_id));
+    return;
+  }
+
+  MainFrameScrollbarVisibleGetCallback* callback =
+      main_frame_scrollbar_visible_callback_map_.Lookup(callback_id);
+  if (!callback)
+    return;
+
+  main_frame_scrollbar_visible_callback_map_.Remove(callback_id);
+  callback->Run(ewk_view(), visible);
+  main_frame_scrollbar_visible_callback_map_.Remove(callback_id);
+}
+
 void EWebView::OnOverscrolled(const gfx::Vector2dF& accumulated_overscroll,
                               const gfx::Vector2dF& latest_overscroll_delta) {
   const gfx::Vector2dF old_overscroll =
@@ -2580,6 +3207,67 @@ void EWebView::OnOverscrolled(const gfx::Vector2dF& accumulated_overscroll,
   }
 }
 
+void EWebView::SetDidChangeThemeColorCallback(
+    Ewk_View_Did_Change_Theme_Color_Callback callback,
+    void* user_data) {
+  did_change_theme_color_callback_.Set(callback, user_data);
+}
+
+void EWebView::DidChangeThemeColor(const SkColor& color) {
+  did_change_theme_color_callback_.Run(ewk_view_, color);
+}
+
+#if BUILDFLAG(IS_TIZEN_TV)
+void EWebView::DrawLabel(Evas_Object* image, Eina_Rectangle rect) {
+  if (rwhva())
+    rwhva()->offscreen_helper()->DrawLabel(image, rect);
+}
+
+void EWebView::DeactivateAtk(bool deactivated) {
+#if defined(TIZEN_ATK_SUPPORT)
+  EWebAccessibilityUtil::GetInstance()->Deactivate(deactivated);
+#endif
+}
+
+void EWebView::ClearLabels() {
+  if (rwhva())
+    rwhva()->offscreen_helper()->ClearLabels();
+}
+
+void EWebView::SetTranslatedURL(const char* url) {
+  if (!rwhva() || !rwhva()->aura_efl_helper())
+    return;
+  rwhva()->aura_efl_helper()->SetTranslatedURL(std::string(url));
+  LOG(INFO) << "translate_url:" << url;
+}
+
+bool EWebView::IsVideoPlaying(Ewk_Is_Video_Playing_Callback callback,
+                              void* user_data) {
+  IsVideoPlayingCallback* cb = new IsVideoPlayingCallback(callback, user_data);
+  int callback_id = is_video_playing_callback_map_.Add(cb);
+
+  if (!rwhva() || !rwhva()->aura_efl_helper()) {
+    LOG(ERROR) << "rwhva() or rwhva()->aura_efl_helper() is false";
+    return false;
+  }
+  rwhva()->aura_efl_helper()->RequestVideoPlaying(callback_id);
+  return true;
+}
+
+void EWebView::InvokeIsVideoPlayingCallback(bool is_playing, int callback_id) {
+  IsVideoPlayingCallback* callback =
+      is_video_playing_callback_map_.Lookup(callback_id);
+  if (!callback) {
+    LOG(INFO) << "callback is null";
+    return;
+  }
+
+  LOG(INFO) << __func__ << " ; is_playing : " << is_playing;
+  callback->Run(ewk_view(), is_playing);
+  is_video_playing_callback_map_.Remove(callback_id);
+}
+#endif
+
 void EWebView::RequestManifest(Ewk_View_Request_Manifest_Callback callback,
                                void* user_data) {
   web_contents_delegate_->RequestManifestInfo(callback, user_data);
@@ -2589,9 +3277,99 @@ void EWebView::DidRespondRequestManifest(
     _Ewk_View_Request_Manifest* manifest,
     Ewk_View_Request_Manifest_Callback callback,
     void* user_data) {
-  callback(evas_object_, manifest, user_data);
+  callback(ewk_view_, manifest, user_data);
+}
+
+void EWebView::SetSessionTimeout(uint64_t timeout) {
+  if (web_contents_->GetPrimaryMainFrame()->IsRenderFrameLive() && rwhva())
+    rwhva()->host()->SetLongPollingGlobalTimeout(timeout);
+}
+
+void EWebView::SetBeforeUnloadConfirmPanelCallback(
+    Ewk_View_Before_Unload_Confirm_Panel_Callback callback,
+    void* user_data) {
+  GetJavaScriptDialogManagerEfl()->SetBeforeUnloadConfirmPanelCallback(
+      callback, user_data);
+}
+
+void EWebView::ReplyBeforeUnloadConfirmPanel(Eina_Bool result) {
+  GetJavaScriptDialogManagerEfl()->ReplyBeforeUnloadConfirmPanel(result);
+}
+
+#if defined(TIZEN_PEPPER_EXTENSIONS)
+void EWebView::InitializePepperExtensionSystem() {
+  RegisterPepperExtensionDelegate();
+  SetWindowId();
+}
+
+EwkExtensionSystemDelegate* EWebView::GetExtensionDelegate() {
+  RenderFrameHost* render_frame_host = web_contents_->GetPrimaryMainFrame();
+  if (!render_frame_host)
+    return nullptr;
+
+  return static_cast<EwkExtensionSystemDelegate*>(
+      ExtensionSystemDelegateManager::GetInstance()->GetDelegateForFrame(render_frame_id_));
+}
+
+void EWebView::SetWindowId() {
+  EwkExtensionSystemDelegate* delegate = GetExtensionDelegate();
+  if (!delegate) {
+    LOG(WARNING) << "No delegate is available to set window id";
+    return;
+  }
+  Evas_Object* main_wind =
+      efl::WindowFactory::GetHostWindow(web_contents_.get());
+  if (!main_wind) {
+    LOG(ERROR) << "Can`t get main window";
+    return;
+  }
+  delegate->SetWindowId(main_wind);
 }
 
+void EWebView::SetPepperExtensionWidgetInfo(Ewk_Value widget_pepper_ext_info) {
+  EwkExtensionSystemDelegate* delegate = GetExtensionDelegate();
+  if (!delegate) {
+    LOG(WARNING) << "No delegate is available to set extension info";
+    return;
+  }
+  delegate->SetExtensionInfo(widget_pepper_ext_info);
+}
+
+void EWebView::SetPepperExtensionCallback(Generic_Sync_Call_Callback cb,
+                                          void* data) {
+  EwkExtensionSystemDelegate* delegate = GetExtensionDelegate();
+  if (!delegate) {
+    LOG(WARNING) << "No delegate is available to set generic callback";
+    return;
+  }
+  delegate->SetGenericSyncCallback(cb, data);
+}
+
+void EWebView::RegisterPepperExtensionDelegate() {
+  RenderFrameHost* render_frame_host = web_contents_->GetPrimaryMainFrame();
+  if (!render_frame_host) {
+    LOG(WARNING) << "render_frame_host is nullptr, can't register delegate";
+    return;
+  }
+
+  render_frame_id_.render_process_id = render_frame_host->GetProcess()->GetID();
+  render_frame_id_.render_frame_id = render_frame_host->GetRoutingID();
+
+  EwkExtensionSystemDelegate* delegate = new EwkExtensionSystemDelegate;
+  ExtensionSystemDelegateManager::GetInstance()->RegisterDelegate(
+      render_frame_id_, std::unique_ptr<EwkExtensionSystemDelegate>{delegate});
+}
+
+void EWebView::UnregisterPepperExtensionDelegate() {
+  if (!web_contents_) {
+    LOG(WARNING) << "web_contents_ is nullptr, can't unregister delegate";
+    return;
+  }
+  if (!ExtensionSystemDelegateManager::GetInstance()->UnregisterDelegate(render_frame_id_))
+    LOG(WARNING) << "Unregistering pepper extension delegate failed";
+}
+#endif  // defined(TIZEN_PEPPER_EXTENSIONS)
+
 void EWebView::SetExceededIndexedDatabaseQuotaCallback(
     Ewk_View_Exceeded_Indexed_Database_Quota_Callback callback,
     void* user_data) {
@@ -2610,8 +3388,7 @@ void EWebView::InvokeExceededIndexedDatabaseQuotaCallback(
     const GURL& origin,
     int64_t current_quota) {
   if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
-    base::ThreadPool::PostTask(
-        FROM_HERE, {BrowserThread::UI},
+    content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
         base::BindOnce(&EWebView::InvokeExceededIndexedDatabaseQuotaCallback,
                        base::Unretained(this), origin, current_quota));
     return;
@@ -2620,7 +3397,7 @@ void EWebView::InvokeExceededIndexedDatabaseQuotaCallback(
   CHECK(!exceeded_indexed_db_quota_origin_.get());
   exceeded_indexed_db_quota_origin_.reset(new Ewk_Security_Origin(origin));
   exceeded_indexed_db_quota_callback_.Run(
-      evas_object_, exceeded_indexed_db_quota_origin_.get(), current_quota);
+      ewk_view_, exceeded_indexed_db_quota_origin_.get(), current_quota);
 }
 
 void EWebView::ExceededIndexedDatabaseQuotaReply(bool allow) {
@@ -2640,6 +3417,137 @@ void EWebView::ExceededIndexedDatabaseQuotaReply(bool allow) {
   exceeded_indexed_db_quota_origin_.reset();
 }
 
+bool EWebView::ShouldIgnoreNavigation(
+    content::NavigationHandle* navigation_handle) {
+  if (!navigation_handle->GetURL().is_valid() ||
+      !navigation_handle->GetURL().SchemeIs("appcontrol") ||
+      (!navigation_handle->HasUserGesture() &&
+       !navigation_handle->WasServerRedirect())) {
+    return false;
+  }
+
+  _Ewk_App_Control app_control(
+      this, navigation_handle->GetURL().possibly_invalid_spec());
+  return app_control.Proceed();
+}
+
+#if BUILDFLAG(IS_TIZEN_TV)
+void EWebView::AddDynamicCertificatePath(const std::string& host,
+                                         const std::string& cert_path) {
+  web_contents_->AddDynamicCertificatePath(host, cert_path);
+}
+
+void EWebView::NotifySubtitleState(int state, double time_stamp) {
+  LOG(INFO) << "subtitle state: " << state
+            << ",(0-Play : 1-Pause : 2-SeekStart : 3-SeekComplete : 4-Stop "
+               ":5-Resume)";
+  switch (state) {
+    case blink::WebMediaPlayer::kSubtitlePause:
+      SmartCallback<EWebViewCallbacks::SubtitlePause>().call();
+      break;
+    case blink::WebMediaPlayer::kSubtitleStop:
+      SmartCallback<EWebViewCallbacks::SubtitleStop>().call();
+      break;
+    case blink::WebMediaPlayer::kSubtitleResume:
+      SmartCallback<EWebViewCallbacks::SubtitleResume>().call();
+      break;
+    case blink::WebMediaPlayer::kSubtitleSeekStart: {
+      double ts = time_stamp;
+      SmartCallback<EWebViewCallbacks::SubtitleSeekStart>().call(&ts);
+    } break;
+    case blink::WebMediaPlayer::kSubtitleSeekComplete:
+      SmartCallback<EWebViewCallbacks::SubtitleSeekComplete>().call();
+      break;
+    default:
+      NOTREACHED();
+      break;
+  }
+}
+
+void EWebView::NotifySubtitlePlay(int active_track_id,
+                                  const char* url,
+                                  const char* lang) {
+  LOG(INFO) << "id:" << active_track_id << ",url:" << url << ",lang:" << lang;
+  Ewk_Media_Subtitle_Info* subtitle_info =
+      ewkMediaSubtitleInfoCreate(active_track_id, url, lang, 0);
+  SmartCallback<EWebViewCallbacks::SubtitlePlay>().call(
+      static_cast<void*>(subtitle_info));
+  ewkMediaSubtitleInfoDelete(subtitle_info);
+}
+
+void EWebView::NotifySubtitleData(int track_id,
+                                  double time_stamp,
+                                  const std::string& data,
+                                  unsigned int size) {
+  const void* buffer = static_cast<const void*>(data.c_str());
+  Ewk_Media_Subtitle_Data* subtitle_data =
+      ewkMediaSubtitleDataCreate(track_id, time_stamp, buffer, size);
+  SmartCallback<EWebViewCallbacks::SubtitleNotifyData>().call(
+      static_cast<void*>(subtitle_data));
+  ewkMediaSubtitleDataDelete(subtitle_data);
+}
+
+void EWebView::UpdateCurrentTime(double current_time) {
+  current_time_ = current_time;
+}
+
+void EWebView::UpdateEventData(void* data) {
+  LOG(INFO) << "EWebView::UpdateEventData data:" << (char*)data;
+  SmartCallback<EWebViewCallbacks::EVENTData>().call(data);
+}
+
+void EWebView::NotifyParentalRatingInfo(const char* info, const char* url) {
+  LOG(INFO) << "info:" << info << ",url:" << url;
+  Ewk_Media_Parental_Rating_Info* data =
+      ewkMediaParentalRatingInfoCreate(info, url);
+  SmartCallback<EWebViewCallbacks::ParentalRatingInfo>().call(
+      static_cast<void*>(data));
+  ewkMediaParentalRatingInfoDelete(data);
+}
+
+void EWebView::SetParentalRatingResult(const char* url, bool is_pass) {
+  LOG(INFO) << "SetParentalRatingResult,url:" << url
+            << ",pass:" << std::boolalpha << is_pass;
+
+  if (!rwhva() || !rwhva()->aura_efl_helper()){
+    LOG(ERROR) << "rwhva() or rwhva()->aura_efl_helper() is false";
+    return;
+  }
+  rwhva()->aura_efl_helper()->SetParentalRatingResult(
+      static_cast<std::string>(url), is_pass);
+}
+void EWebView::NotifyFirstTimeStamp(unsigned long long timestamp,
+                                    int time_base_num,
+                                    int time_base_den) {
+  Ewk_First_Timestamp_Info* info =
+      ewkFirstTimeStampInfoCreate(timestamp, time_base_num, time_base_den);
+  SmartCallback<EWebViewCallbacks::FirstTimestamp>().call(
+      static_cast<void*>(info));
+  ewkFirstTimeStampInfoDelete(info);
+}
+
+void EWebView::NotifyPESData(const std::string& buf,
+                             unsigned int len,
+                             int media_position) {
+  const void* data = static_cast<const void*>(buf.c_str());
+  Ewk_PES_Info* info = ewkPESInfoCreate(data, len, media_position);
+  SmartCallback<EWebViewCallbacks::PESData>().call(static_cast<void*>(info));
+  ewkPESInfoDelete(info);
+}
+
+void EWebView::SetPreferSubtitleLang(const char* lang_list) {
+  LOG(INFO) << "SetPreferSubtitleLang: " << lang_list;
+  const std::string lang(lang_list ? lang_list : "");
+
+  if (!rwhva()) {
+    LOG(ERROR) << "rwhva() is null";
+    return;
+  }
+
+  rwhva()->aura_efl_helper()->SetPreferSubtitleLang(lang);
+}
+#endif
+
 bool EWebView::SetVisibility(bool enable) {
   if (!web_contents_)
     return false;
@@ -2650,4 +3558,223 @@ bool EWebView::SetVisibility(bool enable) {
     web_contents_->WasHidden();
 
   return true;
-}
\ No newline at end of file
+}
+
+void EWebView::SetDoNotTrack(Eina_Bool enable) {
+  // enable: 0 User tend to allow tracking on the target site.
+  // enable: 1 User tend to not be tracked on the target site.
+  if (web_contents_->GetMutableRendererPrefs()->enable_do_not_track == enable)
+    return;
+
+  // Set navigator.doNotTrack attribute
+  web_contents_->GetMutableRendererPrefs()->enable_do_not_track = enable;
+  web_contents_->SyncRendererPrefs();
+
+  // Set or remove DNT HTTP header, the effects will depend on design of target
+  // site.
+  if (!context())
+    return;
+
+  if (enable)
+    context()->HTTPCustomHeaderAdd("DNT", "1");
+  else
+    context()->HTTPCustomHeaderRemove("DNT");
+}
+
+#if defined(TIZEN_ATK_SUPPORT)
+void EWebView::UpdateSpatialNavigationStatus(Eina_Bool enable) {
+  if (settings_->getPreferences().spatial_navigation_enabled == enable)
+    return;
+
+  settings_->getPreferences().spatial_navigation_enabled = enable;
+  WebContentsImpl* wc = static_cast<WebContentsImpl*>(web_contents_.get());
+  if (wc)
+    wc->SetSpatialNavigationEnabled(enable);
+}
+
+void EWebView::UpdateAccessibilityStatus(Eina_Bool enable) {
+  if (settings_->getPreferences().atk_enabled == enable)
+    return;
+
+  settings_->getPreferences().atk_enabled = enable;
+  WebContentsImpl* wc = static_cast<WebContentsImpl*>(web_contents_.get());
+  if (wc)
+    wc->SetAtkEnabled(enable);
+}
+
+void EWebView::InitAtk() {
+#if defined(TIZEN_ATK_SUPPORT)
+  EWebAccessibilityUtil::GetInstance()->ToggleAtk(lazy_initialize_atk_);
+#endif
+}
+
+/* LCOV_EXCL_START */
+bool EWebView::GetAtkStatus() {
+  auto state = content::BrowserAccessibilityStateImpl::GetInstance();
+  if (!state)
+    return false;
+  return state->IsAccessibleBrowser();
+}
+/* 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);
+}
+
+void EWebView::NotifyDownloadableFontInfo(const char* scheme_id_uri,
+                                          const char* value,
+                                          const char* data,
+                                          int type) {
+  LOG(INFO) << "scheme_id_uri:" << scheme_id_uri << ",value:" << value
+            << ",data:" << data << ",type:" << type;
+  Ewk_Media_Downloadable_Font_Info* info =
+      ewkMediaDownloadableFontInfoCreate(scheme_id_uri, value, data, type);
+  SmartCallback<EWebViewCallbacks::DownloadableFontInfo>().call(
+      static_cast<void*>(info));
+  ewkMediaDownloadableFontInfoDelete(info);
+}
+
+std::vector<std::string> EWebView::NotifyPlaybackState(int state,
+                                                       int player_id,
+                                                       const char* url,
+                                                       const char* mime_type) {
+  std::vector<std::string> data;
+  Ewk_Media_Playback_Info* playback_info =
+      ewkMediaPlaybackInfoCreate(player_id, url, mime_type);
+
+  LOG(INFO)
+      << "player_id:" << player_id << ",state: " << state
+      << "(0-load : 1-videoready : 2-ready : 3-start : 4-finish : 5-stop)";
+  switch (state) {
+    case kPlaybackLoad:
+      SmartCallback<EWebViewCallbacks::PlaybackLoad>().call(
+          static_cast<void*>(playback_info));
+      break;
+    case kPlaybackReady:
+      SmartCallback<EWebViewCallbacks::PlaybackReady>().call(
+          static_cast<void*>(playback_info));
+      break;
+    case kPlaybackStart:
+      SmartCallback<EWebViewCallbacks::PlaybackStart>().call(
+          static_cast<void*>(playback_info));
+      break;
+    case kPlaybackFinish:
+      SmartCallback<EWebViewCallbacks::PlaybackFinish>().call(
+          static_cast<void*>(playback_info));
+      break;
+    case kPlaybackStop:
+      SmartCallback<EWebViewCallbacks::PlaybackStop>().call(
+          static_cast<void*>(playback_info));
+      break;
+    default:
+      NOTREACHED();
+      data.push_back("");
+      ewkMediaPlaybackInfoDelete(playback_info);
+      return data;
+  }
+
+  bool media_resource_acquired =
+      ewk_media_playback_info_media_resource_acquired_get(playback_info)
+          ? true
+          : false;
+  data.push_back(media_resource_acquired ? "mediaResourceAcquired" : "");
+  const char* translated_url =
+      ewk_media_playback_info_translated_url_get(playback_info);
+  data.push_back(translated_url ? std::string(translated_url) : "");
+  const char* drm_info = ewk_media_playback_info_drm_info_get(playback_info);
+  data.push_back(drm_info ? std::string(drm_info) : "");
+
+  LOG(INFO) << "evasObject: " << ewk_view_
+            << ", media_resource_acquired :" << media_resource_acquired
+            << ", translated_url:" << translated_url
+            << ", drm_info:" << drm_info;
+  ewkMediaPlaybackInfoDelete(playback_info);
+  return data;
+}
+
+void EWebView::NotifyMediaStateChanged(uint32_t device_type,
+                                       uint32_t previous,
+                                       uint32_t current) {
+  LOG(INFO) << "NotifyMediaStateChanged type : " << device_type
+            << " ;previous: " << previous << " ; current: " << current;
+  Ewk_User_Media_State_Info* user_media_state_info =
+      new _Ewk_User_Media_State_Info;
+  user_media_state_info->device_type =
+      static_cast<Ewk_User_Media_Device_Type>(device_type);
+  user_media_state_info->previous_state = previous;
+  user_media_state_info->current_state = current;
+  SmartCallback<EWebViewCallbacks::UserMediaState>().call(
+      static_cast<void*>(user_media_state_info));
+
+  delete user_media_state_info;
+}
+
+void EWebView::SetHighBitRate(Eina_Bool high_bitrate) {
+  LOG(INFO) << "high_bitrate: " << std::boolalpha << high_bitrate;
+  is_high_bitrate_ = high_bitrate;
+}
+
+void EWebView::OnDeviceListed(const MediaDeviceEnumeration& devices) {
+  int device_count = 0;
+  EwkMediaDeviceInfo* device_list = nullptr;
+  for (const auto& device : devices)
+    device_count += device.size();
+
+  device_list =
+      (EwkMediaDeviceInfo*)malloc(sizeof(EwkMediaDeviceInfo) * device_count);
+  if (!device_list) {
+    LOG(ERROR) << "malloc EwkMediaDeviceInfo failed";
+    device_cb_.Run(device_list, 0);
+    return;
+  }
+
+  int idx = 0;
+  for (int i = 0; i < NUM_MEDIA_DEVICE_TYPES; i++) {
+    blink::WebMediaDeviceInfoArray array = devices[i];
+    for (const auto& device : array) {
+      LOG(INFO) << "OnDeviceListed type:" << i
+                << ",device_id:" << device.device_id
+                << ",lable:" << device.label;
+
+      // convert device info to ewk structure
+      EwkMediaDeviceInfo* data = &device_list[idx++];
+      data->device_id = eina_stringshare_add(device.device_id.c_str());
+      data->label = eina_stringshare_add(device.label.c_str());
+      data->type = static_cast<EwkMediaDeviceType>(i);
+      data->connected = true;
+    }
+  }
+
+  device_cb_.Run(device_list, device_count);
+
+  // free data
+  for (int i = 0; i < device_count; i++) {
+    EwkMediaDeviceInfo* device = &device_list[i];
+    if (device->device_id)
+      eina_stringshare_del(device->device_id);
+    if (device->label)
+      eina_stringshare_del(device->label);
+  }
+  if (device_list) {
+    free(device_list);
+    device_list = NULL;
+  }
+}
+
+void EWebView::GetMediaDeviceList(Ewk_Media_Device_List_Get_Callback callback,
+                                  void* userData) {
+  if (!web_contents_delegate_) {
+    LOG(ERROR) << "no web_contents_delegate_";
+    return;
+  }
+
+  device_cb_.Set(callback, userData);
+
+  web_contents_delegate_->GetMediaDeviceList(
+      base::BindOnce(&EWebView::OnDeviceListed, weak_factory_.GetWeakPtr()));
+}
+#endif