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/compositor/compositor_observer_efl.h"
81 #include "ui/display/screen.h"
82 #include "ui/events/event_switches.h"
83 #include "ui/gfx/geometry/dip_util.h"
84 #include "ui/gfx/geometry/vector2d_f.h"
85 #include "ui/ozone/platform/efl/efl_event_handler.h"
86 #include "ui/platform_window/platform_window_init_properties.h"
87 #include "web_contents_delegate_efl.h"
88 #include "web_contents_efl_delegate_ewk.h"
92 #if defined(TIZEN_ATK_SUPPORT)
93 #include "content/browser/accessibility/browser_accessibility_state_impl.h"
94 #include "eweb_accessibility.h"
95 #include "eweb_accessibility_util.h"
98 #if defined(TIZEN_AUTOFILL_FW)
99 #include "browser/autofill/autofill_request_manager.h"
100 #include "components/autofill/core/common/autofill_switches.h"
103 using namespace content;
104 using web_contents_utils::WebViewFromWebContents;
108 const int kTitleLengthMax = 80;
109 const base::FilePath::CharType kMHTMLFileNameExtension[] =
110 FILE_PATH_LITERAL(".mhtml");
111 const base::FilePath::CharType kMHTMLExtension[] = FILE_PATH_LITERAL("mhtml");
112 const base::FilePath::CharType kDefaultFileName[] =
113 FILE_PATH_LITERAL("saved_page");
114 const char kReplaceChars[] = " ";
115 const char kReplaceWith[] = "_";
117 static const char* kRendererCrashedHTMLMessage =
118 "<html><body><h1>Renderer process has crashed!</h1></body></html>";
120 // "visible,content,changed" is an email-app specific signal which informs
121 // that the web view is only partially visible.
122 static const char* kVisibleContentChangedSignalName = "visible,content,changed";
124 // email-app specific signal which informs that custom scrolling is started.
125 const char* kCustomScrollBeginSignalName = "custom,scroll,begin";
127 // email-app specific signal which informs that custom scrolling is finished.
128 const char* kCustomScrollEndSignalName = "custom,scroll,end";
130 const float kDelayShowContextMenuTime = 0.2f;
132 inline void SetDefaultStringIfNull(const char*& variable,
133 const char* default_string) {
135 variable = default_string;
139 void GetEinaRectFromGfxRect(const gfx::Rect& gfx_rect,
140 Eina_Rectangle* eina_rect) {
141 eina_rect->x = gfx_rect.x();
142 eina_rect->y = gfx_rect.y();
143 eina_rect->w = gfx_rect.width();
144 eina_rect->h = gfx_rect.height();
147 #if BUILDFLAG(IS_TIZEN)
148 static Eina_Bool RotateWindowCb(void* data, int type, void* event) {
149 auto wv = static_cast<EWebView*>(data);
151 ecore_evas_rotation_get(ecore_evas_ecore_evas_get(wv->GetEvas())));
152 return ECORE_CALLBACK_PASS_ON;
156 static content::WebContents* NullCreateWebContents(void*) {
160 base::FilePath GenerateMHTMLFilePath(const GURL& url,
161 const std::string& title,
162 const std::string& base_path) {
163 base::FilePath file_path(base_path);
165 if (base::DirectoryExists(file_path)) {
166 std::string title_part(title.substr(0, kTitleLengthMax));
167 base::ReplaceChars(title_part, kReplaceChars, kReplaceWith, &title_part);
168 base::FilePath file_name =
169 net::GenerateFileName(url, std::string(), std::string(), title_part,
170 std::string(), kDefaultFileName);
171 DCHECK(!file_name.empty());
172 file_path = file_path.Append(file_name);
175 if (file_path.Extension().empty())
176 file_path = file_path.AddExtension(kMHTMLExtension);
177 else if (!file_path.MatchesExtension(kMHTMLFileNameExtension))
178 file_path = file_path.ReplaceExtension(kMHTMLExtension);
180 if (!base::PathExists(file_path))
183 int uniquifier = base::GetUniquePathNumber(file_path);
184 if (uniquifier > 0) {
185 return file_path.InsertBeforeExtensionASCII(
186 base::StringPrintf(" (%d)", uniquifier));
189 return base::FilePath();
192 SelectPickerBase* CreateSelectPicker(
195 std::vector<blink::mojom::MenuItemPtr> items,
196 bool is_multiple_selection,
197 const gfx::Rect& bounds) {
198 SelectPickerBase* picker;
201 new SelectPickerTv(web_view, selected_index, is_multiple_selection);
204 new SelectPickerMobile(web_view, selected_index, is_multiple_selection);
206 // Create two separate Elm_Genlist_Item_Class classes, because EFL cannot swap
207 // item_style at runtime.
208 picker->InitializeItemClass();
209 picker->InitializeGroupClass();
210 picker->Init(std::move(items), bounds);
216 class WebViewAsyncRequestHitTestDataCallback {
218 WebViewAsyncRequestHitTestDataCallback(int x, int y, Ewk_Hit_Test_Mode mode)
219 : x_(x), y_(y), mode_(mode) {}
220 virtual ~WebViewAsyncRequestHitTestDataCallback(){};
222 virtual void Run(_Ewk_Hit_Test* hit_test, EWebView* web_view) = 0;
225 int GetX() const { return x_; }
226 int GetY() const { return y_; }
227 Ewk_Hit_Test_Mode GetMode() const { return mode_; }
232 Ewk_Hit_Test_Mode mode_;
235 class WebViewAsyncRequestHitTestDataUserCallback
236 : public WebViewAsyncRequestHitTestDataCallback {
238 WebViewAsyncRequestHitTestDataUserCallback(
241 Ewk_Hit_Test_Mode mode,
242 Ewk_View_Hit_Test_Request_Callback callback,
244 : WebViewAsyncRequestHitTestDataCallback(x, y, mode),
246 user_data_(user_data) {}
248 void Run(_Ewk_Hit_Test* hit_test, EWebView* web_view) override {
250 callback_(web_view->evas_object(), GetX(), GetY(), GetMode(), hit_test,
255 Ewk_View_Hit_Test_Request_Callback callback_;
259 #if defined(TIZEN_ATK_SUPPORT)
260 class EWebAccessibilityObserver : public EWebAccessibility::Observer {
262 explicit EWebAccessibilityObserver(EWebView* webview) : webview_(webview) {}
263 virtual ~EWebAccessibilityObserver() {}
265 // EWebAccessibility::Observer implementation
266 void OnSpatialNavigationStatusChanged(Eina_Bool enable) override {
267 webview_->UpdateSpatialNavigationStatus(enable);
270 void OnAccessibilityStatusChanged(Eina_Bool enable) override {
271 webview_->UpdateAccessibilityStatus(enable);
279 int EWebView::find_request_id_counter_ = 0;
280 content::WebContentsEflDelegate::WebContentsCreateCallback
281 EWebView::create_new_window_web_contents_cb_ =
282 base::BindRepeating(&NullCreateWebContents);
284 EWebView* EWebView::FromEvasObject(Evas_Object* eo) {
285 return WebViewDelegateEwk::GetInstance().GetWebViewFromEvasObject(eo);
288 void EWebView::OnViewFocusIn(void* data, Evas*, Evas_Object*, void*) {
289 auto view = static_cast<EWebView*>(data);
290 view->SetFocus(EINA_TRUE);
293 void EWebView::OnViewFocusOut(void* data, Evas*, Evas_Object*, void*) {
294 auto view = static_cast<EWebView*>(data);
295 view->SetFocus(EINA_FALSE);
298 void EWebView::VisibleContentChangedCallback(void* user_data,
299 Evas_Object* /*object*/,
301 auto view = static_cast<EWebView*>(user_data);
302 auto rect = static_cast<Eina_Rectangle*>(event_info);
303 view->GetSelectionController()->SetCustomVisibleViewRect(
304 gfx::Rect(rect->x, rect->y, rect->w, rect->h));
307 void EWebView::OnCustomScrollBeginCallback(void* user_data,
308 Evas_Object* /*object*/,
309 void* /*event_info*/) {
310 auto* view = static_cast<EWebView*>(user_data);
311 if (auto* selection_controller = view->GetSelectionController())
312 selection_controller->SetControlsTemporarilyHidden(true,true);
315 void EWebView::OnCustomScrollEndCallback(void* user_data,
316 Evas_Object* /*object*/,
317 void* /*event_info*/) {
318 auto* view = static_cast<EWebView*>(user_data);
319 if (auto* selection_controller = view->GetSelectionController())
320 selection_controller->SetControlsTemporarilyHidden(false,true);
323 EWebView::EWebView(Ewk_Context* context, Evas_Object* object)
325 evas_object_(object),
326 native_view_(object),
327 mouse_events_enabled_(false),
328 text_zoom_factor_(1.0),
329 current_find_request_id_(find_request_id_counter_++),
331 hit_test_completion_(base::WaitableEvent::ResetPolicy::AUTOMATIC,
332 base::WaitableEvent::InitialState::NOT_SIGNALED),
333 page_scale_factor_(1.0),
336 is_initialized_(false) {
338 evas_object_smart_callback_add(evas_object_,
339 kVisibleContentChangedSignalName,
340 VisibleContentChangedCallback, this);
342 evas_object_smart_callback_add(evas_object_, kCustomScrollBeginSignalName,
343 OnCustomScrollBeginCallback, this);
344 evas_object_smart_callback_add(evas_object_, kCustomScrollEndSignalName,
345 OnCustomScrollEndCallback, this);
346 evas_object_event_callback_add(evas_object_, EVAS_CALLBACK_FOCUS_IN,
347 OnViewFocusIn, this);
348 evas_object_event_callback_add(evas_object_, EVAS_CALLBACK_FOCUS_OUT,
349 OnViewFocusOut, this);
350 #if BUILDFLAG(IS_TIZEN)
351 window_rotate_handler_ = ecore_event_handler_add(
352 ECORE_WL2_EVENT_WINDOW_ROTATE, RotateWindowCb, this);
357 void EWebView::Initialize() {
358 if (is_initialized_) {
364 evas_event_handler_ = new WebViewEvasEventHandler(this);
366 scroll_detector_.reset(new ScrollDetector(this));
368 DCHECK(web_contents_->GetRenderViewHost());
369 // Settings (content::WebPreferences) will be initalized by
370 // RenderViewHostImpl::ComputeWebkitPrefs() based on command line switches.
371 settings_.reset(new Ewk_Settings(evas_object_,
372 web_contents_->GetOrCreateWebPreferences()));
373 #if defined(TIZEN_ATK_SUPPORT)
374 std::unique_ptr<EWebAccessibilityObserver> observer(
375 new EWebAccessibilityObserver(this));
376 eweb_accessibility_.reset(new EWebAccessibility(
377 evas_object_, web_contents_.get(), std::move(observer)));
378 lazy_initialize_atk_ = true;
381 base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess();
382 if (cmdline->HasSwitch(switches::kTouchEventFeatureDetection)) {
383 SetTouchEventsEnabled(
384 cmdline->GetSwitchValueASCII(switches::kTouchEventFeatureDetection) ==
385 switches::kTouchEventFeatureDetectionEnabled);
387 SetMouseEventsEnabled(true);
390 std::string user_agent =
391 EflWebView::VersionInfo::GetInstance()->DefaultUserAgent();
392 web_contents_->SetUserAgentOverride(
393 blink::UserAgentOverride::UserAgentOnly(user_agent),
394 false /* override_in_new_tabs */);
396 elm_object_tree_focus_allow_set(native_view_, EINA_TRUE);
397 is_initialized_ = true;
398 evas_object_event_callback_add(native_view_, EVAS_CALLBACK_RESIZE,
399 EWebView::NativeViewResize, this);
401 auto cbce = static_cast<ContentBrowserClientEfl*>(
402 content::GetContentClientExport()->browser());
403 // Initialize accept languages
404 SyncAcceptLanguages(cbce->GetAcceptLangs(nullptr));
405 accept_langs_changed_callback_ =
406 base::BindOnce(&EWebView::SyncAcceptLanguages, base::Unretained(this));
407 cbce->AddAcceptLangsChangedCallback(
408 std::move(accept_langs_changed_callback_));
410 // If EWebView is created by window.open, RenderView is already created
411 // before initializing WebContents. So we should manually invoke
412 // EWebView::RenderViewReady here.
413 if (web_contents_->GetPrimaryMainFrame() &&
414 web_contents_->GetPrimaryMainFrame()->IsRenderFrameLive()) {
419 EWebView::~EWebView() {
420 auto cbce = static_cast<ContentBrowserClientEfl*>(
421 content::GetContentClientExport()->browser());
422 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
423 cbce->RemoveAcceptLangsChangedCallback(
424 std::move(accept_langs_changed_callback_));
427 evas_object_event_callback_del(native_view_, EVAS_CALLBACK_RESIZE,
428 EWebView::NativeViewResize);
429 #if defined(USE_WAYLAND)
430 if (GetSettings()->getClipboardEnabled())
431 ClipboardHelperEfl::GetInstance()->MaybeInvalidateActiveWebview(this);
434 std::map<int64_t, WebViewAsyncRequestHitTestDataCallback*>::iterator
435 hit_test_callback_iterator;
436 for (hit_test_callback_iterator = hit_test_callback_.begin();
437 hit_test_callback_iterator != hit_test_callback_.end();
438 hit_test_callback_iterator++)
439 delete hit_test_callback_iterator->second;
440 hit_test_callback_.clear();
442 for (auto iter = delayed_messages_.begin(); iter != delayed_messages_.end();
446 delayed_messages_.clear();
448 if (!is_initialized_) {
452 #if defined(TIZEN_ATK_SUPPORT)
453 eweb_accessibility_.reset();
456 #if defined(TIZEN_AUTOFILL_FW)
457 if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
458 autofill::switches::kDisableAutofill)) {
459 autofill::AutofillRequestManager::GetInstance()->RemoveRequest(
464 select_picker_.reset();
465 context_menu_.reset();
466 mhtml_callback_map_.Clear();
468 compositor_observer_.reset();
470 // Release manually those scoped pointers to
471 // make sure they are released in correct order
472 web_contents_.reset();
473 web_contents_delegate_.reset();
475 // This code must be executed after WebContents deletion
476 // because WebContents depends on BrowserContext which
477 // is deleted along with EwkContext.
478 CHECK(!web_contents_);
480 permission_popup_manager_.reset();
482 gin_native_bridge_dispatcher_host_.reset();
485 evas_object_event_callback_del(evas_object_, EVAS_CALLBACK_FOCUS_IN,
487 evas_object_event_callback_del(evas_object_, EVAS_CALLBACK_FOCUS_OUT,
489 evas_object_smart_callback_del(evas_object_,
490 kVisibleContentChangedSignalName,
491 VisibleContentChangedCallback);
492 evas_object_smart_callback_del(evas_object_, kCustomScrollBeginSignalName,
493 OnCustomScrollBeginCallback);
494 evas_object_smart_callback_del(evas_object_, kCustomScrollEndSignalName,
495 OnCustomScrollEndCallback);
499 content::RenderWidgetHostViewAura* EWebView::rwhva() const {
500 return static_cast<content::RenderWidgetHostViewAura*>(
501 web_contents_->GetRenderWidgetHostView());
504 content::WebContentsViewAura* EWebView::wcva() const {
505 WebContentsImpl* wc = static_cast<WebContentsImpl*>(web_contents_.get());
506 return static_cast<WebContentsViewAura*>(wc->GetView());
509 void EWebView::NativeViewResize(void* data,
513 auto thiz = static_cast<EWebView*>(data);
514 if (!thiz->context_menu_)
516 int native_view_x, native_view_y, native_view_width, native_view_height;
517 evas_object_geometry_get(obj, &native_view_x, &native_view_y,
518 &native_view_width, &native_view_height);
519 gfx::Rect webview_rect(native_view_x, native_view_y, native_view_width,
521 thiz->context_menu_->Resize(webview_rect);
524 void EWebView::ResetContextMenuController() {
525 return context_menu_.reset();
528 void EWebView::SetFocus(Eina_Bool focus) {
529 if (!web_contents_ || !rwhva() || (HasFocus() == focus))
532 rwhva()->offscreen_helper()->Focus(focus);
535 Eina_Bool EWebView::HasFocus() const {
539 return rwhva()->offscreen_helper()->HasFocus() ? EINA_TRUE : EINA_FALSE;
542 Eina_Bool EWebView::AddJavaScriptMessageHandler(
544 Ewk_View_Script_Message_Cb callback,
546 if (!gin_native_bridge_dispatcher_host_)
549 return gin_native_bridge_dispatcher_host_->AddNamedObject(view, callback,
553 bool EWebView::SetPageVisibility(
554 Ewk_Page_Visibility_State page_visibility_state) {
558 // TODO: We should able to set 'prerender' or 'unloaded' as visibility state.
559 // http://www.w3.org/TR/page-visibility/#dom-document-visibilitystate
560 switch (page_visibility_state) {
561 case EWK_PAGE_VISIBILITY_STATE_VISIBLE:
562 rwhva()->offscreen_helper()->SetPageVisibility(true);
564 case EWK_PAGE_VISIBILITY_STATE_HIDDEN:
565 rwhva()->offscreen_helper()->SetPageVisibility(false);
567 case EWK_PAGE_VISIBILITY_STATE_PRERENDER:
577 bool EWebView::CreateNewWindow(
578 content::WebContentsEflDelegate::WebContentsCreateCallback cb) {
579 create_new_window_web_contents_cb_ = cb;
580 Evas_Object* new_object = NULL;
581 SmartCallback<EWebViewCallbacks::CreateNewWindow>().call(&new_object);
582 create_new_window_web_contents_cb_ =
583 base::BindRepeating(&NullCreateWebContents);
588 Evas_Object* EWebView::GetHostWindowDelegate(const content::WebContents* wc) {
589 EWebView* thiz = WebViewFromWebContents(wc);
590 DCHECK(thiz->evas_object_);
591 Evas_Object* parent = evas_object_above_get(thiz->evas_object_);
593 LOG(WARNING) << "Could not find and visual parents for EWK smart object!.";
594 return thiz->evas_object_;
597 if (elm_object_widget_check(parent)) {
598 Evas_Object* elm_parent = elm_object_top_widget_get(parent);
604 LOG(WARNING) << "Could not find elementary parent for WebView object!";
605 return thiz->evas_object_;
608 Evas_Object* EWebView::GetElmWindow() const {
609 Evas_Object* parent = elm_object_parent_widget_get(evas_object_);
610 return parent ? elm_object_top_widget_get(parent) : nullptr;
613 void EWebView::SetURL(const GURL& url, bool from_api) {
614 NavigationController::LoadURLParams params(url);
617 params.transition_type = ui::PageTransitionFromInt(
618 ui::PAGE_TRANSITION_LINK | ui::PAGE_TRANSITION_FROM_API);
621 params.override_user_agent = NavigationController::UA_OVERRIDE_TRUE;
622 web_contents_->GetController().LoadURLWithParams(params);
625 const GURL& EWebView::GetURL() const {
626 return web_contents_->GetVisibleURL();
629 const GURL& EWebView::GetOriginalURL() const {
630 const auto entry = web_contents_->GetController().GetVisibleEntry();
632 return entry->GetOriginalRequestURL();
634 return web_contents_->GetVisibleURL();
637 void EWebView::Reload() {
638 web_contents_->GetController().Reload(content::ReloadType::NORMAL, true);
641 void EWebView::ReloadBypassingCache() {
642 web_contents_->GetController().Reload(content::ReloadType::BYPASSING_CACHE,
646 Eina_Bool EWebView::CanGoBack() {
647 return web_contents_->GetController().CanGoBack();
650 Eina_Bool EWebView::CanGoForward() {
651 return web_contents_->GetController().CanGoForward();
654 Eina_Bool EWebView::GoBack() {
655 if (!web_contents_->GetController().CanGoBack())
658 #if defined(TIZEN_AUTOFILL_FW)
659 if (web_contents_delegate_)
660 web_contents_delegate_->ResetLastInteractedElements();
663 web_contents_->GetController().GoBack();
667 Eina_Bool EWebView::GoForward() {
668 if (!web_contents_->GetController().CanGoForward())
671 web_contents_->GetController().GoForward();
675 void EWebView::Stop() {
676 if (web_contents_->IsLoading())
677 web_contents_->Stop();
680 void EWebView::Suspend() {
681 CHECK(web_contents_);
682 #if BUILDFLAG(IS_TIZEN)
683 if (IsMobileProfile() && web_contents_->IsFullscreen())
684 web_contents_->ExitFullscreen(true);
686 RenderViewHost* rvh = web_contents_->GetRenderViewHost();
687 RenderFrameHost* rfh = web_contents_->GetPrimaryMainFrame();
690 #if !defined(EWK_BRINGUP) // FIXME: m69 bringup
691 rfh->BlockRequestsForFrame();
694 content::GetIOThreadTaskRunner({})->PostTask(FROM_HERE, base::BindOnce(
695 &content::ResourceDispatcherHost::BlockRequestsForFrameFromUI, rfh));
698 rvh->Send(new EwkViewMsg_SuspendScheduledTask(rvh->GetRoutingID()));
702 void EWebView::Resume() {
703 CHECK(web_contents_);
704 RenderViewHost* rvh = web_contents_->GetRenderViewHost();
705 RenderFrameHost* rfh = web_contents_->GetPrimaryMainFrame();
708 #if !defined(EWK_BRINGUP) // FIXME: m69 bringup
709 rfh->ResumeBlockedRequestsForFrame();
712 content::GetIOThreadTaskRunner({})->PostTask(FROM_HERE, base::BindOnce(
713 &content::ResourceDispatcherHost::ResumeBlockedRequestsForFrameFromUI,
717 rvh->Send(new EwkViewMsg_ResumeScheduledTasks(rvh->GetRoutingID()));
721 double EWebView::GetTextZoomFactor() const {
722 if (text_zoom_factor_ < 0.0)
725 return text_zoom_factor_;
728 void EWebView::SetTextZoomFactor(double text_zoom_factor) {
729 if (text_zoom_factor_ == text_zoom_factor || text_zoom_factor < 0.0)
732 text_zoom_factor_ = text_zoom_factor;
733 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
734 if (!render_view_host)
736 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
737 render_view_host->Send(new ViewMsg_SetTextZoomFactor(
738 render_view_host->GetRoutingID(), text_zoom_factor));
742 double EWebView::GetPageZoomFactor() const {
743 return blink::PageZoomLevelToZoomFactor(
744 content::HostZoomMap::GetZoomLevel(web_contents_.get()));
747 void EWebView::SetPageZoomFactor(double page_zoom_factor) {
748 content::HostZoomMap::SetZoomLevel(
749 web_contents_.get(), blink::PageZoomFactorToZoomLevel(page_zoom_factor));
752 void EWebView::ExecuteEditCommand(const char* command, const char* value) {
753 EINA_SAFETY_ON_NULL_RETURN(command);
755 absl::optional<std::u16string> optional_value;
756 if (value == nullptr)
757 optional_value = absl::nullopt;
759 optional_value = absl::make_optional(base::ASCIIToUTF16(value));
761 WebContentsImpl* wc = static_cast<WebContentsImpl*>(web_contents_.get());
763 wc->GetFocusedFrameWidgetInputHandler()->ExecuteEditCommand(
764 std::string(command), optional_value);
768 #if BUILDFLAG(IS_TIZEN)
769 void EWebView::EnterDragState() {
770 if (IsMobileProfile()) {
771 if (RenderViewHost* render_view_host = web_contents_->GetRenderViewHost())
772 web_contents_->EnterDragState(render_view_host);
777 void EWebView::SetOrientation(int orientation) {
778 if (GetOrientation() == orientation)
781 if (orientation == 0 || orientation == 90 || orientation == 180 ||
782 orientation == 270) {
783 #if !defined(USE_AURA)
784 GetWebContentsViewEfl()->SetOrientation(orientation);
788 const Ecore_Evas* ee =
789 ecore_evas_ecore_evas_get(evas_object_evas_get(evas_object_));
790 ecore_evas_screen_geometry_get(ee, nullptr, nullptr, &width, &height);
791 if (orientation == 90 || orientation == 270)
792 std::swap(width, height);
794 if (popup_controller_)
795 popup_controller_->SetPopupSize(width, height);
796 if (JavaScriptDialogManagerEfl* dialogMG = GetJavaScriptDialogManagerEfl())
797 dialogMG->SetPopupSize(width, height);
801 int EWebView::GetOrientation() {
802 #if !defined(USE_AURA)
803 return GetWebContentsViewEfl()->GetOrientation();
809 void EWebView::Show() {
810 evas_object_show(native_view_);
811 web_contents_->WasShown();
814 void EWebView::Hide() {
815 evas_object_hide(native_view_);
816 web_contents_->WasHidden();
819 void EWebView::SetViewAuthCallback(Ewk_View_Authentication_Callback callback,
821 authentication_cb_.Set(callback, user_data);
824 void EWebView::InvokeAuthCallback(LoginDelegateEfl* login_delegate,
826 const std::string& realm) {
827 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
829 auth_challenge_.reset(new _Ewk_Auth_Challenge(login_delegate, url, realm));
830 authentication_cb_.Run(evas_object_, auth_challenge_.get());
832 if (!auth_challenge_->is_decided && !auth_challenge_->is_suspended) {
833 auth_challenge_->is_decided = true;
834 auth_challenge_->login_delegate->Cancel();
838 void EWebView::InvokePolicyResponseCallback(
839 _Ewk_Policy_Decision* policy_decision,
841 SmartCallback<EWebViewCallbacks::PolicyResponseDecide>().call(
844 if (policy_decision->isSuspended()) {
849 if (!policy_decision->isDecided())
850 policy_decision->Use();
852 policy_decision->SelfDeleteIfNecessary();
855 void EWebView::InvokePolicyNavigationCallback(
856 const NavigationPolicyParams& params,
858 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
860 SmartCallback<EWebViewCallbacks::SaveSessionData>().call();
862 std::unique_ptr<_Ewk_Policy_Decision> policy_decision(
863 new _Ewk_Policy_Decision(params));
865 SmartCallback<EWebViewCallbacks::NavigationPolicyDecision>().call(
866 policy_decision.get());
868 CHECK(!policy_decision->isSuspended());
870 // TODO: Navigation can't be suspended
871 // this aproach is synchronous and requires immediate response
872 // Maybe there is different approach (like resource throttle response
873 // mechanism) that allows us to
874 // suspend navigation
875 if (!policy_decision->isDecided())
876 policy_decision->Use();
878 *handled = policy_decision->GetNavigationPolicyHandler()->GetDecision() ==
879 NavigationPolicyHandlerEfl::Handled;
882 void EWebView::HandleTouchEvents(Ewk_Touch_Event_Type type,
883 const Eina_List* points,
884 const Evas_Modifier* modifiers) {
888 if (GetSettings()->touchFocusEnabled() &&
889 (type == EWK_TOUCH_START && eina_list_count(points) == 1)) {
893 EINA_LIST_FOREACH(points, l, data) {
894 const Ewk_Touch_Point* point = static_cast<Ewk_Touch_Point*>(data);
895 if (point->state == EVAS_TOUCH_POINT_STILL) {
896 // Chromium doesn't expect (and doesn't like) these events.
905 evas_object_geometry_get(evas_object(), nullptr, &delta_y, nullptr,
907 ui::TouchEvent touch_event =
908 ui::MakeTouchEvent(pt, point->state, point->id, 0, delta_y);
909 rwhva()->OnTouchEvent(&touch_event);
914 bool EWebView::TouchEventsEnabled() const {
915 return rwhva()->offscreen_helper()->TouchEventsEnabled();
918 // TODO: Touch events use the same mouse events in EFL API.
919 // Figure out how to distinguish touch and mouse events on touch&mice devices.
920 // Currently mouse and touch support is mutually exclusive.
921 void EWebView::SetTouchEventsEnabled(bool enabled) {
922 if (!rwhva() || !rwhva()->offscreen_helper()) {
923 LOG(WARNING) << "RWHV is not created yet!";
927 if (rwhva()->offscreen_helper()->TouchEventsEnabled() == enabled)
930 rwhva()->offscreen_helper()->SetTouchEventsEnabled(enabled);
932 GetSettings()->getPreferences().touch_event_feature_detection_enabled =
934 GetSettings()->getPreferences().double_tap_to_zoom_enabled = enabled;
935 GetSettings()->getPreferences().editing_behavior =
936 enabled ? blink::mojom::EditingBehavior::kEditingAndroidBehavior
937 : blink::mojom::EditingBehavior::kEditingUnixBehavior,
938 UpdateWebKitPreferences();
941 bool EWebView::MouseEventsEnabled() const {
942 return mouse_events_enabled_;
945 void EWebView::SetMouseEventsEnabled(bool enabled) {
946 if (!rwhva() || !rwhva()->offscreen_helper()) {
947 LOG(WARNING) << "RWHV is not created yet!";
951 if (mouse_events_enabled_ == enabled)
954 mouse_events_enabled_ = enabled;
955 rwhva()->offscreen_helper()->SetTouchEventsEnabled(!enabled);
960 class JavaScriptCallbackDetails {
962 JavaScriptCallbackDetails(Ewk_View_Script_Execute_Callback callback_func,
965 : callback_func_(callback_func), user_data_(user_data), view_(view) {}
967 Ewk_View_Script_Execute_Callback callback_func_;
972 void JavaScriptComplete(JavaScriptCallbackDetails* script_callback_data,
973 base::Value result) {
974 if (!script_callback_data->callback_func_)
977 std::string return_string;
978 if (result.is_string()) {
979 // We don't want to serialize strings with JSONStringValueSerializer
980 // to avoid quotation marks.
981 return_string = result.GetString();
982 } else if (result.is_none()) {
983 // Value::TYPE_NULL is for lack of value, undefined, null
986 JSONStringValueSerializer serializer(&return_string);
987 serializer.Serialize(result);
990 script_callback_data->callback_func_(script_callback_data->view_,
991 return_string.c_str(),
992 script_callback_data->user_data_);
997 bool EWebView::ExecuteJavaScript(const char* script,
998 Ewk_View_Script_Execute_Callback callback,
1000 LOG(INFO) << __FUNCTION__;
1001 if (!web_contents_) {
1002 LOG(ERROR) << __FUNCTION__ << "web_contents_ is null";
1006 RenderFrameHost* render_frame_host = web_contents_->GetPrimaryMainFrame();
1007 if (!render_frame_host) {
1008 LOG(ERROR) << __FUNCTION__ << " render_frame_host is null";
1012 // Note: M37. Execute JavaScript, |script| with
1013 // |RenderFrameHost::ExecuteJavaScript|.
1014 // @see also https://codereview.chromium.org/188893005 for more details.
1015 std::u16string js_script;
1016 base::UTF8ToUTF16(script, strlen(script), &js_script);
1018 JavaScriptCallbackDetails* script_callback_data =
1019 new JavaScriptCallbackDetails(callback, userdata, evas_object_);
1020 RenderFrameHost::JavaScriptResultCallback js_callback =
1021 base::BindOnce(&JavaScriptComplete, base::Owned(script_callback_data));
1022 // In M47, it isn't possible anymore to execute javascript in the generic
1023 // case. We need to call ExecuteJavaScriptForTests to keep the behaviour
1024 // unchanged @see https://codereview.chromium.org/1123783002
1025 render_frame_host->ExecuteJavaScriptWithUserGestureForTests(
1026 js_script, std::move(js_callback));
1028 // We use ExecuteJavaScriptWithUserGestureForTests instead of
1029 // ExecuteJavaScript because
1030 // ExecuteJavaScriptWithUserGestureForTests sets user_gesture to true. This
1032 // behaviour is m34, and we want to keep it that way.
1033 render_frame_host->ExecuteJavaScriptWithUserGestureForTests(
1034 js_script, base::NullCallback());
1040 bool EWebView::SetUserAgent(const char* userAgent) {
1041 content::NavigationController& controller = web_contents_->GetController();
1042 bool override = userAgent && strlen(userAgent);
1043 for (int i = 0; i < controller.GetEntryCount(); ++i)
1044 controller.GetEntryAtIndex(i)->SetIsOverridingUserAgent(override);
1045 // TODO: Check if override_in_new_tabs has to be true.
1046 web_contents_->SetUserAgentOverride(
1047 blink::UserAgentOverride::UserAgentOnly(userAgent),
1048 false /* override_in_new_tabs */);
1052 bool EWebView::SetUserAgentAppName(const char* application_name) {
1053 EflWebView::VersionInfo::GetInstance()->UpdateUserAgentWithAppName(
1054 application_name ? application_name : "");
1055 std::string user_agent =
1056 EflWebView::VersionInfo::GetInstance()->DefaultUserAgent();
1057 web_contents_->SetUserAgentOverride(
1058 blink::UserAgentOverride::UserAgentOnly(user_agent),
1059 false /* override_in_new_tabs */);
1063 #if BUILDFLAG(IS_TIZEN)
1064 bool EWebView::SetPrivateBrowsing(bool incognito) {
1065 if (context_->GetImpl()->browser_context()->IsOffTheRecord() == incognito)
1067 context_->GetImpl()->browser_context()->SetOffTheRecord(incognito);
1071 bool EWebView::GetPrivateBrowsing() const {
1072 return context_->GetImpl()->browser_context()->IsOffTheRecord();
1076 const char* EWebView::GetUserAgent() const {
1077 std::string user_agent =
1078 web_contents_->GetUserAgentOverride().ua_string_override;
1079 if (user_agent.empty())
1080 user_agent_ = content::GetContentClientExport()->browser()->GetUserAgent();
1082 user_agent_ = user_agent;
1084 return user_agent_.c_str();
1087 const char* EWebView::GetUserAgentAppName() const {
1088 user_agent_app_name_ = EflWebView::VersionInfo::GetInstance()->AppName();
1089 return user_agent_app_name_.c_str();
1092 const char* EWebView::CacheSelectedText() {
1096 selected_text_cached_ = base::UTF16ToUTF8(rwhva()->GetSelectedText());
1097 return selected_text_cached_.c_str();
1100 _Ewk_Frame* EWebView::GetMainFrame() {
1101 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1104 frame_.reset(new _Ewk_Frame(web_contents_->GetPrimaryMainFrame()));
1106 return frame_.get();
1109 void EWebView::UpdateWebKitPreferences() {
1110 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1112 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1113 if (!render_view_host)
1116 web_contents_delegate_->OnUpdateSettings(settings_.get());
1117 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
1118 render_view_host->UpdateWebkitPreferences(settings_->getPreferences());
1120 UpdateWebkitPreferencesEfl(render_view_host);
1123 void EWebView::UpdateWebkitPreferencesEfl(RenderViewHost* render_view_host) {
1124 DCHECK(render_view_host);
1125 #if !defined(EWK_BRINGUP) // FIXME: m108 bringup
1126 IPC::Message* message = new EwkSettingsMsg_UpdateWebKitPreferencesEfl(
1127 render_view_host->GetRoutingID(), settings_->getPreferencesEfl());
1129 if (render_view_host->IsRenderViewLive()) {
1130 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
1131 render_view_host->Send(message);
1134 delayed_messages_.push_back(message);
1139 void EWebView::SetContentSecurityPolicy(const char* policy,
1140 Ewk_CSP_Header_Type type) {
1141 web_contents_delegate_->SetContentSecurityPolicy(
1142 (policy ? policy : std::string()), type);
1145 void EWebView::LoadHTMLString(const char* html,
1146 const char* base_uri,
1147 const char* unreachable_uri) {
1148 LoadData(html, std::string::npos, NULL, NULL, base_uri, unreachable_uri);
1151 void EWebView::LoadPlainTextString(const char* plain_text) {
1152 LoadData(plain_text, std::string::npos, "text/plain", NULL, NULL, NULL);
1155 void EWebView::LoadData(const char* data,
1157 const char* mime_type,
1158 const char* encoding,
1159 const char* base_uri,
1160 const char* unreachable_uri) {
1161 SetDefaultStringIfNull(mime_type, "text/html");
1162 SetDefaultStringIfNull(encoding, "utf-8");
1163 SetDefaultStringIfNull(base_uri, "about:blank"); // Webkit2 compatible
1164 SetDefaultStringIfNull(unreachable_uri, "");
1166 std::string str_data = data;
1168 if (size < str_data.length())
1169 str_data = str_data.substr(0, size);
1171 std::string url_str("data:");
1172 url_str.append(mime_type);
1173 url_str.append(";charset=");
1174 url_str.append(encoding);
1175 url_str.append(",");
1177 // GURL constructor performs canonicalization of url string, but this is not
1178 // enough for correctly escaping contents of "data:" url.
1179 url_str.append(base::EscapeUrlEncodedData(str_data, false));
1181 NavigationController::LoadURLParams data_params(GURL(url_str.c_str()));
1183 data_params.base_url_for_data_url = GURL(base_uri);
1184 data_params.virtual_url_for_data_url = GURL(unreachable_uri);
1186 data_params.load_type = NavigationController::LOAD_TYPE_DATA;
1187 data_params.should_replace_current_entry = false;
1188 data_params.override_user_agent = NavigationController::UA_OVERRIDE_TRUE;
1189 web_contents_->GetController().LoadURLWithParams(data_params);
1192 void EWebView::InvokeLoadError(const GURL& url,
1194 bool is_cancellation) {
1195 _Ewk_Error err(error_code, is_cancellation,
1196 url.possibly_invalid_spec().c_str());
1198 SmartCallback<EWebViewCallbacks::LoadError>().call(&err);
1201 void EWebView::SetViewLoadErrorPageCallback(
1202 Ewk_View_Error_Page_Load_Callback callback,
1204 load_error_page_cb_.Set(callback, user_data);
1207 // Remove below code while ewk_error_cancellation_get has been implemented.
1208 const char* EWebView::InvokeViewLoadErrorPageCallback(
1211 const std::string& error_description) {
1212 std::unique_ptr<_Ewk_Error> err(
1213 new _Ewk_Error(error_code, url.possibly_invalid_spec().c_str(),
1214 error_description.c_str()));
1215 _Ewk_Error_Page error_page;
1217 LOG(INFO) << "EWebView::InvokeLoadErrorPageCallback url: "
1218 << url.spec().c_str() << ", error_code: " << error_code;
1220 load_error_page_cb_.Run(evas_object_, err.get(), &error_page);
1221 return error_page.content;
1224 bool EWebView::IsLoadErrorPageCallbackSet() const {
1225 return load_error_page_cb_.IsCallbackSet();
1227 void EWebView::HandlePopupMenu(std::vector<blink::mojom::MenuItemPtr> items,
1230 const gfx::Rect& bounds) {
1231 if (!select_picker_) {
1232 select_picker_.reset(CreateSelectPicker(
1233 this, selectedIndex, std::move(items), multiple, bounds));
1235 // Picker has been shown on top of webview and the page content gets
1236 // partially overlapped. Decrease viewport while showing picker.
1237 AdjustViewPortHeightToPopupMenu(true /* is_popup_menu_visible */);
1238 #if BUILDFLAG(IS_TIZEN_TV)
1239 SmartCallback<EWebViewCallbacks::PopupMenuShow>().call();
1242 select_picker_->UpdatePickerData(selectedIndex, std::move(items), multiple);
1245 select_picker_->Show();
1248 void EWebView::HidePopupMenu() {
1249 if (!select_picker_)
1252 AdjustViewPortHeightToPopupMenu(false /* is_popup_menu_visible */);
1253 #if BUILDFLAG(IS_TIZEN_TV)
1254 SmartCallback<EWebViewCallbacks::PopupMenuHide>().call();
1256 select_picker_.reset();
1259 void EWebView::DidSelectPopupMenuItems(std::vector<int>& indices) {
1260 wcva()->wcva_helper()->DidSelectPopupMenuItems(indices);
1263 void EWebView::DidCancelPopupMenu() {
1264 wcva()->wcva_helper()->DidCancelPopupMenu();
1267 void EWebView::HandleLongPressGesture(
1268 const content::ContextMenuParams& params) {
1269 // This menu is created in renderer process and it does not now anything about
1270 // view scaling factor and it has another calling sequence, so coordinates is
1272 if (settings_ && !settings_->getPreferences().long_press_enabled)
1275 content::ContextMenuParams convertedParams = params;
1276 gfx::Point convertedPoint =
1277 rwhva()->offscreen_helper()->ConvertPointInViewPix(
1278 gfx::Point(params.x, params.y));
1279 convertedParams.x = convertedPoint.x();
1280 convertedParams.y = convertedPoint.y();
1283 evas_object_geometry_get(evas_object(), &x, &y, 0, 0);
1284 convertedParams.x += x;
1285 convertedParams.y += y;
1287 if (GetSelectionController() && GetSelectionController()->GetLongPressed()) {
1288 bool show_context_menu_now =
1289 !GetSelectionController()->HandleLongPressEvent(convertedPoint,
1291 if (show_context_menu_now)
1292 ShowContextMenuInternal(convertedParams);
1296 void EWebView::ShowContextMenu(const content::ContextMenuParams& params) {
1300 // This menu is created in renderer process and it does not now anything about
1301 // view scaling factor and it has another calling sequence, so coordinates is
1303 content::ContextMenuParams convertedParams = params;
1304 gfx::Point convertedPoint =
1305 rwhva()->offscreen_helper()->ConvertPointInViewPix(
1306 gfx::Point(params.x, params.y));
1307 convertedParams.x = convertedPoint.x();
1308 convertedParams.y = convertedPoint.y();
1311 evas_object_geometry_get(evas_object(), &x, &y, 0, 0);
1312 convertedParams.x += x;
1313 convertedParams.y += y;
1315 context_menu_position_ = gfx::Point(convertedParams.x, convertedParams.y);
1317 ShowContextMenuInternal(convertedParams);
1320 void EWebView::ShowContextMenuInternal(
1321 const content::ContextMenuParams& params) {
1322 // We don't want to show 'cut' or 'copy' for inputs of type 'password' in
1323 // selection context menu, but params.input_field_type might not be set
1324 // correctly, because in some cases params is received from SelectionBoxEfl,
1325 // not from FrameHostMsg_ContextMenu message. In SelectionBoxEfl
1326 // ContextMenuParams is constructed on our side with limited information and
1327 // input_field_type is not set.
1329 // To work around this, we query for input type and set it separately. In
1330 // response to EwkViewMsg_QueryInputType we run ::UpdateContextMenu with
1331 // information about input's type.
1333 // FIXME: the way we get ContextMenuParams for context menu is flawed in some
1334 // cases. This should be fixed by restructuring context menu code.
1335 // Context menu creation should be unified to always have
1336 // ContextMenuParams received from FrameHostMsg_ContextMenu.
1337 // Tracked at: http://suprem.sec.samsung.net/jira/browse/TWF-1640
1338 if (params.is_editable) {
1339 saved_context_menu_params_ = params;
1341 rwhva()->host()->QueryInputType();
1343 UpdateContextMenuWithParams(params);
1347 void EWebView::UpdateContextMenu(bool is_password_input) {
1348 if (is_password_input) {
1349 saved_context_menu_params_.input_field_type =
1350 blink::mojom::ContextMenuDataInputFieldType::kPassword;
1352 UpdateContextMenuWithParams(saved_context_menu_params_);
1355 void EWebView::UpdateContextMenuWithParams(
1356 const content::ContextMenuParams& params) {
1357 context_menu_.reset(
1358 new content::ContextMenuControllerEfl(this, *web_contents_.get()));
1360 if (IsMobileProfile()) {
1361 if (delayed_show_context_menu_timer_) {
1362 ecore_timer_del(delayed_show_context_menu_timer_);
1363 delayed_show_context_menu_timer_ = nullptr;
1365 saved_context_menu_params_ = params;
1366 delayed_show_context_menu_timer_ = ecore_timer_add(
1367 kDelayShowContextMenuTime, DelayedPopulateAndShowContextMenu, this);
1369 if (!context_menu_->PopulateAndShowContextMenu(params)) {
1370 context_menu_.reset();
1371 if (GetSelectionController())
1372 GetSelectionController()->HideHandles();
1377 Eina_Bool EWebView::DelayedPopulateAndShowContextMenu(void* data) {
1378 if (IsMobileProfile) {
1379 EWebView* view = static_cast<EWebView*>(data);
1381 if (view->context_menu_ &&
1382 !(view->context_menu_->PopulateAndShowContextMenu(
1383 view->saved_context_menu_params_))) {
1384 view->context_menu_.reset();
1386 view->delayed_show_context_menu_timer_ = nullptr;
1389 return ECORE_CALLBACK_CANCEL;
1392 void EWebView::CancelContextMenu(int request_id) {
1394 context_menu_->HideContextMenu();
1397 void EWebView::Find(const char* text, Ewk_Find_Options ewk_find_options) {
1398 std::u16string find_text = base::UTF8ToUTF16(text);
1399 bool find_next = (previous_text_ == find_text);
1402 current_find_request_id_ = find_request_id_counter_++;
1403 previous_text_ = find_text;
1406 auto find_options = blink::mojom::FindOptions::New();
1407 find_options->forward = !(ewk_find_options & EWK_FIND_OPTIONS_BACKWARDS);
1408 find_options->match_case =
1409 !(ewk_find_options & EWK_FIND_OPTIONS_CASE_INSENSITIVE);
1411 web_contents_->Find(current_find_request_id_, find_text,
1412 std::move(find_options));
1415 void EWebView::SetScale(double scale_factor) {
1416 // Do not cache |scale_factor| here as it may be discarded by Blink's
1417 // minimumPageScaleFactor and maximumPageScaleFactor.
1418 // |scale_factor| is cached as responde to DidChangePageScaleFactor.
1419 WebContentsImpl* wci = static_cast<WebContentsImpl*>(web_contents_.get());
1420 wci->GetPrimaryMainFrame()->GetAssociatedLocalMainFrame()->SetScaleFactor(
1424 void EWebView::ScrollFocusedNodeIntoView() {
1425 if (RenderViewHost* render_view_host = web_contents_->GetRenderViewHost()) {
1426 if (auto& broadcast = static_cast<RenderViewHostImpl*>(render_view_host)
1427 ->GetAssociatedPageBroadcast())
1428 broadcast->ScrollFocusedNodeIntoView();
1432 void EWebView::AdjustViewPortHeightToPopupMenu(bool is_popup_menu_visible) {
1433 if (!rwhva() || !IsMobileProfile() ||
1434 settings_->getPreferences().TizenCompatibilityModeEnabled()) {
1438 int picker_height = select_picker_->GetGeometryDIP().height();
1439 gfx::Rect screen_rect =
1440 display::Screen::GetScreen()->GetPrimaryDisplay().bounds();
1441 gfx::Rect view_rect = rwhva()->offscreen_helper()->GetViewBounds();
1443 screen_rect.height() - (view_rect.y() + view_rect.height());
1445 rwhva()->offscreen_helper()->SetCustomViewportSize(
1446 is_popup_menu_visible
1447 ? gfx::Size(view_rect.width(),
1448 view_rect.height() - picker_height + bottom_height)
1452 void EWebView::SetScaleChangedCallback(Ewk_View_Scale_Changed_Callback callback,
1454 scale_changed_cb_.Set(callback, user_data);
1457 bool EWebView::GetScrollPosition(int* x, int* y) const {
1459 LOG(ERROR) << "rwhva() returns nullptr";
1462 if (scroll_detector_->IsScrollOffsetChanged()) {
1464 *x = previous_scroll_position_.x();
1466 *y = previous_scroll_position_.y();
1468 const gfx::Vector2d scroll_position_dip =
1469 scroll_detector_->GetLastScrollPosition();
1470 const float device_scale_factor = display::Screen::GetScreen()
1471 ->GetPrimaryDisplay()
1472 .device_scale_factor();
1474 *x = base::ClampRound((scroll_position_dip.x() - x_delta_) *
1475 device_scale_factor);
1478 *y = base::ClampRound((scroll_position_dip.y() - y_delta_) *
1479 device_scale_factor);
1485 void EWebView::ChangeScroll(int& x, int& y) {
1487 LOG(ERROR) << "rwhva() returns nullptr";
1492 GetScrollSize(&max_x, &max_y);
1493 previous_scroll_position_.set_x(std::min(std::max(x, 0), max_x));
1494 previous_scroll_position_.set_y(std::min(std::max(y, 0), max_y));
1496 const float device_scale_factor = display::Screen::GetScreen()
1497 ->GetPrimaryDisplay()
1498 .device_scale_factor();
1502 x = base::ClampCeil(x / device_scale_factor);
1503 y = base::ClampCeil(y / device_scale_factor);
1505 x_delta_ = x - (x_input / device_scale_factor);
1506 y_delta_ = y - (y_input / device_scale_factor);
1508 scroll_detector_->SetScrollOffsetChanged();
1511 void EWebView::SetScroll(int x, int y) {
1512 if (auto* render_view_host = web_contents_->GetRenderViewHost()) {
1513 if (auto& broadcast = static_cast<RenderViewHostImpl*>(render_view_host)
1514 ->GetAssociatedPageBroadcast()) {
1516 broadcast->SetScrollOffset(x, y);
1521 void EWebView::UseSettingsFont() {
1522 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
1523 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1524 if (render_view_host)
1525 render_view_host->Send(
1526 new EwkViewMsg_UseSettingsFont(render_view_host->GetRoutingID()));
1530 void EWebView::DidChangeContentsSize(int width, int height) {
1531 contents_size_ = gfx::Size(width, height);
1532 SmartCallback<EWebViewCallbacks::ContentsSizeChanged>().call();
1533 SetScaledContentsSize();
1536 const Eina_Rectangle EWebView::GetContentsSize() const {
1537 Eina_Rectangle rect;
1538 EINA_RECTANGLE_SET(&rect, 0, 0, contents_size_.width(),
1539 contents_size_.height());
1543 void EWebView::SetScaledContentsSize() {
1545 return; // LCOV_EXCL_LINE
1547 const float device_scale_factor =
1548 display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
1549 gfx::SizeF scaled_contents_size = gfx::ConvertSizeToPixels(
1550 contents_size_, device_scale_factor * page_scale_factor_);
1551 rwhva()->offscreen_helper()->SetScaledContentSize(scaled_contents_size);
1554 void EWebView::GetScrollSize(int* width, int* height) {
1557 *width = (rwhva() &&
1558 (w = rwhva()->offscreen_helper()->GetScrollableSize().width()))
1563 *height = (rwhva() &&
1564 (h = rwhva()->offscreen_helper()->GetScrollableSize().height()))
1570 void EWebView::MoveCaret(const gfx::Point& point) {
1572 rwhva()->offscreen_helper()->MoveCaret(point);
1575 SelectionControllerEfl* EWebView::GetSelectionController() const {
1576 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1577 RenderWidgetHostViewAura* view = static_cast<RenderWidgetHostViewAura*>(
1578 render_view_host->GetWidget()->GetView());
1579 return view ? view->offscreen_helper()->GetSelectionController() : 0;
1582 void EWebView::SelectFocusedLink() {
1583 rwhva()->host()->SelectFocusedLink();
1586 bool EWebView::GetSelectionRange(Eina_Rectangle* left_rect,
1587 Eina_Rectangle* right_rect) {
1588 if (left_rect && right_rect) {
1589 gfx::Rect left, right;
1590 if (GetSelectionController()) {
1591 GetSelectionController()->GetSelectionBounds(&left, &right);
1592 GetEinaRectFromGfxRect(left, left_rect);
1593 GetEinaRectFromGfxRect(right, right_rect);
1600 void EWebView::OnSelectionRectReceived(const gfx::Rect& selection_rect) const {
1602 context_menu_->OnSelectionRectReceived(selection_rect);
1605 Eina_Bool EWebView::ClearSelection() {
1609 ResetContextMenuController();
1610 rwhva()->offscreen_helper()->SelectionChanged(std::u16string(), 0,
1613 if (GetSelectionController())
1614 return GetSelectionController()->ClearSelectionViaEWebView();
1619 _Ewk_Hit_Test* EWebView::RequestHitTestDataAt(int x,
1621 Ewk_Hit_Test_Mode mode) {
1622 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1625 EvasToBlinkCords(x, y, &view_x, &view_y);
1627 return RequestHitTestDataAtBlinkCoords(view_x, view_y, mode);
1630 Eina_Bool EWebView::AsyncRequestHitTestDataAt(
1633 Ewk_Hit_Test_Mode mode,
1634 Ewk_View_Hit_Test_Request_Callback callback,
1637 EvasToBlinkCords(x, y, &view_x, &view_y);
1638 return AsyncRequestHitTestDataAtBlinkCords(
1639 view_x, view_y, mode,
1640 new WebViewAsyncRequestHitTestDataUserCallback(x, y, mode, callback,
1644 Eina_Bool EWebView::AsyncRequestHitTestDataAtBlinkCords(
1647 Ewk_Hit_Test_Mode mode,
1648 Ewk_View_Hit_Test_Request_Callback callback,
1650 return AsyncRequestHitTestDataAtBlinkCords(
1652 new WebViewAsyncRequestHitTestDataUserCallback(x, y, mode, callback,
1656 Eina_Bool EWebView::AsyncRequestHitTestDataAtBlinkCords(
1659 Ewk_Hit_Test_Mode mode,
1660 WebViewAsyncRequestHitTestDataCallback* cb) {
1661 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1664 static int64_t request_id = 1;
1667 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1668 DCHECK(render_view_host);
1670 if (render_view_host) {
1671 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
1672 render_view_host->Send(new EwkViewMsg_DoHitTestAsync(
1673 render_view_host->GetRoutingID(), x, y, mode, request_id));
1675 hit_test_callback_[request_id] = cb;
1681 // if failed we delete callback as it is not needed anymore
1686 void EWebView::DispatchAsyncHitTestData(const Hit_Test_Params& params,
1687 int64_t request_id) {
1688 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1690 std::map<int64_t, WebViewAsyncRequestHitTestDataCallback*>::iterator it =
1691 hit_test_callback_.find(request_id);
1693 if (it == hit_test_callback_.end())
1695 std::unique_ptr<_Ewk_Hit_Test> hit_test(new _Ewk_Hit_Test(params));
1697 it->second->Run(hit_test.get(), this);
1699 hit_test_callback_.erase(it);
1702 _Ewk_Hit_Test* EWebView::RequestHitTestDataAtBlinkCoords(
1705 Ewk_Hit_Test_Mode mode) {
1706 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1708 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1710 if (render_view_host) {
1711 // We wait on UI thread till hit test data is updated.
1712 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
1713 render_view_host->Send(
1714 new EwkViewMsg_DoHitTest(render_view_host->GetRoutingID(), x, y, mode));
1716 hit_test_completion_.Wait();
1717 return new _Ewk_Hit_Test(hit_test_params_);
1723 void EWebView::EvasToBlinkCords(int x, int y, int* view_x, int* view_y) {
1724 DCHECK(display::Screen::GetScreen());
1728 gfx::Rect view_bounds = rwhva()->offscreen_helper()->GetViewBoundsInPix();
1731 *view_x = x - view_bounds.x();
1733 display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
1737 *view_y = y - view_bounds.y();
1739 display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
1743 void EWebView::UpdateHitTestData(const Hit_Test_Params& params) {
1744 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
1745 hit_test_params_ = params;
1746 hit_test_completion_.Signal();
1749 void EWebView::OnCopyFromBackingStore(bool success, const SkBitmap& bitmap) {}
1751 void EWebView::OnFocusIn() {
1752 SmartCallback<EWebViewCallbacks::FocusIn>().call();
1753 #if defined(USE_WAYLAND)
1754 if (!rwhva() || !rwhva()->offscreen_helper())
1756 if (GetSettings()->getClipboardEnabled()) {
1757 ClipboardHelperEfl::GetInstance()->OnWebviewFocusIn(
1758 this, rwhva()->offscreen_helper()->content_image_elm_host(),
1759 rwhva()->offscreen_helper()->IsFocusedNodeContentEditable(),
1760 base::BindRepeating(&EWebView::ExecuteEditCommand,
1761 base::Unretained(this)));
1766 void EWebView::OnFocusOut() {
1767 SmartCallback<EWebViewCallbacks::FocusOut>().call();
1768 #if defined(USE_WAYLAND)
1769 if (GetSettings()->getClipboardEnabled())
1770 ClipboardHelperEfl::GetInstance()->MaybeInvalidateActiveWebview(this);
1774 void EWebView::RenderViewReady() {
1776 rwhva()->offscreen_helper()->SetFocusInOutCallbacks(
1777 base::BindRepeating(&EWebView::OnFocusIn, base::Unretained(this)),
1778 base::BindRepeating(&EWebView::OnFocusOut, base::Unretained(this)));
1781 #if defined(TIZEN_VIDEO_HOLE)
1782 if (rwhva() && pending_video_hole_setting_) {
1783 rwhva()->host()->SetVideoHoleForRender(pending_video_hole_setting_);
1784 pending_video_hole_setting_ = false;
1788 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1790 SendDelayedMessages(render_view_host);
1791 UpdateWebkitPreferencesEfl(render_view_host);
1793 if (render_view_host) {
1794 WebContents* content = WebContents::FromRenderViewHost(render_view_host);
1796 RenderProcessHost* host = render_view_host->GetProcess();
1798 host->AddFilter(new WebViewBrowserMessageFilter(content));
1803 void EWebView::SetQuotaPermissionRequestCallback(
1804 Ewk_Quota_Permission_Request_Callback callback,
1806 quota_request_callback_.Set(callback, user_data);
1809 void EWebView::InvokeQuotaPermissionRequest(
1810 _Ewk_Quota_Permission_Request* request,
1811 content::QuotaPermissionContext::PermissionCallback cb) {
1812 quota_permission_request_map_[request] = std::move(cb);
1813 request->setView(evas_object());
1814 if (quota_request_callback_.IsCallbackSet())
1815 quota_request_callback_.Run(evas_object(), request);
1817 QuotaRequestCancel(request);
1820 void EWebView::QuotaRequestReply(const _Ewk_Quota_Permission_Request* request,
1822 DCHECK(quota_permission_request_map_.find(request) !=
1823 quota_permission_request_map_.end());
1825 QuotaPermissionContextEfl::DispatchCallback(
1826 std::move(quota_permission_request_map_[request]),
1827 (allow ? QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_ALLOW
1828 : QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_DISALLOW));
1830 quota_permission_request_map_.erase(request);
1834 void EWebView::QuotaRequestCancel(
1835 const _Ewk_Quota_Permission_Request* request) {
1836 DCHECK(quota_permission_request_map_.find(request) !=
1837 quota_permission_request_map_.end());
1839 QuotaPermissionContextEfl::DispatchCallback(
1840 std::move(quota_permission_request_map_[request]),
1841 QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_CANCELLED);
1842 quota_permission_request_map_.erase(request);
1846 bool EWebView::GetLinkMagnifierEnabled() const {
1847 #if !defined(EWK_BRINGUP) // FIXME: m71 bringup
1848 return web_contents_->GetMutableRendererPrefs()
1849 ->tap_multiple_targets_strategy ==
1850 TAP_MULTIPLE_TARGETS_STRATEGY_POPUP;
1856 void EWebView::SetLinkMagnifierEnabled(bool enabled) {
1857 #if !defined(EWK_BRINGUP) // FIXME: m71 bringup
1858 web_contents_->GetMutableRendererPrefs()->tap_multiple_targets_strategy =
1859 enabled ? TAP_MULTIPLE_TARGETS_STRATEGY_POPUP
1860 : TAP_MULTIPLE_TARGETS_STRATEGY_NONE;
1862 web_contents_->SyncRendererPrefs();
1865 bool EWebView::GetSnapshotAsync(
1866 Eina_Rectangle rect,
1867 Ewk_Web_App_Screenshot_Captured_Callback callback,
1869 float scale_factor) {
1870 if (!rwhva() || !rwhva()->offscreen_helper())
1873 rwhva()->offscreen_helper()->RequestSnapshotAsync(
1874 gfx::Rect(rect.x, rect.y, rect.w, rect.h), callback, user_data,
1879 Evas_Object* EWebView::GetSnapshot(Eina_Rectangle rect, float scale_factor) {
1880 if (!rwhva() || !rwhva()->offscreen_helper())
1883 return rwhva()->offscreen_helper()->GetSnapshot(
1884 gfx::Rect(rect.x, rect.y, rect.w, rect.h), scale_factor);
1887 void EWebView::BackForwardListClear() {
1888 content::NavigationController& controller = web_contents_->GetController();
1890 int entry_count = controller.GetEntryCount();
1891 bool entry_removed = false;
1893 for (int i = 0; i < entry_count; i++) {
1894 if (controller.RemoveEntryAtIndex(i)) {
1895 entry_removed = true;
1896 entry_count = controller.GetEntryCount();
1901 if (entry_removed) {
1902 back_forward_list_->ClearCache();
1903 InvokeBackForwardListChangedCallback();
1907 _Ewk_Back_Forward_List* EWebView::GetBackForwardList() const {
1908 return back_forward_list_.get();
1911 void EWebView::InvokeBackForwardListChangedCallback() {
1912 SmartCallback<EWebViewCallbacks::BackForwardListChange>().call();
1915 _Ewk_History* EWebView::GetBackForwardHistory() const {
1916 return new _Ewk_History(web_contents_->GetController());
1919 bool EWebView::WebAppCapableGet(Ewk_Web_App_Capable_Get_Callback callback,
1921 RenderViewHost* renderViewHost = web_contents_->GetRenderViewHost();
1922 if (!renderViewHost) {
1925 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
1926 WebApplicationCapableGetCallback* cb =
1927 new WebApplicationCapableGetCallback(callback, userData);
1928 int callbackId = web_app_capable_get_callback_map_.Add(cb);
1929 return renderViewHost->Send(new EwkViewMsg_WebAppCapableGet(
1930 renderViewHost->GetRoutingID(), callbackId));
1936 bool EWebView::WebAppIconUrlGet(Ewk_Web_App_Icon_URL_Get_Callback callback,
1938 RenderViewHost* renderViewHost = web_contents_->GetRenderViewHost();
1939 if (!renderViewHost) {
1942 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
1943 WebApplicationIconUrlGetCallback* cb =
1944 new WebApplicationIconUrlGetCallback(callback, userData);
1945 int callbackId = web_app_icon_url_get_callback_map_.Add(cb);
1946 return renderViewHost->Send(new EwkViewMsg_WebAppIconUrlGet(
1947 renderViewHost->GetRoutingID(), callbackId));
1953 bool EWebView::WebAppIconUrlsGet(Ewk_Web_App_Icon_URLs_Get_Callback callback,
1955 RenderViewHost* renderViewHost = web_contents_->GetRenderViewHost();
1956 if (!renderViewHost) {
1959 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
1960 WebApplicationIconUrlsGetCallback* cb =
1961 new WebApplicationIconUrlsGetCallback(callback, userData);
1962 int callbackId = web_app_icon_urls_get_callback_map_.Add(cb);
1963 return renderViewHost->Send(new EwkViewMsg_WebAppIconUrlsGet(
1964 renderViewHost->GetRoutingID(), callbackId));
1970 void EWebView::InvokeWebAppCapableGetCallback(bool capable, int callbackId) {
1971 WebApplicationCapableGetCallback* callback =
1972 web_app_capable_get_callback_map_.Lookup(callbackId);
1975 callback->Run(capable);
1976 web_app_capable_get_callback_map_.Remove(callbackId);
1979 void EWebView::InvokeWebAppIconUrlGetCallback(const std::string& iconUrl,
1981 WebApplicationIconUrlGetCallback* callback =
1982 web_app_icon_url_get_callback_map_.Lookup(callbackId);
1985 callback->Run(iconUrl);
1986 web_app_icon_url_get_callback_map_.Remove(callbackId);
1989 void EWebView::InvokeWebAppIconUrlsGetCallback(const StringMap& iconUrls,
1991 WebApplicationIconUrlsGetCallback* callback =
1992 web_app_icon_urls_get_callback_map_.Lookup(callbackId);
1996 callback->Run(iconUrls);
1997 web_app_icon_urls_get_callback_map_.Remove(callbackId);
2000 void EWebView::SetNotificationPermissionCallback(
2001 Ewk_View_Notification_Permission_Callback callback,
2003 notification_permission_callback_.Set(callback, user_data);
2006 bool EWebView::IsNotificationPermissionCallbackSet() const {
2007 return notification_permission_callback_.IsCallbackSet();
2010 bool EWebView::InvokeNotificationPermissionCallback(
2011 Ewk_Notification_Permission_Request* request) {
2012 Eina_Bool ret = EINA_FALSE;
2013 notification_permission_callback_.Run(evas_object_, request, &ret);
2017 int EWebView::SetEwkViewPlainTextGetCallback(
2018 Ewk_View_Plain_Text_Get_Callback callback,
2020 EwkViewPlainTextGetCallback* view_plain_text_callback_ptr =
2021 new EwkViewPlainTextGetCallback;
2022 view_plain_text_callback_ptr->Set(callback, user_data);
2023 return plain_text_get_callback_map_.Add(view_plain_text_callback_ptr);
2026 bool EWebView::PlainTextGet(Ewk_View_Plain_Text_Get_Callback callback,
2028 auto* render_frame_host = web_contents_->GetPrimaryMainFrame();
2029 if (!render_frame_host)
2032 auto callback_id = SetEwkViewPlainTextGetCallback(callback, user_data);
2033 return render_frame_host->Send(new EwkFrameMsg_GetPlainText(
2034 render_frame_host->GetRoutingID(), callback_id));
2037 void EWebView::InvokePlainTextGetCallback(const std::string& content_text,
2038 int plain_text_get_callback_id) {
2039 EwkViewPlainTextGetCallback* view_plain_text_callback_invoke_ptr =
2040 plain_text_get_callback_map_.Lookup(plain_text_get_callback_id);
2041 view_plain_text_callback_invoke_ptr->Run(evas_object(), content_text.c_str());
2042 plain_text_get_callback_map_.Remove(plain_text_get_callback_id);
2045 void EWebView::SetViewGeolocationPermissionCallback(
2046 Ewk_View_Geolocation_Permission_Callback callback,
2048 geolocation_permission_cb_.Set(callback, user_data);
2051 bool EWebView::InvokeViewGeolocationPermissionCallback(
2052 _Ewk_Geolocation_Permission_Request* permission_context,
2053 Eina_Bool* callback_result) {
2054 return geolocation_permission_cb_.Run(evas_object_, permission_context,
2058 void EWebView::SetViewUserMediaPermissionCallback(
2059 Ewk_View_User_Media_Permission_Callback callback,
2061 user_media_permission_cb_.Set(callback, user_data);
2064 bool EWebView::InvokeViewUserMediaPermissionCallback(
2065 _Ewk_User_Media_Permission_Request* permission_context,
2066 Eina_Bool* callback_result) {
2067 return user_media_permission_cb_.Run(evas_object_, permission_context,
2071 void EWebView::SetViewUserMediaPermissionQueryCallback(
2072 Ewk_View_User_Media_Permission_Query_Callback callback,
2074 user_media_permission_query_cb_.Set(callback, user_data);
2077 Ewk_User_Media_Permission_Query_Result
2078 EWebView::InvokeViewUserMediaPermissionQueryCallback(
2079 _Ewk_User_Media_Permission_Query* permission_context) {
2080 return user_media_permission_query_cb_.Run(evas_object_, permission_context);
2083 void EWebView::SetViewUnfocusAllowCallback(
2084 Ewk_View_Unfocus_Allow_Callback callback,
2086 unfocus_allow_cb_.Set(callback, user_data);
2089 bool EWebView::InvokeViewUnfocusAllowCallback(Ewk_Unfocus_Direction direction,
2090 Eina_Bool* callback_result) {
2091 return unfocus_allow_cb_.Run(evas_object_, direction, callback_result);
2094 void EWebView::StopFinding() {
2095 web_contents_->StopFinding(content::STOP_FIND_ACTION_CLEAR_SELECTION);
2098 void EWebView::SetProgressValue(double progress) {
2099 progress_ = progress;
2102 double EWebView::GetProgressValue() {
2106 const char* EWebView::GetTitle() {
2107 title_ = base::UTF16ToUTF8(web_contents_->GetTitle());
2108 return title_.c_str();
2111 bool EWebView::SaveAsPdf(int width, int height, const std::string& filename) {
2114 rwhva()->host()->PrintToPdf(width, height, base::FilePath(filename));
2118 bool EWebView::GetMHTMLData(Ewk_View_MHTML_Data_Get_Callback callback,
2120 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
2121 if (!render_view_host)
2124 MHTMLCallbackDetails* callback_details = new MHTMLCallbackDetails;
2125 callback_details->Set(callback, user_data);
2126 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
2127 int mhtml_callback_id = mhtml_callback_map_.Add(callback_details);
2128 return render_view_host->Send(new EwkViewMsg_GetMHTMLData(
2129 render_view_host->GetRoutingID(), mhtml_callback_id));
2135 void EWebView::OnMHTMLContentGet(const std::string& mhtml_content,
2137 MHTMLCallbackDetails* callback_details =
2138 mhtml_callback_map_.Lookup(callback_id);
2139 callback_details->Run(evas_object(), mhtml_content.c_str());
2140 mhtml_callback_map_.Remove(callback_id);
2143 bool EWebView::SavePageAsMHTML(const std::string& path,
2144 Ewk_View_Save_Page_Callback callback,
2149 GURL url(web_contents_->GetLastCommittedURL());
2150 std::u16string title(web_contents_->GetTitle());
2152 // Post function that has file access to blocking task runner.
2153 return base::PostTaskAndReplyWithResult(
2154 base::ThreadPool::CreateSequencedTaskRunner(
2155 {base::MayBlock(), base::TaskPriority::BEST_EFFORT,
2156 base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})
2159 base::BindOnce(&GenerateMHTMLFilePath, url, base::UTF16ToUTF8(title),
2161 base::BindOnce(&EWebView::GenerateMHTML, base::Unretained(this), callback,
2165 void EWebView::GenerateMHTML(Ewk_View_Save_Page_Callback callback,
2167 const base::FilePath& file_path) {
2168 if (file_path.empty()) {
2169 LOG(ERROR) << "Generating file path was failed";
2170 callback(evas_object_, nullptr, user_data);
2174 MHTMLGenerationParams params(file_path);
2175 web_contents_->GenerateMHTML(
2176 params, base::BindOnce(&EWebView::MHTMLGenerated, base::Unretained(this),
2177 callback, user_data, file_path));
2180 void EWebView::MHTMLGenerated(Ewk_View_Save_Page_Callback callback,
2182 const base::FilePath& file_path,
2183 int64_t file_size) {
2184 callback(evas_object_, file_size > 0 ? file_path.value().c_str() : nullptr,
2188 bool EWebView::GetBackgroundColor(
2189 Ewk_View_Background_Color_Get_Callback callback,
2193 BackgroundColorGetCallback* cb =
2194 new BackgroundColorGetCallback(callback, user_data);
2195 int callback_id = background_color_get_callback_map_.Add(cb);
2197 rwhva()->host()->RequestBackgroundColor(callback_id);
2201 void EWebView::OnGetBackgroundColor(int callback_id, SkColor bg_color) {
2202 BackgroundColorGetCallback* cb =
2203 background_color_get_callback_map_.Lookup(callback_id);
2208 cb->Run(evas_object(), SkColorGetR(bg_color), SkColorGetG(bg_color),
2209 SkColorGetB(bg_color), SkColorGetA(bg_color));
2210 background_color_get_callback_map_.Remove(callback_id);
2213 bool EWebView::IsFullscreen() {
2214 return web_contents_delegate_->IsFullscreenForTabOrPending(
2215 web_contents_.get());
2218 void EWebView::ExitFullscreen() {
2219 WebContentsImpl* wci = static_cast<WebContentsImpl*>(web_contents_.get());
2220 wci->ExitFullscreen(false);
2223 double EWebView::GetScale() {
2224 return page_scale_factor_;
2227 void EWebView::DidChangePageScaleFactor(double scale_factor) {
2228 page_scale_factor_ = scale_factor;
2229 wcva()->wcva_helper()->SetPageScaleFactor(scale_factor);
2230 SetScaledContentsSize();
2232 // Notify app about the scale change.
2233 scale_changed_cb_.Run(evas_object_, scale_factor);
2236 inline JavaScriptDialogManagerEfl* EWebView::GetJavaScriptDialogManagerEfl() {
2237 return static_cast<JavaScriptDialogManagerEfl*>(
2238 web_contents_delegate_->GetJavaScriptDialogManager(web_contents_.get()));
2241 void EWebView::SetJavaScriptAlertCallback(
2242 Ewk_View_JavaScript_Alert_Callback callback,
2244 GetJavaScriptDialogManagerEfl()->SetAlertCallback(callback, user_data);
2247 void EWebView::JavaScriptAlertReply() {
2248 GetJavaScriptDialogManagerEfl()->ExecuteDialogClosedCallBack(true,
2250 SmartCallback<EWebViewCallbacks::PopupReplyWaitFinish>().call(0);
2253 void EWebView::SetJavaScriptConfirmCallback(
2254 Ewk_View_JavaScript_Confirm_Callback callback,
2256 GetJavaScriptDialogManagerEfl()->SetConfirmCallback(callback, user_data);
2259 void EWebView::JavaScriptConfirmReply(bool result) {
2260 GetJavaScriptDialogManagerEfl()->ExecuteDialogClosedCallBack(result,
2262 SmartCallback<EWebViewCallbacks::PopupReplyWaitFinish>().call(0);
2265 void EWebView::SetJavaScriptPromptCallback(
2266 Ewk_View_JavaScript_Prompt_Callback callback,
2268 GetJavaScriptDialogManagerEfl()->SetPromptCallback(callback, user_data);
2271 void EWebView::JavaScriptPromptReply(const char* result) {
2272 GetJavaScriptDialogManagerEfl()->ExecuteDialogClosedCallBack(
2273 true, (std::string(result)));
2274 SmartCallback<EWebViewCallbacks::PopupReplyWaitFinish>().call(0);
2277 void EWebView::GetPageScaleRange(double* min_scale, double* max_scale) {
2278 auto prefs = web_contents_->GetOrCreateWebPreferences();
2280 *min_scale = prefs.default_minimum_page_scale_factor;
2282 *max_scale = prefs.default_maximum_page_scale_factor;
2285 void EWebView::SetDrawsTransparentBackground(bool enabled) {
2286 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
2287 if (!render_view_host)
2289 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
2290 render_view_host->Send(new EwkViewMsg_SetDrawsTransparentBackground(
2291 render_view_host->GetRoutingID(), enabled));
2295 void EWebView::GetSessionData(const char** data, unsigned* length) const {
2296 static const int MAX_SESSION_ENTRY_SIZE = std::numeric_limits<int>::max();
2298 NavigationController& navigationController = web_contents_->GetController();
2299 base::Pickle sessionPickle;
2300 const int itemCount = navigationController.GetEntryCount();
2302 sessionPickle.WriteInt(itemCount);
2303 sessionPickle.WriteInt(navigationController.GetCurrentEntryIndex());
2305 for (int i = 0; i < itemCount; i++) {
2306 NavigationEntry* navigationEntry = navigationController.GetEntryAtIndex(i);
2307 sessions::SerializedNavigationEntry serializedEntry =
2308 sessions::ContentSerializedNavigationBuilder::FromNavigationEntry(
2309 i, navigationEntry);
2310 serializedEntry.WriteToPickle(MAX_SESSION_ENTRY_SIZE, &sessionPickle);
2313 if (sessionPickle.size() <= 0 ||
2315 static_cast<char*>(malloc(sizeof(char) * sessionPickle.size())))) {
2316 LOG(ERROR) << "Failed to get session data";
2320 memcpy(const_cast<char*>(*data), sessionPickle.data(), sessionPickle.size());
2321 *length = sessionPickle.size();
2324 bool EWebView::RestoreFromSessionData(const char* data, unsigned length) {
2325 base::Pickle sessionPickle(data, length);
2326 base::PickleIterator pickleIterator(sessionPickle);
2330 if (!pickleIterator.ReadInt(&entryCount))
2332 if (!pickleIterator.ReadInt(¤tEntry))
2335 std::vector<sessions::SerializedNavigationEntry> serializedEntries;
2336 serializedEntries.resize(entryCount);
2337 for (int i = 0; i < entryCount; ++i) {
2338 if (!serializedEntries.at(i).ReadFromPickle(&pickleIterator))
2348 std::vector<std::unique_ptr<content::NavigationEntry>> scopedEntries =
2349 sessions::ContentSerializedNavigationBuilder::ToNavigationEntries(
2350 serializedEntries, context()->browser_context());
2352 NavigationController& navigationController = web_contents_->GetController();
2354 if (currentEntry < 0)
2357 if (currentEntry >= static_cast<int>(scopedEntries.size()))
2358 currentEntry = scopedEntries.size() - 1;
2360 navigationController.Restore(currentEntry, RestoreType::kRestored,
2365 void EWebView::SetBrowserFont() {
2366 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
2367 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
2368 if (render_view_host) {
2369 IPC::Message* message =
2370 new EwkViewMsg_SetBrowserFont(render_view_host->GetRoutingID());
2372 if (render_view_host->IsRenderViewLive())
2373 render_view_host->Send(message);
2375 delayed_messages_.push_back(message);
2380 bool EWebView::IsDragging() const {
2381 return wcva()->wcva_helper()->IsDragging();
2384 void EWebView::ShowFileChooser(content::RenderFrameHost* render_frame_host,
2385 const blink::mojom::FileChooserParams& params) {
2386 if (!IsMobileProfile() && !IsWearableProfile())
2389 #if !defined(EWK_BRINGUP) // FIXME: m71 bringup
2390 if (params.capture) {
2391 const std::string capture_types[] = {"video/*", "audio/*", "image/*"};
2392 unsigned int capture_types_num =
2393 sizeof(capture_types) / sizeof(*capture_types);
2394 for (unsigned int i = 0; i < capture_types_num; ++i) {
2395 for (unsigned int j = 0; j < params.accept_types.size(); ++j) {
2396 if (UTF16ToUTF8(params.accept_types[j]) == capture_types[i]) {
2397 filechooser_mode_ = params.mode;
2398 LaunchCamera(params.accept_types[j]);
2404 file_chooser_.reset(
2405 new content::FileChooserControllerEfl(render_frame_host, ¶ms));
2406 file_chooser_->Open();
2410 #if !defined(EWK_BRINGUP) // FIXME: m67 bringup
2411 void EWebView::SetViewMode(blink::WebViewMode view_mode) {
2412 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
2413 if (!render_view_host)
2416 IPC::Message* message =
2417 new ViewMsg_SetViewMode(render_view_host->GetRoutingID(), view_mode);
2418 if (render_view_host->IsRenderViewLive()) {
2419 render_view_host->Send(message);
2421 delayed_messages_.push_back(message);
2426 gfx::Point EWebView::GetContextMenuPosition() const {
2427 return context_menu_position_;
2430 void EWebView::ShowContentsDetectedPopup(const char* message) {
2431 popup_controller_.reset(new PopupControllerEfl(this));
2432 popup_controller_->openPopup(message);
2435 void EWebView::RequestColorPicker(int r, int g, int b, int a) {
2436 input_picker_.reset(new InputPicker(this));
2437 input_picker_->ShowColorPicker(r, g, b, a);
2440 bool EWebView::SetColorPickerColor(int r, int g, int b, int a) {
2441 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
2442 web_contents_->DidChooseColorInColorChooser(SkColorSetARGB(a, r, g, b));
2447 void EWebView::InputPickerShow(ui::TextInputType input_type,
2449 content::DateTimeChooserEfl* date_time_chooser) {
2450 input_picker_.reset(new InputPicker(this));
2451 date_time_chooser_ = date_time_chooser;
2452 input_picker_->ShowDatePicker(input_type, input_value);
2455 void EWebView::LoadNotFoundErrorPage(const std::string& invalidUrl) {
2456 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
2457 RenderFrameHost* render_frame_host = web_contents_->GetPrimaryMainFrame();
2458 if (render_frame_host)
2459 render_frame_host->Send(new EwkFrameMsg_LoadNotFoundErrorPage(
2460 render_frame_host->GetRoutingID(), invalidUrl));
2464 std::string EWebView::GetPlatformLocale() {
2465 char* local_default = setlocale(LC_CTYPE, 0);
2467 return std::string("en-US");
2468 std::string locale = std::string(local_default);
2469 size_t position = locale.find('_');
2470 if (position != std::string::npos)
2471 locale.replace(position, 1, "-");
2472 position = locale.find('.');
2473 if (position != std::string::npos)
2474 locale = locale.substr(0, position);
2478 int EWebView::StartInspectorServer(int port) {
2479 return context_->InspectorServerStart(port);
2482 bool EWebView::StopInspectorServer() {
2483 return context_->InspectorServerStop();
2486 void EWebView::InvokeWebProcessCrashedCallback() {
2487 DCHECK_CURRENTLY_ON(BrowserThread::UI);
2488 const GURL last_url = GetURL();
2489 bool callback_handled = false;
2490 SmartCallback<EWebViewCallbacks::WebProcessCrashed>().call(&callback_handled);
2491 if (!callback_handled)
2492 LoadHTMLString(kRendererCrashedHTMLMessage, NULL,
2493 last_url.possibly_invalid_spec().c_str());
2496 void EWebView::SyncAcceptLanguages(const std::string& accept_languages) {
2497 web_contents_->GetMutableRendererPrefs()->accept_languages = accept_languages;
2498 web_contents_->SyncRendererPrefs();
2499 BrowserContext* browser_context = web_contents_->GetBrowserContext();
2500 if (!browser_context)
2503 auto* storage_partition = browser_context->GetDefaultStoragePartition();
2504 if (!storage_partition)
2507 if (auto* network_context = storage_partition->GetNetworkContext())
2508 network_context->SetAcceptLanguage(accept_languages);
2511 void EWebView::HandleRendererProcessCrash() {
2512 content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
2513 base::BindOnce(&EWebView::InvokeWebProcessCrashedCallback,
2514 base::Unretained(this)));
2517 void EWebView::InitializeContent() {
2518 WebContents* new_contents = create_new_window_web_contents_cb_.Run(this);
2519 if (!new_contents) {
2520 WebContents::CreateParams params(context_->browser_context());
2521 web_contents_.reset(
2522 new WebContentsImplEfl(context_->browser_context(), this));
2523 static_cast<WebContentsImpl*>(web_contents_.get())
2524 ->Init(params, blink::FramePolicy());
2526 web_contents_.reset(new_contents);
2528 // When a new webview is created in response to a request from the
2529 // engine, the BrowserContext instance of the originator WebContents
2530 // is used by the newly created WebContents object.
2531 // See more in WebContentsImplEfl::HandleNewWebContentsCreate.
2533 // Hence, if as part of the WebView creation, the embedding APP
2534 // passes in a Ewk_Context instance that wraps a different instance of
2535 // BrowserContext than the one the originator WebContents holds,
2536 // undefined behavior can be seen.
2538 // This is a snippet code that illustrate the scenario:
2541 // evas_object_smart_callback_add(web_view_, "create,window",
2542 // &OnNewWindowRequest, this);
2545 // void OnNewWindowRequest(void *data, Evas_Object*, void* out_view) {
2547 // EvasObject* new_web_view = ewk_view_add_with_context(GetEvas(),
2548 // ewk_context_new());
2549 // *static_cast<Evas_Object**>(out_view) = new_web_view;
2553 // The new Ewk_Context object created and passed in as parameter to
2554 // ewk_view_add_with_context wraps a different instance of BrowserContext
2555 // than the one the new WebContents object will hold.
2557 // CHECK below aims at catching misuse of this API.
2558 bool should_crash = context_->GetImpl()->browser_context() !=
2559 web_contents_->GetBrowserContext();
2562 << "BrowserContext of new WebContents does not match EWebView's. "
2563 << "Please see 'ewk_view_add*' documentation. "
2564 << "Aborting execution ...";
2567 web_contents_delegate_.reset(new WebContentsDelegateEfl(this));
2568 web_contents_->SetDelegate(web_contents_delegate_.get());
2569 WebContentsImplEfl* wc_efl =
2570 static_cast<WebContentsImplEfl*>(web_contents_.get());
2571 wc_efl->SetEflDelegate(new WebContentsEflDelegateEwk(this));
2572 wcva()->wcva_helper()->SetEflDelegate(wc_efl->GetEflDelegate());
2574 back_forward_list_.reset(new _Ewk_Back_Forward_List(web_contents_.get()));
2576 permission_popup_manager_.reset(new PermissionPopupManager(evas_object_));
2577 gin_native_bridge_dispatcher_host_.reset(
2578 new content::GinNativeBridgeDispatcherHost(web_contents_.get()));
2581 static_cast<WebContentsImplEfl*>(web_contents_.get())->GetEflNativeView();
2582 evas_object_smart_member_add(native_view_, evas_object_);
2583 static_cast<WebContentsImpl*>(web_contents_.get())
2584 ->set_ewk_view(evas_object_);
2585 InitializeWindowTreeHost();
2588 void EWebView::InitializeWindowTreeHost() {
2589 CHECK(aura::Env::GetInstance());
2591 int x, y, width, height;
2593 ecore_evas_ecore_evas_get(evas_object_evas_get(native_view_));
2594 ecore_evas_geometry_get(ee, &x, &y, &width, &height);
2596 gfx::Rect bounds(x, y, width, height);
2597 ui::PlatformWindowInitProperties properties;
2598 properties.bounds = bounds;
2600 host_ = aura::WindowTreeHost::Create(std::move(properties));
2602 host_->window()->Show();
2605 std::make_unique<aura::test::TestFocusClient>(host_->window());
2606 window_parenting_client_ =
2607 std::make_unique<aura::test::TestWindowParentingClient>(host_->window());
2608 compositor_observer_ = std::make_unique<ui::CompositorObserverEfl>(
2609 host_->compositor(), web_contents_.get());
2611 aura::Window* content = web_contents_->GetNativeView();
2612 aura::Window* parent = host_->window();
2613 if (!parent->Contains(content)) {
2614 parent->AddChild(content);
2617 content->SetBounds(bounds);
2618 RenderWidgetHostView* host_view = web_contents_->GetRenderWidgetHostView();
2620 host_view->SetSize(bounds.size());
2623 #if BUILDFLAG(IS_TIZEN) && !defined(EWK_BRINGUP)
2624 void EWebView::cameraResultCb(service_h request,
2626 service_result_e result,
2628 if (!IsMobileProfile() && !IsWearableProfile())
2631 EWebView* webview = static_cast<EWebView*>(data);
2632 RenderViewHost* render_view_host =
2633 webview->web_contents_->GetRenderViewHost();
2634 if (result == SERVICE_RESULT_SUCCEEDED) {
2638 ret = service_get_extra_data_array(reply, SERVICE_DATA_SELECTED,
2639 &filesarray, &number);
2641 for (int i = 0; i < number; i++) {
2642 std::vector<ui::SelectedFileInfo> files;
2643 if (!render_view_host) {
2646 if (filesarray[i]) {
2647 GURL url(filesarray[i]);
2648 if (!url.is_valid()) {
2649 base::FilePath path(url.SchemeIsFile() ? url.path()
2651 files.push_back(ui::SelectedFileInfo(path, base::FilePath()));
2654 render_view_host->FilesSelectedInChooser(files,
2655 webview->filechooser_mode_);
2659 std::vector<ui::SelectedFileInfo> files;
2660 if (render_view_host) {
2661 render_view_host->FilesSelectedInChooser(files,
2662 webview->filechooser_mode_);
2667 bool EWebView::LaunchCamera(std::u16string mimetype) {
2668 service_h svcHandle = 0;
2669 if (service_create(&svcHandle) < 0 || !svcHandle) {
2670 LOG(ERROR) << __FUNCTION__ << " Service Creation Failed ";
2673 service_set_operation(svcHandle, SERVICE_OPERATION_CREATE_CONTENT);
2674 service_set_mime(svcHandle, UTF16ToUTF8(mimetype).c_str());
2675 service_add_extra_data(svcHandle, "CALLER", "Browser");
2677 int ret = service_send_launch_request(svcHandle, cameraResultCb, this);
2678 if (ret != SERVICE_ERROR_NONE) {
2679 LOG(ERROR) << __FUNCTION__ << " Service Launch Failed ";
2680 service_destroy(svcHandle);
2683 service_destroy(svcHandle);
2688 void EWebView::UrlRequestSet(
2690 content::NavigationController::LoadURLType loadtype,
2694 content::NavigationController::LoadURLParams params(gurl);
2695 params.load_type = loadtype;
2696 params.override_user_agent = NavigationController::UA_OVERRIDE_TRUE;
2699 std::string s(body);
2701 network::ResourceRequestBody::CreateFromBytes(s.data(), s.size());
2704 net::HttpRequestHeaders header;
2706 Eina_Iterator* it = eina_hash_iterator_tuple_new(headers);
2708 while (eina_iterator_next(it, reinterpret_cast<void**>(&t))) {
2710 const char* value_str =
2711 t->data ? static_cast<const char*>(t->data) : "";
2712 base::StringPiece name = static_cast<const char*>(t->key);
2713 base::StringPiece value = value_str;
2714 header.SetHeader(name, value);
2715 // net::HttpRequestHeaders.ToString() returns string with newline
2716 params.extra_headers += header.ToString();
2719 eina_iterator_free(it);
2722 web_contents_->GetController().LoadURLWithParams(params);
2725 #if defined(TIZEN_VIDEO_HOLE)
2726 void EWebView::SetVideoHoleSupport(bool enable) {
2727 if (!web_contents_->GetPrimaryMainFrame() ||
2728 !web_contents_->GetPrimaryMainFrame()->IsRenderFrameLive() || !rwhva()) {
2729 pending_video_hole_setting_ = enable;
2733 rwhva()->host()->SetVideoHoleForRender(enable);
2737 bool EWebView::HandleShow() {
2745 bool EWebView::HandleHide() {
2753 bool EWebView::HandleMove(int x, int y) {
2756 evas_object_move(native_view_, x, y);
2758 #if defined(TIZEN_VIDEO_HOLE) && !defined(EWK_BRINGUP)
2760 rwhva()->offscreen_helper()->DidMoveWebView();
2764 context_menu_->Move(x, y);
2769 bool EWebView::HandleResize(int width, int height) {
2772 evas_object_resize(native_view_, width, height);
2774 if (select_picker_) {
2775 AdjustViewPortHeightToPopupMenu(true /* is_popup_menu_visible */);
2776 ScrollFocusedNodeIntoView();
2779 #if defined(USE_AURA) && BUILDFLAG(IS_TIZEN_TV)
2782 evas_object_geometry_get(native_view_, &x, &y, nullptr, nullptr);
2783 gfx::Rect bounds(x, y, width, height);
2784 host_->SetBoundsInPixels(bounds);
2791 bool EWebView::HandleTextSelectionDown(int x, int y) {
2792 if (!GetSelectionController())
2794 return GetSelectionController()->TextSelectionDown(x, y);
2797 bool EWebView::HandleTextSelectionUp(int x, int y) {
2798 if (!GetSelectionController())
2800 return GetSelectionController()->TextSelectionUp(x, y);
2803 void EWebView::HandleTapGestureForSelection(bool is_content_editable) {
2804 if (!GetSelectionController())
2807 GetSelectionController()->PostHandleTapGesture(is_content_editable);
2810 void EWebView::HandleZoomGesture(blink::WebGestureEvent& event) {
2811 blink::WebInputEvent::Type event_type = event.GetType();
2812 if (event_type == blink::WebInputEvent::Type::kGestureDoubleTap ||
2813 event_type == blink::WebInputEvent::Type::kGesturePinchBegin) {
2814 SmartCallback<EWebViewCallbacks::ZoomStarted>().call();
2816 if (event_type == blink::WebInputEvent::Type::kGestureDoubleTap ||
2817 event_type == blink::WebInputEvent::Type::kGesturePinchEnd) {
2818 SmartCallback<EWebViewCallbacks::ZoomFinished>().call();
2822 bool EWebView::GetHorizontalPanningHold() const {
2825 return rwhva()->offscreen_helper()->GetHorizontalPanningHold();
2828 void EWebView::SetHorizontalPanningHold(bool hold) {
2830 rwhva()->offscreen_helper()->SetHorizontalPanningHold(hold);
2833 bool EWebView::GetVerticalPanningHold() const {
2836 return rwhva()->offscreen_helper()->GetVerticalPanningHold();
2839 void EWebView::SetVerticalPanningHold(bool hold) {
2841 rwhva()->offscreen_helper()->SetVerticalPanningHold(hold);
2844 void EWebView::SendDelayedMessages(RenderViewHost* render_view_host) {
2845 DCHECK(render_view_host);
2847 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
2848 content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
2849 base::BindOnce(&EWebView::SendDelayedMessages, base::Unretained(this),
2854 for (auto iter = delayed_messages_.begin(); iter != delayed_messages_.end();
2856 IPC::Message* message = *iter;
2857 message->set_routing_id(render_view_host->GetRoutingID());
2858 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
2859 render_view_host->Send(message);
2863 delayed_messages_.clear();
2866 void EWebView::ClosePage() {
2867 web_contents_->ClosePage();
2870 bool EWebView::SetMainFrameScrollbarVisible(bool visible) {
2871 if (web_contents_->GetPrimaryMainFrame()->IsRenderFrameLive() && rwhva())
2872 rwhva()->host()->SetMainFrameScrollbarVisible(visible);
2876 bool EWebView::GetMainFrameScrollbarVisible(
2877 Ewk_View_Main_Frame_Scrollbar_Visible_Get_Callback callback,
2882 MainFrameScrollbarVisibleGetCallback* callback_ptr =
2883 new MainFrameScrollbarVisibleGetCallback;
2884 callback_ptr->Set(callback, user_data);
2886 main_frame_scrollbar_visible_callback_map_.Add(callback_ptr);
2887 rwhva()->host()->RequestMainFrameScrollbarVisible(callback_id);
2891 void EWebView::InvokeMainFrameScrollbarVisibleCallback(int callback_id,
2893 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
2894 content::GetUIThreadTaskRunner({})->PostTask(
2896 base::BindOnce(&EWebView::InvokeMainFrameScrollbarVisibleCallback,
2897 base::Unretained(this), visible, callback_id));
2901 MainFrameScrollbarVisibleGetCallback* callback =
2902 main_frame_scrollbar_visible_callback_map_.Lookup(callback_id);
2906 main_frame_scrollbar_visible_callback_map_.Remove(callback_id);
2907 callback->Run(evas_object(), visible);
2908 main_frame_scrollbar_visible_callback_map_.Remove(callback_id);
2911 void EWebView::OnOverscrolled(const gfx::Vector2dF& accumulated_overscroll,
2912 const gfx::Vector2dF& latest_overscroll_delta) {
2913 const gfx::Vector2dF old_overscroll =
2914 accumulated_overscroll - latest_overscroll_delta;
2916 if (latest_overscroll_delta.x() && !old_overscroll.x()) {
2917 latest_overscroll_delta.x() < 0
2918 ? SmartCallback<EWebViewCallbacks::OverscrolledLeft>().call()
2919 : SmartCallback<EWebViewCallbacks::OverscrolledRight>().call();
2921 if (latest_overscroll_delta.y() && !old_overscroll.y()) {
2922 latest_overscroll_delta.y() < 0
2923 ? SmartCallback<EWebViewCallbacks::OverscrolledTop>().call()
2924 : SmartCallback<EWebViewCallbacks::OverscrolledBottom>().call();
2928 void EWebView::SetDidChangeThemeColorCallback(
2929 Ewk_View_Did_Change_Theme_Color_Callback callback,
2931 did_change_theme_color_callback_.Set(callback, user_data);
2934 void EWebView::DidChangeThemeColor(const SkColor& color) {
2935 did_change_theme_color_callback_.Run(evas_object_, color);
2938 #if BUILDFLAG(IS_TIZEN_TV)
2939 void EWebView::DrawLabel(Evas_Object* image, Eina_Rectangle rect) {
2941 rwhva()->offscreen_helper()->DrawLabel(image, rect);
2944 void EWebView::DeactivateAtk(bool deactivated) {
2945 EWebAccessibilityUtil::GetInstance()->Deactivate(deactivated);
2948 void EWebView::ClearLabels() {
2950 rwhva()->offscreen_helper()->ClearLabels();
2954 void EWebView::RequestManifest(Ewk_View_Request_Manifest_Callback callback,
2956 web_contents_delegate_->RequestManifestInfo(callback, user_data);
2959 void EWebView::DidRespondRequestManifest(
2960 _Ewk_View_Request_Manifest* manifest,
2961 Ewk_View_Request_Manifest_Callback callback,
2963 callback(evas_object_, manifest, user_data);
2966 void EWebView::SetSessionTimeout(uint64_t timeout) {
2967 if (web_contents_->GetPrimaryMainFrame()->IsRenderFrameLive() && rwhva())
2968 rwhva()->host()->SetLongPollingGlobalTimeout(timeout);
2971 void EWebView::SetBeforeUnloadConfirmPanelCallback(
2972 Ewk_View_Before_Unload_Confirm_Panel_Callback callback,
2974 GetJavaScriptDialogManagerEfl()->SetBeforeUnloadConfirmPanelCallback(
2975 callback, user_data);
2978 void EWebView::ReplyBeforeUnloadConfirmPanel(Eina_Bool result) {
2979 GetJavaScriptDialogManagerEfl()->ReplyBeforeUnloadConfirmPanel(result);
2982 void EWebView::SetExceededIndexedDatabaseQuotaCallback(
2983 Ewk_View_Exceeded_Indexed_Database_Quota_Callback callback,
2985 exceeded_indexed_db_quota_callback_.Set(callback, user_data);
2986 content::BrowserContextEfl* browser_context =
2987 static_cast<content::BrowserContextEfl*>(
2988 web_contents_->GetBrowserContext());
2989 if (browser_context) {
2990 browser_context->GetSpecialStoragePolicyEfl()->SetQuotaExceededCallback(
2991 base::BindOnce(&EWebView::InvokeExceededIndexedDatabaseQuotaCallback,
2992 base::Unretained(this)));
2996 void EWebView::InvokeExceededIndexedDatabaseQuotaCallback(
2998 int64_t current_quota) {
2999 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
3000 content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
3001 base::BindOnce(&EWebView::InvokeExceededIndexedDatabaseQuotaCallback,
3002 base::Unretained(this), origin, current_quota));
3005 LOG(INFO) << __func__ << "()" << origin << ", " << current_quota;
3006 CHECK(!exceeded_indexed_db_quota_origin_.get());
3007 exceeded_indexed_db_quota_origin_.reset(new Ewk_Security_Origin(origin));
3008 exceeded_indexed_db_quota_callback_.Run(
3009 evas_object_, exceeded_indexed_db_quota_origin_.get(), current_quota);
3012 void EWebView::ExceededIndexedDatabaseQuotaReply(bool allow) {
3013 if (!exceeded_indexed_db_quota_origin_.get()) {
3014 LOG(WARNING) << __func__ << "() : callback is not invoked!";
3017 LOG(INFO) << __func__ << "()" << exceeded_indexed_db_quota_origin_->GetURL()
3019 content::BrowserContextEfl* browser_context =
3020 static_cast<content::BrowserContextEfl*>(
3021 web_contents_->GetBrowserContext());
3022 if (browser_context) {
3023 browser_context->GetSpecialStoragePolicyEfl()->SetUnlimitedStoragePolicy(
3024 exceeded_indexed_db_quota_origin_->GetURL(), allow);
3026 exceeded_indexed_db_quota_origin_.reset();
3029 bool EWebView::ShouldIgnoreNavigation(
3030 content::NavigationHandle* navigation_handle) {
3031 if (!navigation_handle->GetURL().is_valid() ||
3032 !navigation_handle->GetURL().SchemeIs("appcontrol") ||
3033 (!navigation_handle->HasUserGesture() &&
3034 !navigation_handle->WasServerRedirect())) {
3038 _Ewk_App_Control app_control(
3039 this, navigation_handle->GetURL().possibly_invalid_spec());
3040 return app_control.Proceed();
3043 bool EWebView::SetVisibility(bool enable) {
3048 web_contents_->WasShown();
3050 web_contents_->WasHidden();
3055 void EWebView::SetDoNotTrack(Eina_Bool enable) {
3056 // enable: 0 User tend to allow tracking on the target site.
3057 // enable: 1 User tend to not be tracked on the target site.
3058 if (web_contents_->GetMutableRendererPrefs()->enable_do_not_track == enable)
3061 // Set navigator.doNotTrack attribute
3062 web_contents_->GetMutableRendererPrefs()->enable_do_not_track = enable;
3063 web_contents_->SyncRendererPrefs();
3065 // Set or remove DNT HTTP header, the effects will depend on design of target
3071 context()->HTTPCustomHeaderAdd("DNT", "1");
3073 context()->HTTPCustomHeaderRemove("DNT");
3076 #if defined(TIZEN_ATK_SUPPORT)
3077 void EWebView::UpdateSpatialNavigationStatus(Eina_Bool enable) {
3078 if (settings_->getPreferences().spatial_navigation_enabled == enable)
3081 settings_->getPreferences().spatial_navigation_enabled = enable;
3082 WebContentsImpl* wc = static_cast<WebContentsImpl*>(web_contents_.get());
3084 wc->SetSpatialNavigationEnabled(enable);
3087 void EWebView::UpdateAccessibilityStatus(Eina_Bool enable) {
3088 if (settings_->getPreferences().atk_enabled == enable)
3091 settings_->getPreferences().atk_enabled = enable;
3092 WebContentsImpl* wc = static_cast<WebContentsImpl*>(web_contents_.get());
3094 wc->SetAtkEnabled(enable);
3097 void EWebView::InitAtk() {
3098 EWebAccessibilityUtil::GetInstance()->ToggleAtk(lazy_initialize_atk_);
3101 /* LCOV_EXCL_START */
3102 bool EWebView::GetAtkStatus() {
3103 auto state = content::BrowserAccessibilityStateImpl::GetInstance();
3106 return state->IsAccessibleBrowser();
3108 /* LCOV_EXCL_STOP */