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