[M108 Migration] Add implementation of SetUserAgentOverride
[platform/framework/web/chromium-efl.git] / tizen_src / ewk / efl_integration / eweb_view.cc
1 // Copyright 2014 Samsung Electronics. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "eweb_view.h"
6
7 #include "base/command_line.h"
8 #include "base/files/file_path.h"
9 #include "base/logging.h"
10 #include "base/pickle.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "browser/navigation_policy_handler_efl.h"
13 #include "browser/quota_permission_context_efl.h"
14 #include "browser/selectpicker/popup_menu_item.h"
15 #include "browser/selectpicker/popup_menu_item_private.h"
16 #include "browser/web_view_browser_message_filter.h"
17 #include "browser/web_view_evas_handler.h"
18 #include "common/content_client_efl.h"
19 #include "common/render_messages_ewk.h"
20 #include "common/version_info.h"
21 #include "common/web_contents_utils.h"
22 #include "components/sessions/content/content_serialized_navigation_builder.h"
23 #include "components/sessions/core/serialized_navigation_entry.h"
24 #include "content/browser/renderer_host/render_view_host_impl.h"
25 #include "content/browser/renderer_host/render_widget_host_view_aura.h"
26 #include "content/browser/renderer_host/ui_events_helper.h"
27 #include "content/browser/web_contents/web_contents_impl_efl.h"
28 #include "content/browser/web_contents/web_contents_view.h"
29 #include "content/common/content_client_export.h"
30 #include "content/public/browser/browser_message_filter.h"
31 #include "content/public/browser/browser_task_traits.h"
32 #include "content/public/browser/browser_thread.h"
33 #include "content/public/browser/host_zoom_map.h"
34 #include "content/public/browser/navigation_controller.h"
35 #include "content/public/browser/navigation_entry.h"
36 #include "content/public/common/content_client.h"
37 #include "content/public/common/content_switches.h"
38 #include "content/public/common/user_agent.h"
39 #include "permission_popup_manager.cc"
40 #include "private/ewk_back_forward_list_private.h"
41 #include "private/ewk_context_private.h"
42 #include "private/ewk_frame_private.h"
43 #include "private/ewk_policy_decision_private.h"
44 #include "private/ewk_quota_permission_request_private.h"
45 #include "private/ewk_settings_private.h"
46 #include "private/ewk_text_style_private.h"
47 #include "private/webview_delegate_ewk.h"
48 #include "public/ewk_hit_test_internal.h"
49 #include "services/network/public/cpp/resource_request_body.h"
50 #include "skia/ext/platform_canvas.h"
51 #include "third_party/blink/public/common/page/page_zoom.h"
52 #include "third_party/blink/public/platform/web_string.h"
53 #include "tizen/system_info.h"
54 #include "ui/aura/env.h"
55 #include "ui/aura/test/test_focus_client.h"
56 #include "ui/aura/test/test_window_parenting_client.h"
57 #include "ui/aura/window.h"
58 #include "ui/base/l10n/l10n_util.h"
59 #include "ui/display/screen.h"
60 #include "ui/gfx/geometry/dip_util.h"
61 #include "ui/gfx/geometry/vector2d_f.h"
62 #include "ui/platform_window/platform_window_init_properties.h"
63 #include "web_contents_delegate_efl.h"
64 #include "web_contents_efl_delegate_ewk.h"
65
66 #include <Ecore_Evas.h>
67 #include <Elementary.h>
68 #include <Eina.h>
69
70 #include <iostream>
71
72 using namespace content;
73 using web_contents_utils::WebViewFromWebContents;
74
75 namespace {
76
77 static const char* kRendererCrashedHTMLMessage =
78     "<html><body><h1>Renderer process has crashed!</h1></body></html>";
79
80 inline void SetDefaultStringIfNull(const char*& variable,
81                                    const char* default_string) {
82   if (!variable) {
83     variable = default_string;
84   }
85 }
86
87 void GetEinaRectFromGfxRect(const gfx::Rect& gfx_rect,
88                             Eina_Rectangle* eina_rect) {
89   eina_rect->x = gfx_rect.x();
90   eina_rect->y = gfx_rect.y();
91   eina_rect->w = gfx_rect.width();
92   eina_rect->h = gfx_rect.height();
93 }
94
95 static content::WebContents* NullCreateWebContents(void*) {
96   return NULL;
97 }
98
99 }  // namespace
100
101 class WebViewAsyncRequestHitTestDataCallback {
102  public:
103   WebViewAsyncRequestHitTestDataCallback(int x, int y, Ewk_Hit_Test_Mode mode)
104       : x_(x), y_(y), mode_(mode) {}
105   virtual ~WebViewAsyncRequestHitTestDataCallback(){};
106
107   virtual void Run(_Ewk_Hit_Test* hit_test, EWebView* web_view) = 0;
108
109  protected:
110   int GetX() const { return x_; }
111   int GetY() const { return y_; }
112   Ewk_Hit_Test_Mode GetMode() const { return mode_; }
113
114  private:
115   int x_;
116   int y_;
117   Ewk_Hit_Test_Mode mode_;
118 };
119
120 class WebViewAsyncRequestHitTestDataUserCallback
121     : public WebViewAsyncRequestHitTestDataCallback {
122  public:
123   WebViewAsyncRequestHitTestDataUserCallback(
124       int x,
125       int y,
126       Ewk_Hit_Test_Mode mode,
127       Ewk_View_Hit_Test_Request_Callback callback,
128       void* user_data)
129       : WebViewAsyncRequestHitTestDataCallback(x, y, mode),
130         callback_(callback),
131         user_data_(user_data) {}
132
133   void Run(_Ewk_Hit_Test* hit_test, EWebView* web_view) override {
134     DCHECK(callback_);
135     callback_(web_view->evas_object(), GetX(), GetY(), GetMode(), hit_test,
136               user_data_);
137   }
138
139  private:
140   Ewk_View_Hit_Test_Request_Callback callback_;
141   void* user_data_;
142 };
143
144 int EWebView::find_request_id_counter_ = 0;
145 content::WebContentsEflDelegate::WebContentsCreateCallback
146     EWebView::create_new_window_web_contents_cb_ =
147         base::BindRepeating(&NullCreateWebContents);
148
149 EWebView* EWebView::FromEvasObject(Evas_Object* eo) {
150   return WebViewDelegateEwk::GetInstance().GetWebViewFromEvasObject(eo);
151 }
152
153 #if !defined(USE_AURA)
154 RenderWidgetHostViewEfl* EWebView::rwhv() const {
155   return static_cast<RenderWidgetHostViewEfl*>(
156       web_contents_->GetRenderWidgetHostView());
157 }
158 #endif
159
160 EWebView::EWebView(Ewk_Context* context, Evas_Object* object)
161     : context_(context),
162       evas_object_(object),
163       native_view_(object),
164       touch_events_enabled_(false),
165       mouse_events_enabled_(false),
166       text_zoom_factor_(1.0),
167       formIsNavigating_(false),
168       current_find_request_id_(find_request_id_counter_++),
169       progress_(0.0),
170       hit_test_completion_(base::WaitableEvent::ResetPolicy::AUTOMATIC,
171                            base::WaitableEvent::InitialState::NOT_SIGNALED),
172       page_scale_factor_(1.0),
173       x_delta_(0.0),
174       y_delta_(0.0),
175       is_initialized_(false) {}
176
177 void EWebView::Initialize() {
178   if (is_initialized_) {
179     return;
180   }
181
182   InitializeContent();
183
184   evas_event_handler_ = new WebViewEvasEventHandler(this);
185
186   scroll_detector_.reset(new ScrollDetector(this));
187
188   web_contents_delegate_.reset(new WebContentsDelegateEfl(this));
189   web_contents_->SetDelegate(web_contents_delegate_.get());
190   back_forward_list_.reset(
191       new _Ewk_Back_Forward_List(web_contents_->GetController()));
192
193   DCHECK(web_contents_->GetRenderViewHost());
194   // Settings (content::WebPreferences) will be initalized by
195   // RenderViewHostImpl::ComputeWebkitPrefs() based on command line switches.
196   settings_.reset(new Ewk_Settings(evas_object_,
197                                    web_contents_->GetOrCreateWebPreferences()));
198   base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess();
199   if (cmdline->HasSwitch(switches::kTouchEventFeatureDetection)) {
200     SetTouchEventsEnabled(
201         cmdline->GetSwitchValueASCII(switches::kTouchEventFeatureDetection) ==
202         switches::kTouchEventFeatureDetectionEnabled);
203   } else {
204     SetMouseEventsEnabled(true);
205   }
206
207   popupMenuItems_ = 0;
208   popupPicker_ = 0;
209
210   formNavigation_.count = 1;
211   formNavigation_.position = 0;
212   formNavigation_.prevState = false;
213   formNavigation_.nextState = false;
214
215   // allow this object and its children to get a focus
216   elm_object_tree_focus_allow_set(native_view_, EINA_TRUE);
217   is_initialized_ = true;
218
219   auto cbce = static_cast<ContentBrowserClientEfl*>(
220       content::GetContentClientExport()->browser());
221   // Initialize accept languages
222   SyncAcceptLanguages(cbce->GetAcceptLangs(nullptr));
223   accept_langs_changed_callback_ =
224       base::BindOnce(&EWebView::SyncAcceptLanguages, base::Unretained(this));
225   cbce->AddAcceptLangsChangedCallback(
226       std::move(accept_langs_changed_callback_));
227 }
228
229 EWebView::~EWebView() {
230   auto cbce = static_cast<ContentBrowserClientEfl*>(
231       content::GetContentClientExport()->browser());
232 #if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
233   cbce->RemoveAcceptLangsChangedCallback(
234       std::move(accept_langs_changed_callback_));
235 #endif
236   std::map<int64_t, WebViewAsyncRequestHitTestDataCallback*>::iterator
237       hit_test_callback_iterator;
238   for (hit_test_callback_iterator = hit_test_callback_.begin();
239        hit_test_callback_iterator != hit_test_callback_.end();
240        hit_test_callback_iterator++)
241     delete hit_test_callback_iterator->second;
242   hit_test_callback_.clear();
243
244   for (auto iter = delayed_messages_.begin(); iter != delayed_messages_.end();
245        ++iter)
246     delete *iter;
247
248   delayed_messages_.clear();
249
250   if (!is_initialized_) {
251     return;
252   }
253
254   context_menu_.reset();
255   mhtml_callback_map_.Clear();
256
257   ReleasePopupMenuList();
258
259   if (popupPicker_)
260     popup_picker_del(popupPicker_);
261
262   formNavigation_.count = 1;
263   formNavigation_.position = 0;
264   formNavigation_.prevState = false;
265   formNavigation_.nextState = false;
266
267   //  evas_object_del(evas_object());
268
269   // Release manually those scoped pointers to
270   // make sure they are released in correct order
271   web_contents_.reset();
272   web_contents_delegate_.reset();
273
274   // This code must be executed after WebContents deletion
275   // because WebContents depends on BrowserContext which
276   // is deleted along with EwkContext.
277   CHECK(!web_contents_);
278   if (old_context_.get()) {
279     Ewk_Context::Delete(context_.get());
280     context_ = old_context_;
281     old_context_ = nullptr;
282   }
283
284   GetPermissionPopupManager()->DeleteAllPermissionRequest();
285   permission_popup_manager_.reset();
286
287   if (context_->GetImpl()->browser_context()->IsOffTheRecord())
288     Ewk_Context::Delete(context_.get());
289 }
290
291 void EWebView::ReleasePopupMenuList() {
292   if (!popupMenuItems_)
293     return;
294
295   void* dummyItem;
296   EINA_LIST_FREE(popupMenuItems_, dummyItem) {
297     delete static_cast<Popup_Menu_Item*>(dummyItem);
298   }
299
300   popupMenuItems_ = 0;
301 }
302
303 content::RenderWidgetHostViewAura* EWebView::rwhva() const {
304   return static_cast<content::RenderWidgetHostViewAura*>(
305       web_contents_->GetRenderWidgetHostView());
306 }
307
308 void EWebView::ResetContextMenuController() {
309   return context_menu_.reset();
310 }
311
312 void EWebView::SetFocus(Eina_Bool focus) {
313   if (!web_contents_ || !rwhva() || (HasFocus() == focus))
314     return;
315
316   rwhva()->offscreen_helper()->Focus(focus);
317 }
318
319 Eina_Bool EWebView::HasFocus() const {
320   if (!rwhva())
321     return EINA_FALSE;
322
323   return rwhva()->offscreen_helper()->HasFocus() ? EINA_TRUE : EINA_FALSE;
324 }
325
326 bool EWebView::CreateNewWindow(
327     content::WebContentsEflDelegate::WebContentsCreateCallback cb) {
328   create_new_window_web_contents_cb_ = cb;
329   Evas_Object* new_object = NULL;
330   SmartCallback<EWebViewCallbacks::CreateNewWindow>().call(&new_object);
331   create_new_window_web_contents_cb_ =
332       base::BindRepeating(&NullCreateWebContents);
333   return !!new_object;
334 }
335
336 // static
337 Evas_Object* EWebView::GetHostWindowDelegate(const content::WebContents* wc) {
338   EWebView* thiz = WebViewFromWebContents(wc);
339   DCHECK(thiz->evas_object_);
340   Evas_Object* parent = evas_object_above_get(thiz->evas_object_);
341   if (!parent) {
342     LOG(WARNING) << "Could not find and visual parents for EWK smart object!.";
343     return thiz->evas_object_;
344   }
345
346   if (elm_object_widget_check(parent)) {
347     Evas_Object* elm_parent = elm_object_top_widget_get(parent);
348     if (elm_parent)
349       return elm_parent;
350     return parent;
351   }
352
353   LOG(WARNING) << "Could not find elementary parent for WebView object!";
354   return thiz->evas_object_;
355 }
356
357 void EWebView::SetURL(const GURL& url) {
358   NavigationController::LoadURLParams params(url);
359   params.override_user_agent = NavigationController::UA_OVERRIDE_TRUE;
360   web_contents_->GetController().LoadURLWithParams(params);
361 }
362
363 const GURL& EWebView::GetURL() const {
364   return web_contents_->GetVisibleURL();
365 }
366
367 const GURL& EWebView::GetOriginalURL() const {
368   const auto entry = web_contents_->GetController().GetVisibleEntry();
369   if (entry)
370     return entry->GetOriginalRequestURL();
371
372   return web_contents_->GetVisibleURL();
373 }
374
375 void EWebView::Reload() {
376   web_contents_->GetController().Reload(content::ReloadType::NORMAL, true);
377 }
378
379 void EWebView::ReloadBypassingCache() {
380   web_contents_->GetController().Reload(content::ReloadType::BYPASSING_CACHE,
381                                         true);
382 }
383
384 Eina_Bool EWebView::CanGoBack() {
385   return web_contents_->GetController().CanGoBack();
386 }
387
388 Eina_Bool EWebView::CanGoForward() {
389   return web_contents_->GetController().CanGoForward();
390 }
391
392 Eina_Bool EWebView::GoBack() {
393   if (!web_contents_->GetController().CanGoBack())
394     return EINA_FALSE;
395
396   web_contents_->GetController().GoBack();
397   return EINA_TRUE;
398 }
399
400 Eina_Bool EWebView::GoForward() {
401   if (!web_contents_->GetController().CanGoForward())
402     return EINA_FALSE;
403
404   web_contents_->GetController().GoForward();
405   return EINA_TRUE;
406 }
407
408 void EWebView::Stop() {
409   if (web_contents_->IsLoading())
410     web_contents_->Stop();
411 }
412
413 void EWebView::Suspend() {
414   CHECK(web_contents_);
415   RenderViewHost* rvh = web_contents_->GetRenderViewHost();
416   RenderFrameHost* rfh = web_contents_->GetPrimaryMainFrame();
417   CHECK(rvh);
418   CHECK(rfh);
419 #if !defined(EWK_BRINGUP)  // FIXME: m69 bringup
420   rfh->BlockRequestsForFrame();
421 #endif
422 #if 0
423   content::BrowserThread::PostTask(
424       content::BrowserThread::IO, FROM_HERE,
425       base::BindOnce(&content::ResourceDispatcherHost::BlockRequestsForFrameFromUI,
426                  rfh));
427
428   if (rvh)
429     rvh->Send(new EwkViewMsg_SuspendScheduledTask(rvh->GetRoutingID()));
430 #endif
431 }
432
433 void EWebView::Resume() {
434   CHECK(web_contents_);
435   RenderViewHost* rvh = web_contents_->GetRenderViewHost();
436   RenderFrameHost* rfh = web_contents_->GetPrimaryMainFrame();
437   CHECK(rvh);
438   CHECK(rfh);
439 #if !defined(EWK_BRINGUP)  // FIXME: m69 bringup
440   rfh->ResumeBlockedRequestsForFrame();
441 #endif
442 #if 0
443   content::BrowserThread::PostTask(
444       content::BrowserThread::IO, FROM_HERE,
445       base::BindOnce(
446           &content::ResourceDispatcherHost::ResumeBlockedRequestsForFrameFromUI,
447           rfh));
448
449   if (rvh)
450     rvh->Send(new EwkViewMsg_ResumeScheduledTasks(rvh->GetRoutingID()));
451 #endif
452 }
453
454 double EWebView::GetTextZoomFactor() const {
455   if (text_zoom_factor_ < 0.0)
456     return -1.0;
457
458   return text_zoom_factor_;
459 }
460
461 void EWebView::SetTextZoomFactor(double text_zoom_factor) {
462   if (text_zoom_factor_ == text_zoom_factor || text_zoom_factor < 0.0)
463     return;
464
465   text_zoom_factor_ = text_zoom_factor;
466   RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
467   if (!render_view_host)
468     return;
469 #if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
470   render_view_host->Send(new ViewMsg_SetTextZoomFactor(
471       render_view_host->GetRoutingID(), text_zoom_factor));
472 #endif
473 }
474
475 double EWebView::GetPageZoomFactor() const {
476   return blink::PageZoomLevelToZoomFactor(
477       content::HostZoomMap::GetZoomLevel(web_contents_.get()));
478 }
479
480 void EWebView::SetPageZoomFactor(double page_zoom_factor) {
481   content::HostZoomMap::SetZoomLevel(
482       web_contents_.get(), blink::PageZoomFactorToZoomLevel(page_zoom_factor));
483 }
484
485 void EWebView::ExecuteEditCommand(const char* command, const char* value) {
486   EINA_SAFETY_ON_NULL_RETURN(command);
487
488   value = (value == NULL) ? "" : value;
489
490   RenderWidgetHostImpl* rwhi = static_cast<RenderWidgetHostImpl*>(
491       web_contents_->GetRenderViewHost()->GetWidget());
492
493 #if !defined(EWK_BRINGUP)  // FIXME: m67 bringup
494   // This is moved to mojo in upstream. Change it.
495   // https://chromium-review.googlesource.com/c/chromium/src/+/541036
496   rwhi->ExecuteEditCommand(command, value);
497 #endif
498
499   // This is workaround for rich text toolbar buttons in email application
500   if (!strcmp(command, "InsertOrderedList") ||
501       !strcmp(command, "InsertUnorderedList") ||
502       !strcmp(command, "AlignCenter") || !strcmp(command, "AlignJustified") ||
503       !strcmp(command, "AlignLeft") || !strcmp(command, "AlignRight")) {
504     QuerySelectionStyle();
505   }
506 }
507
508 void EWebView::SetOrientation(int orientation) {
509   if (GetOrientation() == orientation)
510     return;
511
512   if (orientation == 0 || orientation == 90 || orientation == 180 ||
513       orientation == 270) {
514 #if !defined(USE_AURA)
515     GetWebContentsViewEfl()->SetOrientation(orientation);
516 #endif
517     int width = 0;
518     int height = 0;
519     const Ecore_Evas* ee =
520         ecore_evas_ecore_evas_get(evas_object_evas_get(evas_object_));
521     ecore_evas_screen_geometry_get(ee, nullptr, nullptr, &width, &height);
522     if (orientation == 90 || orientation == 270)
523       std::swap(width, height);
524
525     if (context_menu_)
526       context_menu_->SetPopupSize(width, height);
527     if (inputPicker_)
528       inputPicker_->SetPopupSize(width, height);
529     if (popup_controller_)
530       popup_controller_->SetPopupSize(width, height);
531     if (JavaScriptDialogManagerEfl* dialogMG = GetJavaScriptDialogManagerEfl())
532       dialogMG->SetPopupSize(width, height);
533     if (popupPicker_)
534       popup_picker_resize(popupPicker_, width, height);
535   }
536 }
537
538 int EWebView::GetOrientation() {
539 #if !defined(USE_AURA)
540   return GetWebContentsViewEfl()->GetOrientation();
541 #else
542   return 0;
543 #endif
544 }
545
546 void EWebView::Show() {
547   evas_object_show(native_view_);
548   web_contents_->WasShown();
549 }
550
551 void EWebView::Hide() {
552   evas_object_hide(native_view_);
553   web_contents_->WasHidden();
554 }
555
556 void EWebView::SetViewAuthCallback(Ewk_View_Authentication_Callback callback,
557                                    void* user_data) {
558   authentication_cb_.Set(callback, user_data);
559 }
560
561 void EWebView::InvokeAuthCallback(LoginDelegateEfl* login_delegate,
562                                   const GURL& url,
563                                   const std::string& realm) {
564   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
565
566   auth_challenge_.reset(new _Ewk_Auth_Challenge(login_delegate, url, realm));
567   authentication_cb_.Run(evas_object_, auth_challenge_.get());
568
569   if (!auth_challenge_->is_decided && !auth_challenge_->is_suspended) {
570     auth_challenge_->is_decided = true;
571     auth_challenge_->login_delegate->Cancel();
572   }
573 }
574
575 void EWebView::InvokePolicyResponseCallback(
576     _Ewk_Policy_Decision* policy_decision,
577     bool* defer) {
578   SmartCallback<EWebViewCallbacks::PolicyResponseDecide>().call(
579       policy_decision);
580
581   if (policy_decision->isSuspended()) {
582     *defer = true;
583     return;
584   }
585
586   if (!policy_decision->isDecided())
587     policy_decision->Use();
588
589   policy_decision->SelfDeleteIfNecessary();
590 }
591
592 void EWebView::InvokePolicyNavigationCallback(
593     const NavigationPolicyParams& params,
594     bool* handled) {
595   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
596
597   SmartCallback<EWebViewCallbacks::SaveSessionData>().call();
598
599   std::unique_ptr<_Ewk_Policy_Decision> policy_decision(
600       new _Ewk_Policy_Decision(params));
601
602   SmartCallback<EWebViewCallbacks::NavigationPolicyDecision>().call(
603       policy_decision.get());
604
605   CHECK(!policy_decision->isSuspended());
606
607   // TODO: Navigation can't be suspended
608   // this aproach is synchronous and requires immediate response
609   // Maybe there is different approach (like resource throttle response
610   // mechanism) that allows us to
611   // suspend navigation
612   if (!policy_decision->isDecided())
613     policy_decision->Use();
614
615   *handled = policy_decision->GetNavigationPolicyHandler()->GetDecision() ==
616              NavigationPolicyHandlerEfl::Handled;
617 }
618
619 void EWebView::HandleTouchEvents(Ewk_Touch_Event_Type type,
620                                  const Eina_List* points,
621                                  const Evas_Modifier* modifiers) {
622 #if !defined(USE_AURA)
623   const Eina_List* l;
624   void* data;
625   EINA_LIST_FOREACH(points, l, data) {
626     const Ewk_Touch_Point* point = static_cast<Ewk_Touch_Point*>(data);
627     if (point->state == EVAS_TOUCH_POINT_STILL) {
628       // Chromium doesn't expect (and doesn't like) these events.
629       continue;
630     }
631     if (rwhv()) {
632       Evas_Coord_Point pt;
633       pt.x = point->x;
634       pt.y = point->y;
635       ui::TouchEvent touch_event =
636           MakeTouchEvent(pt, point->state, point->id, evas_object());
637       rwhv()->HandleTouchEvent(&touch_event);
638     }
639   }
640 #endif
641 }
642 #if !defined(USE_AURA)
643 content::WebContentsViewEfl* EWebView::GetWebContentsViewEfl() const {
644   WebContentsImpl* wc = static_cast<WebContentsImpl*>(web_contents_.get());
645   return static_cast<WebContentsViewEfl*>(wc->GetView());
646 }
647 #endif
648 bool EWebView::TouchEventsEnabled() const {
649   return touch_events_enabled_;
650 }
651
652 // TODO: Touch events use the same mouse events in EFL API.
653 // Figure out how to distinguish touch and mouse events on touch&mice devices.
654 // Currently mouse and touch support is mutually exclusive.
655 void EWebView::SetTouchEventsEnabled(bool enabled) {
656   if (touch_events_enabled_ == enabled)
657     return;
658
659   touch_events_enabled_ = enabled;
660 #if !defined(USE_AURA)
661   GetWebContentsViewEfl()->SetTouchEventsEnabled(enabled);
662 #endif
663 #if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
664   // there is no flag touch_enabled in web preferences
665   GetSettings()->getPreferences().touch_enabled = enabled;
666   GetSettings()->getPreferences().double_tap_to_zoom_enabled = enabled;
667   GetSettings()->getPreferences().editing_behavior =
668       enabled ? content::EDITING_BEHAVIOR_ANDROID
669               : content::EDITING_BEHAVIOR_UNIX;
670 #endif
671   UpdateWebKitPreferences();
672 }
673
674 bool EWebView::MouseEventsEnabled() const {
675   return mouse_events_enabled_;
676 }
677
678 void EWebView::SetMouseEventsEnabled(bool enabled) {
679   if (mouse_events_enabled_ == enabled)
680     return;
681
682   mouse_events_enabled_ = enabled;
683 #if !defined(USE_AURA)
684   GetWebContentsViewEfl()->SetTouchEventsEnabled(!enabled);
685 #endif
686 }
687
688 namespace {
689
690 class JavaScriptCallbackDetails {
691  public:
692   JavaScriptCallbackDetails(Ewk_View_Script_Execute_Callback callback_func,
693                             void* user_data,
694                             Evas_Object* view)
695       : callback_func_(callback_func), user_data_(user_data), view_(view) {}
696
697   Ewk_View_Script_Execute_Callback callback_func_;
698   void* user_data_;
699   Evas_Object* view_;
700 };
701
702 void JavaScriptComplete(JavaScriptCallbackDetails* script_callback_data,
703                         const base::Value* result) {
704   if (!script_callback_data->callback_func_)
705     return;
706
707   std::string return_string = result->GetString();
708   script_callback_data->callback_func_(script_callback_data->view_,
709                                        return_string.c_str(),
710                                        script_callback_data->user_data_);
711 }
712
713 }  // namespace
714
715 bool EWebView::ExecuteJavaScript(const char* script,
716                                  Ewk_View_Script_Execute_Callback callback,
717                                  void* userdata) {
718   if (!script)
719     return false;
720
721   if (!web_contents_delegate_)  // question, can I remove this check?
722     return false;
723
724   if (!web_contents_)
725     return false;
726
727   RenderFrameHost* render_frame_host = web_contents_->GetPrimaryMainFrame();
728   if (!render_frame_host)
729     return false;
730
731   // Note: M37. Execute JavaScript, |script| with
732   // |RenderFrameHost::ExecuteJavaScript|.
733   // @see also https://codereview.chromium.org/188893005 for more details.
734   std::u16string js_script;
735   base::UTF8ToUTF16(script, strlen(script), &js_script);
736   if (callback) {
737 #if !defined(EWK_BRINGUP)  // FIXME: m67 bringup
738     JavaScriptCallbackDetails* script_callback_data =
739         new JavaScriptCallbackDetails(callback, userdata, evas_object_);
740     // In M47, it isn't possible anymore to execute javascript in the generic
741     // case. We need to call ExecuteJavaScriptForTests to keep the behaviour
742     // unchanged @see https://codereview.chromium.org/1123783002
743     render_frame_host->ExecuteJavaScriptWithUserGestureForTests(
744         js_script,
745         base::BindOnce(&JavaScriptComplete, base::Owned(script_callback_data)));
746 #endif
747   } else {
748     // We use ExecuteJavaScriptWithUserGestureForTests instead of
749     // ExecuteJavaScript because
750     // ExecuteJavaScriptWithUserGestureForTests sets user_gesture to true. This
751     // was the
752     // behaviour is m34, and we want to keep it that way.
753     render_frame_host->ExecuteJavaScriptWithUserGestureForTests(
754         js_script, base::NullCallback());
755   }
756
757   return true;
758 }
759
760 bool EWebView::SetUserAgent(const char* userAgent) {
761   content::NavigationController& controller = web_contents_->GetController();
762   bool override = userAgent && strlen(userAgent);
763   for (int i = 0; i < controller.GetEntryCount(); ++i)
764     controller.GetEntryAtIndex(i)->SetIsOverridingUserAgent(override);
765   // TODO: Check if override_in_new_tabs has to be true.
766   web_contents_->SetUserAgentOverride(
767       blink::UserAgentOverride::UserAgentOnly(userAgent),
768       false /* override_in_new_tabs */);
769   return true;
770 }
771
772 bool EWebView::SetUserAgentAppName(const char* application_name) {
773   EflWebView::VersionInfo::GetInstance()->SetProductName(
774       application_name ? application_name : "");
775
776   return true;
777 }
778
779 bool EWebView::SetPrivateBrowsing(bool incognito) {
780   if (context_->GetImpl()->browser_context()->IsOffTheRecord() == incognito)
781     return false;
782
783   GURL url = web_contents_->GetVisibleURL();
784   if (old_context_.get()) {
785     DCHECK(!incognito);
786     web_contents_.reset();
787     web_contents_delegate_.reset();
788     Ewk_Context::Delete(context_.get());
789     context_ = old_context_;
790     old_context_ = nullptr;
791   } else {
792     if (incognito) {
793       old_context_ = context_;
794     }
795     context_ = Ewk_Context::Create(incognito);
796   }
797
798   InitializeContent();
799   SetURL(url);
800   return true;
801 }
802
803 bool EWebView::GetPrivateBrowsing() const {
804   return context_->GetImpl()->browser_context()->IsOffTheRecord();
805 }
806
807 void EWebView::set_magnifier(bool status) {
808 #if !defined(USE_AURA)
809   rwhv()->set_magnifier(status);
810 #endif
811 }
812
813 const char* EWebView::GetUserAgent() const {
814   std::string user_agent =
815       web_contents_->GetUserAgentOverride().ua_string_override;
816   if (user_agent.empty())
817     user_agent_ = content::GetContentClientExport()->browser()->GetUserAgent();
818   else
819     user_agent_ = user_agent;
820
821   return user_agent_.c_str();
822 }
823
824 const char* EWebView::GetUserAgentAppName() const {
825   user_agent_app_name_ = EflWebView::VersionInfo::GetInstance()->Name();
826   return user_agent_app_name_.c_str();
827 }
828
829 const char* EWebView::CacheSelectedText() {
830   if (!rwhva())
831     return "";
832
833   selected_text_cached_ = base::UTF16ToUTF8(rwhva()->GetSelectedText());
834   return selected_text_cached_.c_str();
835 }
836
837 _Ewk_Frame* EWebView::GetMainFrame() {
838   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
839
840   if (!frame_.get())
841     frame_.reset(new _Ewk_Frame(web_contents_->GetPrimaryMainFrame()));
842
843   return frame_.get();
844 }
845
846 void EWebView::UpdateWebKitPreferences() {
847   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
848
849   RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
850   if (!render_view_host)
851     return;
852
853   web_contents_delegate_->OnUpdateSettings(settings_.get());
854 #if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
855   render_view_host->UpdateWebkitPreferences(settings_->getPreferences());
856 #endif
857   UpdateWebkitPreferencesEfl(render_view_host);
858 }
859
860 void EWebView::UpdateWebkitPreferencesEfl(RenderViewHost* render_view_host) {
861   DCHECK(render_view_host);
862 #if !defined(EWK_BRINGUP)  // FIXME: m108 bringup
863   IPC::Message* message = new EwkSettingsMsg_UpdateWebKitPreferencesEfl(
864       render_view_host->GetRoutingID(), settings_->getPreferencesEfl());
865
866   if (render_view_host->IsRenderViewLive()) {
867 #if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
868     render_view_host->Send(message);
869 #endif
870   } else {
871     delayed_messages_.push_back(message);
872   }
873 #endif
874 }
875
876 void EWebView::SetContentSecurityPolicy(const char* policy,
877                                         Ewk_CSP_Header_Type type) {
878   web_contents_delegate_->SetContentSecurityPolicy(
879       (policy ? policy : std::string()), type);
880 }
881
882 void EWebView::LoadHTMLString(const char* html,
883                               const char* base_uri,
884                               const char* unreachable_uri) {
885   LoadData(html, std::string::npos, NULL, NULL, base_uri, unreachable_uri);
886 }
887
888 void EWebView::LoadPlainTextString(const char* plain_text) {
889   LoadData(plain_text, std::string::npos, "text/plain", NULL, NULL, NULL);
890 }
891
892 void EWebView::LoadData(const char* data,
893                         size_t size,
894                         const char* mime_type,
895                         const char* encoding,
896                         const char* base_uri,
897                         const char* unreachable_uri) {
898   SetDefaultStringIfNull(mime_type, "text/html");
899   SetDefaultStringIfNull(encoding, "utf-8");
900   SetDefaultStringIfNull(base_uri, "about:blank");  // Webkit2 compatible
901   SetDefaultStringIfNull(unreachable_uri, "");
902
903   std::string str_data = data;
904
905   if (size < str_data.length())
906     str_data = str_data.substr(0, size);
907
908   std::string url_str("data:");
909   url_str.append(mime_type);
910   url_str.append(";charset=");
911   url_str.append(encoding);
912   url_str.append(",");
913   url_str.append(str_data);
914
915   NavigationController::LoadURLParams data_params(GURL(url_str.c_str()));
916
917   data_params.base_url_for_data_url = GURL(base_uri);
918   data_params.virtual_url_for_data_url = GURL(unreachable_uri);
919
920   data_params.load_type = NavigationController::LOAD_TYPE_DATA;
921   data_params.should_replace_current_entry = false;
922   data_params.override_user_agent = NavigationController::UA_OVERRIDE_TRUE;
923   web_contents_->GetController().LoadURLWithParams(data_params);
924 }
925
926 void EWebView::InvokeLoadError(const GURL& url,
927                                int error_code,
928                                bool is_cancellation) {
929   _Ewk_Error err(error_code, is_cancellation,
930                  url.possibly_invalid_spec().c_str());
931
932   SmartCallback<EWebViewCallbacks::LoadError>().call(&err);
933 }
934
935 void EWebView::ShowPopupMenu(const std::vector<blink::MenuItemInfo>& items,
936                              int selectedIndex,
937                              bool multiple) {
938   // Request form navigation information as early as possible,
939   // given that is renderer will ping-back with actual requested data.
940   RenderFrameHostImpl* render_frame_host =
941       static_cast<RenderFrameHostImpl*>(web_contents_->GetPrimaryMainFrame());
942   if (render_frame_host)
943     render_frame_host->Send(new EwkFrameMsg_RequestSelectCollectionInformation(
944         render_frame_host->GetRoutingID()));
945
946   Eina_List* popupItems = 0;
947   const size_t size = items.size();
948   for (size_t i = 0; i < size; ++i) {
949     popupItems = eina_list_append(popupItems, new Popup_Menu_Item(items[i]));
950   }
951
952   ReleasePopupMenuList();
953   popupMenuItems_ = popupItems;
954
955   if (popupPicker_ && FormIsNavigating()) {
956     popupPicker_->multiSelect = multiple;
957     PopupMenuUpdate(popupMenuItems_, selectedIndex);
958     SetFormIsNavigating(false);
959     return;
960   }
961
962   if (popupPicker_)
963     popup_picker_del(popupPicker_);
964   popupPicker_ = 0;
965
966   if (multiple)
967     popupPicker_ =
968         popup_picker_new(this, evas_object(), popupMenuItems_, 0, multiple);
969   else
970     popupPicker_ = popup_picker_new(this, evas_object(), popupMenuItems_,
971                                     selectedIndex, multiple);
972
973   popup_picker_buttons_update(popupPicker_, formNavigation_.position,
974                               formNavigation_.count, false);
975 }
976
977 Eina_Bool EWebView::HidePopupMenu() {
978   if (!popupPicker_)
979     return false;
980
981   if (FormIsNavigating())
982     return true;
983
984   popup_picker_del(popupPicker_);
985   popupPicker_ = 0;
986   return true;
987 }
988
989 void EWebView::UpdateFormNavigation(int formElementCount,
990                                     int currentNodeIndex,
991                                     bool prevState,
992                                     bool nextState) {
993   formNavigation_.count = formElementCount;
994   formNavigation_.position = currentNodeIndex;
995   formNavigation_.prevState = prevState;
996   formNavigation_.nextState = nextState;
997 }
998
999 bool EWebView::IsSelectPickerShown() const {
1000   return (popupPicker_ != NULL);
1001 }
1002
1003 void EWebView::CloseSelectPicker() {
1004   listClosed(popupPicker_, 0, 0, 0);
1005 }
1006
1007 void EWebView::SetFormIsNavigating(bool formIsNavigating) {
1008   formIsNavigating_ = formIsNavigating;
1009 }
1010
1011 Eina_Bool EWebView::PopupMenuUpdate(Eina_List* items, int selectedIndex) {
1012   if (!popupPicker_)
1013     return false;
1014
1015   popup_picker_update(evas_object(), popupPicker_, items, selectedIndex);
1016   popup_picker_buttons_update(popupPicker_, formNavigation_.position,
1017                               formNavigation_.count, false);
1018   return true;
1019 }
1020
1021 void EWebView::FormNavigate(bool direction) {
1022   RenderFrameHostImpl* render_frame_host =
1023       static_cast<RenderFrameHostImpl*>(web_contents_->GetPrimaryMainFrame());
1024   if (!render_frame_host)
1025     return;
1026
1027   popup_picker_buttons_update(popupPicker_, formNavigation_.position,
1028                               formNavigation_.count, true);
1029
1030   if ((direction && formNavigation_.nextState) ||
1031       (!direction && formNavigation_.prevState))
1032     SetFormIsNavigating(true);
1033
1034   listClosed(popupPicker_, 0, 0, 0);
1035   render_frame_host->Send(new EwkFrameMsg_MoveToNextOrPreviousSelectElement(
1036       render_frame_host->GetRoutingID(), direction));
1037 }
1038
1039 Eina_Bool EWebView::DidSelectPopupMenuItem(int selectedIndex) {
1040   RenderFrameHostImpl* render_frame_host =
1041       static_cast<RenderFrameHostImpl*>(web_contents_->GetPrimaryMainFrame());
1042   if (!render_frame_host)
1043     return false;
1044
1045   if (!popupMenuItems_)
1046     return false;
1047
1048   // When user select empty space then no index is selected, so selectedIndex
1049   // value is -1
1050   // In that case we should call valueChanged() with -1 index.That in turn call
1051   // popupDidHide()
1052   // in didChangeSelectedIndex() for reseting the value of m_popupIsVisible in
1053   // RenderMenuList.
1054   if (selectedIndex != -1 &&
1055       selectedIndex >= (int)eina_list_count(popupMenuItems_))
1056     return false;
1057
1058   // In order to reuse RenderFrameHostImpl::DidSelectPopupMenuItems() method in
1059   // Android,
1060   // put selectedIndex into std::vector<int>.
1061   std::vector<int> selectedIndices;
1062   selectedIndices.push_back(selectedIndex);
1063 #if !defined(EWK_BRINGUP)  // FIXME: m67 bringup
1064   render_frame_host->DidSelectPopupMenuItems(selectedIndices);
1065 #endif
1066   return true;
1067 }
1068
1069 Eina_Bool EWebView::DidMultipleSelectPopupMenuItem(
1070     std::vector<int>& selectedIndices) {
1071   RenderFrameHostImpl* render_frame_host =
1072       static_cast<RenderFrameHostImpl*>(web_contents_->GetPrimaryMainFrame());
1073   if (!render_frame_host)
1074     return false;
1075
1076   if (!popupMenuItems_)
1077     return false;
1078 #if !defined(EWK_BRINGUP)  // FIXME: m67 bringup
1079   render_frame_host->DidSelectPopupMenuItems(selectedIndices);
1080 #endif
1081   return true;
1082 }
1083
1084 Eina_Bool EWebView::PopupMenuClose() {
1085 // DJKim : FIXME
1086 #if 0
1087   if (!impl->popupMenuProxy)
1088     return false;
1089
1090   impl->popupMenuProxy = 0;
1091 #endif
1092   HidePopupMenu();
1093
1094   if (!popupMenuItems_)
1095     return false;
1096
1097   void* item;
1098   EINA_LIST_FREE(popupMenuItems_, item)
1099   delete static_cast<Popup_Menu_Item*>(item);
1100   popupMenuItems_ = 0;
1101
1102   RenderFrameHostImpl* render_frame_host =
1103       static_cast<RenderFrameHostImpl*>(web_contents_->GetPrimaryMainFrame());
1104   if (!render_frame_host)
1105     return false;
1106 #if !defined(EWK_BRINGUP)  // FIXME: m67 bringup
1107   render_frame_host->DidCancelPopupMenu();
1108 #endif
1109   return true;
1110 }
1111
1112 void EWebView::HandleLongPressGesture(
1113     const content::ContextMenuParams& params) {
1114 #if !defined(USE_AURA)
1115   // This menu is created in renderer process and it does not now anything about
1116   // view scaling factor and it has another calling sequence, so coordinates is
1117   // not updated.
1118   content::ContextMenuParams convertedParams = params;
1119   gfx::Point convertedPoint =
1120       rwhv()->ConvertPointInViewPix(gfx::Point(params.x, params.y));
1121   convertedParams.x = convertedPoint.x();
1122   convertedParams.y = convertedPoint.y();
1123
1124   Evas_Coord x, y;
1125   evas_object_geometry_get(evas_object(), &x, &y, 0, 0);
1126   convertedParams.x += x;
1127   convertedParams.y += y;
1128
1129   if (GetSelectionController() && GetSelectionController()->GetLongPressed()) {
1130     bool show_context_menu_now =
1131         !GetSelectionController()->HandleLongPressEvent(convertedPoint,
1132                                                         convertedParams);
1133     if (show_context_menu_now)
1134       ShowContextMenuInternal(convertedParams);
1135   }
1136 #endif
1137 }
1138
1139 void EWebView::ShowContextMenu(const content::ContextMenuParams& params) {
1140 #if !defined(USE_AURA)
1141   // This menu is created in renderer process and it does not now anything about
1142   // view scaling factor and it has another calling sequence, so coordinates is
1143   // not updated.
1144   content::ContextMenuParams convertedParams = params;
1145   gfx::Point convertedPoint =
1146       rwhv()->ConvertPointInViewPix(gfx::Point(params.x, params.y));
1147   convertedParams.x = convertedPoint.x();
1148   convertedParams.y = convertedPoint.y();
1149
1150   Evas_Coord x, y;
1151   evas_object_geometry_get(evas_object(), &x, &y, 0, 0);
1152   convertedParams.x += x;
1153   convertedParams.y += y;
1154
1155   context_menu_position_ = gfx::Point(convertedParams.x, convertedParams.y);
1156
1157   ShowContextMenuInternal(convertedParams);
1158 #endif
1159 }
1160
1161 void EWebView::ShowContextMenuInternal(
1162     const content::ContextMenuParams& params) {
1163   context_menu_.reset(
1164       new content::ContextMenuControllerEfl(this, *web_contents_.get()));
1165   if (!context_menu_->PopulateAndShowContextMenu(params)) {
1166     context_menu_.reset();
1167     if (GetSelectionController())
1168       GetSelectionController()->HideHandles();
1169   }
1170 }
1171
1172 void EWebView::CancelContextMenu(int request_id) {
1173   if (context_menu_)
1174     context_menu_->HideContextMenu();
1175 }
1176
1177 void EWebView::Find(const char* text, Ewk_Find_Options ewk_find_options) {
1178   std::u16string find_text = base::UTF8ToUTF16(text);
1179   bool find_next = (previous_text_ == find_text);
1180
1181   if (!find_next) {
1182     current_find_request_id_ = find_request_id_counter_++;
1183     previous_text_ = find_text;
1184   }
1185
1186   auto find_options = blink::mojom::FindOptions::New();
1187   find_options->forward = !(ewk_find_options & EWK_FIND_OPTIONS_BACKWARDS);
1188   find_options->match_case =
1189       !(ewk_find_options & EWK_FIND_OPTIONS_CASE_INSENSITIVE);
1190
1191   web_contents_->Find(current_find_request_id_, find_text,
1192                       std::move(find_options));
1193 }
1194
1195 void EWebView::SetScale(double scale_factor) {
1196   // Do not cache |scale_factor| here as it may be discarded by Blink's
1197   // minimumPageScaleFactor and maximumPageScaleFactor.
1198   // |scale_factor| is cached as responde to DidChangePageScaleFactor.
1199   WebContentsImpl* wci = static_cast<WebContentsImpl*>(web_contents_.get());
1200   wci->GetPrimaryMainFrame()->GetAssociatedLocalMainFrame()->SetScaleFactor(
1201       scale_factor);
1202 }
1203
1204 bool EWebView::GetScrollPosition(int* x, int* y) const {
1205   if (!rwhva()) {
1206     LOG(ERROR) << "rwhva() returns nullptr";
1207     return false;
1208   }
1209   if (scroll_detector_->IsScrollOffsetChanged()) {
1210     if (x)
1211       *x = previous_scroll_position_.x();
1212     if (y)
1213       *y = previous_scroll_position_.y();
1214   } else {
1215     const gfx::Vector2d scroll_position_dip =
1216         scroll_detector_->GetLastScrollPosition();
1217     const float device_scale_factor = display::Screen::GetScreen()
1218                                           ->GetPrimaryDisplay()
1219                                           .device_scale_factor();
1220     if (x) {
1221       *x = base::ClampRound((scroll_position_dip.x() - x_delta_) *
1222                             device_scale_factor);
1223     }
1224     if (y) {
1225       *y = base::ClampRound((scroll_position_dip.y() - y_delta_) *
1226                             device_scale_factor);
1227     }
1228   }
1229   return true;
1230 }
1231
1232 void EWebView::ChangeScroll(int& x, int& y) {
1233   if (!rwhva()) {
1234     LOG(ERROR) << "rwhva() returns nullptr";
1235     return;
1236   }
1237   int max_x = 0;
1238   int max_y = 0;
1239   GetScrollSize(&max_x, &max_y);
1240   previous_scroll_position_.set_x(std::min(std::max(x, 0), max_x));
1241   previous_scroll_position_.set_y(std::min(std::max(y, 0), max_y));
1242
1243   const float device_scale_factor = display::Screen::GetScreen()
1244                                         ->GetPrimaryDisplay()
1245                                         .device_scale_factor();
1246   int x_input = x;
1247   int y_input = y;
1248
1249   x = base::ClampCeil(x / device_scale_factor);
1250   y = base::ClampCeil(y / device_scale_factor);
1251
1252   x_delta_ = x - (x_input / device_scale_factor);
1253   y_delta_ = y - (y_input / device_scale_factor);
1254
1255   scroll_detector_->SetScrollOffsetChanged();
1256 }
1257
1258 void EWebView::SetScroll(int x, int y) {
1259   RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1260   if (!render_view_host)
1261     return;
1262
1263   ChangeScroll(x, y);
1264 #if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
1265   render_view_host->Send(
1266       new EwkViewMsg_SetScroll(render_view_host->GetRoutingID(), x, y));
1267 #endif
1268 }
1269
1270 void EWebView::UseSettingsFont() {
1271 #if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
1272   RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1273   if (render_view_host)
1274     render_view_host->Send(
1275         new EwkViewMsg_UseSettingsFont(render_view_host->GetRoutingID()));
1276 #endif
1277 }
1278
1279 void EWebView::DidChangeContentsSize(int width, int height) {
1280   contents_size_ = gfx::Size(width, height);
1281   SmartCallback<EWebViewCallbacks::ContentsSizeChanged>().call();
1282   SetScaledContentsSize();
1283 }
1284
1285 const Eina_Rectangle EWebView::GetContentsSize() const {
1286   Eina_Rectangle rect;
1287   EINA_RECTANGLE_SET(&rect, 0, 0, contents_size_.width(),
1288                      contents_size_.height());
1289   return rect;
1290 }
1291
1292 void EWebView::SetScaledContentsSize() {
1293   if (!rwhva())
1294     return;  // LCOV_EXCL_LINE
1295
1296   const float device_scale_factor =
1297       display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
1298   gfx::SizeF scaled_contents_size = gfx::ConvertSizeToPixels(
1299       contents_size_, device_scale_factor * page_scale_factor_);
1300   rwhva()->offscreen_helper()->SetScaledContentSize(scaled_contents_size);
1301 }
1302
1303 void EWebView::GetScrollSize(int* width, int* height) {
1304   int w = 0, h = 0;
1305   if (width) {
1306     *width = (rwhva() &&
1307               (w = rwhva()->offscreen_helper()->GetScrollableSize().width()))
1308                  ? w
1309                  : 0;
1310   }
1311   if (height) {
1312     *height = (rwhva() &&
1313                (h = rwhva()->offscreen_helper()->GetScrollableSize().height()))
1314                   ? h
1315                   : 0;
1316   }
1317 }
1318
1319 void EWebView::MoveCaret(const gfx::Point& point) {
1320 #if !defined(USE_AURA)
1321   if (rwhv())
1322     rwhv()->MoveCaret(point);
1323 #endif
1324 }
1325
1326 void EWebView::QuerySelectionStyle() {
1327 #if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
1328   if (GetSettings()->textStyleStateState()) {
1329     RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1330     render_view_host->Send(
1331         new EwkViewMsg_GetSelectionStyle(render_view_host->GetRoutingID()));
1332   }
1333 #endif
1334 }
1335
1336 void EWebView::OnQuerySelectionStyleReply(const SelectionStylePrams& params) {
1337   gfx::Rect left_rect, right_rect;
1338   if (GetSelectionController()) {
1339     GetSelectionController()->GetSelectionBounds(&left_rect, &right_rect);
1340     _Ewk_Text_Style style_data(params, left_rect.origin(),
1341                                right_rect.bottom_right());
1342     SmartCallback<EWebViewCallbacks::TextStyleState>().call(&style_data);
1343   }
1344 }
1345
1346 SelectionControllerEfl* EWebView::GetSelectionController() const {
1347 #if !defined(USE_AURA)
1348   RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1349   RenderWidgetHostViewEfl* view = static_cast<RenderWidgetHostViewEfl*>(
1350       render_view_host->GetWidget()->GetView());
1351   return view ? view->GetSelectionController() : 0;
1352 #else
1353   return nullptr;
1354 #endif
1355 }
1356
1357 void EWebView::SelectLinkText(const gfx::Point& touch_point) {
1358 #if !defined(EWK_BRINGUP)  // FIXME: m67 bringup
1359   float device_scale_factor =
1360       display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
1361   RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1362   render_view_host->Send(new ViewMsg_SelectLinkText(
1363       render_view_host->GetRoutingID(),
1364       gfx::Point(touch_point.x() / device_scale_factor,
1365                  touch_point.y() / device_scale_factor)));
1366 #endif
1367 }
1368
1369 bool EWebView::GetSelectionRange(Eina_Rectangle* left_rect,
1370                                  Eina_Rectangle* right_rect) {
1371   if (left_rect && right_rect) {
1372     gfx::Rect left, right;
1373     if (GetSelectionController()) {
1374       GetSelectionController()->GetSelectionBounds(&left, &right);
1375       GetEinaRectFromGfxRect(left, left_rect);
1376       GetEinaRectFromGfxRect(right, right_rect);
1377       return true;
1378     }
1379   }
1380   return false;
1381 }
1382
1383 Eina_Bool EWebView::ClearSelection() {
1384   if (!rwhva())
1385     return EINA_FALSE;
1386
1387   ResetContextMenuController();
1388   rwhva()->SelectionChanged(std::u16string(), 0, gfx::Range());
1389
1390   if (GetSelectionController())
1391     return GetSelectionController()->ClearSelectionViaEWebView();
1392
1393   return EINA_FALSE;
1394 }
1395
1396 _Ewk_Hit_Test* EWebView::RequestHitTestDataAt(int x,
1397                                               int y,
1398                                               Ewk_Hit_Test_Mode mode) {
1399   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1400
1401   int view_x, view_y;
1402   EvasToBlinkCords(x, y, &view_x, &view_y);
1403
1404   return RequestHitTestDataAtBlinkCoords(view_x, view_y, mode);
1405 }
1406
1407 Eina_Bool EWebView::AsyncRequestHitTestDataAt(
1408     int x,
1409     int y,
1410     Ewk_Hit_Test_Mode mode,
1411     Ewk_View_Hit_Test_Request_Callback callback,
1412     void* user_data) {
1413   int view_x, view_y;
1414   EvasToBlinkCords(x, y, &view_x, &view_y);
1415   return AsyncRequestHitTestDataAtBlinkCords(
1416       view_x, view_y, mode,
1417       new WebViewAsyncRequestHitTestDataUserCallback(x, y, mode, callback,
1418                                                      user_data));
1419 }
1420
1421 Eina_Bool EWebView::AsyncRequestHitTestDataAtBlinkCords(
1422     int x,
1423     int y,
1424     Ewk_Hit_Test_Mode mode,
1425     Ewk_View_Hit_Test_Request_Callback callback,
1426     void* user_data) {
1427   return AsyncRequestHitTestDataAtBlinkCords(
1428       x, y, mode,
1429       new WebViewAsyncRequestHitTestDataUserCallback(x, y, mode, callback,
1430                                                      user_data));
1431 }
1432
1433 Eina_Bool EWebView::AsyncRequestHitTestDataAtBlinkCords(
1434     int x,
1435     int y,
1436     Ewk_Hit_Test_Mode mode,
1437     WebViewAsyncRequestHitTestDataCallback* cb) {
1438   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1439   DCHECK(cb);
1440
1441   static int64_t request_id = 1;
1442
1443   if (cb) {
1444     RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1445     DCHECK(render_view_host);
1446
1447     if (render_view_host) {
1448 #if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
1449       render_view_host->Send(new EwkViewMsg_DoHitTestAsync(
1450           render_view_host->GetRoutingID(), x, y, mode, request_id));
1451 #endif
1452       hit_test_callback_[request_id] = cb;
1453       ++request_id;
1454       return EINA_TRUE;
1455     }
1456   }
1457
1458   // if failed we delete callback as it is not needed anymore
1459   delete cb;
1460   return EINA_FALSE;
1461 }
1462
1463 void EWebView::DispatchAsyncHitTestData(const Hit_Test_Params& params,
1464                                         int64_t request_id) {
1465   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1466
1467   std::map<int64_t, WebViewAsyncRequestHitTestDataCallback*>::iterator it =
1468       hit_test_callback_.find(request_id);
1469
1470   if (it == hit_test_callback_.end())
1471     return;
1472   std::unique_ptr<_Ewk_Hit_Test> hit_test(new _Ewk_Hit_Test(params));
1473
1474   it->second->Run(hit_test.get(), this);
1475   delete it->second;
1476   hit_test_callback_.erase(it);
1477 }
1478
1479 _Ewk_Hit_Test* EWebView::RequestHitTestDataAtBlinkCoords(
1480     int x,
1481     int y,
1482     Ewk_Hit_Test_Mode mode) {
1483   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1484
1485   RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1486   DCHECK(render_view_host);
1487
1488   if (render_view_host) {
1489     // We wait on UI thread till hit test data is updated.
1490 #if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
1491     render_view_host->Send(
1492         new EwkViewMsg_DoHitTest(render_view_host->GetRoutingID(), x, y, mode));
1493 #endif
1494     hit_test_completion_.Wait();
1495     return new _Ewk_Hit_Test(hit_test_params_);
1496   }
1497
1498   return NULL;
1499 }
1500
1501 void EWebView::EvasToBlinkCords(int x, int y, int* view_x, int* view_y) {
1502   DCHECK(display::Screen::GetScreen());
1503   Evas_Coord tmpX, tmpY;
1504   evas_object_geometry_get(evas_object_, &tmpX, &tmpY, NULL, NULL);
1505
1506   if (view_x) {
1507     *view_x = x - tmpX;
1508     *view_x /=
1509         display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
1510   }
1511
1512   if (view_y) {
1513     *view_y = y - tmpY;
1514     *view_y /=
1515         display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
1516   }
1517 }
1518
1519 void EWebView::UpdateHitTestData(const Hit_Test_Params& params) {
1520   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
1521   hit_test_params_ = params;
1522   hit_test_completion_.Signal();
1523 }
1524
1525 void EWebView::OnCopyFromBackingStore(bool success, const SkBitmap& bitmap) {}
1526
1527 void EWebView::RenderViewCreated(RenderViewHost* render_view_host) {
1528   SendDelayedMessages(render_view_host);
1529   UpdateWebkitPreferencesEfl(render_view_host);
1530 #if !defined(USE_AURA)
1531   RenderWidgetHostViewEfl* view = static_cast<RenderWidgetHostViewEfl*>(
1532       render_view_host->GetWidget()->GetView());
1533   if (view)
1534     view->SetEvasHandler(evas_event_handler_);
1535 #endif
1536   if (render_view_host) {
1537     WebContents* content = WebContents::FromRenderViewHost(render_view_host);
1538     if (content) {
1539       RenderProcessHost* host = render_view_host->GetProcess();
1540       if (host)
1541         host->AddFilter(new WebViewBrowserMessageFilter(content));
1542     }
1543   }
1544 }
1545
1546 void EWebView::SetOverrideEncoding(const std::string& encoding) {
1547 // EWK_BRINGUP definition should be removed.
1548 #if !defined(EWK_BRINGUP)  // FIXME: m67 bringup
1549   web_contents_->SetOverrideEncoding(encoding);
1550 #endif  // !defined(EWK_BRINGUP)
1551 }
1552
1553 void EWebView::SetQuotaPermissionRequestCallback(
1554     Ewk_Quota_Permission_Request_Callback callback,
1555     void* user_data) {
1556   quota_request_callback_.Set(callback, user_data);
1557 }
1558
1559 void EWebView::InvokeQuotaPermissionRequest(
1560     _Ewk_Quota_Permission_Request* request,
1561     content::QuotaPermissionContext::PermissionCallback cb) {
1562   quota_permission_request_map_[request] = std::move(cb);
1563   request->setView(evas_object());
1564   if (quota_request_callback_.IsCallbackSet())
1565     quota_request_callback_.Run(evas_object(), request);
1566   else
1567     QuotaRequestCancel(request);
1568 }
1569
1570 void EWebView::QuotaRequestReply(const _Ewk_Quota_Permission_Request* request,
1571                                  bool allow) {
1572   DCHECK(quota_permission_request_map_.find(request) !=
1573          quota_permission_request_map_.end());
1574
1575   QuotaPermissionContextEfl::DispatchCallback(
1576       std::move(quota_permission_request_map_[request]),
1577       (allow ? QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_ALLOW
1578              : QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_DISALLOW));
1579
1580   quota_permission_request_map_.erase(request);
1581   delete request;
1582 }
1583
1584 void EWebView::QuotaRequestCancel(
1585     const _Ewk_Quota_Permission_Request* request) {
1586   DCHECK(quota_permission_request_map_.find(request) !=
1587          quota_permission_request_map_.end());
1588
1589   QuotaPermissionContextEfl::DispatchCallback(
1590       std::move(quota_permission_request_map_[request]),
1591       QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_CANCELLED);
1592   quota_permission_request_map_.erase(request);
1593   delete request;
1594 }
1595
1596 bool EWebView::GetLinkMagnifierEnabled() const {
1597 #if !defined(EWK_BRINGUP)  // FIXME: m71 bringup
1598   return web_contents_->GetMutableRendererPrefs()
1599              ->tap_multiple_targets_strategy ==
1600          TAP_MULTIPLE_TARGETS_STRATEGY_POPUP;
1601 #else
1602   return false;
1603 #endif
1604 }
1605
1606 void EWebView::SetLinkMagnifierEnabled(bool enabled) {
1607 #if !defined(EWK_BRINGUP)  // FIXME: m71 bringup
1608   web_contents_->GetMutableRendererPrefs()->tap_multiple_targets_strategy =
1609       enabled ? TAP_MULTIPLE_TARGETS_STRATEGY_POPUP
1610               : TAP_MULTIPLE_TARGETS_STRATEGY_NONE;
1611 #endif
1612   web_contents_->SyncRendererPrefs();
1613 }
1614
1615 bool EWebView::GetSnapshotAsync(
1616     Eina_Rectangle rect,
1617     Ewk_Web_App_Screenshot_Captured_Callback callback,
1618     void* user_data) {
1619 #if !defined(USE_AURA)
1620   if (!rwhv())
1621     return false;
1622
1623   return rwhv()->RequestSnapshotAsync(rect, callback, user_data);
1624 #else
1625   return false;
1626 #endif
1627 }
1628
1629 Evas_Object* EWebView::GetSnapshot(Eina_Rectangle rect) {
1630   Evas_Object* image = NULL;
1631 #if !defined(USE_AURA)
1632 #if BUILDFLAG(IS_TIZEN)
1633   if (!rwhv() || !rwhv()->MakeCurrent())
1634     return NULL;
1635
1636   int width = rect.w;
1637   int height = rect.h;
1638
1639   if (width > rwhv()->GetViewBoundsInPix().width() - rect.x)
1640     width = rwhv()->GetViewBoundsInPix().width() - rect.x;
1641   if (height > rwhv()->GetViewBoundsInPix().height() - rect.y)
1642     height = rwhv()->GetViewBoundsInPix().height() - rect.y;
1643
1644   int x = rect.x;
1645   int y = rwhv()->GetViewBoundsInPix().height() - height + rect.y;
1646
1647   Evas_GL_API* gl_api = rwhv()->evasGlApi();
1648   DCHECK(gl_api);
1649   int size = width * height * sizeof(GLuint);
1650
1651   GLuint* tmp = (GLuint*)malloc(size);
1652   if (!tmp)
1653     return NULL;
1654
1655   GLuint* bits = (GLuint*)malloc(size);
1656   if (!bits) {
1657     free(tmp);
1658     return NULL;
1659   }
1660
1661   gl_api->glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE,
1662                        (GLubyte*)bits);
1663
1664   // flip the Y axis and change color format from RGBA to BGRA
1665   int i, j, idx1, idx2;
1666   GLuint d;
1667   for (j = 0; j < height; j++) {
1668     for (i = 0; i < width; i++) {
1669       idx1 = (j * width) + i;
1670       idx2 = ((height - 1) - j) * width + i;
1671       d = bits[idx1];
1672       tmp[idx2] = ((d & 0x000000ff) << 16) + ((d & 0x00ff0000) >> 16) +
1673                   ((d & 0xff00ff00));
1674     }
1675   }
1676
1677   image = evas_object_image_filled_add(rwhv()->evas());
1678   if (image) {
1679     evas_object_image_size_set(image, width, height);
1680     evas_object_image_alpha_set(image, EINA_TRUE);
1681     evas_object_image_data_copy_set(image, tmp);
1682     evas_object_resize(image, width, height);
1683   }
1684 #endif
1685 #endif
1686   return image;
1687 }
1688
1689 void EWebView::BackForwardListClear() {
1690   content::NavigationController& controller = web_contents_->GetController();
1691
1692   int entry_count = controller.GetEntryCount();
1693   bool entry_removed = false;
1694
1695   for (int i = 0; i < entry_count; i++) {
1696     if (controller.RemoveEntryAtIndex(i)) {
1697       entry_removed = true;
1698       entry_count = controller.GetEntryCount();
1699       i--;
1700     }
1701   }
1702
1703   if (entry_removed) {
1704     back_forward_list_->ClearCache();
1705     InvokeBackForwardListChangedCallback();
1706   }
1707 }
1708
1709 _Ewk_Back_Forward_List* EWebView::GetBackForwardList() const {
1710   return back_forward_list_.get();
1711 }
1712
1713 void EWebView::InvokeBackForwardListChangedCallback() {
1714   SmartCallback<EWebViewCallbacks::BackForwardListChange>().call();
1715 }
1716
1717 _Ewk_History* EWebView::GetBackForwardHistory() const {
1718   return new _Ewk_History(web_contents_->GetController());
1719 }
1720
1721 bool EWebView::WebAppCapableGet(Ewk_Web_App_Capable_Get_Callback callback,
1722                                 void* userData) {
1723   RenderViewHost* renderViewHost = web_contents_->GetRenderViewHost();
1724   if (!renderViewHost) {
1725     return false;
1726   }
1727 #if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
1728   WebApplicationCapableGetCallback* cb =
1729       new WebApplicationCapableGetCallback(callback, userData);
1730   int callbackId = web_app_capable_get_callback_map_.Add(cb);
1731   return renderViewHost->Send(new EwkViewMsg_WebAppCapableGet(
1732       renderViewHost->GetRoutingID(), callbackId));
1733 #else
1734   return false;
1735 #endif
1736 }
1737
1738 bool EWebView::WebAppIconUrlGet(Ewk_Web_App_Icon_URL_Get_Callback callback,
1739                                 void* userData) {
1740   RenderViewHost* renderViewHost = web_contents_->GetRenderViewHost();
1741   if (!renderViewHost) {
1742     return false;
1743   }
1744 #if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
1745   WebApplicationIconUrlGetCallback* cb =
1746       new WebApplicationIconUrlGetCallback(callback, userData);
1747   int callbackId = web_app_icon_url_get_callback_map_.Add(cb);
1748   return renderViewHost->Send(new EwkViewMsg_WebAppIconUrlGet(
1749       renderViewHost->GetRoutingID(), callbackId));
1750 #else
1751   return false;
1752 #endif
1753 }
1754
1755 bool EWebView::WebAppIconUrlsGet(Ewk_Web_App_Icon_URLs_Get_Callback callback,
1756                                  void* userData) {
1757   RenderViewHost* renderViewHost = web_contents_->GetRenderViewHost();
1758   if (!renderViewHost) {
1759     return false;
1760   }
1761 #if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
1762   WebApplicationIconUrlsGetCallback* cb =
1763       new WebApplicationIconUrlsGetCallback(callback, userData);
1764   int callbackId = web_app_icon_urls_get_callback_map_.Add(cb);
1765   return renderViewHost->Send(new EwkViewMsg_WebAppIconUrlsGet(
1766       renderViewHost->GetRoutingID(), callbackId));
1767 #else
1768   return false;
1769 #endif
1770 }
1771
1772 void EWebView::InvokeWebAppCapableGetCallback(bool capable, int callbackId) {
1773   WebApplicationCapableGetCallback* callback =
1774       web_app_capable_get_callback_map_.Lookup(callbackId);
1775   if (!callback)
1776     return;
1777   callback->Run(capable);
1778   web_app_capable_get_callback_map_.Remove(callbackId);
1779 }
1780
1781 void EWebView::InvokeWebAppIconUrlGetCallback(const std::string& iconUrl,
1782                                               int callbackId) {
1783   WebApplicationIconUrlGetCallback* callback =
1784       web_app_icon_url_get_callback_map_.Lookup(callbackId);
1785   if (!callback)
1786     return;
1787   callback->Run(iconUrl);
1788   web_app_icon_url_get_callback_map_.Remove(callbackId);
1789 }
1790
1791 void EWebView::InvokeWebAppIconUrlsGetCallback(const StringMap& iconUrls,
1792                                                int callbackId) {
1793   WebApplicationIconUrlsGetCallback* callback =
1794       web_app_icon_urls_get_callback_map_.Lookup(callbackId);
1795   if (!callback) {
1796     return;
1797   }
1798   callback->Run(iconUrls);
1799   web_app_icon_urls_get_callback_map_.Remove(callbackId);
1800 }
1801
1802 void EWebView::SetNotificationPermissionCallback(
1803     Ewk_View_Notification_Permission_Callback callback,
1804     void* user_data) {
1805   notification_permission_callback_.Set(callback, user_data);
1806 }
1807
1808 bool EWebView::IsNotificationPermissionCallbackSet() const {
1809   return notification_permission_callback_.IsCallbackSet();
1810 }
1811
1812 bool EWebView::InvokeNotificationPermissionCallback(
1813     Ewk_Notification_Permission_Request* request) {
1814   Eina_Bool ret = EINA_FALSE;
1815   notification_permission_callback_.Run(evas_object_, request, &ret);
1816   return ret;
1817 }
1818
1819 int EWebView::SetEwkViewPlainTextGetCallback(
1820     Ewk_View_Plain_Text_Get_Callback callback,
1821     void* user_data) {
1822   EwkViewPlainTextGetCallback* view_plain_text_callback_ptr =
1823       new EwkViewPlainTextGetCallback;
1824   view_plain_text_callback_ptr->Set(callback, user_data);
1825   return plain_text_get_callback_map_.Add(view_plain_text_callback_ptr);
1826 }
1827
1828 bool EWebView::PlainTextGet(Ewk_View_Plain_Text_Get_Callback callback,
1829                             void* user_data) {
1830   RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1831   if (!render_view_host)
1832     return false;
1833 #if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
1834   int plain_text_get_callback_id =
1835       SetEwkViewPlainTextGetCallback(callback, user_data);
1836   return render_view_host->Send(new EwkViewMsg_PlainTextGet(
1837       render_view_host->GetRoutingID(), plain_text_get_callback_id));
1838 #else
1839   return false;
1840 #endif
1841 }
1842
1843 void EWebView::InvokePlainTextGetCallback(const std::string& content_text,
1844                                           int plain_text_get_callback_id) {
1845   EwkViewPlainTextGetCallback* view_plain_text_callback_invoke_ptr =
1846       plain_text_get_callback_map_.Lookup(plain_text_get_callback_id);
1847   view_plain_text_callback_invoke_ptr->Run(evas_object(), content_text.c_str());
1848   plain_text_get_callback_map_.Remove(plain_text_get_callback_id);
1849 }
1850
1851 void EWebView::SetViewGeolocationPermissionCallback(
1852     Ewk_View_Geolocation_Permission_Callback callback,
1853     void* user_data) {
1854   geolocation_permission_cb_.Set(callback, user_data);
1855 }
1856
1857 bool EWebView::InvokeViewGeolocationPermissionCallback(
1858     _Ewk_Geolocation_Permission_Request* permission_context,
1859     Eina_Bool* callback_result) {
1860   return geolocation_permission_cb_.Run(evas_object_, permission_context,
1861                                         callback_result);
1862 }
1863
1864 void EWebView::SetViewUserMediaPermissionCallback(
1865     Ewk_View_User_Media_Permission_Callback callback,
1866     void* user_data) {
1867   user_media_permission_cb_.Set(callback, user_data);
1868 }
1869
1870 bool EWebView::InvokeViewUserMediaPermissionCallback(
1871     _Ewk_User_Media_Permission_Request* permission_context,
1872     Eina_Bool* callback_result) {
1873   return user_media_permission_cb_.Run(evas_object_, permission_context,
1874                                        callback_result);
1875 }
1876
1877 void EWebView::SetViewUnfocusAllowCallback(
1878     Ewk_View_Unfocus_Allow_Callback callback,
1879     void* user_data) {
1880   unfocus_allow_cb_.Set(callback, user_data);
1881 }
1882
1883 bool EWebView::InvokeViewUnfocusAllowCallback(Ewk_Unfocus_Direction direction,
1884                                               Eina_Bool* callback_result) {
1885   return unfocus_allow_cb_.Run(evas_object_, direction, callback_result);
1886 }
1887
1888 void EWebView::StopFinding() {
1889   web_contents_->StopFinding(content::STOP_FIND_ACTION_CLEAR_SELECTION);
1890 }
1891
1892 void EWebView::SetProgressValue(double progress) {
1893   progress_ = progress;
1894 }
1895
1896 double EWebView::GetProgressValue() {
1897   return progress_;
1898 }
1899
1900 const char* EWebView::GetTitle() {
1901   title_ = base::UTF16ToUTF8(web_contents_->GetTitle());
1902   return title_.c_str();
1903 }
1904
1905 bool EWebView::SaveAsPdf(int width, int height, const std::string& filename) {
1906   RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1907   if (!render_view_host)
1908     return false;
1909 #if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
1910   return render_view_host->Send(
1911       new EwkViewMsg_PrintToPdf(render_view_host->GetRoutingID(), width, height,
1912                                 base::FilePath(filename)));
1913 #else
1914   return false;
1915 #endif
1916 }
1917
1918 bool EWebView::GetMHTMLData(Ewk_View_MHTML_Data_Get_Callback callback,
1919                             void* user_data) {
1920   RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1921   if (!render_view_host)
1922     return false;
1923
1924   MHTMLCallbackDetails* callback_details = new MHTMLCallbackDetails;
1925   callback_details->Set(callback, user_data);
1926 #if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
1927   int mhtml_callback_id = mhtml_callback_map_.Add(callback_details);
1928   return render_view_host->Send(new EwkViewMsg_GetMHTMLData(
1929       render_view_host->GetRoutingID(), mhtml_callback_id));
1930 #else
1931   return false;
1932 #endif
1933 }
1934
1935 void EWebView::OnMHTMLContentGet(const std::string& mhtml_content,
1936                                  int callback_id) {
1937   MHTMLCallbackDetails* callback_details =
1938       mhtml_callback_map_.Lookup(callback_id);
1939   callback_details->Run(evas_object(), mhtml_content.c_str());
1940   mhtml_callback_map_.Remove(callback_id);
1941 }
1942
1943 bool EWebView::IsFullscreen() {
1944   return web_contents_delegate_->IsFullscreenForTabOrPending(
1945       web_contents_.get());
1946 }
1947
1948 void EWebView::ExitFullscreen() {
1949   WebContentsImpl* wci = static_cast<WebContentsImpl*>(web_contents_.get());
1950   wci->ExitFullscreen(false);
1951 }
1952
1953 double EWebView::GetScale() {
1954   return page_scale_factor_;
1955 }
1956
1957 void EWebView::DidChangePageScaleFactor(double scale_factor) {
1958   page_scale_factor_ = scale_factor;
1959 #if !defined(USE_AURA)
1960   GetWebContentsViewEfl()->SetPageScaleFactor(scale_factor);
1961 #endif
1962   SetScaledContentsSize();
1963 }
1964
1965 inline JavaScriptDialogManagerEfl* EWebView::GetJavaScriptDialogManagerEfl() {
1966   return static_cast<JavaScriptDialogManagerEfl*>(
1967       web_contents_delegate_->GetJavaScriptDialogManager(web_contents_.get()));
1968 }
1969
1970 void EWebView::SetJavaScriptAlertCallback(
1971     Ewk_View_JavaScript_Alert_Callback callback,
1972     void* user_data) {
1973   GetJavaScriptDialogManagerEfl()->SetAlertCallback(callback, user_data);
1974 }
1975
1976 void EWebView::JavaScriptAlertReply() {
1977   GetJavaScriptDialogManagerEfl()->ExecuteDialogClosedCallBack(true,
1978                                                                std::string());
1979   SmartCallback<EWebViewCallbacks::PopupReplyWaitFinish>().call(0);
1980 }
1981
1982 void EWebView::SetJavaScriptConfirmCallback(
1983     Ewk_View_JavaScript_Confirm_Callback callback,
1984     void* user_data) {
1985   GetJavaScriptDialogManagerEfl()->SetConfirmCallback(callback, user_data);
1986 }
1987
1988 void EWebView::JavaScriptConfirmReply(bool result) {
1989   GetJavaScriptDialogManagerEfl()->ExecuteDialogClosedCallBack(result,
1990                                                                std::string());
1991   SmartCallback<EWebViewCallbacks::PopupReplyWaitFinish>().call(0);
1992 }
1993
1994 void EWebView::SetJavaScriptPromptCallback(
1995     Ewk_View_JavaScript_Prompt_Callback callback,
1996     void* user_data) {
1997   GetJavaScriptDialogManagerEfl()->SetPromptCallback(callback, user_data);
1998 }
1999
2000 void EWebView::JavaScriptPromptReply(const char* result) {
2001   GetJavaScriptDialogManagerEfl()->ExecuteDialogClosedCallBack(
2002       true, (std::string(result)));
2003   SmartCallback<EWebViewCallbacks::PopupReplyWaitFinish>().call(0);
2004 }
2005
2006 void EWebView::GetPageScaleRange(double* min_scale, double* max_scale) {
2007   auto prefs = web_contents_->GetOrCreateWebPreferences();
2008   if (min_scale)
2009     *min_scale = prefs.default_minimum_page_scale_factor;
2010   if (max_scale)
2011     *max_scale = prefs.default_maximum_page_scale_factor;
2012 }
2013
2014 void EWebView::SetDrawsTransparentBackground(bool enabled) {
2015   RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
2016   if (!render_view_host)
2017     return;
2018 #if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
2019   render_view_host->Send(new EwkViewMsg_SetDrawsTransparentBackground(
2020       render_view_host->GetRoutingID(), enabled));
2021 #endif
2022 }
2023
2024 void EWebView::GetSessionData(const char** data, unsigned* length) const {
2025   static const int MAX_SESSION_ENTRY_SIZE = std::numeric_limits<int>::max();
2026
2027   NavigationController& navigationController = web_contents_->GetController();
2028   base::Pickle sessionPickle;
2029   const int itemCount = navigationController.GetEntryCount();
2030
2031   sessionPickle.WriteInt(itemCount);
2032   sessionPickle.WriteInt(navigationController.GetCurrentEntryIndex());
2033
2034   for (int i = 0; i < itemCount; i++) {
2035     NavigationEntry* navigationEntry = navigationController.GetEntryAtIndex(i);
2036     sessions::SerializedNavigationEntry serializedEntry =
2037         sessions::ContentSerializedNavigationBuilder::FromNavigationEntry(
2038             i, navigationEntry);
2039     serializedEntry.WriteToPickle(MAX_SESSION_ENTRY_SIZE, &sessionPickle);
2040   }
2041
2042   *data = static_cast<char*>(malloc(sizeof(char) * sessionPickle.size()));
2043   memcpy(const_cast<char*>(*data), sessionPickle.data(), sessionPickle.size());
2044   *length = sessionPickle.size();
2045 }
2046
2047 bool EWebView::RestoreFromSessionData(const char* data, unsigned length) {
2048   base::Pickle sessionPickle(data, length);
2049   base::PickleIterator pickleIterator(sessionPickle);
2050   int entryCount;
2051   int currentEntry;
2052
2053   if (!pickleIterator.ReadInt(&entryCount))
2054     return false;
2055   if (!pickleIterator.ReadInt(&currentEntry))
2056     return false;
2057
2058   std::vector<sessions::SerializedNavigationEntry> serializedEntries;
2059   serializedEntries.resize(entryCount);
2060   for (int i = 0; i < entryCount; ++i) {
2061     if (!serializedEntries.at(i).ReadFromPickle(&pickleIterator))
2062       return false;
2063   }
2064
2065   if (!entryCount)
2066     return true;
2067
2068   if (!context())
2069     return false;
2070
2071   std::vector<std::unique_ptr<content::NavigationEntry>> scopedEntries =
2072       sessions::ContentSerializedNavigationBuilder::ToNavigationEntries(
2073           serializedEntries, context()->browser_context());
2074
2075   NavigationController& navigationController = web_contents_->GetController();
2076
2077   if (currentEntry < 0)
2078     currentEntry = 0;
2079
2080   if (currentEntry >= static_cast<int>(scopedEntries.size()))
2081     currentEntry = scopedEntries.size() - 1;
2082
2083 #if !defined(EWK_BRINGUP)  // FIXME: m67 bringup
2084   // FIXME: EWK_BRINGUP definition should be removed.
2085   navigationController.Restore(
2086       currentEntry, NavigationController::RESTORE_LAST_SESSION_EXITED_CLEANLY,
2087       &scopedEntries);
2088 #endif  // !defined(EWK_BRINGUP)
2089   return true;
2090 }
2091
2092 void EWebView::SetBrowserFont() {
2093 #if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
2094   RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
2095   if (render_view_host)
2096     render_view_host->Send(
2097         new EwkViewMsg_SetBrowserFont(render_view_host->GetRoutingID()));
2098 #endif
2099 }
2100
2101 void EWebView::SetCertificatePem(const std::string& certificate) {
2102   pem_certificate_ = certificate;
2103   SmartCallback<EWebViewCallbacks::SetCertificatePem>().call(
2104       pem_certificate_.c_str());
2105 }
2106
2107 bool EWebView::IsDragging() const {
2108 #if !defined(USE_AURA)
2109   return GetWebContentsViewEfl()->IsDragging();
2110 #else
2111   return false;
2112 #endif
2113 }
2114
2115 void EWebView::ShowFileChooser(content::RenderFrameHost* render_frame_host,
2116                                const blink::mojom::FileChooserParams& params) {
2117   if (!IsMobileProfile() && !IsWearableProfile())
2118     return;
2119
2120 #if !defined(EWK_BRINGUP)  // FIXME: m71 bringup
2121   if (params.capture) {
2122     const std::string capture_types[] = {"video/*", "audio/*", "image/*"};
2123     unsigned int capture_types_num =
2124         sizeof(capture_types) / sizeof(*capture_types);
2125     for (unsigned int i = 0; i < capture_types_num; ++i) {
2126       for (unsigned int j = 0; j < params.accept_types.size(); ++j) {
2127         if (UTF16ToUTF8(params.accept_types[j]) == capture_types[i]) {
2128           filechooser_mode_ = params.mode;
2129           LaunchCamera(params.accept_types[j]);
2130           return;
2131         }
2132       }
2133     }
2134   }
2135   file_chooser_.reset(
2136       new content::FileChooserControllerEfl(render_frame_host, &params));
2137   file_chooser_->Open();
2138 #endif
2139 }
2140
2141 #if !defined(EWK_BRINGUP)  // FIXME: m67 bringup
2142 void EWebView::SetViewMode(blink::WebViewMode view_mode) {
2143   RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
2144   if (!render_view_host)
2145     return;
2146
2147   IPC::Message* message =
2148       new ViewMsg_SetViewMode(render_view_host->GetRoutingID(), view_mode);
2149   if (render_view_host->IsRenderViewLive()) {
2150     render_view_host->Send(message);
2151   } else {
2152     delayed_messages_.push_back(message);
2153   }
2154 }
2155 #endif
2156
2157 gfx::Point EWebView::GetContextMenuPosition() const {
2158   return context_menu_position_;
2159 }
2160
2161 void EWebView::ShowContentsDetectedPopup(const char* message) {
2162   popup_controller_.reset(new PopupControllerEfl(this));
2163   popup_controller_->openPopup(message);
2164 }
2165
2166 void EWebView::RequestColorPicker(int r, int g, int b, int a) {
2167   inputPicker_.reset(new InputPicker(*this));
2168   inputPicker_->ShowColorPicker(r, g, b, a);
2169 }
2170
2171 void EWebView::DismissColorPicker() {
2172   inputPicker_->HideColorPicker();
2173 }
2174
2175 bool EWebView::SetColorPickerColor(int r, int g, int b, int a) {
2176 #if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
2177   web_contents_->DidChooseColorInColorChooser(SkColorSetARGB(a, r, g, b));
2178 #endif
2179   return true;
2180 }
2181
2182 void EWebView::InputPickerShow(ui::TextInputType input_type,
2183                                double input_value) {
2184   inputPicker_.reset(new InputPicker(*this));
2185   inputPicker_->showDatePicker(input_type, input_value);
2186 }
2187
2188 void EWebView::LoadNotFoundErrorPage(const std::string& invalidUrl) {
2189 #if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
2190   RenderFrameHost* render_frame_host = web_contents_->GetPrimaryMainFrame();
2191   if (render_frame_host)
2192     render_frame_host->Send(new EwkFrameMsg_LoadNotFoundErrorPage(
2193         render_frame_host->GetRoutingID(), invalidUrl));
2194 #endif
2195 }
2196
2197 std::string EWebView::GetPlatformLocale() {
2198   char* local_default = setlocale(LC_CTYPE, 0);
2199   if (!local_default)
2200     return std::string("en-US");
2201   std::string locale = std::string(local_default);
2202   size_t position = locale.find('_');
2203   if (position != std::string::npos)
2204     locale.replace(position, 1, "-");
2205   position = locale.find('.');
2206   if (position != std::string::npos)
2207     locale = locale.substr(0, position);
2208   return locale;
2209 }
2210
2211 int EWebView::StartInspectorServer(int port) {
2212   return context_->InspectorServerStart(port);
2213 }
2214
2215 bool EWebView::StopInspectorServer() {
2216   return context_->InspectorServerStop();
2217 }
2218
2219 void EWebView::InvokeWebProcessCrashedCallback() {
2220   DCHECK_CURRENTLY_ON(BrowserThread::UI);
2221   const GURL last_url = GetURL();
2222   bool callback_handled = false;
2223   SmartCallback<EWebViewCallbacks::WebProcessCrashed>().call(&callback_handled);
2224   if (!callback_handled)
2225     LoadHTMLString(kRendererCrashedHTMLMessage, NULL,
2226                    last_url.possibly_invalid_spec().c_str());
2227 }
2228
2229 void EWebView::SyncAcceptLanguages(const std::string& accept_languages) {
2230   web_contents_->GetMutableRendererPrefs()->accept_languages = accept_languages;
2231   web_contents_->SyncRendererPrefs();
2232 }
2233
2234 void EWebView::HandleRendererProcessCrash() {
2235   base::ThreadPool::PostTask(
2236       FROM_HERE, {BrowserThread::UI},
2237       base::BindOnce(&EWebView::InvokeWebProcessCrashedCallback,
2238                      base::Unretained(this)));
2239 }
2240
2241 void EWebView::InitializeContent() {
2242   WebContents* new_contents = create_new_window_web_contents_cb_.Run(this);
2243   if (!new_contents) {
2244     WebContents::CreateParams params(context_->browser_context());
2245     web_contents_.reset(
2246         new WebContentsImplEfl(context_->browser_context(), this));
2247     static_cast<WebContentsImpl*>(web_contents_.get())
2248         ->Init(params, blink::FramePolicy());
2249   } else {
2250     web_contents_.reset(new_contents);
2251
2252     // When a new webview is created in response to a request from the
2253     // engine, the BrowserContext instance of the originator WebContents
2254     // is used by the newly created WebContents object.
2255     // See more in WebContentsImplEfl::HandleNewWebContentsCreate.
2256     //
2257     // Hence, if as part of the WebView creation, the embedding APP
2258     // passes in a Ewk_Context instance that wraps a different instance of
2259     // BrowserContext than the one the originator WebContents holds,
2260     // undefined behavior can be seen.
2261     //
2262     // This is a snippet code that illustrate the scenario:
2263     //
2264     // (..)
2265     // evas_object_smart_callback_add(web_view_, "create,window",
2266     //                                &OnNewWindowRequest, this);
2267     // (..)
2268     //
2269     // void OnNewWindowRequest(void *data, Evas_Object*, void* out_view) {
2270     //   (..)
2271     //   EvasObject* new_web_view = ewk_view_add_with_context(GetEvas(),
2272     //   ewk_context_new());
2273     //   *static_cast<Evas_Object**>(out_view) = new_web_view;
2274     //   (..)
2275     // }
2276     //
2277     // The new Ewk_Context object created and passed in as parameter to
2278     // ewk_view_add_with_context wraps a different instance of BrowserContext
2279     // than the one the new WebContents object will hold.
2280     //
2281     // CHECK below aims at catching misuse of this API.
2282     bool should_crash = context_->GetImpl()->browser_context() !=
2283                         web_contents_->GetBrowserContext();
2284     if (should_crash) {
2285       CHECK(false)
2286           << "BrowserContext of new WebContents does not match EWebView's. "
2287           << "Please see 'ewk_view_add*' documentation. "
2288           << "Aborting execution ...";
2289     }
2290   }
2291   web_contents_delegate_.reset(new WebContentsDelegateEfl(this));
2292   web_contents_->SetDelegate(web_contents_delegate_.get());
2293   WebContentsImplEfl* wc_efl =
2294       static_cast<WebContentsImplEfl*>(web_contents_.get());
2295   wc_efl->SetEflDelegate(new WebContentsEflDelegateEwk(this));
2296   back_forward_list_.reset(
2297       new _Ewk_Back_Forward_List(web_contents_->GetController()));
2298
2299   permission_popup_manager_.reset(new PermissionPopupManager(evas_object_));
2300
2301   native_view_ =
2302       static_cast<WebContentsImplEfl*>(web_contents_.get())->GetEflNativeView();
2303   evas_object_smart_member_add(native_view_, evas_object_);
2304   static_cast<WebContentsImpl*>(web_contents_.get())
2305       ->set_ewk_view(evas_object_);
2306   InitializeWindowTreeHost();
2307 }
2308
2309 void EWebView::InitializeWindowTreeHost() {
2310   CHECK(aura::Env::GetInstance());
2311
2312   int x, y, width, height;
2313   Ecore_Evas* ee =
2314       ecore_evas_ecore_evas_get(evas_object_evas_get(native_view_));
2315   ecore_evas_geometry_get(ee, &x, &y, &width, &height);
2316
2317   gfx::Rect bounds(x, y, width, height);
2318   ui::PlatformWindowInitProperties properties;
2319   properties.bounds = bounds;
2320
2321   host_ = aura::WindowTreeHost::Create(std::move(properties));
2322   host_->InitHost();
2323   host_->window()->Show();
2324
2325   focus_client_ =
2326       std::make_unique<aura::test::TestFocusClient>(host_->window());
2327   window_parenting_client_ =
2328       std::make_unique<aura::test::TestWindowParentingClient>(host_->window());
2329
2330   aura::Window* content = web_contents_->GetNativeView();
2331   aura::Window* parent = host_->window();
2332   if (!parent->Contains(content)) {
2333     parent->AddChild(content);
2334     content->Show();
2335   }
2336   content->SetBounds(bounds);
2337   RenderWidgetHostView* host_view = web_contents_->GetRenderWidgetHostView();
2338   if (host_view)
2339     host_view->SetSize(bounds.size());
2340 }
2341
2342 #if BUILDFLAG(IS_TIZEN) && !defined(EWK_BRINGUP)
2343 void EWebView::cameraResultCb(service_h request,
2344                               service_h reply,
2345                               service_result_e result,
2346                               void* data) {
2347   if (!IsMobileProfile() && !IsWearableProfile())
2348     return;
2349
2350   EWebView* webview = static_cast<EWebView*>(data);
2351   RenderViewHost* render_view_host =
2352       webview->web_contents_->GetRenderViewHost();
2353   if (result == SERVICE_RESULT_SUCCEEDED) {
2354     int ret = -1;
2355     char** filesarray;
2356     int number;
2357     ret = service_get_extra_data_array(reply, SERVICE_DATA_SELECTED,
2358                                        &filesarray, &number);
2359     if (filesarray) {
2360       for (int i = 0; i < number; i++) {
2361         std::vector<ui::SelectedFileInfo> files;
2362         if (!render_view_host) {
2363           return;
2364         }
2365         if (filesarray[i]) {
2366           GURL url(filesarray[i]);
2367           if (!url.is_valid()) {
2368             base::FilePath path(url.SchemeIsFile() ? url.path()
2369                                                    : filesarray[i]);
2370             files.push_back(ui::SelectedFileInfo(path, base::FilePath()));
2371           }
2372         }
2373         render_view_host->FilesSelectedInChooser(files,
2374                                                  webview->filechooser_mode_);
2375       }
2376     }
2377   } else {
2378     std::vector<ui::SelectedFileInfo> files;
2379     if (render_view_host) {
2380       render_view_host->FilesSelectedInChooser(files,
2381                                                webview->filechooser_mode_);
2382     }
2383   }
2384 }
2385
2386 bool EWebView::LaunchCamera(std::u16string mimetype) {
2387   service_h svcHandle = 0;
2388   if (service_create(&svcHandle) < 0 || !svcHandle) {
2389     LOG(ERROR) << __FUNCTION__ << " Service Creation Failed ";
2390     return false;
2391   }
2392   service_set_operation(svcHandle, SERVICE_OPERATION_CREATE_CONTENT);
2393   service_set_mime(svcHandle, UTF16ToUTF8(mimetype).c_str());
2394   service_add_extra_data(svcHandle, "CALLER", "Browser");
2395
2396   int ret = service_send_launch_request(svcHandle, cameraResultCb, this);
2397   if (ret != SERVICE_ERROR_NONE) {
2398     LOG(ERROR) << __FUNCTION__ << " Service Launch Failed ";
2399     service_destroy(svcHandle);
2400     return false;
2401   }
2402   service_destroy(svcHandle);
2403   return true;
2404 }
2405 #endif
2406
2407 void EWebView::UrlRequestSet(
2408     const char* url,
2409     content::NavigationController::LoadURLType loadtype,
2410     Eina_Hash* headers,
2411     const char* body) {
2412   GURL gurl(url);
2413   content::NavigationController::LoadURLParams params(gurl);
2414   params.load_type = loadtype;
2415   params.override_user_agent = NavigationController::UA_OVERRIDE_TRUE;
2416
2417   if (body) {
2418     std::string s(body);
2419     params.post_data =
2420         network::ResourceRequestBody::CreateFromBytes(s.data(), s.size());
2421   }
2422
2423   net::HttpRequestHeaders header;
2424   if (headers) {
2425     Eina_Iterator* it = eina_hash_iterator_tuple_new(headers);
2426     Eina_Hash_Tuple* t;
2427     while (eina_iterator_next(it, reinterpret_cast<void**>(&t))) {
2428       if (t->key) {
2429         const char* value_str =
2430             t->data ? static_cast<const char*>(t->data) : "";
2431         base::StringPiece name = static_cast<const char*>(t->key);
2432         base::StringPiece value = value_str;
2433         header.SetHeader(name, value);
2434         // net::HttpRequestHeaders.ToString() returns string with newline
2435         params.extra_headers += header.ToString();
2436       }
2437     }
2438     eina_iterator_free(it);
2439   }
2440
2441   web_contents_->GetController().LoadURLWithParams(params);
2442 }
2443
2444 bool EWebView::HandleShow() {
2445   if (!native_view_)
2446     return false;
2447
2448   Show();
2449   return true;
2450 }
2451
2452 bool EWebView::HandleHide() {
2453   if (!native_view_)
2454     return false;
2455
2456   Hide();
2457   return true;
2458 }
2459
2460 bool EWebView::HandleMove(int x, int y) {
2461   if (!native_view_)
2462     return false;
2463   evas_object_move(native_view_, x, y);
2464   return true;
2465 }
2466
2467 bool EWebView::HandleResize(int width, int height) {
2468   if (!native_view_)
2469     return false;
2470   evas_object_resize(native_view_, width, height);
2471   return true;
2472 }
2473
2474 bool EWebView::HandleTextSelectionDown(int x, int y) {
2475   if (!GetSelectionController())
2476     return false;
2477   return GetSelectionController()->TextSelectionDown(x, y);
2478 }
2479
2480 bool EWebView::HandleTextSelectionUp(int x, int y) {
2481   if (!GetSelectionController())
2482     return false;
2483   return GetSelectionController()->TextSelectionUp(x, y);
2484 }
2485
2486 void EWebView::HandleTapGestureForSelection(bool is_content_editable) {
2487   if (!GetSelectionController())
2488     return;
2489
2490   GetSelectionController()->PostHandleTapGesture(is_content_editable);
2491 }
2492
2493 void EWebView::HandleZoomGesture(blink::WebGestureEvent& event) {
2494   blink::WebInputEvent::Type event_type = event.GetType();
2495   if (event_type == blink::WebInputEvent::Type::kGestureDoubleTap ||
2496       event_type == blink::WebInputEvent::Type::kGesturePinchBegin) {
2497     SmartCallback<EWebViewCallbacks::ZoomStarted>().call();
2498   }
2499   if (event_type == blink::WebInputEvent::Type::kGestureDoubleTap ||
2500       event_type == blink::WebInputEvent::Type::kGesturePinchEnd) {
2501     SmartCallback<EWebViewCallbacks::ZoomFinished>().call();
2502   }
2503 }
2504
2505 void EWebView::SendDelayedMessages(RenderViewHost* render_view_host) {
2506   DCHECK(render_view_host);
2507
2508   if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
2509     base::ThreadPool::PostTask(
2510         FROM_HERE, {BrowserThread::UI},
2511         base::BindOnce(&EWebView::SendDelayedMessages, base::Unretained(this),
2512                        render_view_host));
2513     return;
2514   }
2515
2516   for (auto iter = delayed_messages_.begin(); iter != delayed_messages_.end();
2517        ++iter) {
2518     IPC::Message* message = *iter;
2519     message->set_routing_id(render_view_host->GetRoutingID());
2520 #if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
2521     render_view_host->Send(message);
2522 #endif
2523   }
2524
2525   delayed_messages_.clear();
2526 }
2527
2528 void EWebView::ClosePage() {
2529   web_contents_->ClosePage();
2530 }
2531
2532 void EWebView::OnOverscrolled(const gfx::Vector2dF& accumulated_overscroll,
2533                               const gfx::Vector2dF& latest_overscroll_delta) {
2534   const gfx::Vector2dF old_overscroll =
2535       accumulated_overscroll - latest_overscroll_delta;
2536
2537   if (latest_overscroll_delta.x() && !old_overscroll.x()) {
2538     latest_overscroll_delta.x() < 0
2539         ? SmartCallback<EWebViewCallbacks::OverscrolledLeft>().call()
2540         : SmartCallback<EWebViewCallbacks::OverscrolledRight>().call();
2541   }
2542   if (latest_overscroll_delta.y() && !old_overscroll.y()) {
2543     latest_overscroll_delta.y() < 0
2544         ? SmartCallback<EWebViewCallbacks::OverscrolledTop>().call()
2545         : SmartCallback<EWebViewCallbacks::OverscrolledBottom>().call();
2546   }
2547 }
2548
2549 void EWebView::RequestManifest(Ewk_View_Request_Manifest_Callback callback,
2550                                void* user_data) {
2551   web_contents_delegate_->RequestManifestInfo(callback, user_data);
2552 }
2553
2554 void EWebView::DidRespondRequestManifest(
2555     _Ewk_View_Request_Manifest* manifest,
2556     Ewk_View_Request_Manifest_Callback callback,
2557     void* user_data) {
2558   callback(evas_object_, manifest, user_data);
2559 }