70727b5c8c9cf01081143158ad80cdea9f3e704c
[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   if (!web_contents_->GetUserAgentOverride().ua_string_override.empty())
815     user_agent_ = web_contents_->GetUserAgentOverride().ua_string_override;
816 #if !defined(EWK_BRINGUP)  // FIXME: m73 bringup
817   else
818     user_agent_ = content::GetContentClientExport()->GetUserAgent();
819 #endif
820   return user_agent_.c_str();
821 }
822
823 const char* EWebView::GetUserAgentAppName() const {
824   user_agent_app_name_ = EflWebView::VersionInfo::GetInstance()->Name();
825   return user_agent_app_name_.c_str();
826 }
827
828 const char* EWebView::CacheSelectedText() {
829   if (!rwhva())
830     return "";
831
832   selected_text_cached_ = base::UTF16ToUTF8(rwhva()->GetSelectedText());
833   return selected_text_cached_.c_str();
834 }
835
836 _Ewk_Frame* EWebView::GetMainFrame() {
837   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
838
839   if (!frame_.get())
840     frame_.reset(new _Ewk_Frame(web_contents_->GetPrimaryMainFrame()));
841
842   return frame_.get();
843 }
844
845 void EWebView::UpdateWebKitPreferences() {
846   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
847
848   RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
849   if (!render_view_host)
850     return;
851
852   web_contents_delegate_->OnUpdateSettings(settings_.get());
853 #if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
854   render_view_host->UpdateWebkitPreferences(settings_->getPreferences());
855 #endif
856   UpdateWebkitPreferencesEfl(render_view_host);
857 }
858
859 void EWebView::UpdateWebkitPreferencesEfl(RenderViewHost* render_view_host) {
860   DCHECK(render_view_host);
861 #if !defined(EWK_BRINGUP)  // FIXME: m108 bringup
862   IPC::Message* message = new EwkSettingsMsg_UpdateWebKitPreferencesEfl(
863       render_view_host->GetRoutingID(), settings_->getPreferencesEfl());
864
865   if (render_view_host->IsRenderViewLive()) {
866 #if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
867     render_view_host->Send(message);
868 #endif
869   } else {
870     delayed_messages_.push_back(message);
871   }
872 #endif
873 }
874
875 void EWebView::SetContentSecurityPolicy(const char* policy,
876                                         Ewk_CSP_Header_Type type) {
877   web_contents_delegate_->SetContentSecurityPolicy(
878       (policy ? policy : std::string()), type);
879 }
880
881 void EWebView::LoadHTMLString(const char* html,
882                               const char* base_uri,
883                               const char* unreachable_uri) {
884   LoadData(html, std::string::npos, NULL, NULL, base_uri, unreachable_uri);
885 }
886
887 void EWebView::LoadPlainTextString(const char* plain_text) {
888   LoadData(plain_text, std::string::npos, "text/plain", NULL, NULL, NULL);
889 }
890
891 void EWebView::LoadData(const char* data,
892                         size_t size,
893                         const char* mime_type,
894                         const char* encoding,
895                         const char* base_uri,
896                         const char* unreachable_uri) {
897   SetDefaultStringIfNull(mime_type, "text/html");
898   SetDefaultStringIfNull(encoding, "utf-8");
899   SetDefaultStringIfNull(base_uri, "about:blank");  // Webkit2 compatible
900   SetDefaultStringIfNull(unreachable_uri, "");
901
902   std::string str_data = data;
903
904   if (size < str_data.length())
905     str_data = str_data.substr(0, size);
906
907   std::string url_str("data:");
908   url_str.append(mime_type);
909   url_str.append(";charset=");
910   url_str.append(encoding);
911   url_str.append(",");
912   url_str.append(str_data);
913
914   NavigationController::LoadURLParams data_params(GURL(url_str.c_str()));
915
916   data_params.base_url_for_data_url = GURL(base_uri);
917   data_params.virtual_url_for_data_url = GURL(unreachable_uri);
918
919   data_params.load_type = NavigationController::LOAD_TYPE_DATA;
920   data_params.should_replace_current_entry = false;
921   data_params.override_user_agent = NavigationController::UA_OVERRIDE_TRUE;
922   web_contents_->GetController().LoadURLWithParams(data_params);
923 }
924
925 void EWebView::InvokeLoadError(const GURL& url,
926                                int error_code,
927                                bool is_cancellation) {
928   _Ewk_Error err(error_code, is_cancellation,
929                  url.possibly_invalid_spec().c_str());
930
931   SmartCallback<EWebViewCallbacks::LoadError>().call(&err);
932 }
933
934 void EWebView::ShowPopupMenu(const std::vector<blink::MenuItemInfo>& items,
935                              int selectedIndex,
936                              bool multiple) {
937   // Request form navigation information as early as possible,
938   // given that is renderer will ping-back with actual requested data.
939   RenderFrameHostImpl* render_frame_host =
940       static_cast<RenderFrameHostImpl*>(web_contents_->GetPrimaryMainFrame());
941   if (render_frame_host)
942     render_frame_host->Send(new EwkFrameMsg_RequestSelectCollectionInformation(
943         render_frame_host->GetRoutingID()));
944
945   Eina_List* popupItems = 0;
946   const size_t size = items.size();
947   for (size_t i = 0; i < size; ++i) {
948     popupItems = eina_list_append(popupItems, new Popup_Menu_Item(items[i]));
949   }
950
951   ReleasePopupMenuList();
952   popupMenuItems_ = popupItems;
953
954   if (popupPicker_ && FormIsNavigating()) {
955     popupPicker_->multiSelect = multiple;
956     PopupMenuUpdate(popupMenuItems_, selectedIndex);
957     SetFormIsNavigating(false);
958     return;
959   }
960
961   if (popupPicker_)
962     popup_picker_del(popupPicker_);
963   popupPicker_ = 0;
964
965   if (multiple)
966     popupPicker_ =
967         popup_picker_new(this, evas_object(), popupMenuItems_, 0, multiple);
968   else
969     popupPicker_ = popup_picker_new(this, evas_object(), popupMenuItems_,
970                                     selectedIndex, multiple);
971
972   popup_picker_buttons_update(popupPicker_, formNavigation_.position,
973                               formNavigation_.count, false);
974 }
975
976 Eina_Bool EWebView::HidePopupMenu() {
977   if (!popupPicker_)
978     return false;
979
980   if (FormIsNavigating())
981     return true;
982
983   popup_picker_del(popupPicker_);
984   popupPicker_ = 0;
985   return true;
986 }
987
988 void EWebView::UpdateFormNavigation(int formElementCount,
989                                     int currentNodeIndex,
990                                     bool prevState,
991                                     bool nextState) {
992   formNavigation_.count = formElementCount;
993   formNavigation_.position = currentNodeIndex;
994   formNavigation_.prevState = prevState;
995   formNavigation_.nextState = nextState;
996 }
997
998 bool EWebView::IsSelectPickerShown() const {
999   return (popupPicker_ != NULL);
1000 }
1001
1002 void EWebView::CloseSelectPicker() {
1003   listClosed(popupPicker_, 0, 0, 0);
1004 }
1005
1006 void EWebView::SetFormIsNavigating(bool formIsNavigating) {
1007   formIsNavigating_ = formIsNavigating;
1008 }
1009
1010 Eina_Bool EWebView::PopupMenuUpdate(Eina_List* items, int selectedIndex) {
1011   if (!popupPicker_)
1012     return false;
1013
1014   popup_picker_update(evas_object(), popupPicker_, items, selectedIndex);
1015   popup_picker_buttons_update(popupPicker_, formNavigation_.position,
1016                               formNavigation_.count, false);
1017   return true;
1018 }
1019
1020 void EWebView::FormNavigate(bool direction) {
1021   RenderFrameHostImpl* render_frame_host =
1022       static_cast<RenderFrameHostImpl*>(web_contents_->GetPrimaryMainFrame());
1023   if (!render_frame_host)
1024     return;
1025
1026   popup_picker_buttons_update(popupPicker_, formNavigation_.position,
1027                               formNavigation_.count, true);
1028
1029   if ((direction && formNavigation_.nextState) ||
1030       (!direction && formNavigation_.prevState))
1031     SetFormIsNavigating(true);
1032
1033   listClosed(popupPicker_, 0, 0, 0);
1034   render_frame_host->Send(new EwkFrameMsg_MoveToNextOrPreviousSelectElement(
1035       render_frame_host->GetRoutingID(), direction));
1036 }
1037
1038 Eina_Bool EWebView::DidSelectPopupMenuItem(int selectedIndex) {
1039   RenderFrameHostImpl* render_frame_host =
1040       static_cast<RenderFrameHostImpl*>(web_contents_->GetPrimaryMainFrame());
1041   if (!render_frame_host)
1042     return false;
1043
1044   if (!popupMenuItems_)
1045     return false;
1046
1047   // When user select empty space then no index is selected, so selectedIndex
1048   // value is -1
1049   // In that case we should call valueChanged() with -1 index.That in turn call
1050   // popupDidHide()
1051   // in didChangeSelectedIndex() for reseting the value of m_popupIsVisible in
1052   // RenderMenuList.
1053   if (selectedIndex != -1 &&
1054       selectedIndex >= (int)eina_list_count(popupMenuItems_))
1055     return false;
1056
1057   // In order to reuse RenderFrameHostImpl::DidSelectPopupMenuItems() method in
1058   // Android,
1059   // put selectedIndex into std::vector<int>.
1060   std::vector<int> selectedIndices;
1061   selectedIndices.push_back(selectedIndex);
1062 #if !defined(EWK_BRINGUP)  // FIXME: m67 bringup
1063   render_frame_host->DidSelectPopupMenuItems(selectedIndices);
1064 #endif
1065   return true;
1066 }
1067
1068 Eina_Bool EWebView::DidMultipleSelectPopupMenuItem(
1069     std::vector<int>& selectedIndices) {
1070   RenderFrameHostImpl* render_frame_host =
1071       static_cast<RenderFrameHostImpl*>(web_contents_->GetPrimaryMainFrame());
1072   if (!render_frame_host)
1073     return false;
1074
1075   if (!popupMenuItems_)
1076     return false;
1077 #if !defined(EWK_BRINGUP)  // FIXME: m67 bringup
1078   render_frame_host->DidSelectPopupMenuItems(selectedIndices);
1079 #endif
1080   return true;
1081 }
1082
1083 Eina_Bool EWebView::PopupMenuClose() {
1084 // DJKim : FIXME
1085 #if 0
1086   if (!impl->popupMenuProxy)
1087     return false;
1088
1089   impl->popupMenuProxy = 0;
1090 #endif
1091   HidePopupMenu();
1092
1093   if (!popupMenuItems_)
1094     return false;
1095
1096   void* item;
1097   EINA_LIST_FREE(popupMenuItems_, item)
1098   delete static_cast<Popup_Menu_Item*>(item);
1099   popupMenuItems_ = 0;
1100
1101   RenderFrameHostImpl* render_frame_host =
1102       static_cast<RenderFrameHostImpl*>(web_contents_->GetPrimaryMainFrame());
1103   if (!render_frame_host)
1104     return false;
1105 #if !defined(EWK_BRINGUP)  // FIXME: m67 bringup
1106   render_frame_host->DidCancelPopupMenu();
1107 #endif
1108   return true;
1109 }
1110
1111 void EWebView::HandleLongPressGesture(
1112     const content::ContextMenuParams& params) {
1113 #if !defined(USE_AURA)
1114   // This menu is created in renderer process and it does not now anything about
1115   // view scaling factor and it has another calling sequence, so coordinates is
1116   // not updated.
1117   content::ContextMenuParams convertedParams = params;
1118   gfx::Point convertedPoint =
1119       rwhv()->ConvertPointInViewPix(gfx::Point(params.x, params.y));
1120   convertedParams.x = convertedPoint.x();
1121   convertedParams.y = convertedPoint.y();
1122
1123   Evas_Coord x, y;
1124   evas_object_geometry_get(evas_object(), &x, &y, 0, 0);
1125   convertedParams.x += x;
1126   convertedParams.y += y;
1127
1128   if (GetSelectionController() && GetSelectionController()->GetLongPressed()) {
1129     bool show_context_menu_now =
1130         !GetSelectionController()->HandleLongPressEvent(convertedPoint,
1131                                                         convertedParams);
1132     if (show_context_menu_now)
1133       ShowContextMenuInternal(convertedParams);
1134   }
1135 #endif
1136 }
1137
1138 void EWebView::ShowContextMenu(const content::ContextMenuParams& params) {
1139 #if !defined(USE_AURA)
1140   // This menu is created in renderer process and it does not now anything about
1141   // view scaling factor and it has another calling sequence, so coordinates is
1142   // not updated.
1143   content::ContextMenuParams convertedParams = params;
1144   gfx::Point convertedPoint =
1145       rwhv()->ConvertPointInViewPix(gfx::Point(params.x, params.y));
1146   convertedParams.x = convertedPoint.x();
1147   convertedParams.y = convertedPoint.y();
1148
1149   Evas_Coord x, y;
1150   evas_object_geometry_get(evas_object(), &x, &y, 0, 0);
1151   convertedParams.x += x;
1152   convertedParams.y += y;
1153
1154   context_menu_position_ = gfx::Point(convertedParams.x, convertedParams.y);
1155
1156   ShowContextMenuInternal(convertedParams);
1157 #endif
1158 }
1159
1160 void EWebView::ShowContextMenuInternal(
1161     const content::ContextMenuParams& params) {
1162   context_menu_.reset(
1163       new content::ContextMenuControllerEfl(this, *web_contents_.get()));
1164   if (!context_menu_->PopulateAndShowContextMenu(params)) {
1165     context_menu_.reset();
1166     if (GetSelectionController())
1167       GetSelectionController()->HideHandles();
1168   }
1169 }
1170
1171 void EWebView::CancelContextMenu(int request_id) {
1172   if (context_menu_)
1173     context_menu_->HideContextMenu();
1174 }
1175
1176 void EWebView::Find(const char* text, Ewk_Find_Options ewk_find_options) {
1177   std::u16string find_text = base::UTF8ToUTF16(text);
1178   bool find_next = (previous_text_ == find_text);
1179
1180   if (!find_next) {
1181     current_find_request_id_ = find_request_id_counter_++;
1182     previous_text_ = find_text;
1183   }
1184
1185   auto find_options = blink::mojom::FindOptions::New();
1186   find_options->forward = !(ewk_find_options & EWK_FIND_OPTIONS_BACKWARDS);
1187   find_options->match_case =
1188       !(ewk_find_options & EWK_FIND_OPTIONS_CASE_INSENSITIVE);
1189
1190   web_contents_->Find(current_find_request_id_, find_text,
1191                       std::move(find_options));
1192 }
1193
1194 void EWebView::SetScale(double scale_factor) {
1195   // Do not cache |scale_factor| here as it may be discarded by Blink's
1196   // minimumPageScaleFactor and maximumPageScaleFactor.
1197   // |scale_factor| is cached as responde to DidChangePageScaleFactor.
1198   WebContentsImpl* wci = static_cast<WebContentsImpl*>(web_contents_.get());
1199   wci->GetPrimaryMainFrame()->GetAssociatedLocalMainFrame()->SetScaleFactor(
1200       scale_factor);
1201 }
1202
1203 bool EWebView::GetScrollPosition(int* x, int* y) const {
1204   if (!rwhva()) {
1205     LOG(ERROR) << "rwhva() returns nullptr";
1206     return false;
1207   }
1208   if (scroll_detector_->IsScrollOffsetChanged()) {
1209     if (x)
1210       *x = previous_scroll_position_.x();
1211     if (y)
1212       *y = previous_scroll_position_.y();
1213   } else {
1214     const gfx::Vector2d scroll_position_dip =
1215         scroll_detector_->GetLastScrollPosition();
1216     const float device_scale_factor = display::Screen::GetScreen()
1217                                           ->GetPrimaryDisplay()
1218                                           .device_scale_factor();
1219     if (x) {
1220       *x = base::ClampRound((scroll_position_dip.x() - x_delta_) *
1221                             device_scale_factor);
1222     }
1223     if (y) {
1224       *y = base::ClampRound((scroll_position_dip.y() - y_delta_) *
1225                             device_scale_factor);
1226     }
1227   }
1228   return true;
1229 }
1230
1231 void EWebView::ChangeScroll(int& x, int& y) {
1232   if (!rwhva()) {
1233     LOG(ERROR) << "rwhva() returns nullptr";
1234     return;
1235   }
1236   int max_x = 0;
1237   int max_y = 0;
1238   GetScrollSize(&max_x, &max_y);
1239   previous_scroll_position_.set_x(std::min(std::max(x, 0), max_x));
1240   previous_scroll_position_.set_y(std::min(std::max(y, 0), max_y));
1241
1242   const float device_scale_factor = display::Screen::GetScreen()
1243                                         ->GetPrimaryDisplay()
1244                                         .device_scale_factor();
1245   int x_input = x;
1246   int y_input = y;
1247
1248   x = base::ClampCeil(x / device_scale_factor);
1249   y = base::ClampCeil(y / device_scale_factor);
1250
1251   x_delta_ = x - (x_input / device_scale_factor);
1252   y_delta_ = y - (y_input / device_scale_factor);
1253
1254   scroll_detector_->SetScrollOffsetChanged();
1255 }
1256
1257 void EWebView::SetScroll(int x, int y) {
1258   RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1259   if (!render_view_host)
1260     return;
1261
1262   ChangeScroll(x, y);
1263 #if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
1264   render_view_host->Send(
1265       new EwkViewMsg_SetScroll(render_view_host->GetRoutingID(), x, y));
1266 #endif
1267 }
1268
1269 void EWebView::UseSettingsFont() {
1270 #if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
1271   RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1272   if (render_view_host)
1273     render_view_host->Send(
1274         new EwkViewMsg_UseSettingsFont(render_view_host->GetRoutingID()));
1275 #endif
1276 }
1277
1278 void EWebView::DidChangeContentsSize(int width, int height) {
1279   contents_size_ = gfx::Size(width, height);
1280   SmartCallback<EWebViewCallbacks::ContentsSizeChanged>().call();
1281   SetScaledContentsSize();
1282 }
1283
1284 const Eina_Rectangle EWebView::GetContentsSize() const {
1285   Eina_Rectangle rect;
1286   EINA_RECTANGLE_SET(&rect, 0, 0, contents_size_.width(),
1287                      contents_size_.height());
1288   return rect;
1289 }
1290
1291 void EWebView::SetScaledContentsSize() {
1292   if (!rwhva())
1293     return;  // LCOV_EXCL_LINE
1294
1295   const float device_scale_factor =
1296       display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
1297   gfx::SizeF scaled_contents_size = gfx::ConvertSizeToPixels(
1298       contents_size_, device_scale_factor * page_scale_factor_);
1299   rwhva()->offscreen_helper()->SetScaledContentSize(scaled_contents_size);
1300 }
1301
1302 void EWebView::GetScrollSize(int* width, int* height) {
1303   int w = 0, h = 0;
1304   if (width) {
1305     *width = (rwhva() &&
1306               (w = rwhva()->offscreen_helper()->GetScrollableSize().width()))
1307                  ? w
1308                  : 0;
1309   }
1310   if (height) {
1311     *height = (rwhva() &&
1312                (h = rwhva()->offscreen_helper()->GetScrollableSize().height()))
1313                   ? h
1314                   : 0;
1315   }
1316 }
1317
1318 void EWebView::MoveCaret(const gfx::Point& point) {
1319 #if !defined(USE_AURA)
1320   if (rwhv())
1321     rwhv()->MoveCaret(point);
1322 #endif
1323 }
1324
1325 void EWebView::QuerySelectionStyle() {
1326 #if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
1327   if (GetSettings()->textStyleStateState()) {
1328     RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1329     render_view_host->Send(
1330         new EwkViewMsg_GetSelectionStyle(render_view_host->GetRoutingID()));
1331   }
1332 #endif
1333 }
1334
1335 void EWebView::OnQuerySelectionStyleReply(const SelectionStylePrams& params) {
1336   gfx::Rect left_rect, right_rect;
1337   if (GetSelectionController()) {
1338     GetSelectionController()->GetSelectionBounds(&left_rect, &right_rect);
1339     _Ewk_Text_Style style_data(params, left_rect.origin(),
1340                                right_rect.bottom_right());
1341     SmartCallback<EWebViewCallbacks::TextStyleState>().call(&style_data);
1342   }
1343 }
1344
1345 SelectionControllerEfl* EWebView::GetSelectionController() const {
1346 #if !defined(USE_AURA)
1347   RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1348   RenderWidgetHostViewEfl* view = static_cast<RenderWidgetHostViewEfl*>(
1349       render_view_host->GetWidget()->GetView());
1350   return view ? view->GetSelectionController() : 0;
1351 #else
1352   return nullptr;
1353 #endif
1354 }
1355
1356 void EWebView::SelectLinkText(const gfx::Point& touch_point) {
1357 #if !defined(EWK_BRINGUP)  // FIXME: m67 bringup
1358   float device_scale_factor =
1359       display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
1360   RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1361   render_view_host->Send(new ViewMsg_SelectLinkText(
1362       render_view_host->GetRoutingID(),
1363       gfx::Point(touch_point.x() / device_scale_factor,
1364                  touch_point.y() / device_scale_factor)));
1365 #endif
1366 }
1367
1368 bool EWebView::GetSelectionRange(Eina_Rectangle* left_rect,
1369                                  Eina_Rectangle* right_rect) {
1370   if (left_rect && right_rect) {
1371     gfx::Rect left, right;
1372     if (GetSelectionController()) {
1373       GetSelectionController()->GetSelectionBounds(&left, &right);
1374       GetEinaRectFromGfxRect(left, left_rect);
1375       GetEinaRectFromGfxRect(right, right_rect);
1376       return true;
1377     }
1378   }
1379   return false;
1380 }
1381
1382 Eina_Bool EWebView::ClearSelection() {
1383   if (!rwhva())
1384     return EINA_FALSE;
1385
1386   ResetContextMenuController();
1387   rwhva()->SelectionChanged(std::u16string(), 0, gfx::Range());
1388
1389   if (GetSelectionController())
1390     return GetSelectionController()->ClearSelectionViaEWebView();
1391
1392   return EINA_FALSE;
1393 }
1394
1395 _Ewk_Hit_Test* EWebView::RequestHitTestDataAt(int x,
1396                                               int y,
1397                                               Ewk_Hit_Test_Mode mode) {
1398   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1399
1400   int view_x, view_y;
1401   EvasToBlinkCords(x, y, &view_x, &view_y);
1402
1403   return RequestHitTestDataAtBlinkCoords(view_x, view_y, mode);
1404 }
1405
1406 Eina_Bool EWebView::AsyncRequestHitTestDataAt(
1407     int x,
1408     int y,
1409     Ewk_Hit_Test_Mode mode,
1410     Ewk_View_Hit_Test_Request_Callback callback,
1411     void* user_data) {
1412   int view_x, view_y;
1413   EvasToBlinkCords(x, y, &view_x, &view_y);
1414   return AsyncRequestHitTestDataAtBlinkCords(
1415       view_x, view_y, mode,
1416       new WebViewAsyncRequestHitTestDataUserCallback(x, y, mode, callback,
1417                                                      user_data));
1418 }
1419
1420 Eina_Bool EWebView::AsyncRequestHitTestDataAtBlinkCords(
1421     int x,
1422     int y,
1423     Ewk_Hit_Test_Mode mode,
1424     Ewk_View_Hit_Test_Request_Callback callback,
1425     void* user_data) {
1426   return AsyncRequestHitTestDataAtBlinkCords(
1427       x, y, mode,
1428       new WebViewAsyncRequestHitTestDataUserCallback(x, y, mode, callback,
1429                                                      user_data));
1430 }
1431
1432 Eina_Bool EWebView::AsyncRequestHitTestDataAtBlinkCords(
1433     int x,
1434     int y,
1435     Ewk_Hit_Test_Mode mode,
1436     WebViewAsyncRequestHitTestDataCallback* cb) {
1437   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1438   DCHECK(cb);
1439
1440   static int64_t request_id = 1;
1441
1442   if (cb) {
1443     RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1444     DCHECK(render_view_host);
1445
1446     if (render_view_host) {
1447 #if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
1448       render_view_host->Send(new EwkViewMsg_DoHitTestAsync(
1449           render_view_host->GetRoutingID(), x, y, mode, request_id));
1450 #endif
1451       hit_test_callback_[request_id] = cb;
1452       ++request_id;
1453       return EINA_TRUE;
1454     }
1455   }
1456
1457   // if failed we delete callback as it is not needed anymore
1458   delete cb;
1459   return EINA_FALSE;
1460 }
1461
1462 void EWebView::DispatchAsyncHitTestData(const Hit_Test_Params& params,
1463                                         int64_t request_id) {
1464   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1465
1466   std::map<int64_t, WebViewAsyncRequestHitTestDataCallback*>::iterator it =
1467       hit_test_callback_.find(request_id);
1468
1469   if (it == hit_test_callback_.end())
1470     return;
1471   std::unique_ptr<_Ewk_Hit_Test> hit_test(new _Ewk_Hit_Test(params));
1472
1473   it->second->Run(hit_test.get(), this);
1474   delete it->second;
1475   hit_test_callback_.erase(it);
1476 }
1477
1478 _Ewk_Hit_Test* EWebView::RequestHitTestDataAtBlinkCoords(
1479     int x,
1480     int y,
1481     Ewk_Hit_Test_Mode mode) {
1482   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1483
1484   RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1485   DCHECK(render_view_host);
1486
1487   if (render_view_host) {
1488     // We wait on UI thread till hit test data is updated.
1489 #if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
1490     render_view_host->Send(
1491         new EwkViewMsg_DoHitTest(render_view_host->GetRoutingID(), x, y, mode));
1492 #endif
1493     hit_test_completion_.Wait();
1494     return new _Ewk_Hit_Test(hit_test_params_);
1495   }
1496
1497   return NULL;
1498 }
1499
1500 void EWebView::EvasToBlinkCords(int x, int y, int* view_x, int* view_y) {
1501   DCHECK(display::Screen::GetScreen());
1502   Evas_Coord tmpX, tmpY;
1503   evas_object_geometry_get(evas_object_, &tmpX, &tmpY, NULL, NULL);
1504
1505   if (view_x) {
1506     *view_x = x - tmpX;
1507     *view_x /=
1508         display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
1509   }
1510
1511   if (view_y) {
1512     *view_y = y - tmpY;
1513     *view_y /=
1514         display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
1515   }
1516 }
1517
1518 void EWebView::UpdateHitTestData(const Hit_Test_Params& params) {
1519   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
1520   hit_test_params_ = params;
1521   hit_test_completion_.Signal();
1522 }
1523
1524 void EWebView::OnCopyFromBackingStore(bool success, const SkBitmap& bitmap) {}
1525
1526 void EWebView::RenderViewCreated(RenderViewHost* render_view_host) {
1527   SendDelayedMessages(render_view_host);
1528   UpdateWebkitPreferencesEfl(render_view_host);
1529 #if !defined(USE_AURA)
1530   RenderWidgetHostViewEfl* view = static_cast<RenderWidgetHostViewEfl*>(
1531       render_view_host->GetWidget()->GetView());
1532   if (view)
1533     view->SetEvasHandler(evas_event_handler_);
1534 #endif
1535   if (render_view_host) {
1536     WebContents* content = WebContents::FromRenderViewHost(render_view_host);
1537     if (content) {
1538       RenderProcessHost* host = render_view_host->GetProcess();
1539       if (host)
1540         host->AddFilter(new WebViewBrowserMessageFilter(content));
1541     }
1542   }
1543 }
1544
1545 void EWebView::SetOverrideEncoding(const std::string& encoding) {
1546 // EWK_BRINGUP definition should be removed.
1547 #if !defined(EWK_BRINGUP)  // FIXME: m67 bringup
1548   web_contents_->SetOverrideEncoding(encoding);
1549 #endif  // !defined(EWK_BRINGUP)
1550 }
1551
1552 void EWebView::SetQuotaPermissionRequestCallback(
1553     Ewk_Quota_Permission_Request_Callback callback,
1554     void* user_data) {
1555   quota_request_callback_.Set(callback, user_data);
1556 }
1557
1558 void EWebView::InvokeQuotaPermissionRequest(
1559     _Ewk_Quota_Permission_Request* request,
1560     content::QuotaPermissionContext::PermissionCallback cb) {
1561   quota_permission_request_map_[request] = std::move(cb);
1562   request->setView(evas_object());
1563   if (quota_request_callback_.IsCallbackSet())
1564     quota_request_callback_.Run(evas_object(), request);
1565   else
1566     QuotaRequestCancel(request);
1567 }
1568
1569 void EWebView::QuotaRequestReply(const _Ewk_Quota_Permission_Request* request,
1570                                  bool allow) {
1571   DCHECK(quota_permission_request_map_.find(request) !=
1572          quota_permission_request_map_.end());
1573
1574   QuotaPermissionContextEfl::DispatchCallback(
1575       std::move(quota_permission_request_map_[request]),
1576       (allow ? QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_ALLOW
1577              : QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_DISALLOW));
1578
1579   quota_permission_request_map_.erase(request);
1580   delete request;
1581 }
1582
1583 void EWebView::QuotaRequestCancel(
1584     const _Ewk_Quota_Permission_Request* request) {
1585   DCHECK(quota_permission_request_map_.find(request) !=
1586          quota_permission_request_map_.end());
1587
1588   QuotaPermissionContextEfl::DispatchCallback(
1589       std::move(quota_permission_request_map_[request]),
1590       QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_CANCELLED);
1591   quota_permission_request_map_.erase(request);
1592   delete request;
1593 }
1594
1595 bool EWebView::GetLinkMagnifierEnabled() const {
1596 #if !defined(EWK_BRINGUP)  // FIXME: m71 bringup
1597   return web_contents_->GetMutableRendererPrefs()
1598              ->tap_multiple_targets_strategy ==
1599          TAP_MULTIPLE_TARGETS_STRATEGY_POPUP;
1600 #else
1601   return false;
1602 #endif
1603 }
1604
1605 void EWebView::SetLinkMagnifierEnabled(bool enabled) {
1606 #if !defined(EWK_BRINGUP)  // FIXME: m71 bringup
1607   web_contents_->GetMutableRendererPrefs()->tap_multiple_targets_strategy =
1608       enabled ? TAP_MULTIPLE_TARGETS_STRATEGY_POPUP
1609               : TAP_MULTIPLE_TARGETS_STRATEGY_NONE;
1610 #endif
1611   web_contents_->SyncRendererPrefs();
1612 }
1613
1614 bool EWebView::GetSnapshotAsync(
1615     Eina_Rectangle rect,
1616     Ewk_Web_App_Screenshot_Captured_Callback callback,
1617     void* user_data) {
1618 #if !defined(USE_AURA)
1619   if (!rwhv())
1620     return false;
1621
1622   return rwhv()->RequestSnapshotAsync(rect, callback, user_data);
1623 #else
1624   return false;
1625 #endif
1626 }
1627
1628 Evas_Object* EWebView::GetSnapshot(Eina_Rectangle rect) {
1629   Evas_Object* image = NULL;
1630 #if !defined(USE_AURA)
1631 #if BUILDFLAG(IS_TIZEN)
1632   if (!rwhv() || !rwhv()->MakeCurrent())
1633     return NULL;
1634
1635   int width = rect.w;
1636   int height = rect.h;
1637
1638   if (width > rwhv()->GetViewBoundsInPix().width() - rect.x)
1639     width = rwhv()->GetViewBoundsInPix().width() - rect.x;
1640   if (height > rwhv()->GetViewBoundsInPix().height() - rect.y)
1641     height = rwhv()->GetViewBoundsInPix().height() - rect.y;
1642
1643   int x = rect.x;
1644   int y = rwhv()->GetViewBoundsInPix().height() - height + rect.y;
1645
1646   Evas_GL_API* gl_api = rwhv()->evasGlApi();
1647   DCHECK(gl_api);
1648   int size = width * height * sizeof(GLuint);
1649
1650   GLuint* tmp = (GLuint*)malloc(size);
1651   if (!tmp)
1652     return NULL;
1653
1654   GLuint* bits = (GLuint*)malloc(size);
1655   if (!bits) {
1656     free(tmp);
1657     return NULL;
1658   }
1659
1660   gl_api->glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE,
1661                        (GLubyte*)bits);
1662
1663   // flip the Y axis and change color format from RGBA to BGRA
1664   int i, j, idx1, idx2;
1665   GLuint d;
1666   for (j = 0; j < height; j++) {
1667     for (i = 0; i < width; i++) {
1668       idx1 = (j * width) + i;
1669       idx2 = ((height - 1) - j) * width + i;
1670       d = bits[idx1];
1671       tmp[idx2] = ((d & 0x000000ff) << 16) + ((d & 0x00ff0000) >> 16) +
1672                   ((d & 0xff00ff00));
1673     }
1674   }
1675
1676   image = evas_object_image_filled_add(rwhv()->evas());
1677   if (image) {
1678     evas_object_image_size_set(image, width, height);
1679     evas_object_image_alpha_set(image, EINA_TRUE);
1680     evas_object_image_data_copy_set(image, tmp);
1681     evas_object_resize(image, width, height);
1682   }
1683 #endif
1684 #endif
1685   return image;
1686 }
1687
1688 void EWebView::BackForwardListClear() {
1689   content::NavigationController& controller = web_contents_->GetController();
1690
1691   int entry_count = controller.GetEntryCount();
1692   bool entry_removed = false;
1693
1694   for (int i = 0; i < entry_count; i++) {
1695     if (controller.RemoveEntryAtIndex(i)) {
1696       entry_removed = true;
1697       entry_count = controller.GetEntryCount();
1698       i--;
1699     }
1700   }
1701
1702   if (entry_removed) {
1703     back_forward_list_->ClearCache();
1704     InvokeBackForwardListChangedCallback();
1705   }
1706 }
1707
1708 _Ewk_Back_Forward_List* EWebView::GetBackForwardList() const {
1709   return back_forward_list_.get();
1710 }
1711
1712 void EWebView::InvokeBackForwardListChangedCallback() {
1713   SmartCallback<EWebViewCallbacks::BackForwardListChange>().call();
1714 }
1715
1716 _Ewk_History* EWebView::GetBackForwardHistory() const {
1717   return new _Ewk_History(web_contents_->GetController());
1718 }
1719
1720 bool EWebView::WebAppCapableGet(Ewk_Web_App_Capable_Get_Callback callback,
1721                                 void* userData) {
1722   RenderViewHost* renderViewHost = web_contents_->GetRenderViewHost();
1723   if (!renderViewHost) {
1724     return false;
1725   }
1726 #if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
1727   WebApplicationCapableGetCallback* cb =
1728       new WebApplicationCapableGetCallback(callback, userData);
1729   int callbackId = web_app_capable_get_callback_map_.Add(cb);
1730   return renderViewHost->Send(new EwkViewMsg_WebAppCapableGet(
1731       renderViewHost->GetRoutingID(), callbackId));
1732 #else
1733   return false;
1734 #endif
1735 }
1736
1737 bool EWebView::WebAppIconUrlGet(Ewk_Web_App_Icon_URL_Get_Callback callback,
1738                                 void* userData) {
1739   RenderViewHost* renderViewHost = web_contents_->GetRenderViewHost();
1740   if (!renderViewHost) {
1741     return false;
1742   }
1743 #if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
1744   WebApplicationIconUrlGetCallback* cb =
1745       new WebApplicationIconUrlGetCallback(callback, userData);
1746   int callbackId = web_app_icon_url_get_callback_map_.Add(cb);
1747   return renderViewHost->Send(new EwkViewMsg_WebAppIconUrlGet(
1748       renderViewHost->GetRoutingID(), callbackId));
1749 #else
1750   return false;
1751 #endif
1752 }
1753
1754 bool EWebView::WebAppIconUrlsGet(Ewk_Web_App_Icon_URLs_Get_Callback callback,
1755                                  void* userData) {
1756   RenderViewHost* renderViewHost = web_contents_->GetRenderViewHost();
1757   if (!renderViewHost) {
1758     return false;
1759   }
1760 #if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
1761   WebApplicationIconUrlsGetCallback* cb =
1762       new WebApplicationIconUrlsGetCallback(callback, userData);
1763   int callbackId = web_app_icon_urls_get_callback_map_.Add(cb);
1764   return renderViewHost->Send(new EwkViewMsg_WebAppIconUrlsGet(
1765       renderViewHost->GetRoutingID(), callbackId));
1766 #else
1767   return false;
1768 #endif
1769 }
1770
1771 void EWebView::InvokeWebAppCapableGetCallback(bool capable, int callbackId) {
1772   WebApplicationCapableGetCallback* callback =
1773       web_app_capable_get_callback_map_.Lookup(callbackId);
1774   if (!callback)
1775     return;
1776   callback->Run(capable);
1777   web_app_capable_get_callback_map_.Remove(callbackId);
1778 }
1779
1780 void EWebView::InvokeWebAppIconUrlGetCallback(const std::string& iconUrl,
1781                                               int callbackId) {
1782   WebApplicationIconUrlGetCallback* callback =
1783       web_app_icon_url_get_callback_map_.Lookup(callbackId);
1784   if (!callback)
1785     return;
1786   callback->Run(iconUrl);
1787   web_app_icon_url_get_callback_map_.Remove(callbackId);
1788 }
1789
1790 void EWebView::InvokeWebAppIconUrlsGetCallback(const StringMap& iconUrls,
1791                                                int callbackId) {
1792   WebApplicationIconUrlsGetCallback* callback =
1793       web_app_icon_urls_get_callback_map_.Lookup(callbackId);
1794   if (!callback) {
1795     return;
1796   }
1797   callback->Run(iconUrls);
1798   web_app_icon_urls_get_callback_map_.Remove(callbackId);
1799 }
1800
1801 void EWebView::SetNotificationPermissionCallback(
1802     Ewk_View_Notification_Permission_Callback callback,
1803     void* user_data) {
1804   notification_permission_callback_.Set(callback, user_data);
1805 }
1806
1807 bool EWebView::IsNotificationPermissionCallbackSet() const {
1808   return notification_permission_callback_.IsCallbackSet();
1809 }
1810
1811 bool EWebView::InvokeNotificationPermissionCallback(
1812     Ewk_Notification_Permission_Request* request) {
1813   Eina_Bool ret = EINA_FALSE;
1814   notification_permission_callback_.Run(evas_object_, request, &ret);
1815   return ret;
1816 }
1817
1818 int EWebView::SetEwkViewPlainTextGetCallback(
1819     Ewk_View_Plain_Text_Get_Callback callback,
1820     void* user_data) {
1821   EwkViewPlainTextGetCallback* view_plain_text_callback_ptr =
1822       new EwkViewPlainTextGetCallback;
1823   view_plain_text_callback_ptr->Set(callback, user_data);
1824   return plain_text_get_callback_map_.Add(view_plain_text_callback_ptr);
1825 }
1826
1827 bool EWebView::PlainTextGet(Ewk_View_Plain_Text_Get_Callback callback,
1828                             void* user_data) {
1829   RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1830   if (!render_view_host)
1831     return false;
1832 #if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
1833   int plain_text_get_callback_id =
1834       SetEwkViewPlainTextGetCallback(callback, user_data);
1835   return render_view_host->Send(new EwkViewMsg_PlainTextGet(
1836       render_view_host->GetRoutingID(), plain_text_get_callback_id));
1837 #else
1838   return false;
1839 #endif
1840 }
1841
1842 void EWebView::InvokePlainTextGetCallback(const std::string& content_text,
1843                                           int plain_text_get_callback_id) {
1844   EwkViewPlainTextGetCallback* view_plain_text_callback_invoke_ptr =
1845       plain_text_get_callback_map_.Lookup(plain_text_get_callback_id);
1846   view_plain_text_callback_invoke_ptr->Run(evas_object(), content_text.c_str());
1847   plain_text_get_callback_map_.Remove(plain_text_get_callback_id);
1848 }
1849
1850 void EWebView::SetViewGeolocationPermissionCallback(
1851     Ewk_View_Geolocation_Permission_Callback callback,
1852     void* user_data) {
1853   geolocation_permission_cb_.Set(callback, user_data);
1854 }
1855
1856 bool EWebView::InvokeViewGeolocationPermissionCallback(
1857     _Ewk_Geolocation_Permission_Request* permission_context,
1858     Eina_Bool* callback_result) {
1859   return geolocation_permission_cb_.Run(evas_object_, permission_context,
1860                                         callback_result);
1861 }
1862
1863 void EWebView::SetViewUserMediaPermissionCallback(
1864     Ewk_View_User_Media_Permission_Callback callback,
1865     void* user_data) {
1866   user_media_permission_cb_.Set(callback, user_data);
1867 }
1868
1869 bool EWebView::InvokeViewUserMediaPermissionCallback(
1870     _Ewk_User_Media_Permission_Request* permission_context,
1871     Eina_Bool* callback_result) {
1872   return user_media_permission_cb_.Run(evas_object_, permission_context,
1873                                        callback_result);
1874 }
1875
1876 void EWebView::SetViewUnfocusAllowCallback(
1877     Ewk_View_Unfocus_Allow_Callback callback,
1878     void* user_data) {
1879   unfocus_allow_cb_.Set(callback, user_data);
1880 }
1881
1882 bool EWebView::InvokeViewUnfocusAllowCallback(Ewk_Unfocus_Direction direction,
1883                                               Eina_Bool* callback_result) {
1884   return unfocus_allow_cb_.Run(evas_object_, direction, callback_result);
1885 }
1886
1887 void EWebView::StopFinding() {
1888   web_contents_->StopFinding(content::STOP_FIND_ACTION_CLEAR_SELECTION);
1889 }
1890
1891 void EWebView::SetProgressValue(double progress) {
1892   progress_ = progress;
1893 }
1894
1895 double EWebView::GetProgressValue() {
1896   return progress_;
1897 }
1898
1899 const char* EWebView::GetTitle() {
1900   title_ = base::UTF16ToUTF8(web_contents_->GetTitle());
1901   return title_.c_str();
1902 }
1903
1904 bool EWebView::SaveAsPdf(int width, int height, const std::string& filename) {
1905   RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1906   if (!render_view_host)
1907     return false;
1908 #if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
1909   return render_view_host->Send(
1910       new EwkViewMsg_PrintToPdf(render_view_host->GetRoutingID(), width, height,
1911                                 base::FilePath(filename)));
1912 #else
1913   return false;
1914 #endif
1915 }
1916
1917 bool EWebView::GetMHTMLData(Ewk_View_MHTML_Data_Get_Callback callback,
1918                             void* user_data) {
1919   RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1920   if (!render_view_host)
1921     return false;
1922
1923   MHTMLCallbackDetails* callback_details = new MHTMLCallbackDetails;
1924   callback_details->Set(callback, user_data);
1925 #if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
1926   int mhtml_callback_id = mhtml_callback_map_.Add(callback_details);
1927   return render_view_host->Send(new EwkViewMsg_GetMHTMLData(
1928       render_view_host->GetRoutingID(), mhtml_callback_id));
1929 #else
1930   return false;
1931 #endif
1932 }
1933
1934 void EWebView::OnMHTMLContentGet(const std::string& mhtml_content,
1935                                  int callback_id) {
1936   MHTMLCallbackDetails* callback_details =
1937       mhtml_callback_map_.Lookup(callback_id);
1938   callback_details->Run(evas_object(), mhtml_content.c_str());
1939   mhtml_callback_map_.Remove(callback_id);
1940 }
1941
1942 bool EWebView::IsFullscreen() {
1943   return web_contents_delegate_->IsFullscreenForTabOrPending(
1944       web_contents_.get());
1945 }
1946
1947 void EWebView::ExitFullscreen() {
1948   WebContentsImpl* wci = static_cast<WebContentsImpl*>(web_contents_.get());
1949   wci->ExitFullscreen(false);
1950 }
1951
1952 double EWebView::GetScale() {
1953   return page_scale_factor_;
1954 }
1955
1956 void EWebView::DidChangePageScaleFactor(double scale_factor) {
1957   page_scale_factor_ = scale_factor;
1958 #if !defined(USE_AURA)
1959   GetWebContentsViewEfl()->SetPageScaleFactor(scale_factor);
1960 #endif
1961   SetScaledContentsSize();
1962 }
1963
1964 inline JavaScriptDialogManagerEfl* EWebView::GetJavaScriptDialogManagerEfl() {
1965   return static_cast<JavaScriptDialogManagerEfl*>(
1966       web_contents_delegate_->GetJavaScriptDialogManager(web_contents_.get()));
1967 }
1968
1969 void EWebView::SetJavaScriptAlertCallback(
1970     Ewk_View_JavaScript_Alert_Callback callback,
1971     void* user_data) {
1972   GetJavaScriptDialogManagerEfl()->SetAlertCallback(callback, user_data);
1973 }
1974
1975 void EWebView::JavaScriptAlertReply() {
1976   GetJavaScriptDialogManagerEfl()->ExecuteDialogClosedCallBack(true,
1977                                                                std::string());
1978   SmartCallback<EWebViewCallbacks::PopupReplyWaitFinish>().call(0);
1979 }
1980
1981 void EWebView::SetJavaScriptConfirmCallback(
1982     Ewk_View_JavaScript_Confirm_Callback callback,
1983     void* user_data) {
1984   GetJavaScriptDialogManagerEfl()->SetConfirmCallback(callback, user_data);
1985 }
1986
1987 void EWebView::JavaScriptConfirmReply(bool result) {
1988   GetJavaScriptDialogManagerEfl()->ExecuteDialogClosedCallBack(result,
1989                                                                std::string());
1990   SmartCallback<EWebViewCallbacks::PopupReplyWaitFinish>().call(0);
1991 }
1992
1993 void EWebView::SetJavaScriptPromptCallback(
1994     Ewk_View_JavaScript_Prompt_Callback callback,
1995     void* user_data) {
1996   GetJavaScriptDialogManagerEfl()->SetPromptCallback(callback, user_data);
1997 }
1998
1999 void EWebView::JavaScriptPromptReply(const char* result) {
2000   GetJavaScriptDialogManagerEfl()->ExecuteDialogClosedCallBack(
2001       true, (std::string(result)));
2002   SmartCallback<EWebViewCallbacks::PopupReplyWaitFinish>().call(0);
2003 }
2004
2005 void EWebView::GetPageScaleRange(double* min_scale, double* max_scale) {
2006   auto prefs = web_contents_->GetOrCreateWebPreferences();
2007   if (min_scale)
2008     *min_scale = prefs.default_minimum_page_scale_factor;
2009   if (max_scale)
2010     *max_scale = prefs.default_maximum_page_scale_factor;
2011 }
2012
2013 void EWebView::SetDrawsTransparentBackground(bool enabled) {
2014   RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
2015   if (!render_view_host)
2016     return;
2017 #if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
2018   render_view_host->Send(new EwkViewMsg_SetDrawsTransparentBackground(
2019       render_view_host->GetRoutingID(), enabled));
2020 #endif
2021 }
2022
2023 void EWebView::GetSessionData(const char** data, unsigned* length) const {
2024   static const int MAX_SESSION_ENTRY_SIZE = std::numeric_limits<int>::max();
2025
2026   NavigationController& navigationController = web_contents_->GetController();
2027   base::Pickle sessionPickle;
2028   const int itemCount = navigationController.GetEntryCount();
2029
2030   sessionPickle.WriteInt(itemCount);
2031   sessionPickle.WriteInt(navigationController.GetCurrentEntryIndex());
2032
2033   for (int i = 0; i < itemCount; i++) {
2034     NavigationEntry* navigationEntry = navigationController.GetEntryAtIndex(i);
2035     sessions::SerializedNavigationEntry serializedEntry =
2036         sessions::ContentSerializedNavigationBuilder::FromNavigationEntry(
2037             i, navigationEntry);
2038     serializedEntry.WriteToPickle(MAX_SESSION_ENTRY_SIZE, &sessionPickle);
2039   }
2040
2041   *data = static_cast<char*>(malloc(sizeof(char) * sessionPickle.size()));
2042   memcpy(const_cast<char*>(*data), sessionPickle.data(), sessionPickle.size());
2043   *length = sessionPickle.size();
2044 }
2045
2046 bool EWebView::RestoreFromSessionData(const char* data, unsigned length) {
2047   base::Pickle sessionPickle(data, length);
2048   base::PickleIterator pickleIterator(sessionPickle);
2049   int entryCount;
2050   int currentEntry;
2051
2052   if (!pickleIterator.ReadInt(&entryCount))
2053     return false;
2054   if (!pickleIterator.ReadInt(&currentEntry))
2055     return false;
2056
2057   std::vector<sessions::SerializedNavigationEntry> serializedEntries;
2058   serializedEntries.resize(entryCount);
2059   for (int i = 0; i < entryCount; ++i) {
2060     if (!serializedEntries.at(i).ReadFromPickle(&pickleIterator))
2061       return false;
2062   }
2063
2064   if (!entryCount)
2065     return true;
2066
2067   if (!context())
2068     return false;
2069
2070   std::vector<std::unique_ptr<content::NavigationEntry>> scopedEntries =
2071       sessions::ContentSerializedNavigationBuilder::ToNavigationEntries(
2072           serializedEntries, context()->browser_context());
2073
2074   NavigationController& navigationController = web_contents_->GetController();
2075
2076   if (currentEntry < 0)
2077     currentEntry = 0;
2078
2079   if (currentEntry >= static_cast<int>(scopedEntries.size()))
2080     currentEntry = scopedEntries.size() - 1;
2081
2082 #if !defined(EWK_BRINGUP)  // FIXME: m67 bringup
2083   // FIXME: EWK_BRINGUP definition should be removed.
2084   navigationController.Restore(
2085       currentEntry, NavigationController::RESTORE_LAST_SESSION_EXITED_CLEANLY,
2086       &scopedEntries);
2087 #endif  // !defined(EWK_BRINGUP)
2088   return true;
2089 }
2090
2091 void EWebView::SetBrowserFont() {
2092 #if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
2093   RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
2094   if (render_view_host)
2095     render_view_host->Send(
2096         new EwkViewMsg_SetBrowserFont(render_view_host->GetRoutingID()));
2097 #endif
2098 }
2099
2100 void EWebView::SetCertificatePem(const std::string& certificate) {
2101   pem_certificate_ = certificate;
2102   SmartCallback<EWebViewCallbacks::SetCertificatePem>().call(
2103       pem_certificate_.c_str());
2104 }
2105
2106 bool EWebView::IsDragging() const {
2107 #if !defined(USE_AURA)
2108   return GetWebContentsViewEfl()->IsDragging();
2109 #else
2110   return false;
2111 #endif
2112 }
2113
2114 void EWebView::ShowFileChooser(content::RenderFrameHost* render_frame_host,
2115                                const blink::mojom::FileChooserParams& params) {
2116   if (!IsMobileProfile() && !IsWearableProfile())
2117     return;
2118
2119 #if !defined(EWK_BRINGUP)  // FIXME: m71 bringup
2120   if (params.capture) {
2121     const std::string capture_types[] = {"video/*", "audio/*", "image/*"};
2122     unsigned int capture_types_num =
2123         sizeof(capture_types) / sizeof(*capture_types);
2124     for (unsigned int i = 0; i < capture_types_num; ++i) {
2125       for (unsigned int j = 0; j < params.accept_types.size(); ++j) {
2126         if (UTF16ToUTF8(params.accept_types[j]) == capture_types[i]) {
2127           filechooser_mode_ = params.mode;
2128           LaunchCamera(params.accept_types[j]);
2129           return;
2130         }
2131       }
2132     }
2133   }
2134   file_chooser_.reset(
2135       new content::FileChooserControllerEfl(render_frame_host, &params));
2136   file_chooser_->Open();
2137 #endif
2138 }
2139
2140 #if !defined(EWK_BRINGUP)  // FIXME: m67 bringup
2141 void EWebView::SetViewMode(blink::WebViewMode view_mode) {
2142   RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
2143   if (!render_view_host)
2144     return;
2145
2146   IPC::Message* message =
2147       new ViewMsg_SetViewMode(render_view_host->GetRoutingID(), view_mode);
2148   if (render_view_host->IsRenderViewLive()) {
2149     render_view_host->Send(message);
2150   } else {
2151     delayed_messages_.push_back(message);
2152   }
2153 }
2154 #endif
2155
2156 gfx::Point EWebView::GetContextMenuPosition() const {
2157   return context_menu_position_;
2158 }
2159
2160 void EWebView::ShowContentsDetectedPopup(const char* message) {
2161   popup_controller_.reset(new PopupControllerEfl(this));
2162   popup_controller_->openPopup(message);
2163 }
2164
2165 void EWebView::RequestColorPicker(int r, int g, int b, int a) {
2166   inputPicker_.reset(new InputPicker(*this));
2167   inputPicker_->ShowColorPicker(r, g, b, a);
2168 }
2169
2170 void EWebView::DismissColorPicker() {
2171   inputPicker_->HideColorPicker();
2172 }
2173
2174 bool EWebView::SetColorPickerColor(int r, int g, int b, int a) {
2175 #if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
2176   web_contents_->DidChooseColorInColorChooser(SkColorSetARGB(a, r, g, b));
2177 #endif
2178   return true;
2179 }
2180
2181 void EWebView::InputPickerShow(ui::TextInputType input_type,
2182                                double input_value) {
2183   inputPicker_.reset(new InputPicker(*this));
2184   inputPicker_->showDatePicker(input_type, input_value);
2185 }
2186
2187 void EWebView::LoadNotFoundErrorPage(const std::string& invalidUrl) {
2188 #if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
2189   RenderFrameHost* render_frame_host = web_contents_->GetPrimaryMainFrame();
2190   if (render_frame_host)
2191     render_frame_host->Send(new EwkFrameMsg_LoadNotFoundErrorPage(
2192         render_frame_host->GetRoutingID(), invalidUrl));
2193 #endif
2194 }
2195
2196 std::string EWebView::GetPlatformLocale() {
2197   char* local_default = setlocale(LC_CTYPE, 0);
2198   if (!local_default)
2199     return std::string("en-US");
2200   std::string locale = std::string(local_default);
2201   size_t position = locale.find('_');
2202   if (position != std::string::npos)
2203     locale.replace(position, 1, "-");
2204   position = locale.find('.');
2205   if (position != std::string::npos)
2206     locale = locale.substr(0, position);
2207   return locale;
2208 }
2209
2210 int EWebView::StartInspectorServer(int port) {
2211   return context_->InspectorServerStart(port);
2212 }
2213
2214 bool EWebView::StopInspectorServer() {
2215   return context_->InspectorServerStop();
2216 }
2217
2218 void EWebView::InvokeWebProcessCrashedCallback() {
2219   DCHECK_CURRENTLY_ON(BrowserThread::UI);
2220   const GURL last_url = GetURL();
2221   bool callback_handled = false;
2222   SmartCallback<EWebViewCallbacks::WebProcessCrashed>().call(&callback_handled);
2223   if (!callback_handled)
2224     LoadHTMLString(kRendererCrashedHTMLMessage, NULL,
2225                    last_url.possibly_invalid_spec().c_str());
2226 }
2227
2228 void EWebView::SyncAcceptLanguages(const std::string& accept_languages) {
2229   web_contents_->GetMutableRendererPrefs()->accept_languages = accept_languages;
2230   web_contents_->SyncRendererPrefs();
2231 }
2232
2233 void EWebView::HandleRendererProcessCrash() {
2234   base::ThreadPool::PostTask(
2235       FROM_HERE, {BrowserThread::UI},
2236       base::BindOnce(&EWebView::InvokeWebProcessCrashedCallback,
2237                      base::Unretained(this)));
2238 }
2239
2240 void EWebView::InitializeContent() {
2241   WebContents* new_contents = create_new_window_web_contents_cb_.Run(this);
2242   if (!new_contents) {
2243     WebContents::CreateParams params(context_->browser_context());
2244     web_contents_.reset(
2245         new WebContentsImplEfl(context_->browser_context(), this));
2246     static_cast<WebContentsImpl*>(web_contents_.get())
2247         ->Init(params, blink::FramePolicy());
2248   } else {
2249     web_contents_.reset(new_contents);
2250
2251     // When a new webview is created in response to a request from the
2252     // engine, the BrowserContext instance of the originator WebContents
2253     // is used by the newly created WebContents object.
2254     // See more in WebContentsImplEfl::HandleNewWebContentsCreate.
2255     //
2256     // Hence, if as part of the WebView creation, the embedding APP
2257     // passes in a Ewk_Context instance that wraps a different instance of
2258     // BrowserContext than the one the originator WebContents holds,
2259     // undefined behavior can be seen.
2260     //
2261     // This is a snippet code that illustrate the scenario:
2262     //
2263     // (..)
2264     // evas_object_smart_callback_add(web_view_, "create,window",
2265     //                                &OnNewWindowRequest, this);
2266     // (..)
2267     //
2268     // void OnNewWindowRequest(void *data, Evas_Object*, void* out_view) {
2269     //   (..)
2270     //   EvasObject* new_web_view = ewk_view_add_with_context(GetEvas(),
2271     //   ewk_context_new());
2272     //   *static_cast<Evas_Object**>(out_view) = new_web_view;
2273     //   (..)
2274     // }
2275     //
2276     // The new Ewk_Context object created and passed in as parameter to
2277     // ewk_view_add_with_context wraps a different instance of BrowserContext
2278     // than the one the new WebContents object will hold.
2279     //
2280     // CHECK below aims at catching misuse of this API.
2281     bool should_crash = context_->GetImpl()->browser_context() !=
2282                         web_contents_->GetBrowserContext();
2283     if (should_crash) {
2284       CHECK(false)
2285           << "BrowserContext of new WebContents does not match EWebView's. "
2286           << "Please see 'ewk_view_add*' documentation. "
2287           << "Aborting execution ...";
2288     }
2289   }
2290   web_contents_delegate_.reset(new WebContentsDelegateEfl(this));
2291   web_contents_->SetDelegate(web_contents_delegate_.get());
2292   WebContentsImplEfl* wc_efl =
2293       static_cast<WebContentsImplEfl*>(web_contents_.get());
2294   wc_efl->SetEflDelegate(new WebContentsEflDelegateEwk(this));
2295   back_forward_list_.reset(
2296       new _Ewk_Back_Forward_List(web_contents_->GetController()));
2297
2298   permission_popup_manager_.reset(new PermissionPopupManager(evas_object_));
2299
2300   native_view_ =
2301       static_cast<WebContentsImplEfl*>(web_contents_.get())->GetEflNativeView();
2302   evas_object_smart_member_add(native_view_, evas_object_);
2303   static_cast<WebContentsImpl*>(web_contents_.get())
2304       ->set_ewk_view(evas_object_);
2305   InitializeWindowTreeHost();
2306 }
2307
2308 void EWebView::InitializeWindowTreeHost() {
2309   CHECK(aura::Env::GetInstance());
2310
2311   int x, y, width, height;
2312   Ecore_Evas* ee =
2313       ecore_evas_ecore_evas_get(evas_object_evas_get(native_view_));
2314   ecore_evas_geometry_get(ee, &x, &y, &width, &height);
2315
2316   gfx::Rect bounds(x, y, width, height);
2317   ui::PlatformWindowInitProperties properties;
2318   properties.bounds = bounds;
2319
2320   host_ = aura::WindowTreeHost::Create(std::move(properties));
2321   host_->InitHost();
2322   host_->window()->Show();
2323
2324   focus_client_ =
2325       std::make_unique<aura::test::TestFocusClient>(host_->window());
2326   window_parenting_client_ =
2327       std::make_unique<aura::test::TestWindowParentingClient>(host_->window());
2328
2329   aura::Window* content = web_contents_->GetNativeView();
2330   aura::Window* parent = host_->window();
2331   if (!parent->Contains(content)) {
2332     parent->AddChild(content);
2333     content->Show();
2334   }
2335   content->SetBounds(bounds);
2336   RenderWidgetHostView* host_view = web_contents_->GetRenderWidgetHostView();
2337   if (host_view)
2338     host_view->SetSize(bounds.size());
2339 }
2340
2341 #if BUILDFLAG(IS_TIZEN) && !defined(EWK_BRINGUP)
2342 void EWebView::cameraResultCb(service_h request,
2343                               service_h reply,
2344                               service_result_e result,
2345                               void* data) {
2346   if (!IsMobileProfile() && !IsWearableProfile())
2347     return;
2348
2349   EWebView* webview = static_cast<EWebView*>(data);
2350   RenderViewHost* render_view_host =
2351       webview->web_contents_->GetRenderViewHost();
2352   if (result == SERVICE_RESULT_SUCCEEDED) {
2353     int ret = -1;
2354     char** filesarray;
2355     int number;
2356     ret = service_get_extra_data_array(reply, SERVICE_DATA_SELECTED,
2357                                        &filesarray, &number);
2358     if (filesarray) {
2359       for (int i = 0; i < number; i++) {
2360         std::vector<ui::SelectedFileInfo> files;
2361         if (!render_view_host) {
2362           return;
2363         }
2364         if (filesarray[i]) {
2365           GURL url(filesarray[i]);
2366           if (!url.is_valid()) {
2367             base::FilePath path(url.SchemeIsFile() ? url.path()
2368                                                    : filesarray[i]);
2369             files.push_back(ui::SelectedFileInfo(path, base::FilePath()));
2370           }
2371         }
2372         render_view_host->FilesSelectedInChooser(files,
2373                                                  webview->filechooser_mode_);
2374       }
2375     }
2376   } else {
2377     std::vector<ui::SelectedFileInfo> files;
2378     if (render_view_host) {
2379       render_view_host->FilesSelectedInChooser(files,
2380                                                webview->filechooser_mode_);
2381     }
2382   }
2383 }
2384
2385 bool EWebView::LaunchCamera(std::u16string mimetype) {
2386   service_h svcHandle = 0;
2387   if (service_create(&svcHandle) < 0 || !svcHandle) {
2388     LOG(ERROR) << __FUNCTION__ << " Service Creation Failed ";
2389     return false;
2390   }
2391   service_set_operation(svcHandle, SERVICE_OPERATION_CREATE_CONTENT);
2392   service_set_mime(svcHandle, UTF16ToUTF8(mimetype).c_str());
2393   service_add_extra_data(svcHandle, "CALLER", "Browser");
2394
2395   int ret = service_send_launch_request(svcHandle, cameraResultCb, this);
2396   if (ret != SERVICE_ERROR_NONE) {
2397     LOG(ERROR) << __FUNCTION__ << " Service Launch Failed ";
2398     service_destroy(svcHandle);
2399     return false;
2400   }
2401   service_destroy(svcHandle);
2402   return true;
2403 }
2404 #endif
2405
2406 void EWebView::UrlRequestSet(
2407     const char* url,
2408     content::NavigationController::LoadURLType loadtype,
2409     Eina_Hash* headers,
2410     const char* body) {
2411   GURL gurl(url);
2412   content::NavigationController::LoadURLParams params(gurl);
2413   params.load_type = loadtype;
2414   params.override_user_agent = NavigationController::UA_OVERRIDE_TRUE;
2415
2416   if (body) {
2417     std::string s(body);
2418     params.post_data =
2419         network::ResourceRequestBody::CreateFromBytes(s.data(), s.size());
2420   }
2421
2422   net::HttpRequestHeaders header;
2423   if (headers) {
2424     Eina_Iterator* it = eina_hash_iterator_tuple_new(headers);
2425     Eina_Hash_Tuple* t;
2426     while (eina_iterator_next(it, reinterpret_cast<void**>(&t))) {
2427       if (t->key) {
2428         const char* value_str =
2429             t->data ? static_cast<const char*>(t->data) : "";
2430         base::StringPiece name = static_cast<const char*>(t->key);
2431         base::StringPiece value = value_str;
2432         header.SetHeader(name, value);
2433         // net::HttpRequestHeaders.ToString() returns string with newline
2434         params.extra_headers += header.ToString();
2435       }
2436     }
2437     eina_iterator_free(it);
2438   }
2439
2440   web_contents_->GetController().LoadURLWithParams(params);
2441 }
2442
2443 bool EWebView::HandleShow() {
2444   if (!native_view_)
2445     return false;
2446
2447   Show();
2448   return true;
2449 }
2450
2451 bool EWebView::HandleHide() {
2452   if (!native_view_)
2453     return false;
2454
2455   Hide();
2456   return true;
2457 }
2458
2459 bool EWebView::HandleMove(int x, int y) {
2460   if (!native_view_)
2461     return false;
2462   evas_object_move(native_view_, x, y);
2463   return true;
2464 }
2465
2466 bool EWebView::HandleResize(int width, int height) {
2467   if (!native_view_)
2468     return false;
2469   evas_object_resize(native_view_, width, height);
2470   return true;
2471 }
2472
2473 bool EWebView::HandleTextSelectionDown(int x, int y) {
2474   if (!GetSelectionController())
2475     return false;
2476   return GetSelectionController()->TextSelectionDown(x, y);
2477 }
2478
2479 bool EWebView::HandleTextSelectionUp(int x, int y) {
2480   if (!GetSelectionController())
2481     return false;
2482   return GetSelectionController()->TextSelectionUp(x, y);
2483 }
2484
2485 void EWebView::HandleTapGestureForSelection(bool is_content_editable) {
2486   if (!GetSelectionController())
2487     return;
2488
2489   GetSelectionController()->PostHandleTapGesture(is_content_editable);
2490 }
2491
2492 void EWebView::HandleZoomGesture(blink::WebGestureEvent& event) {
2493   blink::WebInputEvent::Type event_type = event.GetType();
2494   if (event_type == blink::WebInputEvent::Type::kGestureDoubleTap ||
2495       event_type == blink::WebInputEvent::Type::kGesturePinchBegin) {
2496     SmartCallback<EWebViewCallbacks::ZoomStarted>().call();
2497   }
2498   if (event_type == blink::WebInputEvent::Type::kGestureDoubleTap ||
2499       event_type == blink::WebInputEvent::Type::kGesturePinchEnd) {
2500     SmartCallback<EWebViewCallbacks::ZoomFinished>().call();
2501   }
2502 }
2503
2504 void EWebView::SendDelayedMessages(RenderViewHost* render_view_host) {
2505   DCHECK(render_view_host);
2506
2507   if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
2508     base::ThreadPool::PostTask(
2509         FROM_HERE, {BrowserThread::UI},
2510         base::BindOnce(&EWebView::SendDelayedMessages, base::Unretained(this),
2511                        render_view_host));
2512     return;
2513   }
2514
2515   for (auto iter = delayed_messages_.begin(); iter != delayed_messages_.end();
2516        ++iter) {
2517     IPC::Message* message = *iter;
2518     message->set_routing_id(render_view_host->GetRoutingID());
2519 #if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
2520     render_view_host->Send(message);
2521 #endif
2522   }
2523
2524   delayed_messages_.clear();
2525 }
2526
2527 void EWebView::ClosePage() {
2528   web_contents_->ClosePage();
2529 }
2530
2531 void EWebView::OnOverscrolled(const gfx::Vector2dF& accumulated_overscroll,
2532                               const gfx::Vector2dF& latest_overscroll_delta) {
2533   const gfx::Vector2dF old_overscroll =
2534       accumulated_overscroll - latest_overscroll_delta;
2535
2536   if (latest_overscroll_delta.x() && !old_overscroll.x()) {
2537     latest_overscroll_delta.x() < 0
2538         ? SmartCallback<EWebViewCallbacks::OverscrolledLeft>().call()
2539         : SmartCallback<EWebViewCallbacks::OverscrolledRight>().call();
2540   }
2541   if (latest_overscroll_delta.y() && !old_overscroll.y()) {
2542     latest_overscroll_delta.y() < 0
2543         ? SmartCallback<EWebViewCallbacks::OverscrolledTop>().call()
2544         : SmartCallback<EWebViewCallbacks::OverscrolledBottom>().call();
2545   }
2546 }
2547
2548 void EWebView::RequestManifest(Ewk_View_Request_Manifest_Callback callback,
2549                                void* user_data) {
2550   web_contents_delegate_->RequestManifestInfo(callback, user_data);
2551 }
2552
2553 void EWebView::DidRespondRequestManifest(
2554     _Ewk_View_Request_Manifest* manifest,
2555     Ewk_View_Request_Manifest_Callback callback,
2556     void* user_data) {
2557   callback(evas_object_, manifest, user_data);
2558 }