[M120 Migration] Introduces network loading API
[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   if (GetOrientation() == orientation)
857     return;
858
859   if (orientation == 0 || orientation == 90 || orientation == 180 ||
860       orientation == 270) {
861 #if !defined(USE_AURA)
862     GetWebContentsViewEfl()->SetOrientation(orientation);
863 #endif
864     int width = 0;
865     int height = 0;
866     const Ecore_Evas* ee =
867         ecore_evas_ecore_evas_get(evas_object_evas_get(ewk_view_));
868     ecore_evas_screen_geometry_get(ee, nullptr, nullptr, &width, &height);
869     if (orientation == 90 || orientation == 270)
870       std::swap(width, height);
871
872     if (popup_controller_)
873       popup_controller_->SetPopupSize(width, height);
874     if (JavaScriptDialogManagerEfl* dialogMG = GetJavaScriptDialogManagerEfl())
875       dialogMG->SetPopupSize(width, height);
876   }
877 }
878
879 int EWebView::GetOrientation() {
880 #if !defined(USE_AURA)
881   return GetWebContentsViewEfl()->GetOrientation();
882 #else
883   return 0;
884 #endif
885 }
886
887 void EWebView::Show() {
888   evas_object_show(efl_main_layout_);
889   web_contents_->WasShown();
890 }
891
892 void EWebView::Hide() {
893   LOG(INFO) << "EWebView: " << this;
894   evas_object_hide(efl_main_layout_);
895   if (!web_contents_)
896     return;
897   web_contents_->WasHidden();
898 }
899
900 void EWebView::SetViewAuthCallback(Ewk_View_Authentication_Callback callback,
901                                    void* user_data) {
902   authentication_cb_.Set(callback, user_data);
903 }
904
905 void EWebView::InvokeAuthCallback(LoginDelegateEfl* login_delegate,
906                                   const GURL& url,
907                                   const std::string& realm) {
908   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
909
910   auth_challenge_.reset(new _Ewk_Auth_Challenge(login_delegate, url, realm));
911   authentication_cb_.Run(ewk_view_, auth_challenge_.get());
912
913   if (!auth_challenge_->is_decided && !auth_challenge_->is_suspended) {
914     auth_challenge_->is_decided = true;
915     auth_challenge_->login_delegate->Cancel();
916   }
917 }
918
919 void EWebView::InvokePolicyResponseCallback(
920     _Ewk_Policy_Decision* policy_decision,
921     bool* defer) {
922   SmartCallback<EWebViewCallbacks::PolicyResponseDecide>().call(
923       policy_decision);
924
925   if (policy_decision->isSuspended()) {
926     *defer = true;
927     return;
928   }
929
930   if (!policy_decision->isDecided())
931     policy_decision->Use();
932
933   policy_decision->SelfDeleteIfNecessary();
934 }
935
936 void EWebView::InvokePolicyNavigationCallback(
937     const NavigationPolicyParams& params,
938     bool* handled) {
939   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
940
941   SmartCallback<EWebViewCallbacks::SaveSessionData>().call();
942
943   std::unique_ptr<_Ewk_Policy_Decision> policy_decision(
944       new _Ewk_Policy_Decision(params));
945
946   SmartCallback<EWebViewCallbacks::NavigationPolicyDecision>().call(
947       policy_decision.get());
948
949   CHECK(!policy_decision->isSuspended());
950
951   // TODO: Navigation can't be suspended
952   // this aproach is synchronous and requires immediate response
953   // Maybe there is different approach (like resource throttle response
954   // mechanism) that allows us to
955   // suspend navigation
956   if (!policy_decision->isDecided())
957     policy_decision->Use();
958
959   *handled = policy_decision->GetNavigationPolicyHandler()->GetDecision() ==
960              NavigationPolicyHandlerEfl::Handled;
961 }
962
963 void EWebView::HandleTouchEvents(Ewk_Touch_Event_Type type,
964                                  const Eina_List* points,
965                                  const Evas_Modifier* modifiers) {
966   const Eina_List* l;
967   void* data;
968
969   if (GetSettings()->touchFocusEnabled() &&
970       (type == EWK_TOUCH_START && eina_list_count(points) == 1)) {
971     SetFocus(EINA_TRUE);
972   }
973
974   EINA_LIST_FOREACH(points, l, data) {
975     const Ewk_Touch_Point* point = static_cast<Ewk_Touch_Point*>(data);
976     if (point->state == EVAS_TOUCH_POINT_STILL) {
977       // Chromium doesn't expect (and doesn't like) these events.
978       continue;
979     }
980     if (rwhva()) {
981       Evas_Coord_Point pt;
982       pt.x = point->x;
983       pt.y = point->y;
984
985       int delta_y = 0;
986       evas_object_geometry_get(ewk_view(), nullptr, &delta_y, nullptr, nullptr);
987       ui::TouchEvent touch_event =
988           ui::MakeTouchEvent(pt, point->state, point->id, 0, delta_y);
989       rwhva()->OnTouchEvent(&touch_event);
990     }
991   }
992 }
993
994 bool EWebView::TouchEventsEnabled() const {
995   return rwhva()->offscreen_helper()->TouchEventsEnabled();
996 }
997
998 // TODO: Touch events use the same mouse events in EFL API.
999 // Figure out how to distinguish touch and mouse events on touch&mice devices.
1000 // Currently mouse and touch support is mutually exclusive.
1001 void EWebView::SetTouchEventsEnabled(bool enabled) {
1002   if (!rwhva() || !rwhva()->offscreen_helper()) {
1003     LOG(WARNING) << "RWHV is not created yet!";
1004     return;
1005   }
1006
1007   if (rwhva()->offscreen_helper()->TouchEventsEnabled() == enabled)
1008     return;
1009
1010   rwhva()->offscreen_helper()->SetTouchEventsEnabled(enabled);
1011
1012   GetSettings()->getPreferences().touch_event_feature_detection_enabled =
1013       enabled;
1014   GetSettings()->getPreferences().double_tap_to_zoom_enabled = enabled;
1015   GetSettings()->getPreferences().editing_behavior =
1016       enabled ? blink::mojom::EditingBehavior::kEditingAndroidBehavior
1017               : blink::mojom::EditingBehavior::kEditingUnixBehavior,
1018   UpdateWebKitPreferences();
1019 }
1020
1021 bool EWebView::MouseEventsEnabled() const {
1022   return mouse_events_enabled_;
1023 }
1024
1025 void EWebView::SetMouseEventsEnabled(bool enabled) {
1026   if (!rwhva() || !rwhva()->offscreen_helper()) {
1027     LOG(WARNING) << "RWHV is not created yet!";
1028     return;
1029   }
1030
1031   if (mouse_events_enabled_ == enabled)
1032     return;
1033
1034   mouse_events_enabled_ = enabled;
1035   rwhva()->offscreen_helper()->SetTouchEventsEnabled(!enabled);
1036 }
1037
1038 bool EWebView::SetKeyEventsEnabled(bool enabled) {
1039   if (!rwhva() || !rwhva()->aura_efl_helper()) {
1040     LOG(WARNING) << "RWHV is not created yet!";
1041     return false;
1042   }
1043
1044   if (key_events_enabled_ == enabled)
1045     return true;
1046
1047   key_events_enabled_ = enabled;
1048   rwhva()->aura_efl_helper()->SetKeyEventsEnabled(enabled);
1049   return true;
1050 }
1051
1052 void EWebView::SendKeyEvent(Evas_Object* ewk_view,
1053                             void* key_event,
1054                             bool is_press) {
1055   if (!rwhva() || !rwhva()->aura_efl_helper()) {
1056     LOG(WARNING) << "RWHV is not created yet!";
1057     return;
1058   }
1059
1060   rwhva()->aura_efl_helper()->SendKeyEvent(ewk_view, key_event, is_press);
1061 }
1062
1063 namespace {
1064
1065 class JavaScriptCallbackDetails {
1066  public:
1067   JavaScriptCallbackDetails(Ewk_View_Script_Execute_Callback callback_func,
1068                             void* user_data,
1069                             Evas_Object* view)
1070       : callback_func_(callback_func), user_data_(user_data), view_(view) {}
1071
1072   Ewk_View_Script_Execute_Callback callback_func_;
1073   void* user_data_;
1074   Evas_Object* view_;
1075 };
1076
1077 void JavaScriptComplete(JavaScriptCallbackDetails* script_callback_data,
1078                         base::Value result) {
1079   if (!script_callback_data->callback_func_)
1080     return;
1081
1082   std::string return_string;
1083   if (result.is_string()) {
1084     // We don't want to serialize strings with JSONStringValueSerializer
1085     // to avoid quotation marks.
1086     return_string = result.GetString();
1087   } else if (result.is_none()) {
1088     // Value::TYPE_NULL is for lack of value, undefined, null
1089     return_string = "";
1090   } else {
1091     JSONStringValueSerializer serializer(&return_string);
1092     serializer.Serialize(result);
1093   }
1094
1095   script_callback_data->callback_func_(script_callback_data->view_,
1096                                        return_string.c_str(),
1097                                        script_callback_data->user_data_);
1098 }
1099
1100 }  // namespace
1101
1102 bool EWebView::ExecuteJavaScript(const char* script,
1103                                  Ewk_View_Script_Execute_Callback callback,
1104                                  void* userdata) {
1105   LOG(INFO) << __FUNCTION__;
1106   if (!web_contents_) {
1107     LOG(ERROR) << __FUNCTION__ << "web_contents_ is null";
1108     return false;
1109   }
1110
1111   RenderFrameHost* render_frame_host = web_contents_->GetPrimaryMainFrame();
1112   if (!render_frame_host) {
1113     LOG(ERROR) << __FUNCTION__ << " render_frame_host is null";
1114     return false;
1115   }
1116
1117   // Note: M37. Execute JavaScript, |script| with
1118   // |RenderFrameHost::ExecuteJavaScript|.
1119   // @see also https://codereview.chromium.org/188893005 for more details.
1120   std::u16string js_script;
1121   base::UTF8ToUTF16(script, strlen(script), &js_script);
1122   if (callback) {
1123     JavaScriptCallbackDetails* script_callback_data =
1124         new JavaScriptCallbackDetails(callback, userdata, ewk_view_);
1125     RenderFrameHost::JavaScriptResultCallback js_callback =
1126         base::BindOnce(&JavaScriptComplete, base::Owned(script_callback_data));
1127     // In M47, it isn't possible anymore to execute javascript in the generic
1128     // case. We need to call ExecuteJavaScriptForTests to keep the behaviour
1129     // unchanged @see https://codereview.chromium.org/1123783002
1130     render_frame_host->ExecuteJavaScriptWithUserGestureForTests(
1131         js_script, std::move(js_callback));
1132   } else {
1133     // We use ExecuteJavaScriptWithUserGestureForTests instead of
1134     // ExecuteJavaScript because
1135     // ExecuteJavaScriptWithUserGestureForTests sets user_gesture to true. This
1136     // was the
1137     // behaviour is m34, and we want to keep it that way.
1138     render_frame_host->ExecuteJavaScriptWithUserGestureForTests(
1139         js_script, base::NullCallback());
1140   }
1141
1142   return true;
1143 }
1144
1145 bool EWebView::SetUserAgent(const char* userAgent) {
1146   content::NavigationController& controller = web_contents_->GetController();
1147   bool override = userAgent && strlen(userAgent);
1148   for (int i = 0; i < controller.GetEntryCount(); ++i)
1149     controller.GetEntryAtIndex(i)->SetIsOverridingUserAgent(override);
1150   // TODO: Check if override_in_new_tabs has to be true.
1151   web_contents_->SetUserAgentOverride(
1152       blink::UserAgentOverride::UserAgentOnly(userAgent),
1153       false /* override_in_new_tabs */);
1154   return true;
1155 }
1156
1157 bool EWebView::SetUserAgentAppName(const char* application_name) {
1158   EflWebView::VersionInfo::GetInstance()->UpdateUserAgentWithAppName(
1159       application_name ? application_name : "");
1160   std::string user_agent =
1161       EflWebView::VersionInfo::GetInstance()->DefaultUserAgent();
1162   web_contents_->SetUserAgentOverride(
1163       blink::UserAgentOverride::UserAgentOnly(user_agent),
1164       false /* override_in_new_tabs */);
1165   return true;
1166 }
1167
1168 #if BUILDFLAG(IS_TIZEN)
1169 bool EWebView::SetPrivateBrowsing(bool incognito) {
1170   if (context_->GetImpl()->browser_context()->IsOffTheRecord() == incognito)
1171     return false;
1172   context_->GetImpl()->browser_context()->SetOffTheRecord(incognito);
1173   return true;
1174 }
1175
1176 bool EWebView::GetPrivateBrowsing() const {
1177   return context_->GetImpl()->browser_context()->IsOffTheRecord();
1178 }
1179 #endif
1180
1181 const char* EWebView::GetUserAgent() const {
1182   std::string user_agent =
1183       web_contents_->GetUserAgentOverride().ua_string_override;
1184   if (user_agent.empty())
1185     user_agent_ = content::GetContentClientExport()->browser()->GetUserAgent();
1186   else
1187     user_agent_ = user_agent;
1188
1189   return user_agent_.c_str();
1190 }
1191
1192 const char* EWebView::GetUserAgentAppName() const {
1193   user_agent_app_name_ = EflWebView::VersionInfo::GetInstance()->AppName();
1194   return user_agent_app_name_.c_str();
1195 }
1196
1197 const char* EWebView::CacheSelectedText() {
1198   if (!rwhva())
1199     return "";
1200
1201   selected_text_cached_ = base::UTF16ToUTF8(rwhva()->GetSelectedText());
1202   return selected_text_cached_.c_str();
1203 }
1204
1205 _Ewk_Frame* EWebView::GetMainFrame() {
1206   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1207
1208   if (!frame_.get())
1209     frame_.reset(new _Ewk_Frame(web_contents_->GetPrimaryMainFrame()));
1210
1211   return frame_.get();
1212 }
1213
1214 void EWebView::UpdateWebKitPreferences() {
1215   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1216
1217   RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1218   if (!render_view_host)
1219     return;
1220
1221   web_contents_delegate_->OnUpdateSettings(settings_.get());
1222 #if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
1223   render_view_host->UpdateWebkitPreferences(settings_->getPreferences());
1224 #endif
1225   UpdateWebkitPreferencesEfl(render_view_host);
1226 }
1227
1228 void EWebView::UpdateWebkitPreferencesEfl(RenderViewHost* render_view_host) {
1229   DCHECK(render_view_host);
1230 #if !defined(EWK_BRINGUP)  // FIXME: m108 bringup
1231   IPC::Message* message = new EwkSettingsMsg_UpdateWebKitPreferencesEfl(
1232       render_view_host->GetRoutingID(), settings_->getPreferencesEfl());
1233
1234   if (render_view_host->IsRenderViewLive()) {
1235 #if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
1236     render_view_host->Send(message);
1237 #endif
1238   } else {
1239     delayed_messages_.push_back(message);
1240   }
1241 #endif
1242 }
1243
1244 void EWebView::SetContentSecurityPolicy(const char* policy,
1245                                         Ewk_CSP_Header_Type type) {
1246   web_contents_delegate_->SetContentSecurityPolicy(
1247       (policy ? policy : std::string()), type);
1248 }
1249
1250 void EWebView::LoadHTMLString(const char* html,
1251                               const char* base_uri,
1252                               const char* unreachable_uri) {
1253   LoadData(html, std::string::npos, NULL, NULL, base_uri, unreachable_uri);
1254 }
1255
1256 void EWebView::LoadPlainTextString(const char* plain_text) {
1257   LoadData(plain_text, std::string::npos, "text/plain", NULL, NULL, NULL);
1258 }
1259
1260 void EWebView::LoadHTMLStringOverridingCurrentEntry(
1261     const char* html,
1262     const char* base_uri,
1263     const char* unreachable_url) {
1264   LoadData(html, std::string::npos, NULL, NULL, base_uri, unreachable_url,
1265            true);
1266 }
1267
1268 void EWebView::LoadData(const char* data,
1269                         size_t size,
1270                         const char* mime_type,
1271                         const char* encoding,
1272                         const char* base_uri,
1273                         const char* unreachable_uri,
1274                         bool should_replace_current_entry) {
1275   SetDefaultStringIfNull(mime_type, "text/html");
1276   SetDefaultStringIfNull(encoding, "utf-8");
1277   SetDefaultStringIfNull(base_uri, "about:blank");  // Webkit2 compatible
1278   SetDefaultStringIfNull(unreachable_uri, "");
1279
1280   std::string str_data = data;
1281
1282   if (size < str_data.length())
1283     str_data = str_data.substr(0, size);
1284
1285   std::string url_str("data:");
1286   url_str.append(mime_type);
1287   url_str.append(";charset=");
1288   url_str.append(encoding);
1289   url_str.append(",");
1290
1291   // GURL constructor performs canonicalization of url string, but this is not
1292   // enough for correctly escaping contents of "data:" url.
1293   url_str.append(base::EscapeUrlEncodedData(str_data, false));
1294
1295   NavigationController::LoadURLParams data_params(GURL(url_str.c_str()));
1296
1297   data_params.base_url_for_data_url = GURL(base_uri);
1298   data_params.virtual_url_for_data_url = GURL(unreachable_uri);
1299
1300   data_params.load_type = NavigationController::LOAD_TYPE_DATA;
1301   data_params.should_replace_current_entry = should_replace_current_entry;
1302   data_params.override_user_agent = NavigationController::UA_OVERRIDE_TRUE;
1303   web_contents_->GetController().LoadURLWithParams(data_params);
1304 }
1305
1306 void EWebView::InvokeLoadError(const GURL& url,
1307                                int error_code,
1308                                bool is_cancellation) {
1309   _Ewk_Error err(error_code, is_cancellation,
1310                  url.possibly_invalid_spec().c_str());
1311
1312   SmartCallback<EWebViewCallbacks::LoadError>().call(&err);
1313 }
1314
1315 void EWebView::SetViewLoadErrorPageCallback(
1316     Ewk_View_Error_Page_Load_Callback callback,
1317     void* user_data) {
1318   load_error_page_cb_.Set(callback, user_data);
1319 }
1320
1321 // Remove below code while ewk_error_cancellation_get has been implemented.
1322 const char* EWebView::InvokeViewLoadErrorPageCallback(
1323     const GURL& url,
1324     int error_code,
1325     const std::string& error_description) {
1326   std::unique_ptr<_Ewk_Error> err(
1327       new _Ewk_Error(error_code, url.possibly_invalid_spec().c_str(),
1328                      error_description.c_str()));
1329   _Ewk_Error_Page error_page;
1330
1331   LOG(INFO) << "EWebView::InvokeLoadErrorPageCallback url: "
1332             << url.spec().c_str() << ", error_code: " << error_code;
1333
1334   load_error_page_cb_.Run(ewk_view_, err.get(), &error_page);
1335   return error_page.content;
1336 }
1337
1338 bool EWebView::IsLoadErrorPageCallbackSet() const {
1339   return load_error_page_cb_.IsCallbackSet();
1340 }
1341 void EWebView::HandlePopupMenu(std::vector<blink::mojom::MenuItemPtr> items,
1342                                int selectedIndex,
1343                                bool multiple,
1344                                const gfx::Rect& bounds) {
1345   if (!select_picker_) {
1346     select_picker_.reset(CreateSelectPicker(
1347         this, selectedIndex, std::move(items), multiple, bounds));
1348
1349     // Picker has been shown on top of webview and the page content gets
1350     // partially overlapped. Decrease viewport while showing picker.
1351     AdjustViewPortHeightToPopupMenu(true /* is_popup_menu_visible */);
1352 #if BUILDFLAG(IS_TIZEN_TV)
1353     SmartCallback<EWebViewCallbacks::PopupMenuShow>().call();
1354 #endif
1355   } else {
1356     select_picker_->UpdatePickerData(selectedIndex, std::move(items), multiple);
1357   }
1358
1359   select_picker_->Show();
1360 }
1361
1362 void EWebView::HidePopupMenu() {
1363   if (!select_picker_)
1364     return;
1365
1366   AdjustViewPortHeightToPopupMenu(false /* is_popup_menu_visible */);
1367 #if BUILDFLAG(IS_TIZEN_TV)
1368   SmartCallback<EWebViewCallbacks::PopupMenuHide>().call();
1369 #endif
1370   select_picker_.reset();
1371 }
1372
1373 void EWebView::DidSelectPopupMenuItems(std::vector<int>& indices) {
1374   wcva()->wcva_helper()->DidSelectPopupMenuItems(indices);
1375 }
1376
1377 void EWebView::DidCancelPopupMenu() {
1378   wcva()->wcva_helper()->DidCancelPopupMenu();
1379 }
1380
1381 void EWebView::HandleLongPressGesture(
1382     const content::ContextMenuParams& params) {
1383   // This menu is created in renderer process and it does not now anything about
1384   // view scaling factor and it has another calling sequence, so coordinates is
1385   // not updated.
1386   if (settings_ && !settings_->getPreferences().long_press_enabled)
1387     return;
1388
1389   content::ContextMenuParams convertedParams = params;
1390   gfx::Point convertedPoint =
1391       rwhva()->offscreen_helper()->ConvertPointInViewPix(
1392           gfx::Point(params.x, params.y));
1393   convertedParams.x = convertedPoint.x();
1394   convertedParams.y = convertedPoint.y();
1395
1396   Evas_Coord x, y;
1397   evas_object_geometry_get(ewk_view(), &x, &y, 0, 0);
1398   convertedParams.x += x;
1399   convertedParams.y += y;
1400
1401   bool show_context_menu_now = true;
1402   if (GetSelectionController() && GetSelectionController()->GetLongPressed()) {
1403     show_context_menu_now = !GetSelectionController()->HandleLongPressEvent(
1404         convertedPoint, convertedParams);
1405   }
1406   if (show_context_menu_now) {
1407     ShowContextMenuInternal(convertedParams);
1408   }
1409 }
1410
1411 void EWebView::ShowContextMenu(const content::ContextMenuParams& params) {
1412   if (!rwhva())
1413     return;
1414
1415   // This menu is created in renderer process and it does not now anything about
1416   // view scaling factor and it has another calling sequence, so coordinates is
1417   // not updated.
1418   content::ContextMenuParams convertedParams = params;
1419   gfx::Point convertedPoint =
1420       rwhva()->offscreen_helper()->ConvertPointInViewPix(
1421           gfx::Point(params.x, params.y));
1422   convertedParams.x = convertedPoint.x();
1423   convertedParams.y = convertedPoint.y();
1424
1425   Evas_Coord x, y;
1426   evas_object_geometry_get(ewk_view(), &x, &y, 0, 0);
1427   convertedParams.x += x;
1428   convertedParams.y += y;
1429
1430   context_menu_position_ = gfx::Point(convertedParams.x, convertedParams.y);
1431
1432   ShowContextMenuInternal(convertedParams);
1433 }
1434
1435 void EWebView::ShowContextMenuInternal(
1436     const content::ContextMenuParams& params) {
1437   // We don't want to show 'cut' or 'copy' for inputs of type 'password' in
1438   // selection context menu, but params.input_field_type might not be set
1439   // correctly, because in some cases params is received from SelectionBoxEfl,
1440   // not from FrameHostMsg_ContextMenu message. In SelectionBoxEfl
1441   // ContextMenuParams is constructed on our side with limited information and
1442   // input_field_type is not set.
1443   //
1444   // To work around this, we query for input type and set it separately. In
1445   // response to EwkViewMsg_QueryInputType we run ::UpdateContextMenu with
1446   // information about input's type.
1447   //
1448   // FIXME: the way we get ContextMenuParams for context menu is flawed in some
1449   //        cases. This should be fixed by restructuring context menu code.
1450   //        Context menu creation should be unified to always have
1451   //        ContextMenuParams received from FrameHostMsg_ContextMenu.
1452   //        Tracked at: http://suprem.sec.samsung.net/jira/browse/TWF-1640
1453   if (params.is_editable) {
1454     saved_context_menu_params_ = params;
1455     if (rwhva())
1456       rwhva()->host()->QueryInputType();
1457   } else {
1458     UpdateContextMenuWithParams(params);
1459   }
1460 }
1461
1462 void EWebView::UpdateContextMenu(bool is_password_input) {
1463   if (is_password_input) {
1464     saved_context_menu_params_.form_control_type =
1465         blink::mojom::FormControlType::kInputPassword;
1466   }
1467   UpdateContextMenuWithParams(saved_context_menu_params_);
1468 }
1469
1470 void EWebView::UpdateContextMenuWithParams(
1471     const content::ContextMenuParams& params) {
1472   context_menu_.reset(
1473       new content::ContextMenuControllerEfl(this, *web_contents_.get()));
1474
1475   if (IsMobileProfile()) {
1476     if (delayed_show_context_menu_timer_) {
1477       ecore_timer_del(delayed_show_context_menu_timer_);
1478       delayed_show_context_menu_timer_ = nullptr;
1479     }
1480     saved_context_menu_params_ = params;
1481     delayed_show_context_menu_timer_ = ecore_timer_add(
1482         kDelayShowContextMenuTime, DelayedPopulateAndShowContextMenu, this);
1483   } else {
1484     if (!context_menu_->PopulateAndShowContextMenu(params)) {
1485       context_menu_.reset();
1486       if (GetSelectionController())
1487         GetSelectionController()->HideHandles();
1488     }
1489   }
1490 }
1491
1492 Eina_Bool EWebView::DelayedPopulateAndShowContextMenu(void* data) {
1493   if (IsMobileProfile()) {
1494     EWebView* view = static_cast<EWebView*>(data);
1495     if (view) {
1496       if (view->context_menu_ &&
1497           !(view->context_menu_->PopulateAndShowContextMenu(
1498               view->saved_context_menu_params_))) {
1499         view->context_menu_.reset();
1500       }
1501       view->delayed_show_context_menu_timer_ = nullptr;
1502     }
1503   }
1504   return ECORE_CALLBACK_CANCEL;
1505 }
1506
1507 void EWebView::CancelContextMenu(int request_id) {
1508   if (context_menu_)
1509     context_menu_->HideContextMenu();
1510 }
1511
1512 void EWebView::Find(const char* text, Ewk_Find_Options ewk_find_options) {
1513   std::u16string find_text = base::UTF8ToUTF16(text);
1514   bool find_next = (previous_text_ == find_text);
1515
1516   if (!find_next) {
1517     current_find_request_id_ = find_request_id_counter_++;
1518     previous_text_ = find_text;
1519   }
1520
1521   auto find_options = blink::mojom::FindOptions::New();
1522   find_options->forward = !(ewk_find_options & EWK_FIND_OPTIONS_BACKWARDS);
1523   find_options->match_case =
1524       !(ewk_find_options & EWK_FIND_OPTIONS_CASE_INSENSITIVE);
1525
1526   web_contents_->Find(current_find_request_id_, find_text,
1527                       std::move(find_options));
1528 }
1529
1530 void EWebView::SetScale(double scale_factor) {
1531   // Do not cache |scale_factor| here as it may be discarded by Blink's
1532   // minimumPageScaleFactor and maximumPageScaleFactor.
1533   // |scale_factor| is cached as responde to DidChangePageScaleFactor.
1534   WebContentsImpl* wci = static_cast<WebContentsImpl*>(web_contents_.get());
1535   wci->GetPrimaryMainFrame()->GetAssociatedLocalMainFrame()->SetScaleFactor(
1536       scale_factor);
1537 }
1538
1539 void EWebView::ScrollFocusedNodeIntoView() {
1540   if (RenderViewHost* render_view_host = web_contents_->GetRenderViewHost()) {
1541     if (auto& broadcast = static_cast<RenderViewHostImpl*>(render_view_host)
1542                               ->GetAssociatedPageBroadcast())
1543       broadcast->ScrollFocusedNodeIntoView();
1544   }
1545 }
1546
1547 void EWebView::AdjustViewPortHeightToPopupMenu(bool is_popup_menu_visible) {
1548   if (!rwhva() || !IsMobileProfile() ||
1549       settings_->getPreferences().TizenCompatibilityModeEnabled()) {
1550     return;
1551   }
1552
1553   int picker_height = select_picker_->GetGeometryDIP().height();
1554   gfx::Rect screen_rect =
1555       display::Screen::GetScreen()->GetPrimaryDisplay().bounds();
1556   gfx::Rect view_rect = rwhva()->offscreen_helper()->GetViewBounds();
1557   int bottom_height =
1558       screen_rect.height() - (view_rect.y() + view_rect.height());
1559
1560   rwhva()->offscreen_helper()->SetCustomViewportSize(
1561       is_popup_menu_visible
1562           ? gfx::Size(view_rect.width(),
1563                       view_rect.height() - picker_height + bottom_height)
1564           : gfx::Size());
1565 }
1566
1567 void EWebView::SetScaleChangedCallback(Ewk_View_Scale_Changed_Callback callback,
1568                                        void* user_data) {
1569   scale_changed_cb_.Set(callback, user_data);
1570 }
1571
1572 bool EWebView::GetScrollPosition(int* x, int* y) const {
1573   if (!rwhva()) {
1574     LOG(ERROR) << "rwhva() returns nullptr";
1575     return false;
1576   }
1577   if (scroll_detector_->IsScrollOffsetChanged()) {
1578     if (x)
1579       *x = previous_scroll_position_.x();
1580     if (y)
1581       *y = previous_scroll_position_.y();
1582   } else {
1583     const gfx::Vector2d scroll_position_dip =
1584         scroll_detector_->GetLastScrollPosition();
1585     const float device_scale_factor = display::Screen::GetScreen()
1586                                           ->GetPrimaryDisplay()
1587                                           .device_scale_factor();
1588     if (x) {
1589       *x = base::ClampRound((scroll_position_dip.x() - x_delta_) *
1590                             device_scale_factor);
1591     }
1592     if (y) {
1593       *y = base::ClampRound((scroll_position_dip.y() - y_delta_) *
1594                             device_scale_factor);
1595     }
1596   }
1597   return true;
1598 }
1599
1600 void EWebView::ChangeScroll(int& x, int& y) {
1601   if (!rwhva()) {
1602     LOG(ERROR) << "rwhva() returns nullptr";
1603     return;
1604   }
1605   int max_x = 0;
1606   int max_y = 0;
1607   GetScrollSize(&max_x, &max_y);
1608   previous_scroll_position_.set_x(std::min(std::max(x, 0), max_x));
1609   previous_scroll_position_.set_y(std::min(std::max(y, 0), max_y));
1610
1611   const float device_scale_factor = display::Screen::GetScreen()
1612                                         ->GetPrimaryDisplay()
1613                                         .device_scale_factor();
1614   int x_input = x;
1615   int y_input = y;
1616
1617   x = base::ClampCeil(x / device_scale_factor);
1618   y = base::ClampCeil(y / device_scale_factor);
1619
1620   x_delta_ = x - (x_input / device_scale_factor);
1621   y_delta_ = y - (y_input / device_scale_factor);
1622
1623   scroll_detector_->SetScrollOffsetChanged();
1624 }
1625
1626 void EWebView::SetScroll(int x, int y) {
1627   if (auto* render_view_host = web_contents_->GetRenderViewHost()) {
1628     if (auto& broadcast = static_cast<RenderViewHostImpl*>(render_view_host)
1629                               ->GetAssociatedPageBroadcast()) {
1630       ChangeScroll(x, y);
1631       broadcast->SetScrollOffset(x, y);
1632     }
1633   }
1634 }
1635
1636 void EWebView::UseSettingsFont() {
1637 #if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
1638   RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1639   if (render_view_host)
1640     render_view_host->Send(
1641         new EwkViewMsg_UseSettingsFont(render_view_host->GetRoutingID()));
1642 #endif
1643 }
1644
1645 void EWebView::DidChangeContentsSize(int width, int height) {
1646   contents_size_ = gfx::Size(width, height);
1647   SmartCallback<EWebViewCallbacks::ContentsSizeChanged>().call();
1648   SetScaledContentsSize();
1649 }
1650
1651 const Eina_Rectangle EWebView::GetContentsSize() const {
1652   Eina_Rectangle rect;
1653   EINA_RECTANGLE_SET(&rect, 0, 0, contents_size_.width(),
1654                      contents_size_.height());
1655   return rect;
1656 }
1657
1658 void EWebView::SetScaledContentsSize() {
1659   if (!rwhva())
1660     return;  // LCOV_EXCL_LINE
1661
1662   const float device_scale_factor =
1663       display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
1664   gfx::SizeF scaled_contents_size = gfx::ConvertSizeToPixels(
1665       contents_size_, device_scale_factor * page_scale_factor_);
1666   rwhva()->offscreen_helper()->SetScaledContentSize(scaled_contents_size);
1667 }
1668
1669 void EWebView::GetScrollSize(int* width, int* height) {
1670   int w = 0, h = 0;
1671   if (width) {
1672     *width = (rwhva() &&
1673               (w = rwhva()->offscreen_helper()->GetScrollableSize().width()))
1674                  ? w
1675                  : 0;
1676   }
1677   if (height) {
1678     *height = (rwhva() &&
1679                (h = rwhva()->offscreen_helper()->GetScrollableSize().height()))
1680                   ? h
1681                   : 0;
1682   }
1683 }
1684
1685 void EWebView::MoveCaret(const gfx::Point& point) {
1686   if (rwhva())
1687     rwhva()->offscreen_helper()->MoveCaret(point);
1688 }
1689
1690 SelectionControllerEfl* EWebView::GetSelectionController() const {
1691   RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1692   RenderWidgetHostViewAura* view = static_cast<RenderWidgetHostViewAura*>(
1693       render_view_host->GetWidget()->GetView());
1694   return view ? view->offscreen_helper()->GetSelectionController() : 0;
1695 }
1696
1697 void EWebView::SelectFocusedLink() {
1698   rwhva()->host()->SelectFocusedLink();
1699 }
1700
1701 bool EWebView::GetSelectionRange(Eina_Rectangle* left_rect,
1702                                  Eina_Rectangle* right_rect) {
1703   if (left_rect && right_rect) {
1704     gfx::Rect left, right;
1705     if (GetSelectionController()) {
1706       GetSelectionController()->GetSelectionBounds(&left, &right);
1707       GetEinaRectFromGfxRect(left, left_rect);
1708       GetEinaRectFromGfxRect(right, right_rect);
1709       return true;
1710     }
1711   }
1712   return false;
1713 }
1714
1715 void EWebView::OnSelectionRectReceived(const gfx::Rect& selection_rect) const {
1716   if (context_menu_)
1717     context_menu_->OnSelectionRectReceived(selection_rect);
1718 }
1719
1720 Eina_Bool EWebView::ClearSelection() {
1721   if (!rwhva())
1722     return EINA_FALSE;
1723
1724   ResetContextMenuController();
1725   rwhva()->SelectionChanged(std::u16string(), 0, gfx::Range());
1726
1727   if (GetSelectionController())
1728     return GetSelectionController()->ClearSelectionViaEWebView();
1729
1730   return EINA_FALSE;
1731 }
1732
1733 _Ewk_Hit_Test* EWebView::RequestHitTestDataAt(int x,
1734                                               int y,
1735                                               Ewk_Hit_Test_Mode mode) {
1736   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1737
1738   int view_x, view_y;
1739   EvasToBlinkCords(x, y, &view_x, &view_y);
1740
1741   return RequestHitTestDataAtBlinkCoords(view_x, view_y, mode);
1742 }
1743
1744 Eina_Bool EWebView::AsyncRequestHitTestDataAt(
1745     int x,
1746     int y,
1747     Ewk_Hit_Test_Mode mode,
1748     Ewk_View_Hit_Test_Request_Callback callback,
1749     void* user_data) {
1750   int view_x, view_y;
1751   EvasToBlinkCords(x, y, &view_x, &view_y);
1752   return AsyncRequestHitTestDataAtBlinkCords(
1753       view_x, view_y, mode,
1754       new WebViewAsyncRequestHitTestDataUserCallback(x, y, mode, callback,
1755                                                      user_data));
1756 }
1757
1758 Eina_Bool EWebView::AsyncRequestHitTestDataAtBlinkCords(
1759     int x,
1760     int y,
1761     Ewk_Hit_Test_Mode mode,
1762     Ewk_View_Hit_Test_Request_Callback callback,
1763     void* user_data) {
1764   return AsyncRequestHitTestDataAtBlinkCords(
1765       x, y, mode,
1766       new WebViewAsyncRequestHitTestDataUserCallback(x, y, mode, callback,
1767                                                      user_data));
1768 }
1769
1770 Eina_Bool EWebView::AsyncRequestHitTestDataAtBlinkCords(
1771     int x,
1772     int y,
1773     Ewk_Hit_Test_Mode mode,
1774     WebViewAsyncRequestHitTestDataCallback* cb) {
1775   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1776   DCHECK(cb);
1777
1778   static int64_t request_id = 1;
1779
1780   if (cb) {
1781     RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1782     DCHECK(render_view_host);
1783
1784     if (render_view_host) {
1785 #if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
1786       render_view_host->Send(new EwkViewMsg_DoHitTestAsync(
1787           render_view_host->GetRoutingID(), x, y, mode, request_id));
1788 #endif
1789       hit_test_callback_[request_id] = cb;
1790       ++request_id;
1791       return EINA_TRUE;
1792     }
1793   }
1794
1795   // if failed we delete callback as it is not needed anymore
1796   delete cb;
1797   return EINA_FALSE;
1798 }
1799
1800 void EWebView::DispatchAsyncHitTestData(const Hit_Test_Params& params,
1801                                         int64_t request_id) {
1802   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1803
1804   std::map<int64_t, WebViewAsyncRequestHitTestDataCallback*>::iterator it =
1805       hit_test_callback_.find(request_id);
1806
1807   if (it == hit_test_callback_.end())
1808     return;
1809   std::unique_ptr<_Ewk_Hit_Test> hit_test(new _Ewk_Hit_Test(params));
1810
1811   it->second->Run(hit_test.get(), this);
1812   delete it->second;
1813   hit_test_callback_.erase(it);
1814 }
1815
1816 _Ewk_Hit_Test* EWebView::RequestHitTestDataAtBlinkCoords(
1817     int x,
1818     int y,
1819     Ewk_Hit_Test_Mode mode) {
1820   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1821
1822   RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1823
1824   if (render_view_host) {
1825     // We wait on UI thread till hit test data is updated.
1826 #if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
1827     render_view_host->Send(
1828         new EwkViewMsg_DoHitTest(render_view_host->GetRoutingID(), x, y, mode));
1829 #endif
1830     hit_test_completion_.Wait();
1831     return new _Ewk_Hit_Test(hit_test_params_);
1832   }
1833
1834   return nullptr;
1835 }
1836
1837 void EWebView::EvasToBlinkCords(int x, int y, int* view_x, int* view_y) {
1838   DCHECK(display::Screen::GetScreen());
1839   if (!rwhva())
1840     return;
1841
1842   gfx::Rect view_bounds = rwhva()->offscreen_helper()->GetViewBoundsInPix();
1843
1844   if (view_x) {
1845     *view_x = x - view_bounds.x();
1846     *view_x /=
1847         display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
1848   }
1849
1850   if (view_y) {
1851     *view_y = y - view_bounds.y();
1852     *view_y /=
1853         display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
1854   }
1855 }
1856
1857 void EWebView::UpdateHitTestData(const Hit_Test_Params& params) {
1858   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
1859   hit_test_params_ = params;
1860   hit_test_completion_.Signal();
1861 }
1862
1863 void EWebView::OnCopyFromBackingStore(bool success, const SkBitmap& bitmap) {}
1864
1865 void EWebView::OnFocusIn() {
1866   SmartCallback<EWebViewCallbacks::FocusIn>().call();
1867 #if defined(USE_WAYLAND)
1868   if (!rwhva() || !rwhva()->offscreen_helper())
1869     return;
1870   if (GetSettings()->getClipboardEnabled()) {
1871     ClipboardHelperEfl::GetInstance()->OnWebviewFocusIn(
1872         this, rwhva()->offscreen_helper()->content_image_elm_host(),
1873         rwhva()->offscreen_helper()->IsFocusedNodeContentEditable(),
1874         base::BindRepeating(&EWebView::ExecuteEditCommand,
1875                             base::Unretained(this)));
1876   }
1877 #endif
1878 }
1879
1880 void EWebView::OnFocusOut() {
1881 #if defined(TIZEN_ATK_SUPPORT)
1882   if (IsMobileProfile())
1883     eweb_accessibility_->OnFocusOut();
1884 #endif
1885   SmartCallback<EWebViewCallbacks::FocusOut>().call();
1886 #if defined(USE_WAYLAND)
1887   if (GetSettings()->getClipboardEnabled())
1888     ClipboardHelperEfl::GetInstance()->MaybeInvalidateActiveWebview(this);
1889 #endif
1890 }
1891
1892 void EWebView::RenderViewReady() {
1893   if (rwhva()) {
1894     rwhva()->offscreen_helper()->SetFocusInOutCallbacks(
1895         base::BindRepeating(&EWebView::OnFocusIn, base::Unretained(this)),
1896         base::BindRepeating(&EWebView::OnFocusOut, base::Unretained(this)));
1897   }
1898
1899 #if defined(TIZEN_VIDEO_HOLE)
1900   if (rwhva() && pending_video_hole_setting_) {
1901     EnableVideoHoleSupportInternal();
1902     pending_video_hole_setting_ = false;
1903   }
1904 #endif
1905
1906   RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1907
1908   SendDelayedMessages(render_view_host);
1909   UpdateWebkitPreferencesEfl(render_view_host);
1910
1911   if (render_view_host) {
1912     WebContents* content = WebContents::FromRenderViewHost(render_view_host);
1913     if (content) {
1914       RenderProcessHost* host = render_view_host->GetProcess();
1915       if (host)
1916         host->AddFilter(new WebViewBrowserMessageFilter(content));
1917     }
1918   }
1919 }
1920
1921 void EWebView::SetQuotaPermissionRequestCallback(
1922     Ewk_Quota_Permission_Request_Callback callback,
1923     void* user_data) {
1924   quota_request_callback_.Set(callback, user_data);
1925 }
1926
1927 #if !defined(EWK_BRINGUP)  // FIXME: m114 bringup
1928 void EWebView::InvokeQuotaPermissionRequest(
1929     _Ewk_Quota_Permission_Request* request,
1930     content::QuotaPermissionContext::PermissionCallback cb) {
1931   quota_permission_request_map_[request] = std::move(cb);
1932   request->setView(ewk_view());
1933   if (quota_request_callback_.IsCallbackSet())
1934     quota_request_callback_.Run(ewk_view(), request);
1935   else
1936     QuotaRequestCancel(request);
1937 }
1938
1939 void EWebView::QuotaRequestReply(const _Ewk_Quota_Permission_Request* request,
1940                                  bool allow) {
1941   DCHECK(quota_permission_request_map_.find(request) !=
1942          quota_permission_request_map_.end());
1943
1944   QuotaPermissionContextEfl::DispatchCallback(
1945       std::move(quota_permission_request_map_[request]),
1946       (allow ? QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_ALLOW
1947              : QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_DISALLOW));
1948
1949   quota_permission_request_map_.erase(request);
1950   delete request;
1951 }
1952
1953 void EWebView::QuotaRequestCancel(
1954     const _Ewk_Quota_Permission_Request* request) {
1955   DCHECK(quota_permission_request_map_.find(request) !=
1956          quota_permission_request_map_.end());
1957
1958   QuotaPermissionContextEfl::DispatchCallback(
1959       std::move(quota_permission_request_map_[request]),
1960       QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_CANCELLED);
1961   quota_permission_request_map_.erase(request);
1962   delete request;
1963 }
1964 #endif
1965
1966 bool EWebView::GetLinkMagnifierEnabled() const {
1967 #if !defined(EWK_BRINGUP)  // FIXME: m71 bringup
1968   return web_contents_->GetMutableRendererPrefs()
1969              ->tap_multiple_targets_strategy ==
1970          TAP_MULTIPLE_TARGETS_STRATEGY_POPUP;
1971 #else
1972   return false;
1973 #endif
1974 }
1975
1976 void EWebView::SetLinkMagnifierEnabled(bool enabled) {
1977 #if !defined(EWK_BRINGUP)  // FIXME: m71 bringup
1978   web_contents_->GetMutableRendererPrefs()->tap_multiple_targets_strategy =
1979       enabled ? TAP_MULTIPLE_TARGETS_STRATEGY_POPUP
1980               : TAP_MULTIPLE_TARGETS_STRATEGY_NONE;
1981 #endif
1982   web_contents_->SyncRendererPrefs();
1983 }
1984
1985 bool EWebView::GetSnapshotAsync(
1986     Eina_Rectangle rect,
1987     Ewk_Web_App_Screenshot_Captured_Callback callback,
1988     void* user_data,
1989     float scale_factor) {
1990   if (!rwhva() || !rwhva()->offscreen_helper())
1991     return false;
1992
1993   rwhva()->offscreen_helper()->RequestSnapshotAsync(
1994       gfx::Rect(rect.x, rect.y, rect.w, rect.h), callback, user_data,
1995       scale_factor);
1996   return true;
1997 }
1998
1999 Evas_Object* EWebView::GetSnapshot(Eina_Rectangle rect, float scale_factor) {
2000   if (!rwhva() || !rwhva()->offscreen_helper())
2001     return nullptr;
2002
2003   return rwhva()->offscreen_helper()->GetSnapshot(
2004       gfx::Rect(rect.x, rect.y, rect.w, rect.h), scale_factor);
2005 }
2006
2007 void EWebView::BackForwardListClear() {
2008   content::NavigationController& controller = web_contents_->GetController();
2009
2010   int entry_count = controller.GetEntryCount();
2011   bool entry_removed = false;
2012
2013   for (int i = 0; i < entry_count; i++) {
2014     if (controller.RemoveEntryAtIndex(i)) {
2015       entry_removed = true;
2016       entry_count = controller.GetEntryCount();
2017       i--;
2018     }
2019   }
2020
2021   if (entry_removed) {
2022     back_forward_list_->ClearCache();
2023     InvokeBackForwardListChangedCallback();
2024   }
2025 }
2026
2027 _Ewk_Back_Forward_List* EWebView::GetBackForwardList() const {
2028   return back_forward_list_.get();
2029 }
2030
2031 void EWebView::InvokeBackForwardListChangedCallback() {
2032   SmartCallback<EWebViewCallbacks::BackForwardListChange>().call();
2033 }
2034
2035 _Ewk_History* EWebView::GetBackForwardHistory() const {
2036   return new _Ewk_History(web_contents_->GetController());
2037 }
2038
2039 bool EWebView::WebAppCapableGet(Ewk_Web_App_Capable_Get_Callback callback,
2040                                 void* userData) {
2041   RenderViewHost* renderViewHost = web_contents_->GetRenderViewHost();
2042   if (!renderViewHost) {
2043     return false;
2044   }
2045 #if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
2046   WebApplicationCapableGetCallback* cb =
2047       new WebApplicationCapableGetCallback(callback, userData);
2048   int callbackId = web_app_capable_get_callback_map_.Add(cb);
2049   return renderViewHost->Send(new EwkViewMsg_WebAppCapableGet(
2050       renderViewHost->GetRoutingID(), callbackId));
2051 #else
2052   return false;
2053 #endif
2054 }
2055
2056 bool EWebView::WebAppIconUrlGet(Ewk_Web_App_Icon_URL_Get_Callback callback,
2057                                 void* userData) {
2058   RenderViewHost* renderViewHost = web_contents_->GetRenderViewHost();
2059   if (!renderViewHost) {
2060     return false;
2061   }
2062 #if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
2063   WebApplicationIconUrlGetCallback* cb =
2064       new WebApplicationIconUrlGetCallback(callback, userData);
2065   int callbackId = web_app_icon_url_get_callback_map_.Add(cb);
2066   return renderViewHost->Send(new EwkViewMsg_WebAppIconUrlGet(
2067       renderViewHost->GetRoutingID(), callbackId));
2068 #else
2069   return false;
2070 #endif
2071 }
2072
2073 bool EWebView::WebAppIconUrlsGet(Ewk_Web_App_Icon_URLs_Get_Callback callback,
2074                                  void* userData) {
2075   RenderViewHost* renderViewHost = web_contents_->GetRenderViewHost();
2076   if (!renderViewHost) {
2077     return false;
2078   }
2079 #if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
2080   WebApplicationIconUrlsGetCallback* cb =
2081       new WebApplicationIconUrlsGetCallback(callback, userData);
2082   int callbackId = web_app_icon_urls_get_callback_map_.Add(cb);
2083   return renderViewHost->Send(new EwkViewMsg_WebAppIconUrlsGet(
2084       renderViewHost->GetRoutingID(), callbackId));
2085 #else
2086   return false;
2087 #endif
2088 }
2089
2090 void EWebView::InvokeWebAppCapableGetCallback(bool capable, int callbackId) {
2091   WebApplicationCapableGetCallback* callback =
2092       web_app_capable_get_callback_map_.Lookup(callbackId);
2093   if (!callback)
2094     return;
2095   callback->Run(capable);
2096   web_app_capable_get_callback_map_.Remove(callbackId);
2097 }
2098
2099 void EWebView::InvokeWebAppIconUrlGetCallback(const std::string& iconUrl,
2100                                               int callbackId) {
2101   WebApplicationIconUrlGetCallback* callback =
2102       web_app_icon_url_get_callback_map_.Lookup(callbackId);
2103   if (!callback)
2104     return;
2105   callback->Run(iconUrl);
2106   web_app_icon_url_get_callback_map_.Remove(callbackId);
2107 }
2108
2109 void EWebView::InvokeWebAppIconUrlsGetCallback(const StringMap& iconUrls,
2110                                                int callbackId) {
2111   WebApplicationIconUrlsGetCallback* callback =
2112       web_app_icon_urls_get_callback_map_.Lookup(callbackId);
2113   if (!callback) {
2114     return;
2115   }
2116   callback->Run(iconUrls);
2117   web_app_icon_urls_get_callback_map_.Remove(callbackId);
2118 }
2119
2120 void EWebView::SetNotificationPermissionCallback(
2121     Ewk_View_Notification_Permission_Callback callback,
2122     void* user_data) {
2123   notification_permission_callback_.Set(callback, user_data);
2124 }
2125
2126 bool EWebView::IsNotificationPermissionCallbackSet() const {
2127   return notification_permission_callback_.IsCallbackSet();
2128 }
2129
2130 bool EWebView::InvokeNotificationPermissionCallback(
2131     Ewk_Notification_Permission_Request* request) {
2132   Eina_Bool ret = EINA_FALSE;
2133   notification_permission_callback_.Run(ewk_view_, request, &ret);
2134   return ret;
2135 }
2136
2137 int EWebView::SetEwkViewPlainTextGetCallback(
2138     Ewk_View_Plain_Text_Get_Callback callback,
2139     void* user_data) {
2140   EwkViewPlainTextGetCallback* view_plain_text_callback_ptr =
2141       new EwkViewPlainTextGetCallback;
2142   view_plain_text_callback_ptr->Set(callback, user_data);
2143   return plain_text_get_callback_map_.Add(view_plain_text_callback_ptr);
2144 }
2145
2146 bool EWebView::PlainTextGet(Ewk_View_Plain_Text_Get_Callback callback,
2147                             void* user_data) {
2148   auto* render_frame_host = web_contents_->GetPrimaryMainFrame();
2149   if (!render_frame_host)
2150     return false;
2151
2152   auto callback_id = SetEwkViewPlainTextGetCallback(callback, user_data);
2153   return render_frame_host->Send(new EwkFrameMsg_GetPlainText(
2154       render_frame_host->GetRoutingID(), callback_id));
2155 }
2156
2157 void EWebView::InvokePlainTextGetCallback(const std::string& content_text,
2158                                           int plain_text_get_callback_id) {
2159   EwkViewPlainTextGetCallback* view_plain_text_callback_invoke_ptr =
2160       plain_text_get_callback_map_.Lookup(plain_text_get_callback_id);
2161   view_plain_text_callback_invoke_ptr->Run(ewk_view(), content_text.c_str());
2162   plain_text_get_callback_map_.Remove(plain_text_get_callback_id);
2163 }
2164
2165 void EWebView::SetViewGeolocationPermissionCallback(
2166     Ewk_View_Geolocation_Permission_Callback callback,
2167     void* user_data) {
2168   geolocation_permission_cb_.Set(callback, user_data);
2169 }
2170
2171 bool EWebView::InvokeViewGeolocationPermissionCallback(
2172     _Ewk_Geolocation_Permission_Request* permission_context,
2173     Eina_Bool* callback_result) {
2174   return geolocation_permission_cb_.Run(ewk_view_, permission_context,
2175                                         callback_result);
2176 }
2177
2178 void EWebView::SetViewUserMediaPermissionCallback(
2179     Ewk_View_User_Media_Permission_Callback callback,
2180     void* user_data) {
2181   user_media_permission_cb_.Set(callback, user_data);
2182 }
2183
2184 bool EWebView::InvokeViewUserMediaPermissionCallback(
2185     _Ewk_User_Media_Permission_Request* permission_context,
2186     Eina_Bool* callback_result) {
2187   return user_media_permission_cb_.Run(ewk_view_, permission_context,
2188                                        callback_result);
2189 }
2190
2191 void EWebView::SetViewUserMediaPermissionQueryCallback(
2192     Ewk_View_User_Media_Permission_Query_Callback callback,
2193     void* user_data) {
2194   user_media_permission_query_cb_.Set(callback, user_data);
2195 }
2196
2197 Ewk_User_Media_Permission_Query_Result
2198 EWebView::InvokeViewUserMediaPermissionQueryCallback(
2199     _Ewk_User_Media_Permission_Query* permission_context) {
2200   return user_media_permission_query_cb_.Run(ewk_view_, permission_context);
2201 }
2202
2203 void EWebView::SetViewUnfocusAllowCallback(
2204     Ewk_View_Unfocus_Allow_Callback callback,
2205     void* user_data) {
2206   unfocus_allow_cb_.Set(callback, user_data);
2207 }
2208
2209 bool EWebView::InvokeViewUnfocusAllowCallback(Ewk_Unfocus_Direction direction,
2210                                               Eina_Bool* callback_result) {
2211   return unfocus_allow_cb_.Run(ewk_view_, direction, callback_result);
2212 }
2213
2214 void EWebView::StopFinding() {
2215   web_contents_->StopFinding(content::STOP_FIND_ACTION_CLEAR_SELECTION);
2216 }
2217
2218 void EWebView::SetProgressValue(double progress) {
2219   progress_ = progress;
2220 }
2221
2222 double EWebView::GetProgressValue() {
2223   return progress_;
2224 }
2225
2226 const char* EWebView::GetTitle() {
2227   title_ = base::UTF16ToUTF8(web_contents_->GetTitle());
2228   return title_.c_str();
2229 }
2230
2231 bool EWebView::SaveAsPdf(int width, int height, const std::string& filename) {
2232   if (!rwhva())
2233     return false;
2234   rwhva()->host()->PrintToPdf(width, height, base::FilePath(filename));
2235   return true;
2236 }
2237
2238 bool EWebView::GetMHTMLData(Ewk_View_MHTML_Data_Get_Callback callback,
2239                             void* user_data) {
2240   RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
2241   if (!render_view_host)
2242     return false;
2243
2244 #if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
2245   MHTMLCallbackDetails* callback_details = new MHTMLCallbackDetails;
2246   callback_details->Set(callback, user_data);
2247   int mhtml_callback_id = mhtml_callback_map_.Add(callback_details);
2248   return render_view_host->Send(new EwkViewMsg_GetMHTMLData(
2249       render_view_host->GetRoutingID(), mhtml_callback_id));
2250 #else
2251   return false;
2252 #endif
2253 }
2254
2255 void EWebView::OnMHTMLContentGet(const std::string& mhtml_content,
2256                                  int callback_id) {
2257   MHTMLCallbackDetails* callback_details =
2258       mhtml_callback_map_.Lookup(callback_id);
2259   callback_details->Run(ewk_view(), mhtml_content.c_str());
2260   mhtml_callback_map_.Remove(callback_id);
2261 }
2262
2263 bool EWebView::SavePageAsMHTML(const std::string& path,
2264                                Ewk_View_Save_Page_Callback callback,
2265                                void* user_data) {
2266   if (!web_contents_)
2267     return false;
2268
2269   GURL url(web_contents_->GetLastCommittedURL());
2270   std::u16string title(web_contents_->GetTitle());
2271
2272   // Post function that has file access to blocking task runner.
2273   base::ThreadPool::PostTaskAndReplyWithResult(
2274       FROM_HERE,
2275       {base::MayBlock(), base::TaskPriority::BEST_EFFORT,
2276        base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN},
2277       base::BindOnce(&GenerateMHTMLFilePath, url, base::UTF16ToUTF8(title),
2278                      path),
2279       base::BindOnce(&EWebView::GenerateMHTML, base::Unretained(this), callback,
2280                      user_data));
2281   return true;
2282 }
2283
2284 void EWebView::GenerateMHTML(Ewk_View_Save_Page_Callback callback,
2285                              void* user_data,
2286                              const base::FilePath& file_path) {
2287   if (file_path.empty()) {
2288     LOG(ERROR) << "Generating file path was failed";
2289     callback(ewk_view_, nullptr, user_data);
2290     return;
2291   }
2292
2293   MHTMLGenerationParams params(file_path);
2294   web_contents_->GenerateMHTML(
2295       params, base::BindOnce(&EWebView::MHTMLGenerated, base::Unretained(this),
2296                              callback, user_data, file_path));
2297 }
2298
2299 void EWebView::MHTMLGenerated(Ewk_View_Save_Page_Callback callback,
2300                               void* user_data,
2301                               const base::FilePath& file_path,
2302                               int64_t file_size) {
2303   callback(ewk_view_, file_size > 0 ? file_path.value().c_str() : nullptr,
2304            user_data);
2305 }
2306
2307 bool EWebView::GetBackgroundColor(
2308     Ewk_View_Background_Color_Get_Callback callback,
2309     void* user_data) {
2310   if (!rwhva())
2311     return false;
2312   BackgroundColorGetCallback* cb =
2313       new BackgroundColorGetCallback(callback, user_data);
2314   int callback_id = background_color_get_callback_map_.Add(cb);
2315
2316   rwhva()->host()->RequestBackgroundColor(callback_id);
2317   return true;
2318 }
2319
2320 void EWebView::OnGetBackgroundColor(int callback_id, SkColor bg_color) {
2321   BackgroundColorGetCallback* cb =
2322       background_color_get_callback_map_.Lookup(callback_id);
2323
2324   if (!cb)
2325     return;
2326
2327   cb->Run(ewk_view(), SkColorGetR(bg_color), SkColorGetG(bg_color),
2328           SkColorGetB(bg_color), SkColorGetA(bg_color));
2329   background_color_get_callback_map_.Remove(callback_id);
2330 }
2331
2332 bool EWebView::IsFullscreen() {
2333   return web_contents_delegate_->IsFullscreenForTabOrPending(
2334       web_contents_.get());
2335 }
2336
2337 void EWebView::ExitFullscreen() {
2338   WebContentsImpl* wci = static_cast<WebContentsImpl*>(web_contents_.get());
2339   wci->ExitFullscreen(false);
2340 }
2341
2342 double EWebView::GetScale() {
2343   return page_scale_factor_;
2344 }
2345
2346 void EWebView::DidChangePageScaleFactor(double scale_factor) {
2347   page_scale_factor_ = scale_factor;
2348   wcva()->wcva_helper()->SetPageScaleFactor(scale_factor);
2349   SetScaledContentsSize();
2350
2351   // Notify app about the scale change.
2352   scale_changed_cb_.Run(ewk_view_, scale_factor);
2353 }
2354
2355 inline JavaScriptDialogManagerEfl* EWebView::GetJavaScriptDialogManagerEfl() {
2356   return static_cast<JavaScriptDialogManagerEfl*>(
2357       web_contents_delegate_->GetJavaScriptDialogManager(web_contents_.get()));
2358 }
2359
2360 void EWebView::SetJavaScriptAlertCallback(
2361     Ewk_View_JavaScript_Alert_Callback callback,
2362     void* user_data) {
2363   GetJavaScriptDialogManagerEfl()->SetAlertCallback(callback, user_data);
2364 }
2365
2366 void EWebView::JavaScriptAlertReply() {
2367   GetJavaScriptDialogManagerEfl()->ExecuteDialogClosedCallBack(true,
2368                                                                std::string());
2369   SmartCallback<EWebViewCallbacks::PopupReplyWaitFinish>().call(0);
2370 }
2371
2372 void EWebView::SetJavaScriptConfirmCallback(
2373     Ewk_View_JavaScript_Confirm_Callback callback,
2374     void* user_data) {
2375   GetJavaScriptDialogManagerEfl()->SetConfirmCallback(callback, user_data);
2376 }
2377
2378 void EWebView::JavaScriptConfirmReply(bool result) {
2379   GetJavaScriptDialogManagerEfl()->ExecuteDialogClosedCallBack(result,
2380                                                                std::string());
2381   SmartCallback<EWebViewCallbacks::PopupReplyWaitFinish>().call(0);
2382 }
2383
2384 void EWebView::SetJavaScriptPromptCallback(
2385     Ewk_View_JavaScript_Prompt_Callback callback,
2386     void* user_data) {
2387   GetJavaScriptDialogManagerEfl()->SetPromptCallback(callback, user_data);
2388 }
2389
2390 void EWebView::JavaScriptPromptReply(const char* result) {
2391   GetJavaScriptDialogManagerEfl()->ExecuteDialogClosedCallBack(
2392       true, (std::string(result)));
2393   SmartCallback<EWebViewCallbacks::PopupReplyWaitFinish>().call(0);
2394 }
2395
2396 void EWebView::GetPageScaleRange(double* min_scale, double* max_scale) {
2397   auto& prefs = web_contents_->GetOrCreateWebPreferences();
2398   if (min_scale)
2399     *min_scale = prefs.default_minimum_page_scale_factor;
2400   if (max_scale)
2401     *max_scale = prefs.default_maximum_page_scale_factor;
2402 }
2403
2404 content::WebContentsViewAura* EWebView::GetWebContentsViewAura() const {
2405   WebContentsImpl* wc = static_cast<WebContentsImpl*>(web_contents_.get());
2406   return static_cast<WebContentsViewAura*>(wc->GetView());
2407 }
2408
2409 bool EWebView::SetDrawsTransparentBackground(bool enabled) {
2410 #if BUILDFLAG(IS_TIZEN)
2411   RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
2412   if (!render_view_host || !rwhva())
2413     return false;
2414
2415   if (!rwhva()->offscreen_helper())
2416     return false;
2417   elm_object_style_set(rwhva()->offscreen_helper()->content_image_elm_host(),
2418                        enabled ? "transparent" : "default");
2419   evas_object_image_alpha_set(rwhva()->offscreen_helper()->content_image(),
2420                               enabled);
2421   GetWebContentsViewAura()->SetBackgroundColor(enabled ? SK_ColorTRANSPARENT
2422                                                        : SK_ColorWHITE);
2423   static_cast<RenderViewHostImpl*>(render_view_host)
2424       ->GetWidget()
2425       ->GetAssociatedFrameWidget()
2426       ->SetDrawsTransparentBackground(enabled);
2427   rwhva()->SetBackgroundColor(enabled ? SK_ColorTRANSPARENT : SK_ColorWHITE);
2428   return true;
2429 #else
2430   return false;
2431 #endif
2432 }
2433
2434 bool EWebView::GetDrawsTransparentBackground() {
2435 #if BUILDFLAG(IS_TIZEN)
2436   return GetWebContentsViewAura()->GetBackgroundColor() == SK_ColorTRANSPARENT;
2437 #else
2438   return false;
2439 #endif
2440 }
2441
2442 bool EWebView::SetBackgroundColor(int red, int green, int blue, int alpha) {
2443 #if BUILDFLAG(IS_TIZEN)
2444   if (!alpha)
2445     return SetDrawsTransparentBackground(true);
2446
2447   RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
2448   if (!render_view_host || !rwhva())
2449     return false;
2450
2451   if (!rwhva()->offscreen_helper())
2452     return false;
2453   elm_object_style_set(rwhva()->offscreen_helper()->content_image_elm_host(),
2454                        alpha < 255 ? "transparent" : "default");
2455   evas_object_image_alpha_set(rwhva()->offscreen_helper()->content_image(),
2456                               alpha < 255);
2457   GetWebContentsViewAura()->SetBackgroundColor(
2458       SkColorSetARGB(alpha, red, green, blue));
2459   static_cast<RenderViewHostImpl*>(render_view_host)
2460       ->GetWidget()
2461       ->GetAssociatedFrameWidget()
2462       ->SetBackgroundColor(red, green, blue, alpha);
2463   rwhva()->SetBackgroundColor(SkColorSetARGB(alpha, red, green, blue));
2464
2465   return true;
2466 #else
2467   return false;
2468 #endif
2469 }
2470
2471 void EWebView::GetSessionData(const char** data, unsigned* length) const {
2472   static const int MAX_SESSION_ENTRY_SIZE = std::numeric_limits<int>::max();
2473
2474   NavigationController& navigationController = web_contents_->GetController();
2475   base::Pickle sessionPickle;
2476   const int itemCount = navigationController.GetEntryCount();
2477
2478   sessionPickle.WriteInt(itemCount);
2479   sessionPickle.WriteInt(navigationController.GetCurrentEntryIndex());
2480
2481   for (int i = 0; i < itemCount; i++) {
2482     NavigationEntry* navigationEntry = navigationController.GetEntryAtIndex(i);
2483     sessions::SerializedNavigationEntry serializedEntry =
2484         sessions::ContentSerializedNavigationBuilder::FromNavigationEntry(
2485             i, navigationEntry);
2486     serializedEntry.WriteToPickle(MAX_SESSION_ENTRY_SIZE, &sessionPickle);
2487   }
2488
2489   if (sessionPickle.size() <= 0 ||
2490       !(*data =
2491             static_cast<char*>(malloc(sizeof(char) * sessionPickle.size())))) {
2492     LOG(ERROR) << "Failed to get session data";
2493     *length = 0;
2494     return;
2495   }
2496   memcpy(const_cast<char*>(*data), sessionPickle.data(), sessionPickle.size());
2497   *length = sessionPickle.size();
2498 }
2499
2500 bool EWebView::RestoreFromSessionData(const char* data, unsigned length) {
2501   base::Pickle sessionPickle(data, length);
2502   base::PickleIterator pickleIterator(sessionPickle);
2503   int entryCount;
2504   int currentEntry;
2505
2506   if (!pickleIterator.ReadInt(&entryCount))
2507     return false;
2508   if (!pickleIterator.ReadInt(&currentEntry))
2509     return false;
2510
2511   std::vector<sessions::SerializedNavigationEntry> serializedEntries;
2512   serializedEntries.resize(entryCount);
2513   for (int i = 0; i < entryCount; ++i) {
2514     if (!serializedEntries.at(i).ReadFromPickle(&pickleIterator))
2515       return false;
2516   }
2517
2518   if (!entryCount)
2519     return true;
2520
2521   if (!context())
2522     return false;
2523
2524   std::vector<std::unique_ptr<content::NavigationEntry>> scopedEntries =
2525       sessions::ContentSerializedNavigationBuilder::ToNavigationEntries(
2526           serializedEntries, context()->browser_context());
2527
2528   NavigationController& navigationController = web_contents_->GetController();
2529
2530   if (currentEntry < 0)
2531     currentEntry = 0;
2532
2533   if (currentEntry >= static_cast<int>(scopedEntries.size()))
2534     currentEntry = scopedEntries.size() - 1;
2535
2536   navigationController.Restore(currentEntry, RestoreType::kRestored,
2537                                &scopedEntries);
2538   return true;
2539 }
2540
2541 void EWebView::SetBrowserFont() {
2542 #if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
2543   RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
2544   if (render_view_host) {
2545     IPC::Message* message =
2546         new EwkViewMsg_SetBrowserFont(render_view_host->GetRoutingID());
2547
2548     if (render_view_host->IsRenderViewLive())
2549       render_view_host->Send(message);
2550     else
2551       delayed_messages_.push_back(message);
2552   }
2553 #endif
2554 }
2555
2556 bool EWebView::IsDragging() const {
2557   return wcva()->wcva_helper()->IsDragging();
2558 }
2559
2560 void EWebView::ShowFileChooser(
2561     scoped_refptr<content::FileSelectListener> listener,
2562     const blink::mojom::FileChooserParams& params) {
2563 #if BUILDFLAG(IS_TIZEN_TV)
2564   LOG(INFO) << "File chooser request callback.";
2565   file_chooser_request_.reset(new _Ewk_File_Chooser_Request(
2566       std::move(listener), params.accept_types, params.mode));
2567   SmartCallback<EWebViewCallbacks::FileChooserRequest>().call(
2568       file_chooser_request_.get());
2569 #else
2570   if (!IsMobileProfile() && !IsWearableProfile())
2571     return;
2572   file_chooser_.reset(
2573       new content::FileChooserControllerEfl(std::move(listener), params));
2574   file_chooser_->Open();
2575 #endif
2576 }
2577
2578 #if !defined(EWK_BRINGUP)  // FIXME: m67 bringup
2579 void EWebView::SetViewMode(blink::WebViewMode view_mode) {
2580   RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
2581   if (!render_view_host)
2582     return;
2583
2584   IPC::Message* message =
2585       new ViewMsg_SetViewMode(render_view_host->GetRoutingID(), view_mode);
2586   if (render_view_host->IsRenderViewLive()) {
2587     render_view_host->Send(message);
2588   } else {
2589     delayed_messages_.push_back(message);
2590   }
2591 }
2592 #endif
2593
2594 gfx::Point EWebView::GetContextMenuPosition() const {
2595   return context_menu_position_;
2596 }
2597
2598 void EWebView::ShowContentsDetectedPopup(const char* message) {
2599   popup_controller_.reset(new PopupControllerEfl(this));
2600   popup_controller_->openPopup(message);
2601 }
2602
2603 void EWebView::RequestColorPicker(int r, int g, int b, int a) {
2604   input_picker_.reset(new InputPicker(this, web_contents_.get(), ewk_view()));
2605   input_picker_->ShowColorPicker(r, g, b, a);
2606 }
2607
2608 bool EWebView::SetColorPickerColor(int r, int g, int b, int a) {
2609 #if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
2610   web_contents_->DidChooseColorInColorChooser(SkColorSetARGB(a, r, g, b));
2611 #endif
2612   return true;
2613 }
2614
2615 void EWebView::InputPickerShow(ui::TextInputType input_type,
2616                                double input_value,
2617                                content::DateTimeChooserEfl* date_time_chooser) {
2618   input_picker_.reset(new InputPicker(this, web_contents_.get(), ewk_view(),
2619                                       date_time_chooser));
2620   input_picker_->ShowDatePicker(input_type, input_value);
2621 }
2622
2623 void EWebView::LoadNotFoundErrorPage(const std::string& invalidUrl) {
2624 #if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
2625   RenderFrameHost* render_frame_host = web_contents_->GetPrimaryMainFrame();
2626   if (render_frame_host)
2627     render_frame_host->Send(new EwkFrameMsg_LoadNotFoundErrorPage(
2628         render_frame_host->GetRoutingID(), invalidUrl));
2629 #endif
2630 }
2631
2632 std::string EWebView::GetPlatformLocale() {
2633   char* local_default = setlocale(LC_CTYPE, 0);
2634   if (!local_default)
2635     return std::string("en-US");
2636   std::string locale = std::string(local_default);
2637   size_t position = locale.find('_');
2638   if (position != std::string::npos)
2639     locale.replace(position, 1, "-");
2640   position = locale.find('.');
2641   if (position != std::string::npos)
2642     locale = locale.substr(0, position);
2643   return locale;
2644 }
2645
2646 int EWebView::StartInspectorServer(int port) {
2647 #if BUILDFLAG(IS_TIZEN_TV)
2648   if (IsTIZENWRT()) {
2649     use_early_rwi_ = false;
2650     rwi_info_showed_ = false;
2651   }
2652   if (!context_->GetImpl()->GetInspectorServerState()) {
2653     int validPort = 0;
2654     if (!devtools_http_handler::DevToolsPortManager::GetInstance()
2655              ->GetValidPort(validPort))
2656       return 0;
2657
2658     port = validPort;
2659   }
2660 #endif
2661   return context_->InspectorServerStart(port);
2662 }
2663
2664 bool EWebView::StopInspectorServer() {
2665 #if BUILDFLAG(IS_TIZEN_TV)
2666   if (IsTIZENWRT()) {
2667     use_early_rwi_ = false;
2668     rwi_info_showed_ = false;
2669   }
2670 #endif
2671   return context_->InspectorServerStop();
2672 }
2673
2674 void EWebView::InvokeWebProcessCrashedCallback() {
2675   DCHECK_CURRENTLY_ON(BrowserThread::UI);
2676   const GURL last_url = GetURL();
2677   bool callback_handled = false;
2678   SmartCallback<EWebViewCallbacks::WebProcessCrashed>().call(&callback_handled);
2679   if (!callback_handled)
2680     LoadHTMLString(kRendererCrashedHTMLMessage, NULL,
2681                    last_url.possibly_invalid_spec().c_str());
2682 }
2683
2684 void EWebView::SyncAcceptLanguages(const std::string& accept_languages) {
2685   web_contents_->GetMutableRendererPrefs()->accept_languages = accept_languages;
2686   web_contents_->SyncRendererPrefs();
2687   BrowserContext* browser_context = web_contents_->GetBrowserContext();
2688   if (!browser_context)
2689     return;
2690
2691   auto* storage_partition = browser_context->GetDefaultStoragePartition();
2692   if (!storage_partition)
2693     return;
2694
2695   if (auto* network_context = storage_partition->GetNetworkContext())
2696     network_context->SetAcceptLanguage(accept_languages);
2697 }
2698
2699 #if BUILDFLAG(IS_TIZEN_TV)
2700 bool EWebView::EdgeScrollBy(int delta_x, int delta_y) {
2701   if ((delta_x == 0 && delta_y == 0) || is_processing_edge_scroll_)
2702     return false;
2703
2704   RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
2705   if (!render_view_host)
2706     return false;
2707
2708   if (!rwhva())
2709     return false;
2710
2711   gfx::Point offset = gfx::Point(delta_x, delta_y);
2712   gfx::Point mouse_position;
2713   GetMousePosition(mouse_position);
2714   is_processing_edge_scroll_ = true;
2715
2716   static_cast<RenderViewHostImpl*>(render_view_host)
2717       ->GetWidget()
2718       ->GetAssociatedFrameWidget()
2719       ->EdgeScrollBy(offset, mouse_position);
2720   return true;
2721 }
2722
2723 void EWebView::GetMousePosition(gfx::Point& mouse_position) {
2724   int mouse_x, mouse_y;
2725   evas_pointer_output_xy_get(GetEvas(), &mouse_x, &mouse_y);
2726   Evas_Coord x, y, width, height;
2727   evas_object_geometry_get(ewk_view(), &x, &y, &width, &height);
2728
2729   if (mouse_y < y)
2730     mouse_y = y + 1;
2731   else if (mouse_y > y + height)
2732     mouse_y = y + height - 1;
2733   if (mouse_x < x)
2734     mouse_x = x + 1;
2735   else if (mouse_x > x + width)
2736     mouse_x = x + width - 1;
2737
2738   mouse_x -= x;
2739   mouse_y -= y;
2740
2741   mouse_x /=
2742       display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
2743   mouse_y /=
2744       display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
2745
2746   mouse_position.set_x(mouse_x);
2747   mouse_position.set_y(mouse_y);
2748 }
2749
2750 void EWebView::InvokeEdgeScrollByCallback(const gfx::Point& offset,
2751                                           bool handled) {
2752   is_processing_edge_scroll_ = false;
2753
2754   if (offset.x() < 0)
2755     SmartCallback<EWebViewCallbacks::EdgeScrollLeft>().call(&handled);
2756   else if (offset.x() > 0)
2757     SmartCallback<EWebViewCallbacks::EdgeScrollRight>().call(&handled);
2758
2759   if (offset.y() < 0)
2760     SmartCallback<EWebViewCallbacks::EdgeScrollTop>().call(&handled);
2761   else if (offset.y() > 0)
2762     SmartCallback<EWebViewCallbacks::EdgeScrollBottom>().call(&handled);
2763 }
2764 #endif
2765
2766 void EWebView::HandleRendererProcessCrash() {
2767   content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
2768       base::BindOnce(&EWebView::InvokeWebProcessCrashedCallback,
2769                      base::Unretained(this)));
2770 }
2771
2772 void EWebView::InitializeContent() {
2773   LOG(INFO) << "eweb_view.cc  InitializeContent" ;
2774 #if BUILDFLAG(IS_TIZEN_TV)
2775   // When initialize content init inspector server
2776   InitInspectorServer();
2777 #endif
2778   WebContents* new_contents = create_new_window_web_contents_cb_.Run(this);
2779   if (!new_contents) {
2780     WebContents::CreateParams params(context_->browser_context());
2781     web_contents_.reset(
2782         new WebContentsImplEfl(context_->browser_context(), this));
2783     static_cast<WebContentsImpl*>(web_contents_.get())
2784         ->Init(params, blink::FramePolicy());
2785   } else {
2786     web_contents_.reset(new_contents);
2787
2788     // When a new webview is created in response to a request from the
2789     // engine, the BrowserContext instance of the originator WebContents
2790     // is used by the newly created WebContents object.
2791     // See more in WebContentsImplEfl::HandleNewWebContentsCreate.
2792     //
2793     // Hence, if as part of the WebView creation, the embedding APP
2794     // passes in a Ewk_Context instance that wraps a different instance of
2795     // BrowserContext than the one the originator WebContents holds,
2796     // undefined behavior can be seen.
2797     //
2798     // This is a snippet code that illustrate the scenario:
2799     //
2800     // (..)
2801     // evas_object_smart_callback_add(web_view_, "create,window",
2802     //                                &OnNewWindowRequest, this);
2803     // (..)
2804     //
2805     // void OnNewWindowRequest(void *data, Evas_Object*, void* out_view) {
2806     //   (..)
2807     //   EvasObject* new_web_view = ewk_view_add_with_context(GetEvas(),
2808     //   ewk_context_new());
2809     //   *static_cast<Evas_Object**>(out_view) = new_web_view;
2810     //   (..)
2811     // }
2812     //
2813     // The new Ewk_Context object created and passed in as parameter to
2814     // ewk_view_add_with_context wraps a different instance of BrowserContext
2815     // than the one the new WebContents object will hold.
2816     //
2817     // CHECK below aims at catching misuse of this API.
2818     bool should_crash = context_->GetImpl()->browser_context() !=
2819                         web_contents_->GetBrowserContext();
2820     if (should_crash) {
2821       CHECK(false)
2822           << "BrowserContext of new WebContents does not match EWebView's. "
2823           << "Please see 'ewk_view_add*' documentation. "
2824           << "Aborting execution ...";
2825     }
2826   }
2827
2828   web_contents_delegate_.reset(new WebContentsDelegateEfl(this));
2829   web_contents_->SetDelegate(web_contents_delegate_.get());
2830
2831   // EWebView's delegate. Calls to WebContentsImplEfl and
2832   // WebContentsViewAuraHelperEfl are delegated to this class.
2833   // For more details, refer commit message of patch 301647.
2834   webview_delegate_.reset(new WebViewDelegateEfl(this));
2835   WebContentsImplEfl* wc_efl =
2836       static_cast<WebContentsImplEfl*>(web_contents_.get());
2837   wc_efl->SetWebviewDelegate(webview_delegate_.get());
2838   wcva()->wcva_helper()->SetWebviewDelegate(webview_delegate_.get());
2839
2840   back_forward_list_.reset(new _Ewk_Back_Forward_List(web_contents_.get()));
2841
2842   permission_popup_manager_.reset(new PermissionPopupManager(ewk_view_));
2843   gin_native_bridge_dispatcher_host_.reset(
2844       new content::GinNativeBridgeDispatcherHost(web_contents_.get()));
2845
2846   efl_main_layout_ =
2847       static_cast<WebContentsImplEfl*>(web_contents_.get())->GetEflMainLayout();
2848   evas_object_smart_member_add(efl_main_layout_, ewk_view_);
2849   static_cast<WebContentsImpl*>(web_contents_.get())->set_ewk_view(ewk_view_);
2850   InitializeWindowTreeHost();
2851 }
2852
2853 #if BUILDFLAG(IS_TIZEN_TV)
2854 void EWebView::OnDialogClosed() {
2855   if (!use_early_rwi_)
2856     return;
2857
2858   use_early_rwi_ = false;
2859   LOG(INFO) << "[FAST RWI] SetURL Restore [" << rwi_gurl_.spec()
2860             << "] from [about:blank]";
2861   SetURL(rwi_gurl_);
2862   rwi_gurl_ = GURL();
2863   rwi_info_showed_ = true;
2864 }
2865
2866 void EWebView::InitInspectorServer() {
2867   if (devtools_http_handler::DevToolsPortManager::GetInstance()
2868           ->ProcessCompare()) {
2869     int res = StartInspectorServer(0);
2870     if (res) {
2871       LOG(INFO) << "InitInspectorServer SetPort";
2872       devtools_http_handler::DevToolsPortManager::GetInstance()->SetPort(res);
2873     }
2874   }
2875 }
2876 #endif
2877
2878 #if defined(TIZEN_TBM_SUPPORT)
2879 void EWebView::SetOffscreenRendering(bool enable) {
2880   if (host_)
2881     host_->compositor()->SetUseTbmSuraceForOffscreenRendering(enable);
2882 }
2883 #endif
2884
2885 void EWebView::InitializeWindowTreeHost() {
2886   CHECK(aura::Env::GetInstance());
2887
2888   int x, y, width, height;
2889   Ecore_Evas* ee =
2890       ecore_evas_ecore_evas_get(evas_object_evas_get(efl_main_layout_));
2891   ecore_evas_geometry_get(ee, &x, &y, &width, &height);
2892
2893   gfx::Rect bounds(x, y, width, height);
2894   ui::PlatformWindowInitProperties properties;
2895   properties.bounds = bounds;
2896
2897   host_ = aura::WindowTreeHost::Create(std::move(properties));
2898   host_->InitHost();
2899   host_->window()->Show();
2900
2901   focus_client_ =
2902       std::make_unique<aura::test::TestFocusClient>(host_->window());
2903   window_parenting_client_ =
2904       std::make_unique<aura::test::TestWindowParentingClient>(host_->window());
2905   compositor_observer_ = std::make_unique<ui::CompositorObserverEfl>(
2906       host_->compositor(), web_contents_.get());
2907
2908   aura::Window* content = web_contents_->GetNativeView();
2909   aura::Window* parent = host_->window();
2910   if (!parent->Contains(content)) {
2911     parent->AddChild(content);
2912     content->Show();
2913   }
2914   content->SetBounds(bounds);
2915   RenderWidgetHostView* host_view = web_contents_->GetRenderWidgetHostView();
2916   if (host_view)
2917     host_view->SetSize(bounds.size());
2918 }
2919
2920 void EWebView::UrlRequestSet(
2921     const char* url,
2922     content::NavigationController::LoadURLType loadtype,
2923     Eina_Hash* headers,
2924     const char* body) {
2925   GURL gurl(url);
2926   content::NavigationController::LoadURLParams params(gurl);
2927   params.load_type = loadtype;
2928   params.override_user_agent = NavigationController::UA_OVERRIDE_TRUE;
2929
2930   if (body) {
2931     std::string s(body);
2932     params.post_data =
2933         network::ResourceRequestBody::CreateFromBytes(s.data(), s.size());
2934   }
2935
2936   net::HttpRequestHeaders header;
2937   if (headers) {
2938     Eina_Iterator* it = eina_hash_iterator_tuple_new(headers);
2939     Eina_Hash_Tuple* t;
2940     while (eina_iterator_next(it, reinterpret_cast<void**>(&t))) {
2941       if (t->key) {
2942         const char* value_str =
2943             t->data ? static_cast<const char*>(t->data) : "";
2944         base::StringPiece name = static_cast<const char*>(t->key);
2945         base::StringPiece value = value_str;
2946         header.SetHeader(name, value);
2947         // net::HttpRequestHeaders.ToString() returns string with newline
2948         params.extra_headers += header.ToString();
2949       }
2950     }
2951     eina_iterator_free(it);
2952   }
2953
2954   web_contents_->GetController().LoadURLWithParams(params);
2955 }
2956
2957 #if defined(TIZEN_VIDEO_HOLE)
2958 void EWebView::EnableVideoHoleSupport() {
2959   if (!web_contents_->GetPrimaryMainFrame() ||
2960       !web_contents_->GetPrimaryMainFrame()->IsRenderFrameLive() || !rwhva()) {
2961     pending_video_hole_setting_ = true;
2962     return;
2963   }
2964
2965   EnableVideoHoleSupportInternal();
2966 }
2967
2968 void EWebView::EnableVideoHoleSupportInternal() {
2969   if (settings_->getPreferences().video_hole_enabled)
2970     return;
2971
2972   settings_->getPreferences().video_hole_enabled = true;
2973   WebContentsImpl* wc = static_cast<WebContentsImpl*>(web_contents_.get());
2974   if (wc)
2975     wc->EnableVideoHole();
2976 }
2977 #endif
2978
2979 bool EWebView::HandleShow() {
2980   if (!efl_main_layout_)
2981     return false;
2982
2983   Show();
2984   return true;
2985 }
2986
2987 bool EWebView::HandleHide() {
2988   if (!efl_main_layout_)
2989     return false;
2990
2991   Hide();
2992   return true;
2993 }
2994
2995 bool EWebView::HandleMove(int x, int y) {
2996   if (!efl_main_layout_)
2997     return false;
2998   evas_object_move(efl_main_layout_, x, y);
2999   LOG(INFO) << "Move x " << x << " y " << y;
3000 #if defined(TIZEN_VIDEO_HOLE)
3001   if (rwhva())
3002     rwhva()->DidMoveWebView();
3003 #endif
3004
3005   if (context_menu_)
3006     context_menu_->Move(x, y);
3007
3008   return true;
3009 }
3010
3011 bool EWebView::HandleResize(int width, int height) {
3012   if (!efl_main_layout_)
3013     return false;
3014   evas_object_resize(efl_main_layout_, width, height);
3015
3016 #if defined(TIZEN_VIDEO_HOLE)
3017   LOG(INFO) << __func__ << " new size " << width << "*" << height;
3018   if (rwhva())
3019     rwhva()->DidMoveWebView();
3020 #endif
3021
3022   if (select_picker_) {
3023     AdjustViewPortHeightToPopupMenu(true /* is_popup_menu_visible */);
3024     ScrollFocusedNodeIntoView();
3025   }
3026
3027 #if defined(USE_AURA) && BUILDFLAG(IS_TIZEN_TV)
3028   if (host_) {
3029     int x, y;
3030     evas_object_geometry_get(efl_main_layout_, &x, &y, nullptr, nullptr);
3031     gfx::Rect bounds(x, y, width, height);
3032     host_->SetBoundsInPixels(bounds);
3033   }
3034 #endif
3035
3036   return true;
3037 }
3038
3039 bool EWebView::HandleTextSelectionDown(int x, int y) {
3040   if (!GetSelectionController())
3041     return false;
3042   return GetSelectionController()->TextSelectionDown(x, y);
3043 }
3044
3045 bool EWebView::HandleTextSelectionUp(int x, int y) {
3046   if (!GetSelectionController())
3047     return false;
3048   return GetSelectionController()->TextSelectionUp(x, y);
3049 }
3050
3051 void EWebView::HandleTapGestureForSelection(bool is_content_editable) {
3052   if (!GetSelectionController())
3053     return;
3054
3055   GetSelectionController()->PostHandleTapGesture(is_content_editable);
3056 }
3057
3058 void EWebView::HandleZoomGesture(blink::WebGestureEvent& event) {
3059   blink::WebInputEvent::Type event_type = event.GetType();
3060   if (event_type == blink::WebInputEvent::Type::kGestureDoubleTap ||
3061       event_type == blink::WebInputEvent::Type::kGesturePinchBegin) {
3062     SmartCallback<EWebViewCallbacks::ZoomStarted>().call();
3063   }
3064   if (event_type == blink::WebInputEvent::Type::kGestureDoubleTap ||
3065       event_type == blink::WebInputEvent::Type::kGesturePinchEnd) {
3066     SmartCallback<EWebViewCallbacks::ZoomFinished>().call();
3067   }
3068 }
3069
3070 bool EWebView::GetHorizontalPanningHold() const {
3071   if (!rwhva())
3072     return false;
3073   return rwhva()->offscreen_helper()->GetHorizontalPanningHold();
3074 }
3075
3076 void EWebView::SetHorizontalPanningHold(bool hold) {
3077   if (rwhva())
3078     rwhva()->offscreen_helper()->SetHorizontalPanningHold(hold);
3079 }
3080
3081 bool EWebView::GetVerticalPanningHold() const {
3082   if (!rwhva())
3083     return false;
3084   return rwhva()->offscreen_helper()->GetVerticalPanningHold();
3085 }
3086
3087 void EWebView::SetVerticalPanningHold(bool hold) {
3088   if (rwhva())
3089     rwhva()->offscreen_helper()->SetVerticalPanningHold(hold);
3090 }
3091
3092 void EWebView::SendDelayedMessages(RenderViewHost* render_view_host) {
3093   DCHECK(render_view_host);
3094
3095   if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
3096     content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
3097         base::BindOnce(&EWebView::SendDelayedMessages, base::Unretained(this),
3098                        render_view_host));
3099     return;
3100   }
3101
3102 #if BUILDFLAG(IS_TIZEN_TV)
3103   if (pending_setfocus_closure_)
3104     std::move(pending_setfocus_closure_).Run();
3105 #endif
3106
3107   for (auto iter = delayed_messages_.begin(); iter != delayed_messages_.end();
3108        ++iter) {
3109     IPC::Message* message = *iter;
3110     message->set_routing_id(render_view_host->GetRoutingID());
3111 #if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
3112     render_view_host->Send(message);
3113 #endif
3114   }
3115
3116   delayed_messages_.clear();
3117 }
3118
3119 void EWebView::ClosePage() {
3120   web_contents_->ClosePage();
3121 }
3122
3123 bool EWebView::SetMainFrameScrollbarVisible(bool visible) {
3124   if (web_contents_->GetPrimaryMainFrame()->IsRenderFrameLive() && rwhva())
3125     rwhva()->host()->SetMainFrameScrollbarVisible(visible);
3126   return true;
3127 }
3128
3129 bool EWebView::GetMainFrameScrollbarVisible(
3130     Ewk_View_Main_Frame_Scrollbar_Visible_Get_Callback callback,
3131     void* user_data) {
3132   if (!rwhva())
3133     return false;
3134
3135   MainFrameScrollbarVisibleGetCallback* callback_ptr =
3136       new MainFrameScrollbarVisibleGetCallback;
3137   callback_ptr->Set(callback, user_data);
3138   int callback_id =
3139       main_frame_scrollbar_visible_callback_map_.Add(callback_ptr);
3140   rwhva()->host()->RequestMainFrameScrollbarVisible(callback_id);
3141   return true;
3142 }
3143
3144 void EWebView::InvokeMainFrameScrollbarVisibleCallback(int callback_id,
3145                                                        bool visible) {
3146   if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
3147     content::GetUIThreadTaskRunner({})->PostTask(
3148         FROM_HERE,
3149         base::BindOnce(&EWebView::InvokeMainFrameScrollbarVisibleCallback,
3150                        base::Unretained(this), visible, callback_id));
3151     return;
3152   }
3153
3154   MainFrameScrollbarVisibleGetCallback* callback =
3155       main_frame_scrollbar_visible_callback_map_.Lookup(callback_id);
3156   if (!callback)
3157     return;
3158
3159   main_frame_scrollbar_visible_callback_map_.Remove(callback_id);
3160   callback->Run(ewk_view(), visible);
3161   main_frame_scrollbar_visible_callback_map_.Remove(callback_id);
3162 }
3163
3164 void EWebView::OnOverscrolled(const gfx::Vector2dF& accumulated_overscroll,
3165                               const gfx::Vector2dF& latest_overscroll_delta) {
3166   const gfx::Vector2dF old_overscroll =
3167       accumulated_overscroll - latest_overscroll_delta;
3168
3169   if (latest_overscroll_delta.x() && !old_overscroll.x()) {
3170     latest_overscroll_delta.x() < 0
3171         ? SmartCallback<EWebViewCallbacks::OverscrolledLeft>().call()
3172         : SmartCallback<EWebViewCallbacks::OverscrolledRight>().call();
3173   }
3174   if (latest_overscroll_delta.y() && !old_overscroll.y()) {
3175     latest_overscroll_delta.y() < 0
3176         ? SmartCallback<EWebViewCallbacks::OverscrolledTop>().call()
3177         : SmartCallback<EWebViewCallbacks::OverscrolledBottom>().call();
3178   }
3179 }
3180
3181 void EWebView::SetDidChangeThemeColorCallback(
3182     Ewk_View_Did_Change_Theme_Color_Callback callback,
3183     void* user_data) {
3184   did_change_theme_color_callback_.Set(callback, user_data);
3185 }
3186
3187 void EWebView::DidChangeThemeColor(const SkColor& color) {
3188   did_change_theme_color_callback_.Run(ewk_view_, color);
3189 }
3190
3191 #if BUILDFLAG(IS_TIZEN_TV)
3192 void EWebView::DrawLabel(Evas_Object* image, Eina_Rectangle rect) {
3193   if (rwhva())
3194     rwhva()->offscreen_helper()->DrawLabel(image, rect);
3195 }
3196
3197 void EWebView::DeactivateAtk(bool deactivated) {
3198 #if defined(TIZEN_ATK_SUPPORT)
3199   EWebAccessibilityUtil::GetInstance()->Deactivate(deactivated);
3200 #endif
3201 }
3202
3203 void EWebView::ClearLabels() {
3204   if (rwhva())
3205     rwhva()->offscreen_helper()->ClearLabels();
3206 }
3207
3208 void EWebView::SetTranslatedURL(const char* url) {
3209   if (!rwhva() || !rwhva()->aura_efl_helper())
3210     return;
3211   rwhva()->aura_efl_helper()->SetTranslatedURL(std::string(url));
3212   LOG(INFO) << "translate_url:" << url;
3213 }
3214
3215 bool EWebView::IsVideoPlaying(Ewk_Is_Video_Playing_Callback callback,
3216                               void* user_data) {
3217   IsVideoPlayingCallback* cb = new IsVideoPlayingCallback(callback, user_data);
3218   int callback_id = is_video_playing_callback_map_.Add(cb);
3219
3220   if (!rwhva() || !rwhva()->aura_efl_helper()) {
3221     LOG(ERROR) << "rwhva() or rwhva()->aura_efl_helper() is false";
3222     return false;
3223   }
3224   rwhva()->aura_efl_helper()->RequestVideoPlaying(callback_id);
3225   return true;
3226 }
3227
3228 void EWebView::InvokeIsVideoPlayingCallback(bool is_playing, int callback_id) {
3229   IsVideoPlayingCallback* callback =
3230       is_video_playing_callback_map_.Lookup(callback_id);
3231   if (!callback) {
3232     LOG(INFO) << "callback is null";
3233     return;
3234   }
3235
3236   LOG(INFO) << __func__ << " ; is_playing : " << is_playing;
3237   callback->Run(ewk_view(), is_playing);
3238   is_video_playing_callback_map_.Remove(callback_id);
3239 }
3240 #endif
3241
3242 void EWebView::RequestManifest(Ewk_View_Request_Manifest_Callback callback,
3243                                void* user_data) {
3244   web_contents_delegate_->RequestManifestInfo(callback, user_data);
3245 }
3246
3247 void EWebView::DidRespondRequestManifest(
3248     _Ewk_View_Request_Manifest* manifest,
3249     Ewk_View_Request_Manifest_Callback callback,
3250     void* user_data) {
3251   callback(ewk_view_, manifest, user_data);
3252 }
3253
3254 void EWebView::SetSessionTimeout(uint64_t timeout) {
3255   if (web_contents_->GetPrimaryMainFrame()->IsRenderFrameLive() && rwhva())
3256     rwhva()->host()->SetLongPollingGlobalTimeout(timeout);
3257 }
3258
3259 void EWebView::SetBeforeUnloadConfirmPanelCallback(
3260     Ewk_View_Before_Unload_Confirm_Panel_Callback callback,
3261     void* user_data) {
3262   GetJavaScriptDialogManagerEfl()->SetBeforeUnloadConfirmPanelCallback(
3263       callback, user_data);
3264 }
3265
3266 void EWebView::ReplyBeforeUnloadConfirmPanel(Eina_Bool result) {
3267   GetJavaScriptDialogManagerEfl()->ReplyBeforeUnloadConfirmPanel(result);
3268 }
3269
3270 #if defined(TIZEN_PEPPER_EXTENSIONS)
3271 void EWebView::InitializePepperExtensionSystem() {
3272   RegisterPepperExtensionDelegate();
3273   SetWindowId();
3274 }
3275
3276 EwkExtensionSystemDelegate* EWebView::GetExtensionDelegate() {
3277   RenderFrameHost* render_frame_host = web_contents_->GetPrimaryMainFrame();
3278   if (!render_frame_host)
3279     return nullptr;
3280
3281   return static_cast<EwkExtensionSystemDelegate*>(
3282       ExtensionSystemDelegateManager::GetInstance()->GetDelegateForFrame(render_frame_id_));
3283 }
3284
3285 void EWebView::SetWindowId() {
3286   EwkExtensionSystemDelegate* delegate = GetExtensionDelegate();
3287   if (!delegate) {
3288     LOG(WARNING) << "No delegate is available to set window id";
3289     return;
3290   }
3291   Evas_Object* main_wind =
3292       efl::WindowFactory::GetHostWindow(web_contents_.get());
3293   if (!main_wind) {
3294     LOG(ERROR) << "Can`t get main window";
3295     return;
3296   }
3297   delegate->SetWindowId(main_wind);
3298 }
3299
3300 void EWebView::SetPepperExtensionWidgetInfo(Ewk_Value widget_pepper_ext_info) {
3301   EwkExtensionSystemDelegate* delegate = GetExtensionDelegate();
3302   if (!delegate) {
3303     LOG(WARNING) << "No delegate is available to set extension info";
3304     return;
3305   }
3306   delegate->SetExtensionInfo(widget_pepper_ext_info);
3307 }
3308
3309 void EWebView::SetPepperExtensionCallback(Generic_Sync_Call_Callback cb,
3310                                           void* data) {
3311   EwkExtensionSystemDelegate* delegate = GetExtensionDelegate();
3312   if (!delegate) {
3313     LOG(WARNING) << "No delegate is available to set generic callback";
3314     return;
3315   }
3316   delegate->SetGenericSyncCallback(cb, data);
3317 }
3318
3319 void EWebView::RegisterPepperExtensionDelegate() {
3320   RenderFrameHost* render_frame_host = web_contents_->GetPrimaryMainFrame();
3321   if (!render_frame_host) {
3322     LOG(WARNING) << "render_frame_host is nullptr, can't register delegate";
3323     return;
3324   }
3325
3326   render_frame_id_.render_process_id = render_frame_host->GetProcess()->GetID();
3327   render_frame_id_.render_frame_id = render_frame_host->GetRoutingID();
3328
3329   EwkExtensionSystemDelegate* delegate = new EwkExtensionSystemDelegate;
3330   ExtensionSystemDelegateManager::GetInstance()->RegisterDelegate(
3331       render_frame_id_, std::unique_ptr<EwkExtensionSystemDelegate>{delegate});
3332 }
3333
3334 void EWebView::UnregisterPepperExtensionDelegate() {
3335   if (!web_contents_) {
3336     LOG(WARNING) << "web_contents_ is nullptr, can't unregister delegate";
3337     return;
3338   }
3339   if (!ExtensionSystemDelegateManager::GetInstance()->UnregisterDelegate(render_frame_id_))
3340     LOG(WARNING) << "Unregistering pepper extension delegate failed";
3341 }
3342 #endif  // defined(TIZEN_PEPPER_EXTENSIONS)
3343
3344 void EWebView::SetExceededIndexedDatabaseQuotaCallback(
3345     Ewk_View_Exceeded_Indexed_Database_Quota_Callback callback,
3346     void* user_data) {
3347   exceeded_indexed_db_quota_callback_.Set(callback, user_data);
3348   content::BrowserContextEfl* browser_context =
3349       static_cast<content::BrowserContextEfl*>(
3350           web_contents_->GetBrowserContext());
3351   if (browser_context) {
3352     browser_context->GetSpecialStoragePolicyEfl()->SetQuotaExceededCallback(
3353         base::BindOnce(&EWebView::InvokeExceededIndexedDatabaseQuotaCallback,
3354                        base::Unretained(this)));
3355   }
3356 }
3357
3358 void EWebView::InvokeExceededIndexedDatabaseQuotaCallback(
3359     const GURL& origin,
3360     int64_t current_quota) {
3361   if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
3362     content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
3363         base::BindOnce(&EWebView::InvokeExceededIndexedDatabaseQuotaCallback,
3364                        base::Unretained(this), origin, current_quota));
3365     return;
3366   }
3367   LOG(INFO) << __func__ << "()" << origin << ", " << current_quota;
3368   CHECK(!exceeded_indexed_db_quota_origin_.get());
3369   exceeded_indexed_db_quota_origin_.reset(new Ewk_Security_Origin(origin));
3370   exceeded_indexed_db_quota_callback_.Run(
3371       ewk_view_, exceeded_indexed_db_quota_origin_.get(), current_quota);
3372 }
3373
3374 void EWebView::ExceededIndexedDatabaseQuotaReply(bool allow) {
3375   if (!exceeded_indexed_db_quota_origin_.get()) {
3376     LOG(WARNING) << __func__ << "() : callback is not invoked!";
3377     return;
3378   }
3379   LOG(INFO) << __func__ << "()" << exceeded_indexed_db_quota_origin_->GetURL()
3380             << ", " << allow;
3381   content::BrowserContextEfl* browser_context =
3382       static_cast<content::BrowserContextEfl*>(
3383           web_contents_->GetBrowserContext());
3384   if (browser_context) {
3385     browser_context->GetSpecialStoragePolicyEfl()->SetUnlimitedStoragePolicy(
3386         exceeded_indexed_db_quota_origin_->GetURL(), allow);
3387   }
3388   exceeded_indexed_db_quota_origin_.reset();
3389 }
3390
3391 bool EWebView::ShouldIgnoreNavigation(
3392     content::NavigationHandle* navigation_handle) {
3393   if (!navigation_handle->GetURL().is_valid() ||
3394       !navigation_handle->GetURL().SchemeIs("appcontrol") ||
3395       (!navigation_handle->HasUserGesture() &&
3396        !navigation_handle->WasServerRedirect())) {
3397     return false;
3398   }
3399
3400   _Ewk_App_Control app_control(
3401       this, navigation_handle->GetURL().possibly_invalid_spec());
3402   return app_control.Proceed();
3403 }
3404
3405 #if BUILDFLAG(IS_TIZEN_TV)
3406 void EWebView::AddDynamicCertificatePath(const std::string& host,
3407                                          const std::string& cert_path) {
3408   web_contents_->AddDynamicCertificatePath(host, cert_path);
3409 }
3410
3411 void EWebView::NotifySubtitleState(int state, double time_stamp) {
3412   LOG(INFO) << "subtitle state: " << state
3413             << ",(0-Play : 1-Pause : 2-SeekStart : 3-SeekComplete : 4-Stop "
3414                ":5-Resume)";
3415   switch (state) {
3416     case blink::WebMediaPlayer::kSubtitlePause:
3417       SmartCallback<EWebViewCallbacks::SubtitlePause>().call();
3418       break;
3419     case blink::WebMediaPlayer::kSubtitleStop:
3420       SmartCallback<EWebViewCallbacks::SubtitleStop>().call();
3421       break;
3422     case blink::WebMediaPlayer::kSubtitleResume:
3423       SmartCallback<EWebViewCallbacks::SubtitleResume>().call();
3424       break;
3425     case blink::WebMediaPlayer::kSubtitleSeekStart: {
3426       double ts = time_stamp;
3427       SmartCallback<EWebViewCallbacks::SubtitleSeekStart>().call(&ts);
3428     } break;
3429     case blink::WebMediaPlayer::kSubtitleSeekComplete:
3430       SmartCallback<EWebViewCallbacks::SubtitleSeekComplete>().call();
3431       break;
3432     default:
3433       NOTREACHED();
3434       break;
3435   }
3436 }
3437
3438 void EWebView::NotifySubtitlePlay(int active_track_id,
3439                                   const char* url,
3440                                   const char* lang) {
3441   LOG(INFO) << "id:" << active_track_id << ",url:" << url << ",lang:" << lang;
3442   Ewk_Media_Subtitle_Info* subtitle_info =
3443       ewkMediaSubtitleInfoCreate(active_track_id, url, lang, 0);
3444   SmartCallback<EWebViewCallbacks::SubtitlePlay>().call(
3445       static_cast<void*>(subtitle_info));
3446   ewkMediaSubtitleInfoDelete(subtitle_info);
3447 }
3448
3449 void EWebView::NotifySubtitleData(int track_id,
3450                                   double time_stamp,
3451                                   const std::string& data,
3452                                   unsigned int size) {
3453   const void* buffer = static_cast<const void*>(data.c_str());
3454   Ewk_Media_Subtitle_Data* subtitle_data =
3455       ewkMediaSubtitleDataCreate(track_id, time_stamp, buffer, size);
3456   SmartCallback<EWebViewCallbacks::SubtitleNotifyData>().call(
3457       static_cast<void*>(subtitle_data));
3458   ewkMediaSubtitleDataDelete(subtitle_data);
3459 }
3460
3461 void EWebView::UpdateCurrentTime(double current_time) {
3462   current_time_ = current_time;
3463 }
3464
3465 void EWebView::UpdateEventData(void* data) {
3466   LOG(INFO) << "EWebView::UpdateEventData data:" << (char*)data;
3467   SmartCallback<EWebViewCallbacks::EVENTData>().call(data);
3468 }
3469
3470 void EWebView::NotifyParentalRatingInfo(const char* info, const char* url) {
3471   LOG(INFO) << "info:" << info << ",url:" << url;
3472   Ewk_Media_Parental_Rating_Info* data =
3473       ewkMediaParentalRatingInfoCreate(info, url);
3474   SmartCallback<EWebViewCallbacks::ParentalRatingInfo>().call(
3475       static_cast<void*>(data));
3476   ewkMediaParentalRatingInfoDelete(data);
3477 }
3478
3479 void EWebView::SetParentalRatingResult(const char* url, bool is_pass) {
3480   LOG(INFO) << "SetParentalRatingResult,url:" << url
3481             << ",pass:" << std::boolalpha << is_pass;
3482
3483   if (!rwhva() || !rwhva()->aura_efl_helper()){
3484     LOG(ERROR) << "rwhva() or rwhva()->aura_efl_helper() is false";
3485     return;
3486   }
3487   rwhva()->aura_efl_helper()->SetParentalRatingResult(
3488       static_cast<std::string>(url), is_pass);
3489 }
3490 void EWebView::NotifyFirstTimeStamp(unsigned long long timestamp,
3491                                     int time_base_num,
3492                                     int time_base_den) {
3493   Ewk_First_Timestamp_Info* info =
3494       ewkFirstTimeStampInfoCreate(timestamp, time_base_num, time_base_den);
3495   SmartCallback<EWebViewCallbacks::FirstTimestamp>().call(
3496       static_cast<void*>(info));
3497   ewkFirstTimeStampInfoDelete(info);
3498 }
3499
3500 void EWebView::NotifyPESData(const std::string& buf,
3501                              unsigned int len,
3502                              int media_position) {
3503   const void* data = static_cast<const void*>(buf.c_str());
3504   Ewk_PES_Info* info = ewkPESInfoCreate(data, len, media_position);
3505   SmartCallback<EWebViewCallbacks::PESData>().call(static_cast<void*>(info));
3506   ewkPESInfoDelete(info);
3507 }
3508
3509 void EWebView::SetPreferSubtitleLang(const char* lang_list) {
3510   LOG(INFO) << "SetPreferSubtitleLang: " << lang_list;
3511   const std::string lang(lang_list ? lang_list : "");
3512
3513   if (!rwhva()) {
3514     LOG(ERROR) << "rwhva() is null";
3515     return;
3516   }
3517
3518   rwhva()->aura_efl_helper()->SetPreferSubtitleLang(lang);
3519 }
3520 #endif
3521
3522 bool EWebView::SetVisibility(bool enable) {
3523   if (!web_contents_)
3524     return false;
3525
3526   if (enable)
3527     web_contents_->WasShown();
3528   else
3529     web_contents_->WasHidden();
3530
3531   return true;
3532 }
3533
3534 void EWebView::SetDoNotTrack(Eina_Bool enable) {
3535   // enable: 0 User tend to allow tracking on the target site.
3536   // enable: 1 User tend to not be tracked on the target site.
3537   if (web_contents_->GetMutableRendererPrefs()->enable_do_not_track == enable)
3538     return;
3539
3540   // Set navigator.doNotTrack attribute
3541   web_contents_->GetMutableRendererPrefs()->enable_do_not_track = enable;
3542   web_contents_->SyncRendererPrefs();
3543
3544   // Set or remove DNT HTTP header, the effects will depend on design of target
3545   // site.
3546   if (!context())
3547     return;
3548
3549   if (enable)
3550     context()->HTTPCustomHeaderAdd("DNT", "1");
3551   else
3552     context()->HTTPCustomHeaderRemove("DNT");
3553 }
3554
3555 #if defined(TIZEN_ATK_SUPPORT)
3556 void EWebView::UpdateSpatialNavigationStatus(Eina_Bool enable) {
3557   if (settings_->getPreferences().spatial_navigation_enabled == enable)
3558     return;
3559
3560   settings_->getPreferences().spatial_navigation_enabled = enable;
3561   WebContentsImpl* wc = static_cast<WebContentsImpl*>(web_contents_.get());
3562   if (wc)
3563     wc->SetSpatialNavigationEnabled(enable);
3564 }
3565
3566 void EWebView::UpdateAccessibilityStatus(Eina_Bool enable) {
3567   if (settings_->getPreferences().atk_enabled == enable)
3568     return;
3569
3570   settings_->getPreferences().atk_enabled = enable;
3571   WebContentsImpl* wc = static_cast<WebContentsImpl*>(web_contents_.get());
3572   if (wc)
3573     wc->SetAtkEnabled(enable);
3574 }
3575
3576 void EWebView::InitAtk() {
3577 #if defined(TIZEN_ATK_SUPPORT)
3578   EWebAccessibilityUtil::GetInstance()->ToggleAtk(lazy_initialize_atk_);
3579 #endif
3580 }
3581
3582 /* LCOV_EXCL_START */
3583 bool EWebView::GetAtkStatus() {
3584   auto state = content::BrowserAccessibilityStateImpl::GetInstance();
3585   if (!state)
3586     return false;
3587   return state->IsAccessibleBrowser();
3588 }
3589 /* LCOV_EXCL_STOP */
3590 #endif
3591
3592 #if BUILDFLAG(IS_TIZEN_TV)
3593 bool EWebView::SetMixedContents(bool allow) {
3594   MixedContentObserver* mixed_content_observer =
3595       MixedContentObserver::FromWebContents(web_contents_.get());
3596   return mixed_content_observer->MixedContentReply(allow);
3597 }
3598
3599 void EWebView::NotifyDownloadableFontInfo(const char* scheme_id_uri,
3600                                           const char* value,
3601                                           const char* data,
3602                                           int type) {
3603   LOG(INFO) << "scheme_id_uri:" << scheme_id_uri << ",value:" << value
3604             << ",data:" << data << ",type:" << type;
3605   Ewk_Media_Downloadable_Font_Info* info =
3606       ewkMediaDownloadableFontInfoCreate(scheme_id_uri, value, data, type);
3607   SmartCallback<EWebViewCallbacks::DownloadableFontInfo>().call(
3608       static_cast<void*>(info));
3609   ewkMediaDownloadableFontInfoDelete(info);
3610 }
3611
3612 std::vector<std::string> EWebView::NotifyPlaybackState(int state,
3613                                                        int player_id,
3614                                                        const char* url,
3615                                                        const char* mime_type) {
3616   std::vector<std::string> data;
3617   Ewk_Media_Playback_Info* playback_info =
3618       ewkMediaPlaybackInfoCreate(player_id, url, mime_type);
3619
3620   LOG(INFO)
3621       << "player_id:" << player_id << ",state: " << state
3622       << "(0-load : 1-videoready : 2-ready : 3-start : 4-finish : 5-stop)";
3623   switch (state) {
3624     case kPlaybackLoad:
3625       SmartCallback<EWebViewCallbacks::PlaybackLoad>().call(
3626           static_cast<void*>(playback_info));
3627       break;
3628     case kPlaybackReady:
3629       SmartCallback<EWebViewCallbacks::PlaybackReady>().call(
3630           static_cast<void*>(playback_info));
3631       break;
3632     case kPlaybackStart:
3633       SmartCallback<EWebViewCallbacks::PlaybackStart>().call(
3634           static_cast<void*>(playback_info));
3635       break;
3636     case kPlaybackFinish:
3637       SmartCallback<EWebViewCallbacks::PlaybackFinish>().call(
3638           static_cast<void*>(playback_info));
3639       break;
3640     case kPlaybackStop:
3641       SmartCallback<EWebViewCallbacks::PlaybackStop>().call(
3642           static_cast<void*>(playback_info));
3643       break;
3644     default:
3645       NOTREACHED();
3646       data.push_back("");
3647       ewkMediaPlaybackInfoDelete(playback_info);
3648       return data;
3649   }
3650
3651   bool media_resource_acquired =
3652       ewk_media_playback_info_media_resource_acquired_get(playback_info)
3653           ? true
3654           : false;
3655   data.push_back(media_resource_acquired ? "mediaResourceAcquired" : "");
3656   const char* translated_url =
3657       ewk_media_playback_info_translated_url_get(playback_info);
3658   data.push_back(translated_url ? std::string(translated_url) : "");
3659   const char* drm_info = ewk_media_playback_info_drm_info_get(playback_info);
3660   data.push_back(drm_info ? std::string(drm_info) : "");
3661
3662   LOG(INFO) << "evasObject: " << ewk_view_
3663             << ", media_resource_acquired :" << media_resource_acquired
3664             << ", translated_url:" << translated_url
3665             << ", drm_info:" << drm_info;
3666   ewkMediaPlaybackInfoDelete(playback_info);
3667   return data;
3668 }
3669
3670 void EWebView::NotifyMediaStateChanged(uint32_t device_type,
3671                                        uint32_t previous,
3672                                        uint32_t current) {
3673   LOG(INFO) << "NotifyMediaStateChanged type : " << device_type
3674             << " ;previous: " << previous << " ; current: " << current;
3675   Ewk_User_Media_State_Info* user_media_state_info =
3676       new _Ewk_User_Media_State_Info;
3677   user_media_state_info->device_type =
3678       static_cast<Ewk_User_Media_Device_Type>(device_type);
3679   user_media_state_info->previous_state = previous;
3680   user_media_state_info->current_state = current;
3681   SmartCallback<EWebViewCallbacks::UserMediaState>().call(
3682       static_cast<void*>(user_media_state_info));
3683
3684   delete user_media_state_info;
3685 }
3686
3687 void EWebView::SetHighBitRate(Eina_Bool high_bitrate) {
3688   LOG(INFO) << "high_bitrate: " << std::boolalpha << high_bitrate;
3689   is_high_bitrate_ = high_bitrate;
3690 }
3691
3692 void EWebView::OnDeviceListed(const MediaDeviceEnumeration& devices) {
3693   int device_count = 0;
3694   EwkMediaDeviceInfo* device_list = nullptr;
3695   for (const auto& device : devices)
3696     device_count += device.size();
3697
3698   device_list =
3699       (EwkMediaDeviceInfo*)malloc(sizeof(EwkMediaDeviceInfo) * device_count);
3700   if (!device_list) {
3701     LOG(ERROR) << "malloc EwkMediaDeviceInfo failed";
3702     device_cb_.Run(device_list, 0);
3703     return;
3704   }
3705
3706   int idx = 0;
3707   for (int i = 0; i < NUM_MEDIA_DEVICE_TYPES; i++) {
3708     blink::WebMediaDeviceInfoArray array = devices[i];
3709     for (const auto& device : array) {
3710       LOG(INFO) << "OnDeviceListed type:" << i
3711                 << ",device_id:" << device.device_id
3712                 << ",lable:" << device.label;
3713
3714       // convert device info to ewk structure
3715       EwkMediaDeviceInfo* data = &device_list[idx++];
3716       data->device_id = eina_stringshare_add(device.device_id.c_str());
3717       data->label = eina_stringshare_add(device.label.c_str());
3718       data->type = static_cast<EwkMediaDeviceType>(i);
3719       data->connected = true;
3720     }
3721   }
3722
3723   device_cb_.Run(device_list, device_count);
3724
3725   // free data
3726   for (int i = 0; i < device_count; i++) {
3727     EwkMediaDeviceInfo* device = &device_list[i];
3728     if (device->device_id)
3729       eina_stringshare_del(device->device_id);
3730     if (device->label)
3731       eina_stringshare_del(device->label);
3732   }
3733   if (device_list) {
3734     free(device_list);
3735     device_list = NULL;
3736   }
3737 }
3738
3739 void EWebView::GetMediaDeviceList(Ewk_Media_Device_List_Get_Callback callback,
3740                                   void* userData) {
3741   if (!web_contents_delegate_) {
3742     LOG(ERROR) << "no web_contents_delegate_";
3743     return;
3744   }
3745
3746   device_cb_.Set(callback, userData);
3747
3748   web_contents_delegate_->GetMediaDeviceList(
3749       base::BindOnce(&EWebView::OnDeviceListed, weak_factory_.GetWeakPtr()));
3750 }
3751 #endif