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