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