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