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.
7 #include <Ecore_Evas.h>
9 #include <Elementary.h>
11 #include "base/bind.h"
12 #include "base/command_line.h"
13 #include "base/files/file_path.h"
14 #include "base/files/file_util.h"
15 #include "base/json/json_string_value_serializer.h"
16 #include "base/logging.h"
17 #include "base/pickle.h"
18 #include "base/strings/escape.h"
19 #include "base/strings/utf_string_conversions.h"
20 #include "base/task/task_runner_util.h"
21 #include "browser/javascript_dialog_manager_efl.h"
22 #include "browser/javascript_interface/gin_native_bridge_dispatcher_host.h"
23 #include "browser/navigation_policy_handler_efl.h"
24 #include "browser/quota_permission_context_efl.h"
25 #include "browser/scoped_allow_wait_for_legacy_web_view_api.h"
26 #include "browser/select_picker/select_picker_mobile.h"
27 #include "browser/select_picker/select_picker_tv.h"
28 #include "browser/web_view_browser_message_filter.h"
29 #include "browser/web_view_evas_handler.h"
30 #include "browser_context_efl.h"
31 #include "common/content_client_efl.h"
32 #include "common/render_messages_ewk.h"
33 #include "common/version_info.h"
34 #include "common/web_contents_utils.h"
35 #include "components/sessions/content/content_serialized_navigation_builder.h"
36 #include "components/sessions/core/serialized_navigation_entry.h"
37 #include "content/browser/renderer_host/render_view_host_impl.h"
38 #include "content/browser/renderer_host/render_widget_host_view_aura.h"
39 #include "content/browser/renderer_host/ui_events_helper.h"
40 #include "content/browser/web_contents/web_contents_impl_efl.h"
41 #include "content/browser/web_contents/web_contents_view.h"
42 #include "content/browser/web_contents/web_contents_view_aura.h"
43 #include "content/browser/web_contents/web_contents_view_aura_helper_efl.h"
44 #include "content/common/content_client_export.h"
45 #include "content/public/browser/browser_message_filter.h"
46 #include "content/public/browser/browser_task_traits.h"
47 #include "content/public/browser/browser_thread.h"
48 #include "content/public/browser/host_zoom_map.h"
49 #include "content/public/browser/navigation_controller.h"
50 #include "content/public/browser/navigation_entry.h"
51 #include "content/public/browser/navigation_handle.h"
52 #include "content/public/common/content_client.h"
53 #include "content/public/common/content_switches.h"
54 #include "content/public/common/mhtml_generation_params.h"
55 #include "content/public/common/user_agent.h"
56 #include "net/base/filename_util.h"
57 #include "permission_popup_manager.cc"
58 #include "private/ewk_app_control_private.h"
59 #include "private/ewk_back_forward_list_private.h"
60 #include "private/ewk_context_private.h"
61 #include "private/ewk_frame_private.h"
62 #include "private/ewk_policy_decision_private.h"
63 #include "private/ewk_quota_permission_request_private.h"
64 #include "private/ewk_settings_private.h"
65 #include "private/webview_delegate_ewk.h"
66 #include "public/ewk_hit_test_internal.h"
67 #include "services/network/public/cpp/features.h"
68 #include "services/network/public/cpp/resource_request_body.h"
69 #include "services/network/public/mojom/network_context.mojom.h"
70 #include "skia/ext/platform_canvas.h"
71 #include "third_party/blink/public/common/page/page_zoom.h"
72 #include "third_party/blink/public/platform/web_string.h"
73 #include "tizen/system_info.h"
74 #include "ui/aura/env.h"
75 #include "ui/aura/test/test_focus_client.h"
76 #include "ui/aura/test/test_window_parenting_client.h"
77 #include "ui/aura/window.h"
78 #include "ui/base/clipboard/clipboard_helper_efl.h"
79 #include "ui/base/l10n/l10n_util.h"
80 #include "ui/display/screen.h"
81 #include "ui/events/event_switches.h"
82 #include "ui/gfx/geometry/dip_util.h"
83 #include "ui/gfx/geometry/vector2d_f.h"
84 #include "ui/ozone/platform/efl/efl_event_handler.h"
85 #include "ui/platform_window/platform_window_init_properties.h"
86 #include "web_contents_delegate_efl.h"
87 #include "web_contents_efl_delegate_ewk.h"
91 #if defined(TIZEN_ATK_SUPPORT)
92 #include "content/browser/accessibility/browser_accessibility_state_impl.h"
93 #include "eweb_accessibility.h"
94 #include "eweb_accessibility_util.h"
97 using namespace content;
98 using web_contents_utils::WebViewFromWebContents;
102 const int kTitleLengthMax = 80;
103 const base::FilePath::CharType kMHTMLFileNameExtension[] =
104 FILE_PATH_LITERAL(".mhtml");
105 const base::FilePath::CharType kMHTMLExtension[] = FILE_PATH_LITERAL("mhtml");
106 const base::FilePath::CharType kDefaultFileName[] =
107 FILE_PATH_LITERAL("saved_page");
108 const char kReplaceChars[] = " ";
109 const char kReplaceWith[] = "_";
111 static const char* kRendererCrashedHTMLMessage =
112 "<html><body><h1>Renderer process has crashed!</h1></body></html>";
114 // "visible,content,changed" is an email-app specific signal which informs
115 // that the web view is only partially visible.
116 static const char* kVisibleContentChangedSignalName = "visible,content,changed";
118 inline void SetDefaultStringIfNull(const char*& variable,
119 const char* default_string) {
121 variable = default_string;
125 void GetEinaRectFromGfxRect(const gfx::Rect& gfx_rect,
126 Eina_Rectangle* eina_rect) {
127 eina_rect->x = gfx_rect.x();
128 eina_rect->y = gfx_rect.y();
129 eina_rect->w = gfx_rect.width();
130 eina_rect->h = gfx_rect.height();
133 static content::WebContents* NullCreateWebContents(void*) {
137 base::FilePath GenerateMHTMLFilePath(const GURL& url,
138 const std::string& title,
139 const std::string& base_path) {
140 base::FilePath file_path(base_path);
142 if (base::DirectoryExists(file_path)) {
143 std::string title_part(title.substr(0, kTitleLengthMax));
144 base::ReplaceChars(title_part, kReplaceChars, kReplaceWith, &title_part);
145 base::FilePath file_name =
146 net::GenerateFileName(url, std::string(), std::string(), title_part,
147 std::string(), kDefaultFileName);
148 DCHECK(!file_name.empty());
149 file_path = file_path.Append(file_name);
152 if (file_path.Extension().empty())
153 file_path = file_path.AddExtension(kMHTMLExtension);
154 else if (!file_path.MatchesExtension(kMHTMLFileNameExtension))
155 file_path = file_path.ReplaceExtension(kMHTMLExtension);
157 if (!base::PathExists(file_path))
160 int uniquifier = base::GetUniquePathNumber(file_path);
161 if (uniquifier > 0) {
162 return file_path.InsertBeforeExtensionASCII(
163 base::StringPrintf(" (%d)", uniquifier));
166 return base::FilePath();
169 SelectPickerBase* CreateSelectPicker(
172 std::vector<blink::mojom::MenuItemPtr> items,
173 bool is_multiple_selection,
174 const gfx::Rect& bounds) {
175 SelectPickerBase* picker;
178 new SelectPickerTv(web_view, selected_index, is_multiple_selection);
181 new SelectPickerMobile(web_view, selected_index, is_multiple_selection);
183 // Create two separate Elm_Genlist_Item_Class classes, because EFL cannot swap
184 // item_style at runtime.
185 picker->InitializeItemClass();
186 picker->InitializeGroupClass();
187 picker->Init(std::move(items), bounds);
193 class WebViewAsyncRequestHitTestDataCallback {
195 WebViewAsyncRequestHitTestDataCallback(int x, int y, Ewk_Hit_Test_Mode mode)
196 : x_(x), y_(y), mode_(mode) {}
197 virtual ~WebViewAsyncRequestHitTestDataCallback(){};
199 virtual void Run(_Ewk_Hit_Test* hit_test, EWebView* web_view) = 0;
202 int GetX() const { return x_; }
203 int GetY() const { return y_; }
204 Ewk_Hit_Test_Mode GetMode() const { return mode_; }
209 Ewk_Hit_Test_Mode mode_;
212 class WebViewAsyncRequestHitTestDataUserCallback
213 : public WebViewAsyncRequestHitTestDataCallback {
215 WebViewAsyncRequestHitTestDataUserCallback(
218 Ewk_Hit_Test_Mode mode,
219 Ewk_View_Hit_Test_Request_Callback callback,
221 : WebViewAsyncRequestHitTestDataCallback(x, y, mode),
223 user_data_(user_data) {}
225 void Run(_Ewk_Hit_Test* hit_test, EWebView* web_view) override {
227 callback_(web_view->evas_object(), GetX(), GetY(), GetMode(), hit_test,
232 Ewk_View_Hit_Test_Request_Callback callback_;
236 #if defined(TIZEN_ATK_SUPPORT)
237 class EWebAccessibilityObserver : public EWebAccessibility::Observer {
239 explicit EWebAccessibilityObserver(EWebView* webview) : webview_(webview) {}
240 virtual ~EWebAccessibilityObserver() {}
242 // EWebAccessibility::Observer implementation
243 void OnSpatialNavigationStatusChanged(Eina_Bool enable) override {
244 webview_->UpdateSpatialNavigationStatus(enable);
247 void OnAccessibilityStatusChanged(Eina_Bool enable) override {
248 webview_->UpdateAccessibilityStatus(enable);
256 int EWebView::find_request_id_counter_ = 0;
257 content::WebContentsEflDelegate::WebContentsCreateCallback
258 EWebView::create_new_window_web_contents_cb_ =
259 base::BindRepeating(&NullCreateWebContents);
261 EWebView* EWebView::FromEvasObject(Evas_Object* eo) {
262 return WebViewDelegateEwk::GetInstance().GetWebViewFromEvasObject(eo);
265 void EWebView::OnViewFocusIn(void* data, Evas*, Evas_Object*, void*) {
266 auto view = static_cast<EWebView*>(data);
267 view->SetFocus(EINA_TRUE);
270 void EWebView::OnViewFocusOut(void* data, Evas*, Evas_Object*, void*) {
271 auto view = static_cast<EWebView*>(data);
272 view->SetFocus(EINA_FALSE);
275 void EWebView::VisibleContentChangedCallback(void* user_data,
276 Evas_Object* /*object*/,
278 auto view = static_cast<EWebView*>(user_data);
279 auto rect = static_cast<Eina_Rectangle*>(event_info);
280 view->GetSelectionController()->SetCustomVisibleViewRect(
281 gfx::Rect(rect->x, rect->y, rect->w, rect->h));
284 EWebView::EWebView(Ewk_Context* context, Evas_Object* object)
286 evas_object_(object),
287 native_view_(object),
288 mouse_events_enabled_(false),
289 text_zoom_factor_(1.0),
290 current_find_request_id_(find_request_id_counter_++),
292 hit_test_completion_(base::WaitableEvent::ResetPolicy::AUTOMATIC,
293 base::WaitableEvent::InitialState::NOT_SIGNALED),
294 page_scale_factor_(1.0),
297 is_initialized_(false) {
299 evas_object_smart_callback_add(evas_object_,
300 kVisibleContentChangedSignalName,
301 VisibleContentChangedCallback, this);
303 evas_object_event_callback_add(evas_object_, EVAS_CALLBACK_FOCUS_IN,
304 OnViewFocusIn, this);
305 evas_object_event_callback_add(evas_object_, EVAS_CALLBACK_FOCUS_OUT,
306 OnViewFocusOut, this);
310 void EWebView::Initialize() {
311 if (is_initialized_) {
317 evas_event_handler_ = new WebViewEvasEventHandler(this);
319 scroll_detector_.reset(new ScrollDetector(this));
321 DCHECK(web_contents_->GetRenderViewHost());
322 // Settings (content::WebPreferences) will be initalized by
323 // RenderViewHostImpl::ComputeWebkitPrefs() based on command line switches.
324 settings_.reset(new Ewk_Settings(evas_object_,
325 web_contents_->GetOrCreateWebPreferences()));
326 #if defined(TIZEN_ATK_SUPPORT)
327 std::unique_ptr<EWebAccessibilityObserver> observer(
328 new EWebAccessibilityObserver(this));
329 eweb_accessibility_.reset(new EWebAccessibility(
330 evas_object_, web_contents_.get(), std::move(observer)));
331 lazy_initialize_atk_ = true;
334 base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess();
335 if (cmdline->HasSwitch(switches::kTouchEventFeatureDetection)) {
336 SetTouchEventsEnabled(
337 cmdline->GetSwitchValueASCII(switches::kTouchEventFeatureDetection) ==
338 switches::kTouchEventFeatureDetectionEnabled);
340 SetMouseEventsEnabled(true);
343 std::string user_agent =
344 EflWebView::VersionInfo::GetInstance()->DefaultUserAgent();
345 web_contents_->SetUserAgentOverride(
346 blink::UserAgentOverride::UserAgentOnly(user_agent),
347 false /* override_in_new_tabs */);
349 elm_object_tree_focus_allow_set(native_view_, EINA_TRUE);
350 is_initialized_ = true;
352 auto cbce = static_cast<ContentBrowserClientEfl*>(
353 content::GetContentClientExport()->browser());
354 // Initialize accept languages
355 SyncAcceptLanguages(cbce->GetAcceptLangs(nullptr));
356 accept_langs_changed_callback_ =
357 base::BindOnce(&EWebView::SyncAcceptLanguages, base::Unretained(this));
358 cbce->AddAcceptLangsChangedCallback(
359 std::move(accept_langs_changed_callback_));
361 // If EWebView is created by window.open, RenderView is already created
362 // before initializing WebContents. So we should manually invoke
363 // EWebView::RenderViewReady here.
364 if (web_contents_->GetPrimaryMainFrame() &&
365 web_contents_->GetPrimaryMainFrame()->IsRenderFrameLive()) {
370 EWebView::~EWebView() {
371 auto cbce = static_cast<ContentBrowserClientEfl*>(
372 content::GetContentClientExport()->browser());
373 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
374 cbce->RemoveAcceptLangsChangedCallback(
375 std::move(accept_langs_changed_callback_));
378 #if defined(USE_WAYLAND) && !BUILDFLAG(IS_TIZEN_TV)
379 ClipboardHelperEfl::GetInstance()->MaybeInvalidateActiveWebview(this);
382 std::map<int64_t, WebViewAsyncRequestHitTestDataCallback*>::iterator
383 hit_test_callback_iterator;
384 for (hit_test_callback_iterator = hit_test_callback_.begin();
385 hit_test_callback_iterator != hit_test_callback_.end();
386 hit_test_callback_iterator++)
387 delete hit_test_callback_iterator->second;
388 hit_test_callback_.clear();
390 for (auto iter = delayed_messages_.begin(); iter != delayed_messages_.end();
394 delayed_messages_.clear();
396 if (!is_initialized_) {
400 #if defined(TIZEN_ATK_SUPPORT)
401 eweb_accessibility_.reset();
404 select_picker_.reset();
405 context_menu_.reset();
406 mhtml_callback_map_.Clear();
408 // Release manually those scoped pointers to
409 // make sure they are released in correct order
410 web_contents_.reset();
411 web_contents_delegate_.reset();
413 // This code must be executed after WebContents deletion
414 // because WebContents depends on BrowserContext which
415 // is deleted along with EwkContext.
416 CHECK(!web_contents_);
418 permission_popup_manager_.reset();
420 gin_native_bridge_dispatcher_host_.reset();
423 evas_object_event_callback_del(evas_object_, EVAS_CALLBACK_FOCUS_IN,
425 evas_object_event_callback_del(evas_object_, EVAS_CALLBACK_FOCUS_OUT,
427 evas_object_smart_callback_del(evas_object_,
428 kVisibleContentChangedSignalName,
429 VisibleContentChangedCallback);
433 content::RenderWidgetHostViewAura* EWebView::rwhva() const {
434 return static_cast<content::RenderWidgetHostViewAura*>(
435 web_contents_->GetRenderWidgetHostView());
438 content::WebContentsViewAura* EWebView::wcva() const {
439 WebContentsImpl* wc = static_cast<WebContentsImpl*>(web_contents_.get());
440 return static_cast<WebContentsViewAura*>(wc->GetView());
443 void EWebView::ResetContextMenuController() {
444 return context_menu_.reset();
447 void EWebView::SetFocus(Eina_Bool focus) {
448 if (!web_contents_ || !rwhva() || (HasFocus() == focus))
451 rwhva()->offscreen_helper()->Focus(focus);
454 Eina_Bool EWebView::HasFocus() const {
458 return rwhva()->offscreen_helper()->HasFocus() ? EINA_TRUE : EINA_FALSE;
461 Eina_Bool EWebView::AddJavaScriptMessageHandler(
463 Ewk_View_Script_Message_Cb callback,
465 if (!gin_native_bridge_dispatcher_host_)
468 return gin_native_bridge_dispatcher_host_->AddNamedObject(view, callback,
472 bool EWebView::SetPageVisibility(
473 Ewk_Page_Visibility_State page_visibility_state) {
477 // TODO: We should able to set 'prerender' or 'unloaded' as visibility state.
478 // http://www.w3.org/TR/page-visibility/#dom-document-visibilitystate
479 switch (page_visibility_state) {
480 case EWK_PAGE_VISIBILITY_STATE_VISIBLE:
481 rwhva()->offscreen_helper()->SetPageVisibility(true);
483 case EWK_PAGE_VISIBILITY_STATE_HIDDEN:
484 rwhva()->offscreen_helper()->SetPageVisibility(false);
486 case EWK_PAGE_VISIBILITY_STATE_PRERENDER:
496 bool EWebView::CreateNewWindow(
497 content::WebContentsEflDelegate::WebContentsCreateCallback cb) {
498 create_new_window_web_contents_cb_ = cb;
499 Evas_Object* new_object = NULL;
500 SmartCallback<EWebViewCallbacks::CreateNewWindow>().call(&new_object);
501 create_new_window_web_contents_cb_ =
502 base::BindRepeating(&NullCreateWebContents);
507 Evas_Object* EWebView::GetHostWindowDelegate(const content::WebContents* wc) {
508 EWebView* thiz = WebViewFromWebContents(wc);
509 DCHECK(thiz->evas_object_);
510 Evas_Object* parent = evas_object_above_get(thiz->evas_object_);
512 LOG(WARNING) << "Could not find and visual parents for EWK smart object!.";
513 return thiz->evas_object_;
516 if (elm_object_widget_check(parent)) {
517 Evas_Object* elm_parent = elm_object_top_widget_get(parent);
523 LOG(WARNING) << "Could not find elementary parent for WebView object!";
524 return thiz->evas_object_;
527 Evas_Object* EWebView::GetElmWindow() const {
528 Evas_Object* parent = elm_object_parent_widget_get(evas_object_);
529 return parent ? elm_object_top_widget_get(parent) : nullptr;
532 void EWebView::SetURL(const GURL& url, bool from_api) {
533 NavigationController::LoadURLParams params(url);
536 params.transition_type = ui::PageTransitionFromInt(
537 ui::PAGE_TRANSITION_LINK | ui::PAGE_TRANSITION_FROM_API);
540 params.override_user_agent = NavigationController::UA_OVERRIDE_TRUE;
541 web_contents_->GetController().LoadURLWithParams(params);
544 const GURL& EWebView::GetURL() const {
545 return web_contents_->GetVisibleURL();
548 const GURL& EWebView::GetOriginalURL() const {
549 const auto entry = web_contents_->GetController().GetVisibleEntry();
551 return entry->GetOriginalRequestURL();
553 return web_contents_->GetVisibleURL();
556 void EWebView::Reload() {
557 web_contents_->GetController().Reload(content::ReloadType::NORMAL, true);
560 void EWebView::ReloadBypassingCache() {
561 web_contents_->GetController().Reload(content::ReloadType::BYPASSING_CACHE,
565 Eina_Bool EWebView::CanGoBack() {
566 return web_contents_->GetController().CanGoBack();
569 Eina_Bool EWebView::CanGoForward() {
570 return web_contents_->GetController().CanGoForward();
573 Eina_Bool EWebView::GoBack() {
574 if (!web_contents_->GetController().CanGoBack())
577 web_contents_->GetController().GoBack();
581 Eina_Bool EWebView::GoForward() {
582 if (!web_contents_->GetController().CanGoForward())
585 web_contents_->GetController().GoForward();
589 void EWebView::Stop() {
590 if (web_contents_->IsLoading())
591 web_contents_->Stop();
594 void EWebView::Suspend() {
595 CHECK(web_contents_);
596 #if BUILDFLAG(IS_TIZEN)
597 if (IsMobileProfile() && web_contents_->IsFullscreen())
598 web_contents_->ExitFullscreen(true);
600 RenderViewHost* rvh = web_contents_->GetRenderViewHost();
601 RenderFrameHost* rfh = web_contents_->GetPrimaryMainFrame();
604 #if !defined(EWK_BRINGUP) // FIXME: m69 bringup
605 rfh->BlockRequestsForFrame();
608 content::GetIOThreadTaskRunner({})->PostTask(FROM_HERE, base::BindOnce(
609 &content::ResourceDispatcherHost::BlockRequestsForFrameFromUI, rfh));
612 rvh->Send(new EwkViewMsg_SuspendScheduledTask(rvh->GetRoutingID()));
616 void EWebView::Resume() {
617 CHECK(web_contents_);
618 RenderViewHost* rvh = web_contents_->GetRenderViewHost();
619 RenderFrameHost* rfh = web_contents_->GetPrimaryMainFrame();
622 #if !defined(EWK_BRINGUP) // FIXME: m69 bringup
623 rfh->ResumeBlockedRequestsForFrame();
626 content::GetIOThreadTaskRunner({})->PostTask(FROM_HERE, base::BindOnce(
627 &content::ResourceDispatcherHost::ResumeBlockedRequestsForFrameFromUI,
631 rvh->Send(new EwkViewMsg_ResumeScheduledTasks(rvh->GetRoutingID()));
635 double EWebView::GetTextZoomFactor() const {
636 if (text_zoom_factor_ < 0.0)
639 return text_zoom_factor_;
642 void EWebView::SetTextZoomFactor(double text_zoom_factor) {
643 if (text_zoom_factor_ == text_zoom_factor || text_zoom_factor < 0.0)
646 text_zoom_factor_ = text_zoom_factor;
647 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
648 if (!render_view_host)
650 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
651 render_view_host->Send(new ViewMsg_SetTextZoomFactor(
652 render_view_host->GetRoutingID(), text_zoom_factor));
656 double EWebView::GetPageZoomFactor() const {
657 return blink::PageZoomLevelToZoomFactor(
658 content::HostZoomMap::GetZoomLevel(web_contents_.get()));
661 void EWebView::SetPageZoomFactor(double page_zoom_factor) {
662 content::HostZoomMap::SetZoomLevel(
663 web_contents_.get(), blink::PageZoomFactorToZoomLevel(page_zoom_factor));
666 void EWebView::ExecuteEditCommand(const char* command, const char* value) {
667 EINA_SAFETY_ON_NULL_RETURN(command);
669 value = (value == nullptr) ? "" : value;
671 absl::optional<std::u16string> optional_value =
672 absl::make_optional(base::ASCIIToUTF16(value));
674 WebContentsImpl* wc = static_cast<WebContentsImpl*>(web_contents_.get());
676 wc->GetFocusedFrameWidgetInputHandler()->ExecuteEditCommand(
677 std::string(command), optional_value);
681 void EWebView::SetOrientation(int orientation) {
682 if (GetOrientation() == orientation)
685 if (orientation == 0 || orientation == 90 || orientation == 180 ||
686 orientation == 270) {
687 #if !defined(USE_AURA)
688 GetWebContentsViewEfl()->SetOrientation(orientation);
692 const Ecore_Evas* ee =
693 ecore_evas_ecore_evas_get(evas_object_evas_get(evas_object_));
694 ecore_evas_screen_geometry_get(ee, nullptr, nullptr, &width, &height);
695 if (orientation == 90 || orientation == 270)
696 std::swap(width, height);
699 context_menu_->SetPopupSize(width, height);
700 if (popup_controller_)
701 popup_controller_->SetPopupSize(width, height);
702 if (JavaScriptDialogManagerEfl* dialogMG = GetJavaScriptDialogManagerEfl())
703 dialogMG->SetPopupSize(width, height);
707 int EWebView::GetOrientation() {
708 #if !defined(USE_AURA)
709 return GetWebContentsViewEfl()->GetOrientation();
715 void EWebView::Show() {
716 evas_object_show(native_view_);
717 web_contents_->WasShown();
720 void EWebView::Hide() {
721 evas_object_hide(native_view_);
722 web_contents_->WasHidden();
725 void EWebView::SetViewAuthCallback(Ewk_View_Authentication_Callback callback,
727 authentication_cb_.Set(callback, user_data);
730 void EWebView::InvokeAuthCallback(LoginDelegateEfl* login_delegate,
732 const std::string& realm) {
733 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
735 auth_challenge_.reset(new _Ewk_Auth_Challenge(login_delegate, url, realm));
736 authentication_cb_.Run(evas_object_, auth_challenge_.get());
738 if (!auth_challenge_->is_decided && !auth_challenge_->is_suspended) {
739 auth_challenge_->is_decided = true;
740 auth_challenge_->login_delegate->Cancel();
744 void EWebView::InvokePolicyResponseCallback(
745 _Ewk_Policy_Decision* policy_decision,
747 SmartCallback<EWebViewCallbacks::PolicyResponseDecide>().call(
750 if (policy_decision->isSuspended()) {
755 if (!policy_decision->isDecided())
756 policy_decision->Use();
758 policy_decision->SelfDeleteIfNecessary();
761 void EWebView::InvokePolicyNavigationCallback(
762 const NavigationPolicyParams& params,
764 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
766 SmartCallback<EWebViewCallbacks::SaveSessionData>().call();
768 std::unique_ptr<_Ewk_Policy_Decision> policy_decision(
769 new _Ewk_Policy_Decision(params));
771 SmartCallback<EWebViewCallbacks::NavigationPolicyDecision>().call(
772 policy_decision.get());
774 CHECK(!policy_decision->isSuspended());
776 // TODO: Navigation can't be suspended
777 // this aproach is synchronous and requires immediate response
778 // Maybe there is different approach (like resource throttle response
779 // mechanism) that allows us to
780 // suspend navigation
781 if (!policy_decision->isDecided())
782 policy_decision->Use();
784 *handled = policy_decision->GetNavigationPolicyHandler()->GetDecision() ==
785 NavigationPolicyHandlerEfl::Handled;
788 void EWebView::HandleTouchEvents(Ewk_Touch_Event_Type type,
789 const Eina_List* points,
790 const Evas_Modifier* modifiers) {
793 EINA_LIST_FOREACH(points, l, data) {
794 const Ewk_Touch_Point* point = static_cast<Ewk_Touch_Point*>(data);
795 if (point->state == EVAS_TOUCH_POINT_STILL) {
796 // Chromium doesn't expect (and doesn't like) these events.
805 evas_object_geometry_get(evas_object(), nullptr, &delta_y, nullptr,
807 ui::TouchEvent touch_event =
808 ui::MakeTouchEvent(pt, point->state, point->id, 0, delta_y);
809 rwhva()->OnTouchEvent(&touch_event);
814 bool EWebView::TouchEventsEnabled() const {
815 return rwhva()->offscreen_helper()->TouchEventsEnabled();
818 // TODO: Touch events use the same mouse events in EFL API.
819 // Figure out how to distinguish touch and mouse events on touch&mice devices.
820 // Currently mouse and touch support is mutually exclusive.
821 void EWebView::SetTouchEventsEnabled(bool enabled) {
822 if (!rwhva() || !rwhva()->offscreen_helper()) {
823 LOG(WARNING) << "RWHV is not created yet!";
827 if (rwhva()->offscreen_helper()->TouchEventsEnabled() == enabled)
830 rwhva()->offscreen_helper()->SetTouchEventsEnabled(enabled);
832 GetSettings()->getPreferences().touch_event_feature_detection_enabled =
834 GetSettings()->getPreferences().double_tap_to_zoom_enabled = enabled;
835 GetSettings()->getPreferences().editing_behavior =
836 enabled ? blink::mojom::EditingBehavior::kEditingAndroidBehavior
837 : blink::mojom::EditingBehavior::kEditingUnixBehavior,
838 UpdateWebKitPreferences();
841 bool EWebView::MouseEventsEnabled() const {
842 return mouse_events_enabled_;
845 void EWebView::SetMouseEventsEnabled(bool enabled) {
846 if (!rwhva() || !rwhva()->offscreen_helper()) {
847 LOG(WARNING) << "RWHV is not created yet!";
851 if (mouse_events_enabled_ == enabled)
854 mouse_events_enabled_ = enabled;
855 rwhva()->offscreen_helper()->SetTouchEventsEnabled(!enabled);
860 class JavaScriptCallbackDetails {
862 JavaScriptCallbackDetails(Ewk_View_Script_Execute_Callback callback_func,
865 : callback_func_(callback_func), user_data_(user_data), view_(view) {}
867 Ewk_View_Script_Execute_Callback callback_func_;
872 void JavaScriptComplete(JavaScriptCallbackDetails* script_callback_data,
873 base::Value result) {
874 if (!script_callback_data->callback_func_)
877 std::string return_string;
878 if (result.is_string()) {
879 // We don't want to serialize strings with JSONStringValueSerializer
880 // to avoid quotation marks.
881 return_string = result.GetString();
882 } else if (result.is_none()) {
883 // Value::TYPE_NULL is for lack of value, undefined, null
886 JSONStringValueSerializer serializer(&return_string);
887 serializer.Serialize(result);
890 script_callback_data->callback_func_(script_callback_data->view_,
891 return_string.c_str(),
892 script_callback_data->user_data_);
897 bool EWebView::ExecuteJavaScript(const char* script,
898 Ewk_View_Script_Execute_Callback callback,
900 LOG(INFO) << __FUNCTION__;
901 if (!web_contents_) {
902 LOG(ERROR) << __FUNCTION__ << "web_contents_ is null";
906 RenderFrameHost* render_frame_host = web_contents_->GetPrimaryMainFrame();
907 if (!render_frame_host) {
908 LOG(ERROR) << __FUNCTION__ << " render_frame_host is null";
912 // Note: M37. Execute JavaScript, |script| with
913 // |RenderFrameHost::ExecuteJavaScript|.
914 // @see also https://codereview.chromium.org/188893005 for more details.
915 std::u16string js_script;
916 base::UTF8ToUTF16(script, strlen(script), &js_script);
918 JavaScriptCallbackDetails* script_callback_data =
919 new JavaScriptCallbackDetails(callback, userdata, evas_object_);
920 RenderFrameHost::JavaScriptResultCallback js_callback =
921 base::BindOnce(&JavaScriptComplete, base::Owned(script_callback_data));
922 // In M47, it isn't possible anymore to execute javascript in the generic
923 // case. We need to call ExecuteJavaScriptForTests to keep the behaviour
924 // unchanged @see https://codereview.chromium.org/1123783002
925 render_frame_host->ExecuteJavaScriptWithUserGestureForTests(
926 js_script, std::move(js_callback));
928 // We use ExecuteJavaScriptWithUserGestureForTests instead of
929 // ExecuteJavaScript because
930 // ExecuteJavaScriptWithUserGestureForTests sets user_gesture to true. This
932 // behaviour is m34, and we want to keep it that way.
933 render_frame_host->ExecuteJavaScriptWithUserGestureForTests(
934 js_script, base::NullCallback());
940 bool EWebView::SetUserAgent(const char* userAgent) {
941 content::NavigationController& controller = web_contents_->GetController();
942 bool override = userAgent && strlen(userAgent);
943 for (int i = 0; i < controller.GetEntryCount(); ++i)
944 controller.GetEntryAtIndex(i)->SetIsOverridingUserAgent(override);
945 // TODO: Check if override_in_new_tabs has to be true.
946 web_contents_->SetUserAgentOverride(
947 blink::UserAgentOverride::UserAgentOnly(userAgent),
948 false /* override_in_new_tabs */);
952 bool EWebView::SetUserAgentAppName(const char* application_name) {
953 EflWebView::VersionInfo::GetInstance()->UpdateUserAgentWithAppName(
954 application_name ? application_name : "");
955 std::string user_agent =
956 EflWebView::VersionInfo::GetInstance()->DefaultUserAgent();
957 web_contents_->SetUserAgentOverride(
958 blink::UserAgentOverride::UserAgentOnly(user_agent),
959 false /* override_in_new_tabs */);
963 #if BUILDFLAG(IS_TIZEN)
964 bool EWebView::SetPrivateBrowsing(bool incognito) {
965 if (context_->GetImpl()->browser_context()->IsOffTheRecord() == incognito)
967 context_->GetImpl()->browser_context()->SetOffTheRecord(incognito);
971 bool EWebView::GetPrivateBrowsing() const {
972 return context_->GetImpl()->browser_context()->IsOffTheRecord();
976 const char* EWebView::GetUserAgent() const {
977 std::string user_agent =
978 web_contents_->GetUserAgentOverride().ua_string_override;
979 if (user_agent.empty())
980 user_agent_ = content::GetContentClientExport()->browser()->GetUserAgent();
982 user_agent_ = user_agent;
984 return user_agent_.c_str();
987 const char* EWebView::GetUserAgentAppName() const {
988 user_agent_app_name_ = EflWebView::VersionInfo::GetInstance()->AppName();
989 return user_agent_app_name_.c_str();
992 const char* EWebView::CacheSelectedText() {
996 selected_text_cached_ = base::UTF16ToUTF8(rwhva()->GetSelectedText());
997 return selected_text_cached_.c_str();
1000 _Ewk_Frame* EWebView::GetMainFrame() {
1001 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1004 frame_.reset(new _Ewk_Frame(web_contents_->GetPrimaryMainFrame()));
1006 return frame_.get();
1009 void EWebView::UpdateWebKitPreferences() {
1010 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1012 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1013 if (!render_view_host)
1016 web_contents_delegate_->OnUpdateSettings(settings_.get());
1017 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
1018 render_view_host->UpdateWebkitPreferences(settings_->getPreferences());
1020 UpdateWebkitPreferencesEfl(render_view_host);
1023 void EWebView::UpdateWebkitPreferencesEfl(RenderViewHost* render_view_host) {
1024 DCHECK(render_view_host);
1025 #if !defined(EWK_BRINGUP) // FIXME: m108 bringup
1026 IPC::Message* message = new EwkSettingsMsg_UpdateWebKitPreferencesEfl(
1027 render_view_host->GetRoutingID(), settings_->getPreferencesEfl());
1029 if (render_view_host->IsRenderViewLive()) {
1030 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
1031 render_view_host->Send(message);
1034 delayed_messages_.push_back(message);
1039 void EWebView::SetContentSecurityPolicy(const char* policy,
1040 Ewk_CSP_Header_Type type) {
1041 web_contents_delegate_->SetContentSecurityPolicy(
1042 (policy ? policy : std::string()), type);
1045 void EWebView::LoadHTMLString(const char* html,
1046 const char* base_uri,
1047 const char* unreachable_uri) {
1048 LoadData(html, std::string::npos, NULL, NULL, base_uri, unreachable_uri);
1051 void EWebView::LoadPlainTextString(const char* plain_text) {
1052 LoadData(plain_text, std::string::npos, "text/plain", NULL, NULL, NULL);
1055 void EWebView::LoadData(const char* data,
1057 const char* mime_type,
1058 const char* encoding,
1059 const char* base_uri,
1060 const char* unreachable_uri) {
1061 SetDefaultStringIfNull(mime_type, "text/html");
1062 SetDefaultStringIfNull(encoding, "utf-8");
1063 SetDefaultStringIfNull(base_uri, "about:blank"); // Webkit2 compatible
1064 SetDefaultStringIfNull(unreachable_uri, "");
1066 std::string str_data = data;
1068 if (size < str_data.length())
1069 str_data = str_data.substr(0, size);
1071 std::string url_str("data:");
1072 url_str.append(mime_type);
1073 url_str.append(";charset=");
1074 url_str.append(encoding);
1075 url_str.append(",");
1077 // GURL constructor performs canonicalization of url string, but this is not
1078 // enough for correctly escaping contents of "data:" url.
1079 url_str.append(base::EscapeUrlEncodedData(str_data, false));
1081 NavigationController::LoadURLParams data_params(GURL(url_str.c_str()));
1083 data_params.base_url_for_data_url = GURL(base_uri);
1084 data_params.virtual_url_for_data_url = GURL(unreachable_uri);
1086 data_params.load_type = NavigationController::LOAD_TYPE_DATA;
1087 data_params.should_replace_current_entry = false;
1088 data_params.override_user_agent = NavigationController::UA_OVERRIDE_TRUE;
1089 web_contents_->GetController().LoadURLWithParams(data_params);
1092 void EWebView::InvokeLoadError(const GURL& url,
1094 bool is_cancellation) {
1095 _Ewk_Error err(error_code, is_cancellation,
1096 url.possibly_invalid_spec().c_str());
1098 SmartCallback<EWebViewCallbacks::LoadError>().call(&err);
1101 void EWebView::HandlePopupMenu(std::vector<blink::mojom::MenuItemPtr> items,
1104 const gfx::Rect& bounds) {
1105 if (!select_picker_) {
1106 select_picker_.reset(CreateSelectPicker(
1107 this, selectedIndex, std::move(items), multiple, bounds));
1109 // Picker has been shown on top of webview and the page content gets
1110 // partially overlapped. Decrease viewport while showing picker.
1111 AdjustViewPortHeightToPopupMenu(true /* is_popup_menu_visible */);
1113 select_picker_->UpdatePickerData(selectedIndex, std::move(items), multiple);
1116 select_picker_->Show();
1119 void EWebView::HidePopupMenu() {
1120 if (!select_picker_)
1123 AdjustViewPortHeightToPopupMenu(false /* is_popup_menu_visible */);
1124 select_picker_.reset();
1127 void EWebView::DidSelectPopupMenuItems(std::vector<int>& indices) {
1128 wcva()->wcva_helper()->DidSelectPopupMenuItems(indices);
1131 void EWebView::DidCancelPopupMenu() {
1132 wcva()->wcva_helper()->DidCancelPopupMenu();
1135 void EWebView::HandleLongPressGesture(
1136 const content::ContextMenuParams& params) {
1137 // This menu is created in renderer process and it does not now anything about
1138 // view scaling factor and it has another calling sequence, so coordinates is
1140 if (settings_ && !settings_->getPreferences().long_press_enabled)
1143 content::ContextMenuParams convertedParams = params;
1144 gfx::Point convertedPoint =
1145 rwhva()->offscreen_helper()->ConvertPointInViewPix(
1146 gfx::Point(params.x, params.y));
1147 convertedParams.x = convertedPoint.x();
1148 convertedParams.y = convertedPoint.y();
1151 evas_object_geometry_get(evas_object(), &x, &y, 0, 0);
1152 convertedParams.x += x;
1153 convertedParams.y += y;
1155 if (GetSelectionController() && GetSelectionController()->GetLongPressed()) {
1156 bool show_context_menu_now =
1157 !GetSelectionController()->HandleLongPressEvent(convertedPoint,
1159 if (show_context_menu_now)
1160 ShowContextMenuInternal(convertedParams);
1164 void EWebView::ShowContextMenu(const content::ContextMenuParams& params) {
1168 // This menu is created in renderer process and it does not now anything about
1169 // view scaling factor and it has another calling sequence, so coordinates is
1171 content::ContextMenuParams convertedParams = params;
1172 gfx::Point convertedPoint =
1173 rwhva()->offscreen_helper()->ConvertPointInViewPix(
1174 gfx::Point(params.x, params.y));
1175 convertedParams.x = convertedPoint.x();
1176 convertedParams.y = convertedPoint.y();
1179 evas_object_geometry_get(evas_object(), &x, &y, 0, 0);
1180 convertedParams.x += x;
1181 convertedParams.y += y;
1183 context_menu_position_ = gfx::Point(convertedParams.x, convertedParams.y);
1185 ShowContextMenuInternal(convertedParams);
1188 void EWebView::ShowContextMenuInternal(
1189 const content::ContextMenuParams& params) {
1190 context_menu_.reset(
1191 new content::ContextMenuControllerEfl(this, *web_contents_.get()));
1192 if (!context_menu_->PopulateAndShowContextMenu(params)) {
1193 context_menu_.reset();
1194 if (GetSelectionController())
1195 GetSelectionController()->HideHandles();
1199 void EWebView::CancelContextMenu(int request_id) {
1201 context_menu_->HideContextMenu();
1204 void EWebView::Find(const char* text, Ewk_Find_Options ewk_find_options) {
1205 std::u16string find_text = base::UTF8ToUTF16(text);
1206 bool find_next = (previous_text_ == find_text);
1209 current_find_request_id_ = find_request_id_counter_++;
1210 previous_text_ = find_text;
1213 auto find_options = blink::mojom::FindOptions::New();
1214 find_options->forward = !(ewk_find_options & EWK_FIND_OPTIONS_BACKWARDS);
1215 find_options->match_case =
1216 !(ewk_find_options & EWK_FIND_OPTIONS_CASE_INSENSITIVE);
1218 web_contents_->Find(current_find_request_id_, find_text,
1219 std::move(find_options));
1222 void EWebView::SetScale(double scale_factor) {
1223 // Do not cache |scale_factor| here as it may be discarded by Blink's
1224 // minimumPageScaleFactor and maximumPageScaleFactor.
1225 // |scale_factor| is cached as responde to DidChangePageScaleFactor.
1226 WebContentsImpl* wci = static_cast<WebContentsImpl*>(web_contents_.get());
1227 wci->GetPrimaryMainFrame()->GetAssociatedLocalMainFrame()->SetScaleFactor(
1231 void EWebView::ScrollFocusedNodeIntoView() {
1232 if (RenderViewHost* render_view_host = web_contents_->GetRenderViewHost()) {
1233 if (auto& broadcast = static_cast<RenderViewHostImpl*>(render_view_host)
1234 ->GetAssociatedPageBroadcast())
1235 broadcast->ScrollFocusedNodeIntoView();
1239 void EWebView::AdjustViewPortHeightToPopupMenu(bool is_popup_menu_visible) {
1240 if (!rwhva() || !IsMobileProfile() ||
1241 settings_->getPreferences().TizenCompatibilityModeEnabled()) {
1245 int picker_height = select_picker_->GetGeometryDIP().height();
1246 gfx::Rect screen_rect =
1247 display::Screen::GetScreen()->GetPrimaryDisplay().bounds();
1248 gfx::Rect view_rect = rwhva()->offscreen_helper()->GetViewBounds();
1250 screen_rect.height() - (view_rect.y() + view_rect.height());
1252 rwhva()->offscreen_helper()->SetCustomViewportSize(
1253 is_popup_menu_visible
1254 ? gfx::Size(view_rect.width(),
1255 view_rect.height() - picker_height + bottom_height)
1259 void EWebView::SetScaleChangedCallback(Ewk_View_Scale_Changed_Callback callback,
1261 scale_changed_cb_.Set(callback, user_data);
1264 bool EWebView::GetScrollPosition(int* x, int* y) const {
1266 LOG(ERROR) << "rwhva() returns nullptr";
1269 if (scroll_detector_->IsScrollOffsetChanged()) {
1271 *x = previous_scroll_position_.x();
1273 *y = previous_scroll_position_.y();
1275 const gfx::Vector2d scroll_position_dip =
1276 scroll_detector_->GetLastScrollPosition();
1277 const float device_scale_factor = display::Screen::GetScreen()
1278 ->GetPrimaryDisplay()
1279 .device_scale_factor();
1281 *x = base::ClampRound((scroll_position_dip.x() - x_delta_) *
1282 device_scale_factor);
1285 *y = base::ClampRound((scroll_position_dip.y() - y_delta_) *
1286 device_scale_factor);
1292 void EWebView::ChangeScroll(int& x, int& y) {
1294 LOG(ERROR) << "rwhva() returns nullptr";
1299 GetScrollSize(&max_x, &max_y);
1300 previous_scroll_position_.set_x(std::min(std::max(x, 0), max_x));
1301 previous_scroll_position_.set_y(std::min(std::max(y, 0), max_y));
1303 const float device_scale_factor = display::Screen::GetScreen()
1304 ->GetPrimaryDisplay()
1305 .device_scale_factor();
1309 x = base::ClampCeil(x / device_scale_factor);
1310 y = base::ClampCeil(y / device_scale_factor);
1312 x_delta_ = x - (x_input / device_scale_factor);
1313 y_delta_ = y - (y_input / device_scale_factor);
1315 scroll_detector_->SetScrollOffsetChanged();
1318 void EWebView::SetScroll(int x, int y) {
1319 if (auto* render_view_host = web_contents_->GetRenderViewHost()) {
1320 if (auto& broadcast = static_cast<RenderViewHostImpl*>(render_view_host)
1321 ->GetAssociatedPageBroadcast()) {
1323 broadcast->SetScrollOffset(x, y);
1328 void EWebView::UseSettingsFont() {
1329 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
1330 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1331 if (render_view_host)
1332 render_view_host->Send(
1333 new EwkViewMsg_UseSettingsFont(render_view_host->GetRoutingID()));
1337 void EWebView::DidChangeContentsSize(int width, int height) {
1338 contents_size_ = gfx::Size(width, height);
1339 SmartCallback<EWebViewCallbacks::ContentsSizeChanged>().call();
1340 SetScaledContentsSize();
1343 const Eina_Rectangle EWebView::GetContentsSize() const {
1344 Eina_Rectangle rect;
1345 EINA_RECTANGLE_SET(&rect, 0, 0, contents_size_.width(),
1346 contents_size_.height());
1350 void EWebView::SetScaledContentsSize() {
1352 return; // LCOV_EXCL_LINE
1354 const float device_scale_factor =
1355 display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
1356 gfx::SizeF scaled_contents_size = gfx::ConvertSizeToPixels(
1357 contents_size_, device_scale_factor * page_scale_factor_);
1358 rwhva()->offscreen_helper()->SetScaledContentSize(scaled_contents_size);
1361 void EWebView::GetScrollSize(int* width, int* height) {
1364 *width = (rwhva() &&
1365 (w = rwhva()->offscreen_helper()->GetScrollableSize().width()))
1370 *height = (rwhva() &&
1371 (h = rwhva()->offscreen_helper()->GetScrollableSize().height()))
1377 void EWebView::MoveCaret(const gfx::Point& point) {
1379 rwhva()->offscreen_helper()->MoveCaret(point);
1382 SelectionControllerEfl* EWebView::GetSelectionController() const {
1383 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1384 RenderWidgetHostViewAura* view = static_cast<RenderWidgetHostViewAura*>(
1385 render_view_host->GetWidget()->GetView());
1386 return view ? view->offscreen_helper()->GetSelectionController() : 0;
1389 void EWebView::SelectLinkText(const gfx::Point& touch_point) {
1390 #if !defined(EWK_BRINGUP) // FIXME: m67 bringup
1391 float device_scale_factor =
1392 display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
1393 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1394 render_view_host->Send(new ViewMsg_SelectLinkText(
1395 render_view_host->GetRoutingID(),
1396 gfx::Point(touch_point.x() / device_scale_factor,
1397 touch_point.y() / device_scale_factor)));
1401 bool EWebView::GetSelectionRange(Eina_Rectangle* left_rect,
1402 Eina_Rectangle* right_rect) {
1403 if (left_rect && right_rect) {
1404 gfx::Rect left, right;
1405 if (GetSelectionController()) {
1406 GetSelectionController()->GetSelectionBounds(&left, &right);
1407 GetEinaRectFromGfxRect(left, left_rect);
1408 GetEinaRectFromGfxRect(right, right_rect);
1415 Eina_Bool EWebView::ClearSelection() {
1419 ResetContextMenuController();
1420 rwhva()->offscreen_helper()->SelectionChanged(std::u16string(), 0,
1423 if (GetSelectionController())
1424 return GetSelectionController()->ClearSelectionViaEWebView();
1429 _Ewk_Hit_Test* EWebView::RequestHitTestDataAt(int x,
1431 Ewk_Hit_Test_Mode mode) {
1432 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1435 EvasToBlinkCords(x, y, &view_x, &view_y);
1437 return RequestHitTestDataAtBlinkCoords(view_x, view_y, mode);
1440 Eina_Bool EWebView::AsyncRequestHitTestDataAt(
1443 Ewk_Hit_Test_Mode mode,
1444 Ewk_View_Hit_Test_Request_Callback callback,
1447 EvasToBlinkCords(x, y, &view_x, &view_y);
1448 return AsyncRequestHitTestDataAtBlinkCords(
1449 view_x, view_y, mode,
1450 new WebViewAsyncRequestHitTestDataUserCallback(x, y, mode, callback,
1454 Eina_Bool EWebView::AsyncRequestHitTestDataAtBlinkCords(
1457 Ewk_Hit_Test_Mode mode,
1458 Ewk_View_Hit_Test_Request_Callback callback,
1460 return AsyncRequestHitTestDataAtBlinkCords(
1462 new WebViewAsyncRequestHitTestDataUserCallback(x, y, mode, callback,
1466 Eina_Bool EWebView::AsyncRequestHitTestDataAtBlinkCords(
1469 Ewk_Hit_Test_Mode mode,
1470 WebViewAsyncRequestHitTestDataCallback* cb) {
1471 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1474 static int64_t request_id = 1;
1477 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1478 DCHECK(render_view_host);
1480 if (render_view_host) {
1481 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
1482 render_view_host->Send(new EwkViewMsg_DoHitTestAsync(
1483 render_view_host->GetRoutingID(), x, y, mode, request_id));
1485 hit_test_callback_[request_id] = cb;
1491 // if failed we delete callback as it is not needed anymore
1496 void EWebView::DispatchAsyncHitTestData(const Hit_Test_Params& params,
1497 int64_t request_id) {
1498 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1500 std::map<int64_t, WebViewAsyncRequestHitTestDataCallback*>::iterator it =
1501 hit_test_callback_.find(request_id);
1503 if (it == hit_test_callback_.end())
1505 std::unique_ptr<_Ewk_Hit_Test> hit_test(new _Ewk_Hit_Test(params));
1507 it->second->Run(hit_test.get(), this);
1509 hit_test_callback_.erase(it);
1512 _Ewk_Hit_Test* EWebView::RequestHitTestDataAtBlinkCoords(
1515 Ewk_Hit_Test_Mode mode) {
1516 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1518 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1520 if (render_view_host) {
1521 // We wait on UI thread till hit test data is updated.
1522 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
1523 render_view_host->Send(
1524 new EwkViewMsg_DoHitTest(render_view_host->GetRoutingID(), x, y, mode));
1526 hit_test_completion_.Wait();
1527 return new _Ewk_Hit_Test(hit_test_params_);
1533 void EWebView::EvasToBlinkCords(int x, int y, int* view_x, int* view_y) {
1534 DCHECK(display::Screen::GetScreen());
1538 gfx::Rect view_bounds = rwhva()->offscreen_helper()->GetViewBoundsInPix();
1541 *view_x = x - view_bounds.x();
1543 display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
1547 *view_y = y - view_bounds.y();
1549 display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
1553 void EWebView::UpdateHitTestData(const Hit_Test_Params& params) {
1554 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
1555 hit_test_params_ = params;
1556 hit_test_completion_.Signal();
1559 void EWebView::OnCopyFromBackingStore(bool success, const SkBitmap& bitmap) {}
1561 void EWebView::OnFocusIn() {
1562 SmartCallback<EWebViewCallbacks::FocusIn>().call();
1563 #if defined(USE_WAYLAND) && !BUILDFLAG(IS_TIZEN_TV)
1564 if (!rwhva() || !rwhva()->offscreen_helper())
1566 ClipboardHelperEfl::GetInstance()->OnWebviewFocusIn(
1567 this, rwhva()->offscreen_helper()->content_image_elm_host(),
1568 rwhva()->offscreen_helper()->IsFocusedNodeContentEditable(),
1569 base::BindRepeating(&EWebView::ExecuteEditCommand,
1570 base::Unretained(this)));
1574 void EWebView::OnFocusOut() {
1575 SmartCallback<EWebViewCallbacks::FocusOut>().call();
1576 #if defined(USE_WAYLAND) && !BUILDFLAG(IS_TIZEN_TV)
1577 ClipboardHelperEfl::GetInstance()->MaybeInvalidateActiveWebview(this);
1581 void EWebView::RenderViewReady() {
1583 rwhva()->offscreen_helper()->SetFocusInOutCallbacks(
1584 base::BindRepeating(&EWebView::OnFocusIn, base::Unretained(this)),
1585 base::BindRepeating(&EWebView::OnFocusOut, base::Unretained(this)));
1588 #if defined(TIZEN_VIDEO_HOLE)
1589 if (rwhva() && pending_video_hole_setting_) {
1590 rwhva()->host()->SetVideoHoleForRender(pending_video_hole_setting_);
1591 pending_video_hole_setting_ = false;
1595 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1597 SendDelayedMessages(render_view_host);
1598 UpdateWebkitPreferencesEfl(render_view_host);
1600 if (render_view_host) {
1601 WebContents* content = WebContents::FromRenderViewHost(render_view_host);
1603 RenderProcessHost* host = render_view_host->GetProcess();
1605 host->AddFilter(new WebViewBrowserMessageFilter(content));
1610 void EWebView::SetQuotaPermissionRequestCallback(
1611 Ewk_Quota_Permission_Request_Callback callback,
1613 quota_request_callback_.Set(callback, user_data);
1616 void EWebView::InvokeQuotaPermissionRequest(
1617 _Ewk_Quota_Permission_Request* request,
1618 content::QuotaPermissionContext::PermissionCallback cb) {
1619 quota_permission_request_map_[request] = std::move(cb);
1620 request->setView(evas_object());
1621 if (quota_request_callback_.IsCallbackSet())
1622 quota_request_callback_.Run(evas_object(), request);
1624 QuotaRequestCancel(request);
1627 void EWebView::QuotaRequestReply(const _Ewk_Quota_Permission_Request* request,
1629 DCHECK(quota_permission_request_map_.find(request) !=
1630 quota_permission_request_map_.end());
1632 QuotaPermissionContextEfl::DispatchCallback(
1633 std::move(quota_permission_request_map_[request]),
1634 (allow ? QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_ALLOW
1635 : QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_DISALLOW));
1637 quota_permission_request_map_.erase(request);
1641 void EWebView::QuotaRequestCancel(
1642 const _Ewk_Quota_Permission_Request* request) {
1643 DCHECK(quota_permission_request_map_.find(request) !=
1644 quota_permission_request_map_.end());
1646 QuotaPermissionContextEfl::DispatchCallback(
1647 std::move(quota_permission_request_map_[request]),
1648 QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_CANCELLED);
1649 quota_permission_request_map_.erase(request);
1653 bool EWebView::GetLinkMagnifierEnabled() const {
1654 #if !defined(EWK_BRINGUP) // FIXME: m71 bringup
1655 return web_contents_->GetMutableRendererPrefs()
1656 ->tap_multiple_targets_strategy ==
1657 TAP_MULTIPLE_TARGETS_STRATEGY_POPUP;
1663 void EWebView::SetLinkMagnifierEnabled(bool enabled) {
1664 #if !defined(EWK_BRINGUP) // FIXME: m71 bringup
1665 web_contents_->GetMutableRendererPrefs()->tap_multiple_targets_strategy =
1666 enabled ? TAP_MULTIPLE_TARGETS_STRATEGY_POPUP
1667 : TAP_MULTIPLE_TARGETS_STRATEGY_NONE;
1669 web_contents_->SyncRendererPrefs();
1672 bool EWebView::GetSnapshotAsync(
1673 Eina_Rectangle rect,
1674 Ewk_Web_App_Screenshot_Captured_Callback callback,
1676 float scale_factor) {
1677 if (!rwhva() || !rwhva()->offscreen_helper())
1680 rwhva()->offscreen_helper()->RequestSnapshotAsync(
1681 gfx::Rect(rect.x, rect.y, rect.w, rect.h), callback, user_data,
1686 Evas_Object* EWebView::GetSnapshot(Eina_Rectangle rect, float scale_factor) {
1687 if (!rwhva() || !rwhva()->offscreen_helper())
1690 return rwhva()->offscreen_helper()->GetSnapshot(
1691 gfx::Rect(rect.x, rect.y, rect.w, rect.h), scale_factor);
1694 void EWebView::BackForwardListClear() {
1695 content::NavigationController& controller = web_contents_->GetController();
1697 int entry_count = controller.GetEntryCount();
1698 bool entry_removed = false;
1700 for (int i = 0; i < entry_count; i++) {
1701 if (controller.RemoveEntryAtIndex(i)) {
1702 entry_removed = true;
1703 entry_count = controller.GetEntryCount();
1708 if (entry_removed) {
1709 back_forward_list_->ClearCache();
1710 InvokeBackForwardListChangedCallback();
1714 _Ewk_Back_Forward_List* EWebView::GetBackForwardList() const {
1715 return back_forward_list_.get();
1718 void EWebView::InvokeBackForwardListChangedCallback() {
1719 SmartCallback<EWebViewCallbacks::BackForwardListChange>().call();
1722 _Ewk_History* EWebView::GetBackForwardHistory() const {
1723 return new _Ewk_History(web_contents_->GetController());
1726 bool EWebView::WebAppCapableGet(Ewk_Web_App_Capable_Get_Callback callback,
1728 RenderViewHost* renderViewHost = web_contents_->GetRenderViewHost();
1729 if (!renderViewHost) {
1732 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
1733 WebApplicationCapableGetCallback* cb =
1734 new WebApplicationCapableGetCallback(callback, userData);
1735 int callbackId = web_app_capable_get_callback_map_.Add(cb);
1736 return renderViewHost->Send(new EwkViewMsg_WebAppCapableGet(
1737 renderViewHost->GetRoutingID(), callbackId));
1743 bool EWebView::WebAppIconUrlGet(Ewk_Web_App_Icon_URL_Get_Callback callback,
1745 RenderViewHost* renderViewHost = web_contents_->GetRenderViewHost();
1746 if (!renderViewHost) {
1749 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
1750 WebApplicationIconUrlGetCallback* cb =
1751 new WebApplicationIconUrlGetCallback(callback, userData);
1752 int callbackId = web_app_icon_url_get_callback_map_.Add(cb);
1753 return renderViewHost->Send(new EwkViewMsg_WebAppIconUrlGet(
1754 renderViewHost->GetRoutingID(), callbackId));
1760 bool EWebView::WebAppIconUrlsGet(Ewk_Web_App_Icon_URLs_Get_Callback callback,
1762 RenderViewHost* renderViewHost = web_contents_->GetRenderViewHost();
1763 if (!renderViewHost) {
1766 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
1767 WebApplicationIconUrlsGetCallback* cb =
1768 new WebApplicationIconUrlsGetCallback(callback, userData);
1769 int callbackId = web_app_icon_urls_get_callback_map_.Add(cb);
1770 return renderViewHost->Send(new EwkViewMsg_WebAppIconUrlsGet(
1771 renderViewHost->GetRoutingID(), callbackId));
1777 void EWebView::InvokeWebAppCapableGetCallback(bool capable, int callbackId) {
1778 WebApplicationCapableGetCallback* callback =
1779 web_app_capable_get_callback_map_.Lookup(callbackId);
1782 callback->Run(capable);
1783 web_app_capable_get_callback_map_.Remove(callbackId);
1786 void EWebView::InvokeWebAppIconUrlGetCallback(const std::string& iconUrl,
1788 WebApplicationIconUrlGetCallback* callback =
1789 web_app_icon_url_get_callback_map_.Lookup(callbackId);
1792 callback->Run(iconUrl);
1793 web_app_icon_url_get_callback_map_.Remove(callbackId);
1796 void EWebView::InvokeWebAppIconUrlsGetCallback(const StringMap& iconUrls,
1798 WebApplicationIconUrlsGetCallback* callback =
1799 web_app_icon_urls_get_callback_map_.Lookup(callbackId);
1803 callback->Run(iconUrls);
1804 web_app_icon_urls_get_callback_map_.Remove(callbackId);
1807 void EWebView::SetNotificationPermissionCallback(
1808 Ewk_View_Notification_Permission_Callback callback,
1810 notification_permission_callback_.Set(callback, user_data);
1813 bool EWebView::IsNotificationPermissionCallbackSet() const {
1814 return notification_permission_callback_.IsCallbackSet();
1817 bool EWebView::InvokeNotificationPermissionCallback(
1818 Ewk_Notification_Permission_Request* request) {
1819 Eina_Bool ret = EINA_FALSE;
1820 notification_permission_callback_.Run(evas_object_, request, &ret);
1824 int EWebView::SetEwkViewPlainTextGetCallback(
1825 Ewk_View_Plain_Text_Get_Callback callback,
1827 EwkViewPlainTextGetCallback* view_plain_text_callback_ptr =
1828 new EwkViewPlainTextGetCallback;
1829 view_plain_text_callback_ptr->Set(callback, user_data);
1830 return plain_text_get_callback_map_.Add(view_plain_text_callback_ptr);
1833 bool EWebView::PlainTextGet(Ewk_View_Plain_Text_Get_Callback callback,
1835 auto* render_frame_host = web_contents_->GetPrimaryMainFrame();
1836 if (!render_frame_host)
1839 auto callback_id = SetEwkViewPlainTextGetCallback(callback, user_data);
1840 return render_frame_host->Send(new EwkFrameMsg_GetPlainText(
1841 render_frame_host->GetRoutingID(), callback_id));
1844 void EWebView::InvokePlainTextGetCallback(const std::string& content_text,
1845 int plain_text_get_callback_id) {
1846 EwkViewPlainTextGetCallback* view_plain_text_callback_invoke_ptr =
1847 plain_text_get_callback_map_.Lookup(plain_text_get_callback_id);
1848 view_plain_text_callback_invoke_ptr->Run(evas_object(), content_text.c_str());
1849 plain_text_get_callback_map_.Remove(plain_text_get_callback_id);
1852 void EWebView::SetViewGeolocationPermissionCallback(
1853 Ewk_View_Geolocation_Permission_Callback callback,
1855 geolocation_permission_cb_.Set(callback, user_data);
1858 bool EWebView::InvokeViewGeolocationPermissionCallback(
1859 _Ewk_Geolocation_Permission_Request* permission_context,
1860 Eina_Bool* callback_result) {
1861 return geolocation_permission_cb_.Run(evas_object_, permission_context,
1865 void EWebView::SetViewUserMediaPermissionCallback(
1866 Ewk_View_User_Media_Permission_Callback callback,
1868 user_media_permission_cb_.Set(callback, user_data);
1871 bool EWebView::InvokeViewUserMediaPermissionCallback(
1872 _Ewk_User_Media_Permission_Request* permission_context,
1873 Eina_Bool* callback_result) {
1874 return user_media_permission_cb_.Run(evas_object_, permission_context,
1878 void EWebView::SetViewUserMediaPermissionQueryCallback(
1879 Ewk_View_User_Media_Permission_Query_Callback callback,
1881 user_media_permission_query_cb_.Set(callback, user_data);
1884 Ewk_User_Media_Permission_Query_Result
1885 EWebView::InvokeViewUserMediaPermissionQueryCallback(
1886 _Ewk_User_Media_Permission_Query* permission_context) {
1887 return user_media_permission_query_cb_.Run(evas_object_, permission_context);
1890 void EWebView::SetViewUnfocusAllowCallback(
1891 Ewk_View_Unfocus_Allow_Callback callback,
1893 unfocus_allow_cb_.Set(callback, user_data);
1896 bool EWebView::InvokeViewUnfocusAllowCallback(Ewk_Unfocus_Direction direction,
1897 Eina_Bool* callback_result) {
1898 return unfocus_allow_cb_.Run(evas_object_, direction, callback_result);
1901 void EWebView::StopFinding() {
1902 web_contents_->StopFinding(content::STOP_FIND_ACTION_CLEAR_SELECTION);
1905 void EWebView::SetProgressValue(double progress) {
1906 progress_ = progress;
1909 double EWebView::GetProgressValue() {
1913 const char* EWebView::GetTitle() {
1914 title_ = base::UTF16ToUTF8(web_contents_->GetTitle());
1915 return title_.c_str();
1918 bool EWebView::SaveAsPdf(int width, int height, const std::string& filename) {
1921 rwhva()->host()->PrintToPdf(width, height, base::FilePath(filename));
1925 bool EWebView::GetMHTMLData(Ewk_View_MHTML_Data_Get_Callback callback,
1927 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1928 if (!render_view_host)
1931 MHTMLCallbackDetails* callback_details = new MHTMLCallbackDetails;
1932 callback_details->Set(callback, user_data);
1933 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
1934 int mhtml_callback_id = mhtml_callback_map_.Add(callback_details);
1935 return render_view_host->Send(new EwkViewMsg_GetMHTMLData(
1936 render_view_host->GetRoutingID(), mhtml_callback_id));
1942 void EWebView::OnMHTMLContentGet(const std::string& mhtml_content,
1944 MHTMLCallbackDetails* callback_details =
1945 mhtml_callback_map_.Lookup(callback_id);
1946 callback_details->Run(evas_object(), mhtml_content.c_str());
1947 mhtml_callback_map_.Remove(callback_id);
1950 bool EWebView::SavePageAsMHTML(const std::string& path,
1951 Ewk_View_Save_Page_Callback callback,
1956 GURL url(web_contents_->GetLastCommittedURL());
1957 std::u16string title(web_contents_->GetTitle());
1959 // Post function that has file access to blocking task runner.
1960 return base::PostTaskAndReplyWithResult(
1961 base::ThreadPool::CreateSequencedTaskRunner(
1962 {base::MayBlock(), base::TaskPriority::BEST_EFFORT,
1963 base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})
1966 base::BindOnce(&GenerateMHTMLFilePath, url, base::UTF16ToUTF8(title),
1968 base::BindOnce(&EWebView::GenerateMHTML, base::Unretained(this), callback,
1972 void EWebView::GenerateMHTML(Ewk_View_Save_Page_Callback callback,
1974 const base::FilePath& file_path) {
1975 if (file_path.empty()) {
1976 LOG(ERROR) << "Generating file path was failed";
1977 callback(evas_object_, nullptr, user_data);
1981 MHTMLGenerationParams params(file_path);
1982 web_contents_->GenerateMHTML(
1983 params, base::BindOnce(&EWebView::MHTMLGenerated, base::Unretained(this),
1984 callback, user_data, file_path));
1987 void EWebView::MHTMLGenerated(Ewk_View_Save_Page_Callback callback,
1989 const base::FilePath& file_path,
1990 int64_t file_size) {
1991 callback(evas_object_, file_size > 0 ? file_path.value().c_str() : nullptr,
1995 bool EWebView::GetBackgroundColor(
1996 Ewk_View_Background_Color_Get_Callback callback,
2000 BackgroundColorGetCallback* cb =
2001 new BackgroundColorGetCallback(callback, user_data);
2002 int callback_id = background_color_get_callback_map_.Add(cb);
2004 rwhva()->host()->RequestBackgroundColor(callback_id);
2008 void EWebView::OnGetBackgroundColor(int callback_id, SkColor bg_color) {
2009 BackgroundColorGetCallback* cb =
2010 background_color_get_callback_map_.Lookup(callback_id);
2015 cb->Run(evas_object(), SkColorGetR(bg_color), SkColorGetG(bg_color),
2016 SkColorGetB(bg_color), SkColorGetA(bg_color));
2017 background_color_get_callback_map_.Remove(callback_id);
2020 bool EWebView::IsFullscreen() {
2021 return web_contents_delegate_->IsFullscreenForTabOrPending(
2022 web_contents_.get());
2025 void EWebView::ExitFullscreen() {
2026 WebContentsImpl* wci = static_cast<WebContentsImpl*>(web_contents_.get());
2027 wci->ExitFullscreen(false);
2030 double EWebView::GetScale() {
2031 return page_scale_factor_;
2034 void EWebView::DidChangePageScaleFactor(double scale_factor) {
2035 page_scale_factor_ = scale_factor;
2036 wcva()->wcva_helper()->SetPageScaleFactor(scale_factor);
2037 SetScaledContentsSize();
2039 // Notify app about the scale change.
2040 scale_changed_cb_.Run(evas_object_, scale_factor);
2043 inline JavaScriptDialogManagerEfl* EWebView::GetJavaScriptDialogManagerEfl() {
2044 return static_cast<JavaScriptDialogManagerEfl*>(
2045 web_contents_delegate_->GetJavaScriptDialogManager(web_contents_.get()));
2048 void EWebView::SetJavaScriptAlertCallback(
2049 Ewk_View_JavaScript_Alert_Callback callback,
2051 GetJavaScriptDialogManagerEfl()->SetAlertCallback(callback, user_data);
2054 void EWebView::JavaScriptAlertReply() {
2055 GetJavaScriptDialogManagerEfl()->ExecuteDialogClosedCallBack(true,
2057 SmartCallback<EWebViewCallbacks::PopupReplyWaitFinish>().call(0);
2060 void EWebView::SetJavaScriptConfirmCallback(
2061 Ewk_View_JavaScript_Confirm_Callback callback,
2063 GetJavaScriptDialogManagerEfl()->SetConfirmCallback(callback, user_data);
2066 void EWebView::JavaScriptConfirmReply(bool result) {
2067 GetJavaScriptDialogManagerEfl()->ExecuteDialogClosedCallBack(result,
2069 SmartCallback<EWebViewCallbacks::PopupReplyWaitFinish>().call(0);
2072 void EWebView::SetJavaScriptPromptCallback(
2073 Ewk_View_JavaScript_Prompt_Callback callback,
2075 GetJavaScriptDialogManagerEfl()->SetPromptCallback(callback, user_data);
2078 void EWebView::JavaScriptPromptReply(const char* result) {
2079 GetJavaScriptDialogManagerEfl()->ExecuteDialogClosedCallBack(
2080 true, (std::string(result)));
2081 SmartCallback<EWebViewCallbacks::PopupReplyWaitFinish>().call(0);
2084 void EWebView::GetPageScaleRange(double* min_scale, double* max_scale) {
2085 auto prefs = web_contents_->GetOrCreateWebPreferences();
2087 *min_scale = prefs.default_minimum_page_scale_factor;
2089 *max_scale = prefs.default_maximum_page_scale_factor;
2092 void EWebView::SetDrawsTransparentBackground(bool enabled) {
2093 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
2094 if (!render_view_host)
2096 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
2097 render_view_host->Send(new EwkViewMsg_SetDrawsTransparentBackground(
2098 render_view_host->GetRoutingID(), enabled));
2102 void EWebView::GetSessionData(const char** data, unsigned* length) const {
2103 static const int MAX_SESSION_ENTRY_SIZE = std::numeric_limits<int>::max();
2105 NavigationController& navigationController = web_contents_->GetController();
2106 base::Pickle sessionPickle;
2107 const int itemCount = navigationController.GetEntryCount();
2109 sessionPickle.WriteInt(itemCount);
2110 sessionPickle.WriteInt(navigationController.GetCurrentEntryIndex());
2112 for (int i = 0; i < itemCount; i++) {
2113 NavigationEntry* navigationEntry = navigationController.GetEntryAtIndex(i);
2114 sessions::SerializedNavigationEntry serializedEntry =
2115 sessions::ContentSerializedNavigationBuilder::FromNavigationEntry(
2116 i, navigationEntry);
2117 serializedEntry.WriteToPickle(MAX_SESSION_ENTRY_SIZE, &sessionPickle);
2120 if (sessionPickle.size() <= 0 ||
2122 static_cast<char*>(malloc(sizeof(char) * sessionPickle.size())))) {
2123 LOG(ERROR) << "Failed to get session data";
2127 memcpy(const_cast<char*>(*data), sessionPickle.data(), sessionPickle.size());
2128 *length = sessionPickle.size();
2131 bool EWebView::RestoreFromSessionData(const char* data, unsigned length) {
2132 base::Pickle sessionPickle(data, length);
2133 base::PickleIterator pickleIterator(sessionPickle);
2137 if (!pickleIterator.ReadInt(&entryCount))
2139 if (!pickleIterator.ReadInt(¤tEntry))
2142 std::vector<sessions::SerializedNavigationEntry> serializedEntries;
2143 serializedEntries.resize(entryCount);
2144 for (int i = 0; i < entryCount; ++i) {
2145 if (!serializedEntries.at(i).ReadFromPickle(&pickleIterator))
2155 std::vector<std::unique_ptr<content::NavigationEntry>> scopedEntries =
2156 sessions::ContentSerializedNavigationBuilder::ToNavigationEntries(
2157 serializedEntries, context()->browser_context());
2159 NavigationController& navigationController = web_contents_->GetController();
2161 if (currentEntry < 0)
2164 if (currentEntry >= static_cast<int>(scopedEntries.size()))
2165 currentEntry = scopedEntries.size() - 1;
2167 navigationController.Restore(currentEntry, RestoreType::kRestored,
2172 void EWebView::SetBrowserFont() {
2173 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
2174 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
2175 if (render_view_host) {
2176 IPC::Message* message =
2177 new EwkViewMsg_SetBrowserFont(render_view_host->GetRoutingID());
2179 if (render_view_host->IsRenderViewLive())
2180 render_view_host->Send(message);
2182 delayed_messages_.push_back(message);
2187 bool EWebView::IsDragging() const {
2188 return wcva()->wcva_helper()->IsDragging();
2191 void EWebView::ShowFileChooser(content::RenderFrameHost* render_frame_host,
2192 const blink::mojom::FileChooserParams& params) {
2193 if (!IsMobileProfile() && !IsWearableProfile())
2196 #if !defined(EWK_BRINGUP) // FIXME: m71 bringup
2197 if (params.capture) {
2198 const std::string capture_types[] = {"video/*", "audio/*", "image/*"};
2199 unsigned int capture_types_num =
2200 sizeof(capture_types) / sizeof(*capture_types);
2201 for (unsigned int i = 0; i < capture_types_num; ++i) {
2202 for (unsigned int j = 0; j < params.accept_types.size(); ++j) {
2203 if (UTF16ToUTF8(params.accept_types[j]) == capture_types[i]) {
2204 filechooser_mode_ = params.mode;
2205 LaunchCamera(params.accept_types[j]);
2211 file_chooser_.reset(
2212 new content::FileChooserControllerEfl(render_frame_host, ¶ms));
2213 file_chooser_->Open();
2217 #if !defined(EWK_BRINGUP) // FIXME: m67 bringup
2218 void EWebView::SetViewMode(blink::WebViewMode view_mode) {
2219 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
2220 if (!render_view_host)
2223 IPC::Message* message =
2224 new ViewMsg_SetViewMode(render_view_host->GetRoutingID(), view_mode);
2225 if (render_view_host->IsRenderViewLive()) {
2226 render_view_host->Send(message);
2228 delayed_messages_.push_back(message);
2233 gfx::Point EWebView::GetContextMenuPosition() const {
2234 return context_menu_position_;
2237 void EWebView::ShowContentsDetectedPopup(const char* message) {
2238 popup_controller_.reset(new PopupControllerEfl(this));
2239 popup_controller_->openPopup(message);
2242 void EWebView::RequestColorPicker(int r, int g, int b, int a) {
2243 input_picker_.reset(new InputPicker(this));
2244 input_picker_->ShowColorPicker(r, g, b, a);
2247 bool EWebView::SetColorPickerColor(int r, int g, int b, int a) {
2248 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
2249 web_contents_->DidChooseColorInColorChooser(SkColorSetARGB(a, r, g, b));
2254 void EWebView::InputPickerShow(ui::TextInputType input_type,
2256 content::DateTimeChooserEfl* date_time_chooser) {
2257 input_picker_.reset(new InputPicker(this));
2258 date_time_chooser_ = date_time_chooser;
2259 input_picker_->ShowDatePicker(input_type, input_value);
2262 void EWebView::LoadNotFoundErrorPage(const std::string& invalidUrl) {
2263 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
2264 RenderFrameHost* render_frame_host = web_contents_->GetPrimaryMainFrame();
2265 if (render_frame_host)
2266 render_frame_host->Send(new EwkFrameMsg_LoadNotFoundErrorPage(
2267 render_frame_host->GetRoutingID(), invalidUrl));
2271 std::string EWebView::GetPlatformLocale() {
2272 char* local_default = setlocale(LC_CTYPE, 0);
2274 return std::string("en-US");
2275 std::string locale = std::string(local_default);
2276 size_t position = locale.find('_');
2277 if (position != std::string::npos)
2278 locale.replace(position, 1, "-");
2279 position = locale.find('.');
2280 if (position != std::string::npos)
2281 locale = locale.substr(0, position);
2285 int EWebView::StartInspectorServer(int port) {
2286 return context_->InspectorServerStart(port);
2289 bool EWebView::StopInspectorServer() {
2290 return context_->InspectorServerStop();
2293 void EWebView::InvokeWebProcessCrashedCallback() {
2294 DCHECK_CURRENTLY_ON(BrowserThread::UI);
2295 const GURL last_url = GetURL();
2296 bool callback_handled = false;
2297 SmartCallback<EWebViewCallbacks::WebProcessCrashed>().call(&callback_handled);
2298 if (!callback_handled)
2299 LoadHTMLString(kRendererCrashedHTMLMessage, NULL,
2300 last_url.possibly_invalid_spec().c_str());
2303 void EWebView::SyncAcceptLanguages(const std::string& accept_languages) {
2304 web_contents_->GetMutableRendererPrefs()->accept_languages = accept_languages;
2305 web_contents_->SyncRendererPrefs();
2306 BrowserContext* browser_context = web_contents_->GetBrowserContext();
2307 if (!browser_context)
2310 auto* storage_partition = browser_context->GetDefaultStoragePartition();
2311 if (!storage_partition)
2314 if (auto* network_context = storage_partition->GetNetworkContext())
2315 network_context->SetAcceptLanguage(accept_languages);
2318 void EWebView::HandleRendererProcessCrash() {
2319 content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
2320 base::BindOnce(&EWebView::InvokeWebProcessCrashedCallback,
2321 base::Unretained(this)));
2324 void EWebView::InitializeContent() {
2325 WebContents* new_contents = create_new_window_web_contents_cb_.Run(this);
2326 if (!new_contents) {
2327 WebContents::CreateParams params(context_->browser_context());
2328 web_contents_.reset(
2329 new WebContentsImplEfl(context_->browser_context(), this));
2330 static_cast<WebContentsImpl*>(web_contents_.get())
2331 ->Init(params, blink::FramePolicy());
2333 web_contents_.reset(new_contents);
2335 // When a new webview is created in response to a request from the
2336 // engine, the BrowserContext instance of the originator WebContents
2337 // is used by the newly created WebContents object.
2338 // See more in WebContentsImplEfl::HandleNewWebContentsCreate.
2340 // Hence, if as part of the WebView creation, the embedding APP
2341 // passes in a Ewk_Context instance that wraps a different instance of
2342 // BrowserContext than the one the originator WebContents holds,
2343 // undefined behavior can be seen.
2345 // This is a snippet code that illustrate the scenario:
2348 // evas_object_smart_callback_add(web_view_, "create,window",
2349 // &OnNewWindowRequest, this);
2352 // void OnNewWindowRequest(void *data, Evas_Object*, void* out_view) {
2354 // EvasObject* new_web_view = ewk_view_add_with_context(GetEvas(),
2355 // ewk_context_new());
2356 // *static_cast<Evas_Object**>(out_view) = new_web_view;
2360 // The new Ewk_Context object created and passed in as parameter to
2361 // ewk_view_add_with_context wraps a different instance of BrowserContext
2362 // than the one the new WebContents object will hold.
2364 // CHECK below aims at catching misuse of this API.
2365 bool should_crash = context_->GetImpl()->browser_context() !=
2366 web_contents_->GetBrowserContext();
2369 << "BrowserContext of new WebContents does not match EWebView's. "
2370 << "Please see 'ewk_view_add*' documentation. "
2371 << "Aborting execution ...";
2374 web_contents_delegate_.reset(new WebContentsDelegateEfl(this));
2375 web_contents_->SetDelegate(web_contents_delegate_.get());
2376 WebContentsImplEfl* wc_efl =
2377 static_cast<WebContentsImplEfl*>(web_contents_.get());
2378 wc_efl->SetEflDelegate(new WebContentsEflDelegateEwk(this));
2379 wcva()->wcva_helper()->SetEflDelegate(wc_efl->GetEflDelegate());
2381 back_forward_list_.reset(new _Ewk_Back_Forward_List(web_contents_.get()));
2383 permission_popup_manager_.reset(new PermissionPopupManager(evas_object_));
2384 gin_native_bridge_dispatcher_host_.reset(
2385 new content::GinNativeBridgeDispatcherHost(web_contents_.get()));
2388 static_cast<WebContentsImplEfl*>(web_contents_.get())->GetEflNativeView();
2389 evas_object_smart_member_add(native_view_, evas_object_);
2390 static_cast<WebContentsImpl*>(web_contents_.get())
2391 ->set_ewk_view(evas_object_);
2392 InitializeWindowTreeHost();
2395 void EWebView::InitializeWindowTreeHost() {
2396 CHECK(aura::Env::GetInstance());
2398 int x, y, width, height;
2400 ecore_evas_ecore_evas_get(evas_object_evas_get(native_view_));
2401 ecore_evas_geometry_get(ee, &x, &y, &width, &height);
2403 gfx::Rect bounds(x, y, width, height);
2404 ui::PlatformWindowInitProperties properties;
2405 properties.bounds = bounds;
2407 host_ = aura::WindowTreeHost::Create(std::move(properties));
2409 host_->window()->Show();
2412 std::make_unique<aura::test::TestFocusClient>(host_->window());
2413 window_parenting_client_ =
2414 std::make_unique<aura::test::TestWindowParentingClient>(host_->window());
2416 aura::Window* content = web_contents_->GetNativeView();
2417 aura::Window* parent = host_->window();
2418 if (!parent->Contains(content)) {
2419 parent->AddChild(content);
2422 content->SetBounds(bounds);
2423 RenderWidgetHostView* host_view = web_contents_->GetRenderWidgetHostView();
2425 host_view->SetSize(bounds.size());
2428 #if BUILDFLAG(IS_TIZEN) && !defined(EWK_BRINGUP)
2429 void EWebView::cameraResultCb(service_h request,
2431 service_result_e result,
2433 if (!IsMobileProfile() && !IsWearableProfile())
2436 EWebView* webview = static_cast<EWebView*>(data);
2437 RenderViewHost* render_view_host =
2438 webview->web_contents_->GetRenderViewHost();
2439 if (result == SERVICE_RESULT_SUCCEEDED) {
2443 ret = service_get_extra_data_array(reply, SERVICE_DATA_SELECTED,
2444 &filesarray, &number);
2446 for (int i = 0; i < number; i++) {
2447 std::vector<ui::SelectedFileInfo> files;
2448 if (!render_view_host) {
2451 if (filesarray[i]) {
2452 GURL url(filesarray[i]);
2453 if (!url.is_valid()) {
2454 base::FilePath path(url.SchemeIsFile() ? url.path()
2456 files.push_back(ui::SelectedFileInfo(path, base::FilePath()));
2459 render_view_host->FilesSelectedInChooser(files,
2460 webview->filechooser_mode_);
2464 std::vector<ui::SelectedFileInfo> files;
2465 if (render_view_host) {
2466 render_view_host->FilesSelectedInChooser(files,
2467 webview->filechooser_mode_);
2472 bool EWebView::LaunchCamera(std::u16string mimetype) {
2473 service_h svcHandle = 0;
2474 if (service_create(&svcHandle) < 0 || !svcHandle) {
2475 LOG(ERROR) << __FUNCTION__ << " Service Creation Failed ";
2478 service_set_operation(svcHandle, SERVICE_OPERATION_CREATE_CONTENT);
2479 service_set_mime(svcHandle, UTF16ToUTF8(mimetype).c_str());
2480 service_add_extra_data(svcHandle, "CALLER", "Browser");
2482 int ret = service_send_launch_request(svcHandle, cameraResultCb, this);
2483 if (ret != SERVICE_ERROR_NONE) {
2484 LOG(ERROR) << __FUNCTION__ << " Service Launch Failed ";
2485 service_destroy(svcHandle);
2488 service_destroy(svcHandle);
2493 void EWebView::UrlRequestSet(
2495 content::NavigationController::LoadURLType loadtype,
2499 content::NavigationController::LoadURLParams params(gurl);
2500 params.load_type = loadtype;
2501 params.override_user_agent = NavigationController::UA_OVERRIDE_TRUE;
2504 std::string s(body);
2506 network::ResourceRequestBody::CreateFromBytes(s.data(), s.size());
2509 net::HttpRequestHeaders header;
2511 Eina_Iterator* it = eina_hash_iterator_tuple_new(headers);
2513 while (eina_iterator_next(it, reinterpret_cast<void**>(&t))) {
2515 const char* value_str =
2516 t->data ? static_cast<const char*>(t->data) : "";
2517 base::StringPiece name = static_cast<const char*>(t->key);
2518 base::StringPiece value = value_str;
2519 header.SetHeader(name, value);
2520 // net::HttpRequestHeaders.ToString() returns string with newline
2521 params.extra_headers += header.ToString();
2524 eina_iterator_free(it);
2527 web_contents_->GetController().LoadURLWithParams(params);
2530 #if defined(TIZEN_VIDEO_HOLE)
2531 void EWebView::SetVideoHoleSupport(bool enable) {
2532 if (!web_contents_->GetPrimaryMainFrame() ||
2533 !web_contents_->GetPrimaryMainFrame()->IsRenderFrameLive() || !rwhva()) {
2534 pending_video_hole_setting_ = enable;
2538 rwhva()->host()->SetVideoHoleForRender(enable);
2542 bool EWebView::HandleShow() {
2550 bool EWebView::HandleHide() {
2558 bool EWebView::HandleMove(int x, int y) {
2561 evas_object_move(native_view_, x, y);
2563 #if defined(TIZEN_VIDEO_HOLE) && !defined(EWK_BRINGUP)
2565 rwhva()->offscreen_helper()->DidMoveWebView();
2571 bool EWebView::HandleResize(int width, int height) {
2574 evas_object_resize(native_view_, width, height);
2576 if (select_picker_) {
2577 AdjustViewPortHeightToPopupMenu(true /* is_popup_menu_visible */);
2578 ScrollFocusedNodeIntoView();
2584 bool EWebView::HandleTextSelectionDown(int x, int y) {
2585 if (!GetSelectionController())
2587 return GetSelectionController()->TextSelectionDown(x, y);
2590 bool EWebView::HandleTextSelectionUp(int x, int y) {
2591 if (!GetSelectionController())
2593 return GetSelectionController()->TextSelectionUp(x, y);
2596 void EWebView::HandleTapGestureForSelection(bool is_content_editable) {
2597 if (!GetSelectionController())
2600 GetSelectionController()->PostHandleTapGesture(is_content_editable);
2603 void EWebView::HandleZoomGesture(blink::WebGestureEvent& event) {
2604 blink::WebInputEvent::Type event_type = event.GetType();
2605 if (event_type == blink::WebInputEvent::Type::kGestureDoubleTap ||
2606 event_type == blink::WebInputEvent::Type::kGesturePinchBegin) {
2607 SmartCallback<EWebViewCallbacks::ZoomStarted>().call();
2609 if (event_type == blink::WebInputEvent::Type::kGestureDoubleTap ||
2610 event_type == blink::WebInputEvent::Type::kGesturePinchEnd) {
2611 SmartCallback<EWebViewCallbacks::ZoomFinished>().call();
2615 bool EWebView::GetHorizontalPanningHold() const {
2618 return rwhva()->offscreen_helper()->GetHorizontalPanningHold();
2621 void EWebView::SetHorizontalPanningHold(bool hold) {
2623 rwhva()->offscreen_helper()->SetHorizontalPanningHold(hold);
2626 bool EWebView::GetVerticalPanningHold() const {
2629 return rwhva()->offscreen_helper()->GetVerticalPanningHold();
2632 void EWebView::SetVerticalPanningHold(bool hold) {
2634 rwhva()->offscreen_helper()->SetVerticalPanningHold(hold);
2637 void EWebView::SendDelayedMessages(RenderViewHost* render_view_host) {
2638 DCHECK(render_view_host);
2640 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
2641 content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
2642 base::BindOnce(&EWebView::SendDelayedMessages, base::Unretained(this),
2647 for (auto iter = delayed_messages_.begin(); iter != delayed_messages_.end();
2649 IPC::Message* message = *iter;
2650 message->set_routing_id(render_view_host->GetRoutingID());
2651 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
2652 render_view_host->Send(message);
2656 delayed_messages_.clear();
2659 void EWebView::ClosePage() {
2660 web_contents_->ClosePage();
2663 bool EWebView::SetMainFrameScrollbarVisible(bool visible) {
2664 if (web_contents_->GetPrimaryMainFrame()->IsRenderFrameLive() && rwhva())
2665 rwhva()->host()->SetMainFrameScrollbarVisible(visible);
2669 bool EWebView::GetMainFrameScrollbarVisible(
2670 Ewk_View_Main_Frame_Scrollbar_Visible_Get_Callback callback,
2675 MainFrameScrollbarVisibleGetCallback* callback_ptr =
2676 new MainFrameScrollbarVisibleGetCallback;
2677 callback_ptr->Set(callback, user_data);
2679 main_frame_scrollbar_visible_callback_map_.Add(callback_ptr);
2680 rwhva()->host()->RequestMainFrameScrollbarVisible(callback_id);
2684 void EWebView::InvokeMainFrameScrollbarVisibleCallback(int callback_id,
2686 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
2687 content::GetUIThreadTaskRunner({})->PostTask(
2689 base::BindOnce(&EWebView::InvokeMainFrameScrollbarVisibleCallback,
2690 base::Unretained(this), visible, callback_id));
2694 MainFrameScrollbarVisibleGetCallback* callback =
2695 main_frame_scrollbar_visible_callback_map_.Lookup(callback_id);
2699 main_frame_scrollbar_visible_callback_map_.Remove(callback_id);
2700 callback->Run(evas_object(), visible);
2701 main_frame_scrollbar_visible_callback_map_.Remove(callback_id);
2704 void EWebView::OnOverscrolled(const gfx::Vector2dF& accumulated_overscroll,
2705 const gfx::Vector2dF& latest_overscroll_delta) {
2706 const gfx::Vector2dF old_overscroll =
2707 accumulated_overscroll - latest_overscroll_delta;
2709 if (latest_overscroll_delta.x() && !old_overscroll.x()) {
2710 latest_overscroll_delta.x() < 0
2711 ? SmartCallback<EWebViewCallbacks::OverscrolledLeft>().call()
2712 : SmartCallback<EWebViewCallbacks::OverscrolledRight>().call();
2714 if (latest_overscroll_delta.y() && !old_overscroll.y()) {
2715 latest_overscroll_delta.y() < 0
2716 ? SmartCallback<EWebViewCallbacks::OverscrolledTop>().call()
2717 : SmartCallback<EWebViewCallbacks::OverscrolledBottom>().call();
2721 void EWebView::SetDidChangeThemeColorCallback(
2722 Ewk_View_Did_Change_Theme_Color_Callback callback,
2724 did_change_theme_color_callback_.Set(callback, user_data);
2727 void EWebView::DidChangeThemeColor(const SkColor& color) {
2728 did_change_theme_color_callback_.Run(evas_object_, color);
2731 #if BUILDFLAG(IS_TIZEN_TV)
2732 void EWebView::DrawLabel(Evas_Object* image, Eina_Rectangle rect) {
2734 rwhva()->offscreen_helper()->DrawLabel(image, rect);
2737 void EWebView::ClearLabels() {
2739 rwhva()->offscreen_helper()->ClearLabels();
2743 void EWebView::RequestManifest(Ewk_View_Request_Manifest_Callback callback,
2745 web_contents_delegate_->RequestManifestInfo(callback, user_data);
2748 void EWebView::DidRespondRequestManifest(
2749 _Ewk_View_Request_Manifest* manifest,
2750 Ewk_View_Request_Manifest_Callback callback,
2752 callback(evas_object_, manifest, user_data);
2755 void EWebView::SetSessionTimeout(uint64_t timeout) {
2756 if (web_contents_->GetPrimaryMainFrame()->IsRenderFrameLive() && rwhva())
2757 rwhva()->host()->SetLongPollingGlobalTimeout(timeout);
2760 void EWebView::SetExceededIndexedDatabaseQuotaCallback(
2761 Ewk_View_Exceeded_Indexed_Database_Quota_Callback callback,
2763 exceeded_indexed_db_quota_callback_.Set(callback, user_data);
2764 content::BrowserContextEfl* browser_context =
2765 static_cast<content::BrowserContextEfl*>(
2766 web_contents_->GetBrowserContext());
2767 if (browser_context) {
2768 browser_context->GetSpecialStoragePolicyEfl()->SetQuotaExceededCallback(
2769 base::BindOnce(&EWebView::InvokeExceededIndexedDatabaseQuotaCallback,
2770 base::Unretained(this)));
2774 void EWebView::InvokeExceededIndexedDatabaseQuotaCallback(
2776 int64_t current_quota) {
2777 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
2778 content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
2779 base::BindOnce(&EWebView::InvokeExceededIndexedDatabaseQuotaCallback,
2780 base::Unretained(this), origin, current_quota));
2783 LOG(INFO) << __func__ << "()" << origin << ", " << current_quota;
2784 CHECK(!exceeded_indexed_db_quota_origin_.get());
2785 exceeded_indexed_db_quota_origin_.reset(new Ewk_Security_Origin(origin));
2786 exceeded_indexed_db_quota_callback_.Run(
2787 evas_object_, exceeded_indexed_db_quota_origin_.get(), current_quota);
2790 void EWebView::ExceededIndexedDatabaseQuotaReply(bool allow) {
2791 if (!exceeded_indexed_db_quota_origin_.get()) {
2792 LOG(WARNING) << __func__ << "() : callback is not invoked!";
2795 LOG(INFO) << __func__ << "()" << exceeded_indexed_db_quota_origin_->GetURL()
2797 content::BrowserContextEfl* browser_context =
2798 static_cast<content::BrowserContextEfl*>(
2799 web_contents_->GetBrowserContext());
2800 if (browser_context) {
2801 browser_context->GetSpecialStoragePolicyEfl()->SetUnlimitedStoragePolicy(
2802 exceeded_indexed_db_quota_origin_->GetURL(), allow);
2804 exceeded_indexed_db_quota_origin_.reset();
2807 bool EWebView::ShouldIgnoreNavigation(
2808 content::NavigationHandle* navigation_handle) {
2809 if (!navigation_handle->GetURL().is_valid() ||
2810 !navigation_handle->GetURL().SchemeIs("appcontrol") ||
2811 (!navigation_handle->HasUserGesture() &&
2812 !navigation_handle->WasServerRedirect())) {
2816 _Ewk_App_Control app_control(
2817 this, navigation_handle->GetURL().possibly_invalid_spec());
2818 return app_control.Proceed();
2821 bool EWebView::SetVisibility(bool enable) {
2826 web_contents_->WasShown();
2828 web_contents_->WasHidden();
2833 #if defined(TIZEN_ATK_SUPPORT)
2834 void EWebView::UpdateSpatialNavigationStatus(Eina_Bool enable) {
2835 if (settings_->getPreferences().spatial_navigation_enabled == enable)
2838 settings_->getPreferences().spatial_navigation_enabled = enable;
2839 WebContentsImpl* wc = static_cast<WebContentsImpl*>(web_contents_.get());
2841 wc->SetSpatialNavigationEnabled(enable);
2844 void EWebView::UpdateAccessibilityStatus(Eina_Bool enable) {
2845 if (settings_->getPreferences().atk_enabled == enable)
2848 settings_->getPreferences().atk_enabled = enable;
2849 WebContentsImpl* wc = static_cast<WebContentsImpl*>(web_contents_.get());
2851 wc->SetAtkEnabled(enable);
2854 void EWebView::InitAtk() {
2855 EWebAccessibilityUtil::GetInstance()->ToggleAtk(lazy_initialize_atk_);
2858 /* LCOV_EXCL_START */
2859 bool EWebView::GetAtkStatus() {
2860 auto state = content::BrowserAccessibilityStateImpl::GetInstance();
2863 return state->IsAccessibleBrowser();
2865 /* LCOV_EXCL_STOP */