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