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 #if BUILDFLAG(IS_TIZEN_TV)
104 #include "common/application_type.h"
105 #include "devtools_port_manager.h"
106 #include "public/ewk_media_downloadable_font_info.h"
107 #endif // OS_TIZEN_TV_PRODUCT
109 using namespace content;
110 using web_contents_utils::WebViewFromWebContents;
114 const int kTitleLengthMax = 80;
115 const base::FilePath::CharType kMHTMLFileNameExtension[] =
116 FILE_PATH_LITERAL(".mhtml");
117 const base::FilePath::CharType kMHTMLExtension[] = FILE_PATH_LITERAL("mhtml");
118 const base::FilePath::CharType kDefaultFileName[] =
119 FILE_PATH_LITERAL("saved_page");
120 const char kReplaceChars[] = " ";
121 const char kReplaceWith[] = "_";
123 static const char* kRendererCrashedHTMLMessage =
124 "<html><body><h1>Renderer process has crashed!</h1></body></html>";
126 // "visible,content,changed" is an email-app specific signal which informs
127 // that the web view is only partially visible.
128 static const char* kVisibleContentChangedSignalName = "visible,content,changed";
130 // email-app specific signal which informs that custom scrolling is started.
131 const char* kCustomScrollBeginSignalName = "custom,scroll,begin";
133 // email-app specific signal which informs that custom scrolling is finished.
134 const char* kCustomScrollEndSignalName = "custom,scroll,end";
136 const float kDelayShowContextMenuTime = 0.2f;
138 inline void SetDefaultStringIfNull(const char*& variable,
139 const char* default_string) {
141 variable = default_string;
145 void GetEinaRectFromGfxRect(const gfx::Rect& gfx_rect,
146 Eina_Rectangle* eina_rect) {
147 eina_rect->x = gfx_rect.x();
148 eina_rect->y = gfx_rect.y();
149 eina_rect->w = gfx_rect.width();
150 eina_rect->h = gfx_rect.height();
153 #if BUILDFLAG(IS_TIZEN)
154 static Eina_Bool RotateWindowCb(void* data, int type, void* event) {
155 auto wv = static_cast<EWebView*>(data);
157 ecore_evas_rotation_get(ecore_evas_ecore_evas_get(wv->GetEvas())));
158 return ECORE_CALLBACK_PASS_ON;
162 static content::WebContents* NullCreateWebContents(void*) {
166 base::FilePath GenerateMHTMLFilePath(const GURL& url,
167 const std::string& title,
168 const std::string& base_path) {
169 base::FilePath file_path(base_path);
171 if (base::DirectoryExists(file_path)) {
172 std::string title_part(title.substr(0, kTitleLengthMax));
173 base::ReplaceChars(title_part, kReplaceChars, kReplaceWith, &title_part);
174 base::FilePath file_name =
175 net::GenerateFileName(url, std::string(), std::string(), title_part,
176 std::string(), kDefaultFileName);
177 DCHECK(!file_name.empty());
178 file_path = file_path.Append(file_name);
181 if (file_path.Extension().empty())
182 file_path = file_path.AddExtension(kMHTMLExtension);
183 else if (!file_path.MatchesExtension(kMHTMLFileNameExtension))
184 file_path = file_path.ReplaceExtension(kMHTMLExtension);
186 if (!base::PathExists(file_path))
189 int uniquifier = base::GetUniquePathNumber(file_path);
190 if (uniquifier > 0) {
191 return file_path.InsertBeforeExtensionASCII(
192 base::StringPrintf(" (%d)", uniquifier));
195 return base::FilePath();
198 SelectPickerBase* CreateSelectPicker(
201 std::vector<blink::mojom::MenuItemPtr> items,
202 bool is_multiple_selection,
203 const gfx::Rect& bounds) {
204 SelectPickerBase* picker;
207 new SelectPickerTv(web_view, selected_index, is_multiple_selection);
210 new SelectPickerMobile(web_view, selected_index, is_multiple_selection);
212 // Create two separate Elm_Genlist_Item_Class classes, because EFL cannot swap
213 // item_style at runtime.
214 picker->InitializeItemClass();
215 picker->InitializeGroupClass();
216 picker->Init(std::move(items), bounds);
222 class WebViewAsyncRequestHitTestDataCallback {
224 WebViewAsyncRequestHitTestDataCallback(int x, int y, Ewk_Hit_Test_Mode mode)
225 : x_(x), y_(y), mode_(mode) {}
226 virtual ~WebViewAsyncRequestHitTestDataCallback(){};
228 virtual void Run(_Ewk_Hit_Test* hit_test, EWebView* web_view) = 0;
231 int GetX() const { return x_; }
232 int GetY() const { return y_; }
233 Ewk_Hit_Test_Mode GetMode() const { return mode_; }
238 Ewk_Hit_Test_Mode mode_;
241 class WebViewAsyncRequestHitTestDataUserCallback
242 : public WebViewAsyncRequestHitTestDataCallback {
244 WebViewAsyncRequestHitTestDataUserCallback(
247 Ewk_Hit_Test_Mode mode,
248 Ewk_View_Hit_Test_Request_Callback callback,
250 : WebViewAsyncRequestHitTestDataCallback(x, y, mode),
252 user_data_(user_data) {}
254 void Run(_Ewk_Hit_Test* hit_test, EWebView* web_view) override {
256 callback_(web_view->evas_object(), GetX(), GetY(), GetMode(), hit_test,
261 Ewk_View_Hit_Test_Request_Callback callback_;
265 #if defined(TIZEN_ATK_SUPPORT)
266 class EWebAccessibilityObserver : public EWebAccessibility::Observer {
268 explicit EWebAccessibilityObserver(EWebView* webview) : webview_(webview) {}
269 virtual ~EWebAccessibilityObserver() {}
271 // EWebAccessibility::Observer implementation
272 void OnSpatialNavigationStatusChanged(Eina_Bool enable) override {
273 webview_->UpdateSpatialNavigationStatus(enable);
276 void OnAccessibilityStatusChanged(Eina_Bool enable) override {
277 webview_->UpdateAccessibilityStatus(enable);
285 int EWebView::find_request_id_counter_ = 0;
286 content::WebContentsEflDelegate::WebContentsCreateCallback
287 EWebView::create_new_window_web_contents_cb_ =
288 base::BindRepeating(&NullCreateWebContents);
290 EWebView* EWebView::FromEvasObject(Evas_Object* eo) {
291 return WebViewDelegateEwk::GetInstance().GetWebViewFromEvasObject(eo);
294 void EWebView::OnViewFocusIn(void* data, Evas*, Evas_Object*, void*) {
295 auto view = static_cast<EWebView*>(data);
296 view->SetFocus(EINA_TRUE);
299 void EWebView::OnViewFocusOut(void* data, Evas*, Evas_Object*, void*) {
300 auto view = static_cast<EWebView*>(data);
301 view->SetFocus(EINA_FALSE);
304 void EWebView::VisibleContentChangedCallback(void* user_data,
305 Evas_Object* /*object*/,
307 auto view = static_cast<EWebView*>(user_data);
308 auto rect = static_cast<Eina_Rectangle*>(event_info);
309 view->GetSelectionController()->SetCustomVisibleViewRect(
310 gfx::Rect(rect->x, rect->y, rect->w, rect->h));
313 void EWebView::OnCustomScrollBeginCallback(void* user_data,
314 Evas_Object* /*object*/,
315 void* /*event_info*/) {
316 auto* view = static_cast<EWebView*>(user_data);
317 if (auto* selection_controller = view->GetSelectionController())
318 selection_controller->SetControlsTemporarilyHidden(true,true);
321 void EWebView::OnCustomScrollEndCallback(void* user_data,
322 Evas_Object* /*object*/,
323 void* /*event_info*/) {
324 auto* view = static_cast<EWebView*>(user_data);
325 if (auto* selection_controller = view->GetSelectionController())
326 selection_controller->SetControlsTemporarilyHidden(false,true);
329 EWebView::EWebView(Ewk_Context* context, Evas_Object* object)
331 evas_object_(object),
332 native_view_(object),
333 mouse_events_enabled_(false),
334 text_zoom_factor_(1.0),
335 current_find_request_id_(find_request_id_counter_++),
337 hit_test_completion_(base::WaitableEvent::ResetPolicy::AUTOMATIC,
338 base::WaitableEvent::InitialState::NOT_SIGNALED),
339 page_scale_factor_(1.0),
342 #if BUILDFLAG(IS_TIZEN_TV)
343 use_early_rwi_(false),
344 rwi_info_showed_(false),
346 is_initialized_(false) {
348 evas_object_smart_callback_add(evas_object_,
349 kVisibleContentChangedSignalName,
350 VisibleContentChangedCallback, this);
352 evas_object_smart_callback_add(evas_object_, kCustomScrollBeginSignalName,
353 OnCustomScrollBeginCallback, this);
354 evas_object_smart_callback_add(evas_object_, kCustomScrollEndSignalName,
355 OnCustomScrollEndCallback, this);
356 evas_object_event_callback_add(evas_object_, EVAS_CALLBACK_FOCUS_IN,
357 OnViewFocusIn, this);
358 evas_object_event_callback_add(evas_object_, EVAS_CALLBACK_FOCUS_OUT,
359 OnViewFocusOut, this);
360 #if BUILDFLAG(IS_TIZEN)
361 window_rotate_handler_ = ecore_event_handler_add(
362 ECORE_WL2_EVENT_WINDOW_ROTATE, RotateWindowCb, this);
367 void EWebView::Initialize() {
368 if (is_initialized_) {
374 evas_event_handler_ = new WebViewEvasEventHandler(this);
376 scroll_detector_.reset(new ScrollDetector(this));
378 DCHECK(web_contents_->GetRenderViewHost());
379 // Settings (content::WebPreferences) will be initalized by
380 // RenderViewHostImpl::ComputeWebkitPrefs() based on command line switches.
381 settings_.reset(new Ewk_Settings(evas_object_,
382 web_contents_->GetOrCreateWebPreferences()));
383 #if defined(TIZEN_ATK_SUPPORT)
384 std::unique_ptr<EWebAccessibilityObserver> observer(
385 new EWebAccessibilityObserver(this));
386 eweb_accessibility_.reset(new EWebAccessibility(
387 evas_object_, web_contents_.get(), std::move(observer)));
388 lazy_initialize_atk_ = true;
391 base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess();
392 if (cmdline->HasSwitch(switches::kTouchEventFeatureDetection)) {
393 SetTouchEventsEnabled(
394 cmdline->GetSwitchValueASCII(switches::kTouchEventFeatureDetection) ==
395 switches::kTouchEventFeatureDetectionEnabled);
397 SetMouseEventsEnabled(true);
400 std::string user_agent =
401 EflWebView::VersionInfo::GetInstance()->DefaultUserAgent();
402 web_contents_->SetUserAgentOverride(
403 blink::UserAgentOverride::UserAgentOnly(user_agent),
404 false /* override_in_new_tabs */);
406 elm_object_tree_focus_allow_set(native_view_, EINA_TRUE);
407 is_initialized_ = true;
408 evas_object_event_callback_add(native_view_, EVAS_CALLBACK_RESIZE,
409 EWebView::NativeViewResize, this);
411 auto cbce = static_cast<ContentBrowserClientEfl*>(
412 content::GetContentClientExport()->browser());
413 // Initialize accept languages
414 SyncAcceptLanguages(cbce->GetAcceptLangs(nullptr));
415 accept_langs_changed_callback_ =
416 base::BindOnce(&EWebView::SyncAcceptLanguages, base::Unretained(this));
417 cbce->AddAcceptLangsChangedCallback(
418 std::move(accept_langs_changed_callback_));
420 // If EWebView is created by window.open, RenderView is already created
421 // before initializing WebContents. So we should manually invoke
422 // EWebView::RenderViewReady here.
423 if (web_contents_->GetPrimaryMainFrame() &&
424 web_contents_->GetPrimaryMainFrame()->IsRenderFrameLive()) {
429 EWebView::~EWebView() {
430 auto cbce = static_cast<ContentBrowserClientEfl*>(
431 content::GetContentClientExport()->browser());
432 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
433 cbce->RemoveAcceptLangsChangedCallback(
434 std::move(accept_langs_changed_callback_));
437 evas_object_event_callback_del(native_view_, EVAS_CALLBACK_RESIZE,
438 EWebView::NativeViewResize);
439 #if defined(USE_WAYLAND)
440 if (GetSettings()->getClipboardEnabled())
441 ClipboardHelperEfl::GetInstance()->MaybeInvalidateActiveWebview(this);
444 std::map<int64_t, WebViewAsyncRequestHitTestDataCallback*>::iterator
445 hit_test_callback_iterator;
446 for (hit_test_callback_iterator = hit_test_callback_.begin();
447 hit_test_callback_iterator != hit_test_callback_.end();
448 hit_test_callback_iterator++)
449 delete hit_test_callback_iterator->second;
450 hit_test_callback_.clear();
452 for (auto iter = delayed_messages_.begin(); iter != delayed_messages_.end();
456 delayed_messages_.clear();
458 if (!is_initialized_) {
462 #if defined(TIZEN_ATK_SUPPORT)
463 eweb_accessibility_.reset();
466 #if defined(TIZEN_AUTOFILL_FW)
467 if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
468 autofill::switches::kDisableAutofill)) {
469 autofill::AutofillRequestManager::GetInstance()->RemoveRequest(
474 select_picker_.reset();
475 context_menu_.reset();
476 mhtml_callback_map_.Clear();
478 compositor_observer_.reset();
480 // Release manually those scoped pointers to
481 // make sure they are released in correct order
482 web_contents_.reset();
483 web_contents_delegate_.reset();
485 // This code must be executed after WebContents deletion
486 // because WebContents depends on BrowserContext which
487 // is deleted along with EwkContext.
488 CHECK(!web_contents_);
490 permission_popup_manager_.reset();
492 gin_native_bridge_dispatcher_host_.reset();
495 evas_object_event_callback_del(evas_object_, EVAS_CALLBACK_FOCUS_IN,
497 evas_object_event_callback_del(evas_object_, EVAS_CALLBACK_FOCUS_OUT,
499 evas_object_smart_callback_del(evas_object_,
500 kVisibleContentChangedSignalName,
501 VisibleContentChangedCallback);
502 evas_object_smart_callback_del(evas_object_, kCustomScrollBeginSignalName,
503 OnCustomScrollBeginCallback);
504 evas_object_smart_callback_del(evas_object_, kCustomScrollEndSignalName,
505 OnCustomScrollEndCallback);
509 content::RenderWidgetHostViewAura* EWebView::rwhva() const {
510 return static_cast<content::RenderWidgetHostViewAura*>(
511 web_contents_->GetRenderWidgetHostView());
514 content::WebContentsViewAura* EWebView::wcva() const {
515 WebContentsImpl* wc = static_cast<WebContentsImpl*>(web_contents_.get());
516 return static_cast<WebContentsViewAura*>(wc->GetView());
519 void EWebView::NativeViewResize(void* data,
523 auto thiz = static_cast<EWebView*>(data);
524 if (!thiz->context_menu_)
526 int native_view_x, native_view_y, native_view_width, native_view_height;
527 evas_object_geometry_get(obj, &native_view_x, &native_view_y,
528 &native_view_width, &native_view_height);
529 gfx::Rect webview_rect(native_view_x, native_view_y, native_view_width,
531 thiz->context_menu_->Resize(webview_rect);
534 void EWebView::ResetContextMenuController() {
535 return context_menu_.reset();
538 void EWebView::SetFocus(Eina_Bool focus) {
539 if (!web_contents_ || !rwhva() || (HasFocus() == focus))
542 rwhva()->offscreen_helper()->Focus(focus);
545 Eina_Bool EWebView::HasFocus() const {
549 return rwhva()->offscreen_helper()->HasFocus() ? EINA_TRUE : EINA_FALSE;
552 Eina_Bool EWebView::AddJavaScriptMessageHandler(
554 Ewk_View_Script_Message_Cb callback,
556 if (!gin_native_bridge_dispatcher_host_)
559 return gin_native_bridge_dispatcher_host_->AddNamedObject(view, callback,
563 bool EWebView::SetPageVisibility(
564 Ewk_Page_Visibility_State page_visibility_state) {
568 // TODO: We should able to set 'prerender' or 'unloaded' as visibility state.
569 // http://www.w3.org/TR/page-visibility/#dom-document-visibilitystate
570 switch (page_visibility_state) {
571 case EWK_PAGE_VISIBILITY_STATE_VISIBLE:
572 rwhva()->offscreen_helper()->SetPageVisibility(true);
574 case EWK_PAGE_VISIBILITY_STATE_HIDDEN:
575 rwhva()->offscreen_helper()->SetPageVisibility(false);
577 case EWK_PAGE_VISIBILITY_STATE_PRERENDER:
587 bool EWebView::CreateNewWindow(
588 content::WebContentsEflDelegate::WebContentsCreateCallback cb) {
589 create_new_window_web_contents_cb_ = cb;
590 Evas_Object* new_object = NULL;
591 SmartCallback<EWebViewCallbacks::CreateNewWindow>().call(&new_object);
592 create_new_window_web_contents_cb_ =
593 base::BindRepeating(&NullCreateWebContents);
598 Evas_Object* EWebView::GetHostWindowDelegate(const content::WebContents* wc) {
599 EWebView* thiz = WebViewFromWebContents(wc);
600 DCHECK(thiz->evas_object_);
601 Evas_Object* parent = evas_object_above_get(thiz->evas_object_);
603 LOG(WARNING) << "Could not find and visual parents for EWK smart object!.";
604 return thiz->evas_object_;
607 if (elm_object_widget_check(parent)) {
608 Evas_Object* elm_parent = elm_object_top_widget_get(parent);
614 LOG(WARNING) << "Could not find elementary parent for WebView object!";
615 return thiz->evas_object_;
618 Evas_Object* EWebView::GetElmWindow() const {
619 Evas_Object* parent = elm_object_parent_widget_get(evas_object_);
620 return parent ? elm_object_top_widget_get(parent) : nullptr;
623 void EWebView::SetURL(const GURL& url, bool from_api) {
624 NavigationController::LoadURLParams params(url);
627 params.transition_type = ui::PageTransitionFromInt(
628 ui::PAGE_TRANSITION_LINK | ui::PAGE_TRANSITION_FROM_API);
631 #if BUILDFLAG(IS_TIZEN_TV)
632 if (use_early_rwi_) {
633 LOG(INFO) << "[FAST RWI] SetURL Replace [" << url.spec()
634 << "] to [about:blank]";
636 params.url = GURL("about:blank");
640 params.override_user_agent = NavigationController::UA_OVERRIDE_TRUE;
641 web_contents_->GetController().LoadURLWithParams(params);
644 const GURL& EWebView::GetURL() const {
645 return web_contents_->GetVisibleURL();
648 const GURL& EWebView::GetOriginalURL() const {
649 const auto entry = web_contents_->GetController().GetVisibleEntry();
651 return entry->GetOriginalRequestURL();
653 return web_contents_->GetVisibleURL();
656 void EWebView::Reload() {
657 web_contents_->GetController().Reload(content::ReloadType::NORMAL, true);
660 void EWebView::ReloadBypassingCache() {
661 web_contents_->GetController().Reload(content::ReloadType::BYPASSING_CACHE,
665 Eina_Bool EWebView::CanGoBack() {
666 return web_contents_->GetController().CanGoBack();
669 Eina_Bool EWebView::CanGoForward() {
670 return web_contents_->GetController().CanGoForward();
673 Eina_Bool EWebView::GoBack() {
674 if (!web_contents_->GetController().CanGoBack())
677 #if defined(TIZEN_AUTOFILL_FW)
678 if (web_contents_delegate_)
679 web_contents_delegate_->ResetLastInteractedElements();
682 web_contents_->GetController().GoBack();
686 Eina_Bool EWebView::GoForward() {
687 if (!web_contents_->GetController().CanGoForward())
690 web_contents_->GetController().GoForward();
694 void EWebView::Stop() {
695 if (web_contents_->IsLoading())
696 web_contents_->Stop();
699 void EWebView::Suspend() {
700 CHECK(web_contents_);
701 #if BUILDFLAG(IS_TIZEN)
702 if (IsMobileProfile() && web_contents_->IsFullscreen())
703 web_contents_->ExitFullscreen(true);
705 RenderViewHost* rvh = web_contents_->GetRenderViewHost();
706 RenderFrameHost* rfh = web_contents_->GetPrimaryMainFrame();
709 #if !defined(EWK_BRINGUP) // FIXME: m69 bringup
710 rfh->BlockRequestsForFrame();
713 content::GetIOThreadTaskRunner({})->PostTask(FROM_HERE, base::BindOnce(
714 &content::ResourceDispatcherHost::BlockRequestsForFrameFromUI, rfh));
717 rvh->Send(new EwkViewMsg_SuspendScheduledTask(rvh->GetRoutingID()));
721 void EWebView::Resume() {
722 CHECK(web_contents_);
723 RenderViewHost* rvh = web_contents_->GetRenderViewHost();
724 RenderFrameHost* rfh = web_contents_->GetPrimaryMainFrame();
727 #if !defined(EWK_BRINGUP) // FIXME: m69 bringup
728 rfh->ResumeBlockedRequestsForFrame();
731 content::GetIOThreadTaskRunner({})->PostTask(FROM_HERE, base::BindOnce(
732 &content::ResourceDispatcherHost::ResumeBlockedRequestsForFrameFromUI,
736 rvh->Send(new EwkViewMsg_ResumeScheduledTasks(rvh->GetRoutingID()));
740 double EWebView::GetTextZoomFactor() const {
741 if (text_zoom_factor_ < 0.0)
744 return text_zoom_factor_;
747 void EWebView::SetTextZoomFactor(double text_zoom_factor) {
748 if (text_zoom_factor_ == text_zoom_factor || text_zoom_factor < 0.0)
751 text_zoom_factor_ = text_zoom_factor;
752 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
753 if (!render_view_host)
755 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
756 render_view_host->Send(new ViewMsg_SetTextZoomFactor(
757 render_view_host->GetRoutingID(), text_zoom_factor));
761 double EWebView::GetPageZoomFactor() const {
762 return blink::PageZoomLevelToZoomFactor(
763 content::HostZoomMap::GetZoomLevel(web_contents_.get()));
766 void EWebView::SetPageZoomFactor(double page_zoom_factor) {
767 content::HostZoomMap::SetZoomLevel(
768 web_contents_.get(), blink::PageZoomFactorToZoomLevel(page_zoom_factor));
771 void EWebView::ExecuteEditCommand(const char* command, const char* value) {
772 EINA_SAFETY_ON_NULL_RETURN(command);
774 absl::optional<std::u16string> optional_value;
775 if (value == nullptr)
776 optional_value = absl::nullopt;
778 optional_value = absl::make_optional(base::ASCIIToUTF16(value));
780 WebContentsImpl* wc = static_cast<WebContentsImpl*>(web_contents_.get());
782 wc->GetFocusedFrameWidgetInputHandler()->ExecuteEditCommand(
783 std::string(command), optional_value);
787 #if BUILDFLAG(IS_TIZEN)
788 void EWebView::EnterDragState() {
789 if (IsMobileProfile()) {
790 if (RenderViewHost* render_view_host = web_contents_->GetRenderViewHost())
791 web_contents_->EnterDragState(render_view_host);
796 void EWebView::SetOrientation(int orientation) {
797 if (GetOrientation() == orientation)
800 if (orientation == 0 || orientation == 90 || orientation == 180 ||
801 orientation == 270) {
802 #if !defined(USE_AURA)
803 GetWebContentsViewEfl()->SetOrientation(orientation);
807 const Ecore_Evas* ee =
808 ecore_evas_ecore_evas_get(evas_object_evas_get(evas_object_));
809 ecore_evas_screen_geometry_get(ee, nullptr, nullptr, &width, &height);
810 if (orientation == 90 || orientation == 270)
811 std::swap(width, height);
813 if (popup_controller_)
814 popup_controller_->SetPopupSize(width, height);
815 if (JavaScriptDialogManagerEfl* dialogMG = GetJavaScriptDialogManagerEfl())
816 dialogMG->SetPopupSize(width, height);
820 int EWebView::GetOrientation() {
821 #if !defined(USE_AURA)
822 return GetWebContentsViewEfl()->GetOrientation();
828 void EWebView::Show() {
829 evas_object_show(native_view_);
830 web_contents_->WasShown();
833 void EWebView::Hide() {
834 evas_object_hide(native_view_);
835 web_contents_->WasHidden();
838 void EWebView::SetViewAuthCallback(Ewk_View_Authentication_Callback callback,
840 authentication_cb_.Set(callback, user_data);
843 void EWebView::InvokeAuthCallback(LoginDelegateEfl* login_delegate,
845 const std::string& realm) {
846 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
848 auth_challenge_.reset(new _Ewk_Auth_Challenge(login_delegate, url, realm));
849 authentication_cb_.Run(evas_object_, auth_challenge_.get());
851 if (!auth_challenge_->is_decided && !auth_challenge_->is_suspended) {
852 auth_challenge_->is_decided = true;
853 auth_challenge_->login_delegate->Cancel();
857 void EWebView::InvokePolicyResponseCallback(
858 _Ewk_Policy_Decision* policy_decision,
860 SmartCallback<EWebViewCallbacks::PolicyResponseDecide>().call(
863 if (policy_decision->isSuspended()) {
868 if (!policy_decision->isDecided())
869 policy_decision->Use();
871 policy_decision->SelfDeleteIfNecessary();
874 void EWebView::InvokePolicyNavigationCallback(
875 const NavigationPolicyParams& params,
877 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
879 SmartCallback<EWebViewCallbacks::SaveSessionData>().call();
881 std::unique_ptr<_Ewk_Policy_Decision> policy_decision(
882 new _Ewk_Policy_Decision(params));
884 SmartCallback<EWebViewCallbacks::NavigationPolicyDecision>().call(
885 policy_decision.get());
887 CHECK(!policy_decision->isSuspended());
889 // TODO: Navigation can't be suspended
890 // this aproach is synchronous and requires immediate response
891 // Maybe there is different approach (like resource throttle response
892 // mechanism) that allows us to
893 // suspend navigation
894 if (!policy_decision->isDecided())
895 policy_decision->Use();
897 *handled = policy_decision->GetNavigationPolicyHandler()->GetDecision() ==
898 NavigationPolicyHandlerEfl::Handled;
901 void EWebView::HandleTouchEvents(Ewk_Touch_Event_Type type,
902 const Eina_List* points,
903 const Evas_Modifier* modifiers) {
907 if (GetSettings()->touchFocusEnabled() &&
908 (type == EWK_TOUCH_START && eina_list_count(points) == 1)) {
912 EINA_LIST_FOREACH(points, l, data) {
913 const Ewk_Touch_Point* point = static_cast<Ewk_Touch_Point*>(data);
914 if (point->state == EVAS_TOUCH_POINT_STILL) {
915 // Chromium doesn't expect (and doesn't like) these events.
924 evas_object_geometry_get(evas_object(), nullptr, &delta_y, nullptr,
926 ui::TouchEvent touch_event =
927 ui::MakeTouchEvent(pt, point->state, point->id, 0, delta_y);
928 rwhva()->OnTouchEvent(&touch_event);
933 bool EWebView::TouchEventsEnabled() const {
934 return rwhva()->offscreen_helper()->TouchEventsEnabled();
937 // TODO: Touch events use the same mouse events in EFL API.
938 // Figure out how to distinguish touch and mouse events on touch&mice devices.
939 // Currently mouse and touch support is mutually exclusive.
940 void EWebView::SetTouchEventsEnabled(bool enabled) {
941 if (!rwhva() || !rwhva()->offscreen_helper()) {
942 LOG(WARNING) << "RWHV is not created yet!";
946 if (rwhva()->offscreen_helper()->TouchEventsEnabled() == enabled)
949 rwhva()->offscreen_helper()->SetTouchEventsEnabled(enabled);
951 GetSettings()->getPreferences().touch_event_feature_detection_enabled =
953 GetSettings()->getPreferences().double_tap_to_zoom_enabled = enabled;
954 GetSettings()->getPreferences().editing_behavior =
955 enabled ? blink::mojom::EditingBehavior::kEditingAndroidBehavior
956 : blink::mojom::EditingBehavior::kEditingUnixBehavior,
957 UpdateWebKitPreferences();
960 bool EWebView::MouseEventsEnabled() const {
961 return mouse_events_enabled_;
964 void EWebView::SetMouseEventsEnabled(bool enabled) {
965 if (!rwhva() || !rwhva()->offscreen_helper()) {
966 LOG(WARNING) << "RWHV is not created yet!";
970 if (mouse_events_enabled_ == enabled)
973 mouse_events_enabled_ = enabled;
974 rwhva()->offscreen_helper()->SetTouchEventsEnabled(!enabled);
979 class JavaScriptCallbackDetails {
981 JavaScriptCallbackDetails(Ewk_View_Script_Execute_Callback callback_func,
984 : callback_func_(callback_func), user_data_(user_data), view_(view) {}
986 Ewk_View_Script_Execute_Callback callback_func_;
991 void JavaScriptComplete(JavaScriptCallbackDetails* script_callback_data,
992 base::Value result) {
993 if (!script_callback_data->callback_func_)
996 std::string return_string;
997 if (result.is_string()) {
998 // We don't want to serialize strings with JSONStringValueSerializer
999 // to avoid quotation marks.
1000 return_string = result.GetString();
1001 } else if (result.is_none()) {
1002 // Value::TYPE_NULL is for lack of value, undefined, null
1005 JSONStringValueSerializer serializer(&return_string);
1006 serializer.Serialize(result);
1009 script_callback_data->callback_func_(script_callback_data->view_,
1010 return_string.c_str(),
1011 script_callback_data->user_data_);
1016 bool EWebView::ExecuteJavaScript(const char* script,
1017 Ewk_View_Script_Execute_Callback callback,
1019 LOG(INFO) << __FUNCTION__;
1020 if (!web_contents_) {
1021 LOG(ERROR) << __FUNCTION__ << "web_contents_ is null";
1025 RenderFrameHost* render_frame_host = web_contents_->GetPrimaryMainFrame();
1026 if (!render_frame_host) {
1027 LOG(ERROR) << __FUNCTION__ << " render_frame_host is null";
1031 // Note: M37. Execute JavaScript, |script| with
1032 // |RenderFrameHost::ExecuteJavaScript|.
1033 // @see also https://codereview.chromium.org/188893005 for more details.
1034 std::u16string js_script;
1035 base::UTF8ToUTF16(script, strlen(script), &js_script);
1037 JavaScriptCallbackDetails* script_callback_data =
1038 new JavaScriptCallbackDetails(callback, userdata, evas_object_);
1039 RenderFrameHost::JavaScriptResultCallback js_callback =
1040 base::BindOnce(&JavaScriptComplete, base::Owned(script_callback_data));
1041 // In M47, it isn't possible anymore to execute javascript in the generic
1042 // case. We need to call ExecuteJavaScriptForTests to keep the behaviour
1043 // unchanged @see https://codereview.chromium.org/1123783002
1044 render_frame_host->ExecuteJavaScriptWithUserGestureForTests(
1045 js_script, std::move(js_callback));
1047 // We use ExecuteJavaScriptWithUserGestureForTests instead of
1048 // ExecuteJavaScript because
1049 // ExecuteJavaScriptWithUserGestureForTests sets user_gesture to true. This
1051 // behaviour is m34, and we want to keep it that way.
1052 render_frame_host->ExecuteJavaScriptWithUserGestureForTests(
1053 js_script, base::NullCallback());
1059 bool EWebView::SetUserAgent(const char* userAgent) {
1060 content::NavigationController& controller = web_contents_->GetController();
1061 bool override = userAgent && strlen(userAgent);
1062 for (int i = 0; i < controller.GetEntryCount(); ++i)
1063 controller.GetEntryAtIndex(i)->SetIsOverridingUserAgent(override);
1064 // TODO: Check if override_in_new_tabs has to be true.
1065 web_contents_->SetUserAgentOverride(
1066 blink::UserAgentOverride::UserAgentOnly(userAgent),
1067 false /* override_in_new_tabs */);
1071 bool EWebView::SetUserAgentAppName(const char* application_name) {
1072 EflWebView::VersionInfo::GetInstance()->UpdateUserAgentWithAppName(
1073 application_name ? application_name : "");
1074 std::string user_agent =
1075 EflWebView::VersionInfo::GetInstance()->DefaultUserAgent();
1076 web_contents_->SetUserAgentOverride(
1077 blink::UserAgentOverride::UserAgentOnly(user_agent),
1078 false /* override_in_new_tabs */);
1082 #if BUILDFLAG(IS_TIZEN)
1083 bool EWebView::SetPrivateBrowsing(bool incognito) {
1084 if (context_->GetImpl()->browser_context()->IsOffTheRecord() == incognito)
1086 context_->GetImpl()->browser_context()->SetOffTheRecord(incognito);
1090 bool EWebView::GetPrivateBrowsing() const {
1091 return context_->GetImpl()->browser_context()->IsOffTheRecord();
1095 const char* EWebView::GetUserAgent() const {
1096 std::string user_agent =
1097 web_contents_->GetUserAgentOverride().ua_string_override;
1098 if (user_agent.empty())
1099 user_agent_ = content::GetContentClientExport()->browser()->GetUserAgent();
1101 user_agent_ = user_agent;
1103 return user_agent_.c_str();
1106 const char* EWebView::GetUserAgentAppName() const {
1107 user_agent_app_name_ = EflWebView::VersionInfo::GetInstance()->AppName();
1108 return user_agent_app_name_.c_str();
1111 const char* EWebView::CacheSelectedText() {
1115 selected_text_cached_ = base::UTF16ToUTF8(rwhva()->GetSelectedText());
1116 return selected_text_cached_.c_str();
1119 _Ewk_Frame* EWebView::GetMainFrame() {
1120 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1123 frame_.reset(new _Ewk_Frame(web_contents_->GetPrimaryMainFrame()));
1125 return frame_.get();
1128 void EWebView::UpdateWebKitPreferences() {
1129 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1131 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1132 if (!render_view_host)
1135 web_contents_delegate_->OnUpdateSettings(settings_.get());
1136 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
1137 render_view_host->UpdateWebkitPreferences(settings_->getPreferences());
1139 UpdateWebkitPreferencesEfl(render_view_host);
1142 void EWebView::UpdateWebkitPreferencesEfl(RenderViewHost* render_view_host) {
1143 DCHECK(render_view_host);
1144 #if !defined(EWK_BRINGUP) // FIXME: m108 bringup
1145 IPC::Message* message = new EwkSettingsMsg_UpdateWebKitPreferencesEfl(
1146 render_view_host->GetRoutingID(), settings_->getPreferencesEfl());
1148 if (render_view_host->IsRenderViewLive()) {
1149 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
1150 render_view_host->Send(message);
1153 delayed_messages_.push_back(message);
1158 void EWebView::SetContentSecurityPolicy(const char* policy,
1159 Ewk_CSP_Header_Type type) {
1160 web_contents_delegate_->SetContentSecurityPolicy(
1161 (policy ? policy : std::string()), type);
1164 void EWebView::LoadHTMLString(const char* html,
1165 const char* base_uri,
1166 const char* unreachable_uri) {
1167 LoadData(html, std::string::npos, NULL, NULL, base_uri, unreachable_uri);
1170 void EWebView::LoadPlainTextString(const char* plain_text) {
1171 LoadData(plain_text, std::string::npos, "text/plain", NULL, NULL, NULL);
1174 void EWebView::LoadHTMLStringOverridingCurrentEntry(
1176 const char* base_uri,
1177 const char* unreachable_url) {
1178 LoadData(html, std::string::npos, NULL, NULL, base_uri, unreachable_url,
1182 void EWebView::LoadData(const char* data,
1184 const char* mime_type,
1185 const char* encoding,
1186 const char* base_uri,
1187 const char* unreachable_uri,
1188 bool should_replace_current_entry) {
1189 SetDefaultStringIfNull(mime_type, "text/html");
1190 SetDefaultStringIfNull(encoding, "utf-8");
1191 SetDefaultStringIfNull(base_uri, "about:blank"); // Webkit2 compatible
1192 SetDefaultStringIfNull(unreachable_uri, "");
1194 std::string str_data = data;
1196 if (size < str_data.length())
1197 str_data = str_data.substr(0, size);
1199 std::string url_str("data:");
1200 url_str.append(mime_type);
1201 url_str.append(";charset=");
1202 url_str.append(encoding);
1203 url_str.append(",");
1205 // GURL constructor performs canonicalization of url string, but this is not
1206 // enough for correctly escaping contents of "data:" url.
1207 url_str.append(base::EscapeUrlEncodedData(str_data, false));
1209 NavigationController::LoadURLParams data_params(GURL(url_str.c_str()));
1211 data_params.base_url_for_data_url = GURL(base_uri);
1212 data_params.virtual_url_for_data_url = GURL(unreachable_uri);
1214 data_params.load_type = NavigationController::LOAD_TYPE_DATA;
1215 data_params.should_replace_current_entry = should_replace_current_entry;
1216 data_params.override_user_agent = NavigationController::UA_OVERRIDE_TRUE;
1217 web_contents_->GetController().LoadURLWithParams(data_params);
1220 void EWebView::InvokeLoadError(const GURL& url,
1222 bool is_cancellation) {
1223 _Ewk_Error err(error_code, is_cancellation,
1224 url.possibly_invalid_spec().c_str());
1226 SmartCallback<EWebViewCallbacks::LoadError>().call(&err);
1229 void EWebView::SetViewLoadErrorPageCallback(
1230 Ewk_View_Error_Page_Load_Callback callback,
1232 load_error_page_cb_.Set(callback, user_data);
1235 // Remove below code while ewk_error_cancellation_get has been implemented.
1236 const char* EWebView::InvokeViewLoadErrorPageCallback(
1239 const std::string& error_description) {
1240 std::unique_ptr<_Ewk_Error> err(
1241 new _Ewk_Error(error_code, url.possibly_invalid_spec().c_str(),
1242 error_description.c_str()));
1243 _Ewk_Error_Page error_page;
1245 LOG(INFO) << "EWebView::InvokeLoadErrorPageCallback url: "
1246 << url.spec().c_str() << ", error_code: " << error_code;
1248 load_error_page_cb_.Run(evas_object_, err.get(), &error_page);
1249 return error_page.content;
1252 bool EWebView::IsLoadErrorPageCallbackSet() const {
1253 return load_error_page_cb_.IsCallbackSet();
1255 void EWebView::HandlePopupMenu(std::vector<blink::mojom::MenuItemPtr> items,
1258 const gfx::Rect& bounds) {
1259 if (!select_picker_) {
1260 select_picker_.reset(CreateSelectPicker(
1261 this, selectedIndex, std::move(items), multiple, bounds));
1263 // Picker has been shown on top of webview and the page content gets
1264 // partially overlapped. Decrease viewport while showing picker.
1265 AdjustViewPortHeightToPopupMenu(true /* is_popup_menu_visible */);
1266 #if BUILDFLAG(IS_TIZEN_TV)
1267 SmartCallback<EWebViewCallbacks::PopupMenuShow>().call();
1270 select_picker_->UpdatePickerData(selectedIndex, std::move(items), multiple);
1273 select_picker_->Show();
1276 void EWebView::HidePopupMenu() {
1277 if (!select_picker_)
1280 AdjustViewPortHeightToPopupMenu(false /* is_popup_menu_visible */);
1281 #if BUILDFLAG(IS_TIZEN_TV)
1282 SmartCallback<EWebViewCallbacks::PopupMenuHide>().call();
1284 select_picker_.reset();
1287 void EWebView::DidSelectPopupMenuItems(std::vector<int>& indices) {
1288 wcva()->wcva_helper()->DidSelectPopupMenuItems(indices);
1291 void EWebView::DidCancelPopupMenu() {
1292 wcva()->wcva_helper()->DidCancelPopupMenu();
1295 void EWebView::HandleLongPressGesture(
1296 const content::ContextMenuParams& params) {
1297 // This menu is created in renderer process and it does not now anything about
1298 // view scaling factor and it has another calling sequence, so coordinates is
1300 if (settings_ && !settings_->getPreferences().long_press_enabled)
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 if (GetSelectionController() && GetSelectionController()->GetLongPressed()) {
1316 bool show_context_menu_now =
1317 !GetSelectionController()->HandleLongPressEvent(convertedPoint,
1319 if (show_context_menu_now)
1320 ShowContextMenuInternal(convertedParams);
1324 void EWebView::ShowContextMenu(const content::ContextMenuParams& params) {
1328 // This menu is created in renderer process and it does not now anything about
1329 // view scaling factor and it has another calling sequence, so coordinates is
1331 content::ContextMenuParams convertedParams = params;
1332 gfx::Point convertedPoint =
1333 rwhva()->offscreen_helper()->ConvertPointInViewPix(
1334 gfx::Point(params.x, params.y));
1335 convertedParams.x = convertedPoint.x();
1336 convertedParams.y = convertedPoint.y();
1339 evas_object_geometry_get(evas_object(), &x, &y, 0, 0);
1340 convertedParams.x += x;
1341 convertedParams.y += y;
1343 context_menu_position_ = gfx::Point(convertedParams.x, convertedParams.y);
1345 ShowContextMenuInternal(convertedParams);
1348 void EWebView::ShowContextMenuInternal(
1349 const content::ContextMenuParams& params) {
1350 // We don't want to show 'cut' or 'copy' for inputs of type 'password' in
1351 // selection context menu, but params.input_field_type might not be set
1352 // correctly, because in some cases params is received from SelectionBoxEfl,
1353 // not from FrameHostMsg_ContextMenu message. In SelectionBoxEfl
1354 // ContextMenuParams is constructed on our side with limited information and
1355 // input_field_type is not set.
1357 // To work around this, we query for input type and set it separately. In
1358 // response to EwkViewMsg_QueryInputType we run ::UpdateContextMenu with
1359 // information about input's type.
1361 // FIXME: the way we get ContextMenuParams for context menu is flawed in some
1362 // cases. This should be fixed by restructuring context menu code.
1363 // Context menu creation should be unified to always have
1364 // ContextMenuParams received from FrameHostMsg_ContextMenu.
1365 // Tracked at: http://suprem.sec.samsung.net/jira/browse/TWF-1640
1366 if (params.is_editable) {
1367 saved_context_menu_params_ = params;
1369 rwhva()->host()->QueryInputType();
1371 UpdateContextMenuWithParams(params);
1375 void EWebView::UpdateContextMenu(bool is_password_input) {
1376 if (is_password_input) {
1377 saved_context_menu_params_.input_field_type =
1378 blink::mojom::ContextMenuDataInputFieldType::kPassword;
1380 UpdateContextMenuWithParams(saved_context_menu_params_);
1383 void EWebView::UpdateContextMenuWithParams(
1384 const content::ContextMenuParams& params) {
1385 context_menu_.reset(
1386 new content::ContextMenuControllerEfl(this, *web_contents_.get()));
1388 if (IsMobileProfile()) {
1389 if (delayed_show_context_menu_timer_) {
1390 ecore_timer_del(delayed_show_context_menu_timer_);
1391 delayed_show_context_menu_timer_ = nullptr;
1393 saved_context_menu_params_ = params;
1394 delayed_show_context_menu_timer_ = ecore_timer_add(
1395 kDelayShowContextMenuTime, DelayedPopulateAndShowContextMenu, this);
1397 if (!context_menu_->PopulateAndShowContextMenu(params)) {
1398 context_menu_.reset();
1399 if (GetSelectionController())
1400 GetSelectionController()->HideHandles();
1405 Eina_Bool EWebView::DelayedPopulateAndShowContextMenu(void* data) {
1406 if (IsMobileProfile) {
1407 EWebView* view = static_cast<EWebView*>(data);
1409 if (view->context_menu_ &&
1410 !(view->context_menu_->PopulateAndShowContextMenu(
1411 view->saved_context_menu_params_))) {
1412 view->context_menu_.reset();
1414 view->delayed_show_context_menu_timer_ = nullptr;
1417 return ECORE_CALLBACK_CANCEL;
1420 void EWebView::CancelContextMenu(int request_id) {
1422 context_menu_->HideContextMenu();
1425 void EWebView::Find(const char* text, Ewk_Find_Options ewk_find_options) {
1426 std::u16string find_text = base::UTF8ToUTF16(text);
1427 bool find_next = (previous_text_ == find_text);
1430 current_find_request_id_ = find_request_id_counter_++;
1431 previous_text_ = find_text;
1434 auto find_options = blink::mojom::FindOptions::New();
1435 find_options->forward = !(ewk_find_options & EWK_FIND_OPTIONS_BACKWARDS);
1436 find_options->match_case =
1437 !(ewk_find_options & EWK_FIND_OPTIONS_CASE_INSENSITIVE);
1439 web_contents_->Find(current_find_request_id_, find_text,
1440 std::move(find_options));
1443 void EWebView::SetScale(double scale_factor) {
1444 // Do not cache |scale_factor| here as it may be discarded by Blink's
1445 // minimumPageScaleFactor and maximumPageScaleFactor.
1446 // |scale_factor| is cached as responde to DidChangePageScaleFactor.
1447 WebContentsImpl* wci = static_cast<WebContentsImpl*>(web_contents_.get());
1448 wci->GetPrimaryMainFrame()->GetAssociatedLocalMainFrame()->SetScaleFactor(
1452 void EWebView::ScrollFocusedNodeIntoView() {
1453 if (RenderViewHost* render_view_host = web_contents_->GetRenderViewHost()) {
1454 if (auto& broadcast = static_cast<RenderViewHostImpl*>(render_view_host)
1455 ->GetAssociatedPageBroadcast())
1456 broadcast->ScrollFocusedNodeIntoView();
1460 void EWebView::AdjustViewPortHeightToPopupMenu(bool is_popup_menu_visible) {
1461 if (!rwhva() || !IsMobileProfile() ||
1462 settings_->getPreferences().TizenCompatibilityModeEnabled()) {
1466 int picker_height = select_picker_->GetGeometryDIP().height();
1467 gfx::Rect screen_rect =
1468 display::Screen::GetScreen()->GetPrimaryDisplay().bounds();
1469 gfx::Rect view_rect = rwhva()->offscreen_helper()->GetViewBounds();
1471 screen_rect.height() - (view_rect.y() + view_rect.height());
1473 rwhva()->offscreen_helper()->SetCustomViewportSize(
1474 is_popup_menu_visible
1475 ? gfx::Size(view_rect.width(),
1476 view_rect.height() - picker_height + bottom_height)
1480 void EWebView::SetScaleChangedCallback(Ewk_View_Scale_Changed_Callback callback,
1482 scale_changed_cb_.Set(callback, user_data);
1485 bool EWebView::GetScrollPosition(int* x, int* y) const {
1487 LOG(ERROR) << "rwhva() returns nullptr";
1490 if (scroll_detector_->IsScrollOffsetChanged()) {
1492 *x = previous_scroll_position_.x();
1494 *y = previous_scroll_position_.y();
1496 const gfx::Vector2d scroll_position_dip =
1497 scroll_detector_->GetLastScrollPosition();
1498 const float device_scale_factor = display::Screen::GetScreen()
1499 ->GetPrimaryDisplay()
1500 .device_scale_factor();
1502 *x = base::ClampRound((scroll_position_dip.x() - x_delta_) *
1503 device_scale_factor);
1506 *y = base::ClampRound((scroll_position_dip.y() - y_delta_) *
1507 device_scale_factor);
1513 void EWebView::ChangeScroll(int& x, int& y) {
1515 LOG(ERROR) << "rwhva() returns nullptr";
1520 GetScrollSize(&max_x, &max_y);
1521 previous_scroll_position_.set_x(std::min(std::max(x, 0), max_x));
1522 previous_scroll_position_.set_y(std::min(std::max(y, 0), max_y));
1524 const float device_scale_factor = display::Screen::GetScreen()
1525 ->GetPrimaryDisplay()
1526 .device_scale_factor();
1530 x = base::ClampCeil(x / device_scale_factor);
1531 y = base::ClampCeil(y / device_scale_factor);
1533 x_delta_ = x - (x_input / device_scale_factor);
1534 y_delta_ = y - (y_input / device_scale_factor);
1536 scroll_detector_->SetScrollOffsetChanged();
1539 void EWebView::SetScroll(int x, int y) {
1540 if (auto* render_view_host = web_contents_->GetRenderViewHost()) {
1541 if (auto& broadcast = static_cast<RenderViewHostImpl*>(render_view_host)
1542 ->GetAssociatedPageBroadcast()) {
1544 broadcast->SetScrollOffset(x, y);
1549 void EWebView::UseSettingsFont() {
1550 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
1551 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1552 if (render_view_host)
1553 render_view_host->Send(
1554 new EwkViewMsg_UseSettingsFont(render_view_host->GetRoutingID()));
1558 void EWebView::DidChangeContentsSize(int width, int height) {
1559 contents_size_ = gfx::Size(width, height);
1560 SmartCallback<EWebViewCallbacks::ContentsSizeChanged>().call();
1561 SetScaledContentsSize();
1564 const Eina_Rectangle EWebView::GetContentsSize() const {
1565 Eina_Rectangle rect;
1566 EINA_RECTANGLE_SET(&rect, 0, 0, contents_size_.width(),
1567 contents_size_.height());
1571 void EWebView::SetScaledContentsSize() {
1573 return; // LCOV_EXCL_LINE
1575 const float device_scale_factor =
1576 display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
1577 gfx::SizeF scaled_contents_size = gfx::ConvertSizeToPixels(
1578 contents_size_, device_scale_factor * page_scale_factor_);
1579 rwhva()->offscreen_helper()->SetScaledContentSize(scaled_contents_size);
1582 void EWebView::GetScrollSize(int* width, int* height) {
1585 *width = (rwhva() &&
1586 (w = rwhva()->offscreen_helper()->GetScrollableSize().width()))
1591 *height = (rwhva() &&
1592 (h = rwhva()->offscreen_helper()->GetScrollableSize().height()))
1598 void EWebView::MoveCaret(const gfx::Point& point) {
1600 rwhva()->offscreen_helper()->MoveCaret(point);
1603 SelectionControllerEfl* EWebView::GetSelectionController() const {
1604 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1605 RenderWidgetHostViewAura* view = static_cast<RenderWidgetHostViewAura*>(
1606 render_view_host->GetWidget()->GetView());
1607 return view ? view->offscreen_helper()->GetSelectionController() : 0;
1610 void EWebView::SelectFocusedLink() {
1611 rwhva()->host()->SelectFocusedLink();
1614 bool EWebView::GetSelectionRange(Eina_Rectangle* left_rect,
1615 Eina_Rectangle* right_rect) {
1616 if (left_rect && right_rect) {
1617 gfx::Rect left, right;
1618 if (GetSelectionController()) {
1619 GetSelectionController()->GetSelectionBounds(&left, &right);
1620 GetEinaRectFromGfxRect(left, left_rect);
1621 GetEinaRectFromGfxRect(right, right_rect);
1628 void EWebView::OnSelectionRectReceived(const gfx::Rect& selection_rect) const {
1630 context_menu_->OnSelectionRectReceived(selection_rect);
1633 Eina_Bool EWebView::ClearSelection() {
1637 ResetContextMenuController();
1638 rwhva()->offscreen_helper()->SelectionChanged(std::u16string(), 0,
1641 if (GetSelectionController())
1642 return GetSelectionController()->ClearSelectionViaEWebView();
1647 _Ewk_Hit_Test* EWebView::RequestHitTestDataAt(int x,
1649 Ewk_Hit_Test_Mode mode) {
1650 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1653 EvasToBlinkCords(x, y, &view_x, &view_y);
1655 return RequestHitTestDataAtBlinkCoords(view_x, view_y, mode);
1658 Eina_Bool EWebView::AsyncRequestHitTestDataAt(
1661 Ewk_Hit_Test_Mode mode,
1662 Ewk_View_Hit_Test_Request_Callback callback,
1665 EvasToBlinkCords(x, y, &view_x, &view_y);
1666 return AsyncRequestHitTestDataAtBlinkCords(
1667 view_x, view_y, mode,
1668 new WebViewAsyncRequestHitTestDataUserCallback(x, y, mode, callback,
1672 Eina_Bool EWebView::AsyncRequestHitTestDataAtBlinkCords(
1675 Ewk_Hit_Test_Mode mode,
1676 Ewk_View_Hit_Test_Request_Callback callback,
1678 return AsyncRequestHitTestDataAtBlinkCords(
1680 new WebViewAsyncRequestHitTestDataUserCallback(x, y, mode, callback,
1684 Eina_Bool EWebView::AsyncRequestHitTestDataAtBlinkCords(
1687 Ewk_Hit_Test_Mode mode,
1688 WebViewAsyncRequestHitTestDataCallback* cb) {
1689 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1692 static int64_t request_id = 1;
1695 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1696 DCHECK(render_view_host);
1698 if (render_view_host) {
1699 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
1700 render_view_host->Send(new EwkViewMsg_DoHitTestAsync(
1701 render_view_host->GetRoutingID(), x, y, mode, request_id));
1703 hit_test_callback_[request_id] = cb;
1709 // if failed we delete callback as it is not needed anymore
1714 void EWebView::DispatchAsyncHitTestData(const Hit_Test_Params& params,
1715 int64_t request_id) {
1716 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1718 std::map<int64_t, WebViewAsyncRequestHitTestDataCallback*>::iterator it =
1719 hit_test_callback_.find(request_id);
1721 if (it == hit_test_callback_.end())
1723 std::unique_ptr<_Ewk_Hit_Test> hit_test(new _Ewk_Hit_Test(params));
1725 it->second->Run(hit_test.get(), this);
1727 hit_test_callback_.erase(it);
1730 _Ewk_Hit_Test* EWebView::RequestHitTestDataAtBlinkCoords(
1733 Ewk_Hit_Test_Mode mode) {
1734 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1736 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1738 if (render_view_host) {
1739 // We wait on UI thread till hit test data is updated.
1740 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
1741 render_view_host->Send(
1742 new EwkViewMsg_DoHitTest(render_view_host->GetRoutingID(), x, y, mode));
1744 hit_test_completion_.Wait();
1745 return new _Ewk_Hit_Test(hit_test_params_);
1751 void EWebView::EvasToBlinkCords(int x, int y, int* view_x, int* view_y) {
1752 DCHECK(display::Screen::GetScreen());
1756 gfx::Rect view_bounds = rwhva()->offscreen_helper()->GetViewBoundsInPix();
1759 *view_x = x - view_bounds.x();
1761 display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
1765 *view_y = y - view_bounds.y();
1767 display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
1771 void EWebView::UpdateHitTestData(const Hit_Test_Params& params) {
1772 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
1773 hit_test_params_ = params;
1774 hit_test_completion_.Signal();
1777 void EWebView::OnCopyFromBackingStore(bool success, const SkBitmap& bitmap) {}
1779 void EWebView::OnFocusIn() {
1780 SmartCallback<EWebViewCallbacks::FocusIn>().call();
1781 #if defined(USE_WAYLAND)
1782 if (!rwhva() || !rwhva()->offscreen_helper())
1784 if (GetSettings()->getClipboardEnabled()) {
1785 ClipboardHelperEfl::GetInstance()->OnWebviewFocusIn(
1786 this, rwhva()->offscreen_helper()->content_image_elm_host(),
1787 rwhva()->offscreen_helper()->IsFocusedNodeContentEditable(),
1788 base::BindRepeating(&EWebView::ExecuteEditCommand,
1789 base::Unretained(this)));
1794 void EWebView::OnFocusOut() {
1795 SmartCallback<EWebViewCallbacks::FocusOut>().call();
1796 #if defined(USE_WAYLAND)
1797 if (GetSettings()->getClipboardEnabled())
1798 ClipboardHelperEfl::GetInstance()->MaybeInvalidateActiveWebview(this);
1802 void EWebView::RenderViewReady() {
1804 rwhva()->offscreen_helper()->SetFocusInOutCallbacks(
1805 base::BindRepeating(&EWebView::OnFocusIn, base::Unretained(this)),
1806 base::BindRepeating(&EWebView::OnFocusOut, base::Unretained(this)));
1809 #if defined(TIZEN_VIDEO_HOLE)
1810 if (rwhva() && pending_video_hole_setting_) {
1811 rwhva()->host()->SetVideoHoleForRender(pending_video_hole_setting_);
1812 pending_video_hole_setting_ = false;
1816 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1818 SendDelayedMessages(render_view_host);
1819 UpdateWebkitPreferencesEfl(render_view_host);
1821 if (render_view_host) {
1822 WebContents* content = WebContents::FromRenderViewHost(render_view_host);
1824 RenderProcessHost* host = render_view_host->GetProcess();
1826 host->AddFilter(new WebViewBrowserMessageFilter(content));
1831 void EWebView::SetQuotaPermissionRequestCallback(
1832 Ewk_Quota_Permission_Request_Callback callback,
1834 quota_request_callback_.Set(callback, user_data);
1837 void EWebView::InvokeQuotaPermissionRequest(
1838 _Ewk_Quota_Permission_Request* request,
1839 content::QuotaPermissionContext::PermissionCallback cb) {
1840 quota_permission_request_map_[request] = std::move(cb);
1841 request->setView(evas_object());
1842 if (quota_request_callback_.IsCallbackSet())
1843 quota_request_callback_.Run(evas_object(), request);
1845 QuotaRequestCancel(request);
1848 void EWebView::QuotaRequestReply(const _Ewk_Quota_Permission_Request* request,
1850 DCHECK(quota_permission_request_map_.find(request) !=
1851 quota_permission_request_map_.end());
1853 QuotaPermissionContextEfl::DispatchCallback(
1854 std::move(quota_permission_request_map_[request]),
1855 (allow ? QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_ALLOW
1856 : QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_DISALLOW));
1858 quota_permission_request_map_.erase(request);
1862 void EWebView::QuotaRequestCancel(
1863 const _Ewk_Quota_Permission_Request* request) {
1864 DCHECK(quota_permission_request_map_.find(request) !=
1865 quota_permission_request_map_.end());
1867 QuotaPermissionContextEfl::DispatchCallback(
1868 std::move(quota_permission_request_map_[request]),
1869 QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_CANCELLED);
1870 quota_permission_request_map_.erase(request);
1874 bool EWebView::GetLinkMagnifierEnabled() const {
1875 #if !defined(EWK_BRINGUP) // FIXME: m71 bringup
1876 return web_contents_->GetMutableRendererPrefs()
1877 ->tap_multiple_targets_strategy ==
1878 TAP_MULTIPLE_TARGETS_STRATEGY_POPUP;
1884 void EWebView::SetLinkMagnifierEnabled(bool enabled) {
1885 #if !defined(EWK_BRINGUP) // FIXME: m71 bringup
1886 web_contents_->GetMutableRendererPrefs()->tap_multiple_targets_strategy =
1887 enabled ? TAP_MULTIPLE_TARGETS_STRATEGY_POPUP
1888 : TAP_MULTIPLE_TARGETS_STRATEGY_NONE;
1890 web_contents_->SyncRendererPrefs();
1893 bool EWebView::GetSnapshotAsync(
1894 Eina_Rectangle rect,
1895 Ewk_Web_App_Screenshot_Captured_Callback callback,
1897 float scale_factor) {
1898 if (!rwhva() || !rwhva()->offscreen_helper())
1901 rwhva()->offscreen_helper()->RequestSnapshotAsync(
1902 gfx::Rect(rect.x, rect.y, rect.w, rect.h), callback, user_data,
1907 Evas_Object* EWebView::GetSnapshot(Eina_Rectangle rect, float scale_factor) {
1908 if (!rwhva() || !rwhva()->offscreen_helper())
1911 return rwhva()->offscreen_helper()->GetSnapshot(
1912 gfx::Rect(rect.x, rect.y, rect.w, rect.h), scale_factor);
1915 void EWebView::BackForwardListClear() {
1916 content::NavigationController& controller = web_contents_->GetController();
1918 int entry_count = controller.GetEntryCount();
1919 bool entry_removed = false;
1921 for (int i = 0; i < entry_count; i++) {
1922 if (controller.RemoveEntryAtIndex(i)) {
1923 entry_removed = true;
1924 entry_count = controller.GetEntryCount();
1929 if (entry_removed) {
1930 back_forward_list_->ClearCache();
1931 InvokeBackForwardListChangedCallback();
1935 _Ewk_Back_Forward_List* EWebView::GetBackForwardList() const {
1936 return back_forward_list_.get();
1939 void EWebView::InvokeBackForwardListChangedCallback() {
1940 SmartCallback<EWebViewCallbacks::BackForwardListChange>().call();
1943 _Ewk_History* EWebView::GetBackForwardHistory() const {
1944 return new _Ewk_History(web_contents_->GetController());
1947 bool EWebView::WebAppCapableGet(Ewk_Web_App_Capable_Get_Callback callback,
1949 RenderViewHost* renderViewHost = web_contents_->GetRenderViewHost();
1950 if (!renderViewHost) {
1953 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
1954 WebApplicationCapableGetCallback* cb =
1955 new WebApplicationCapableGetCallback(callback, userData);
1956 int callbackId = web_app_capable_get_callback_map_.Add(cb);
1957 return renderViewHost->Send(new EwkViewMsg_WebAppCapableGet(
1958 renderViewHost->GetRoutingID(), callbackId));
1964 bool EWebView::WebAppIconUrlGet(Ewk_Web_App_Icon_URL_Get_Callback callback,
1966 RenderViewHost* renderViewHost = web_contents_->GetRenderViewHost();
1967 if (!renderViewHost) {
1970 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
1971 WebApplicationIconUrlGetCallback* cb =
1972 new WebApplicationIconUrlGetCallback(callback, userData);
1973 int callbackId = web_app_icon_url_get_callback_map_.Add(cb);
1974 return renderViewHost->Send(new EwkViewMsg_WebAppIconUrlGet(
1975 renderViewHost->GetRoutingID(), callbackId));
1981 bool EWebView::WebAppIconUrlsGet(Ewk_Web_App_Icon_URLs_Get_Callback callback,
1983 RenderViewHost* renderViewHost = web_contents_->GetRenderViewHost();
1984 if (!renderViewHost) {
1987 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
1988 WebApplicationIconUrlsGetCallback* cb =
1989 new WebApplicationIconUrlsGetCallback(callback, userData);
1990 int callbackId = web_app_icon_urls_get_callback_map_.Add(cb);
1991 return renderViewHost->Send(new EwkViewMsg_WebAppIconUrlsGet(
1992 renderViewHost->GetRoutingID(), callbackId));
1998 void EWebView::InvokeWebAppCapableGetCallback(bool capable, int callbackId) {
1999 WebApplicationCapableGetCallback* callback =
2000 web_app_capable_get_callback_map_.Lookup(callbackId);
2003 callback->Run(capable);
2004 web_app_capable_get_callback_map_.Remove(callbackId);
2007 void EWebView::InvokeWebAppIconUrlGetCallback(const std::string& iconUrl,
2009 WebApplicationIconUrlGetCallback* callback =
2010 web_app_icon_url_get_callback_map_.Lookup(callbackId);
2013 callback->Run(iconUrl);
2014 web_app_icon_url_get_callback_map_.Remove(callbackId);
2017 void EWebView::InvokeWebAppIconUrlsGetCallback(const StringMap& iconUrls,
2019 WebApplicationIconUrlsGetCallback* callback =
2020 web_app_icon_urls_get_callback_map_.Lookup(callbackId);
2024 callback->Run(iconUrls);
2025 web_app_icon_urls_get_callback_map_.Remove(callbackId);
2028 void EWebView::SetNotificationPermissionCallback(
2029 Ewk_View_Notification_Permission_Callback callback,
2031 notification_permission_callback_.Set(callback, user_data);
2034 bool EWebView::IsNotificationPermissionCallbackSet() const {
2035 return notification_permission_callback_.IsCallbackSet();
2038 bool EWebView::InvokeNotificationPermissionCallback(
2039 Ewk_Notification_Permission_Request* request) {
2040 Eina_Bool ret = EINA_FALSE;
2041 notification_permission_callback_.Run(evas_object_, request, &ret);
2045 int EWebView::SetEwkViewPlainTextGetCallback(
2046 Ewk_View_Plain_Text_Get_Callback callback,
2048 EwkViewPlainTextGetCallback* view_plain_text_callback_ptr =
2049 new EwkViewPlainTextGetCallback;
2050 view_plain_text_callback_ptr->Set(callback, user_data);
2051 return plain_text_get_callback_map_.Add(view_plain_text_callback_ptr);
2054 bool EWebView::PlainTextGet(Ewk_View_Plain_Text_Get_Callback callback,
2056 auto* render_frame_host = web_contents_->GetPrimaryMainFrame();
2057 if (!render_frame_host)
2060 auto callback_id = SetEwkViewPlainTextGetCallback(callback, user_data);
2061 return render_frame_host->Send(new EwkFrameMsg_GetPlainText(
2062 render_frame_host->GetRoutingID(), callback_id));
2065 void EWebView::InvokePlainTextGetCallback(const std::string& content_text,
2066 int plain_text_get_callback_id) {
2067 EwkViewPlainTextGetCallback* view_plain_text_callback_invoke_ptr =
2068 plain_text_get_callback_map_.Lookup(plain_text_get_callback_id);
2069 view_plain_text_callback_invoke_ptr->Run(evas_object(), content_text.c_str());
2070 plain_text_get_callback_map_.Remove(plain_text_get_callback_id);
2073 void EWebView::SetViewGeolocationPermissionCallback(
2074 Ewk_View_Geolocation_Permission_Callback callback,
2076 geolocation_permission_cb_.Set(callback, user_data);
2079 bool EWebView::InvokeViewGeolocationPermissionCallback(
2080 _Ewk_Geolocation_Permission_Request* permission_context,
2081 Eina_Bool* callback_result) {
2082 return geolocation_permission_cb_.Run(evas_object_, permission_context,
2086 void EWebView::SetViewUserMediaPermissionCallback(
2087 Ewk_View_User_Media_Permission_Callback callback,
2089 user_media_permission_cb_.Set(callback, user_data);
2092 bool EWebView::InvokeViewUserMediaPermissionCallback(
2093 _Ewk_User_Media_Permission_Request* permission_context,
2094 Eina_Bool* callback_result) {
2095 return user_media_permission_cb_.Run(evas_object_, permission_context,
2099 void EWebView::SetViewUserMediaPermissionQueryCallback(
2100 Ewk_View_User_Media_Permission_Query_Callback callback,
2102 user_media_permission_query_cb_.Set(callback, user_data);
2105 Ewk_User_Media_Permission_Query_Result
2106 EWebView::InvokeViewUserMediaPermissionQueryCallback(
2107 _Ewk_User_Media_Permission_Query* permission_context) {
2108 return user_media_permission_query_cb_.Run(evas_object_, permission_context);
2111 void EWebView::SetViewUnfocusAllowCallback(
2112 Ewk_View_Unfocus_Allow_Callback callback,
2114 unfocus_allow_cb_.Set(callback, user_data);
2117 bool EWebView::InvokeViewUnfocusAllowCallback(Ewk_Unfocus_Direction direction,
2118 Eina_Bool* callback_result) {
2119 return unfocus_allow_cb_.Run(evas_object_, direction, callback_result);
2122 void EWebView::StopFinding() {
2123 web_contents_->StopFinding(content::STOP_FIND_ACTION_CLEAR_SELECTION);
2126 void EWebView::SetProgressValue(double progress) {
2127 progress_ = progress;
2130 double EWebView::GetProgressValue() {
2134 const char* EWebView::GetTitle() {
2135 title_ = base::UTF16ToUTF8(web_contents_->GetTitle());
2136 return title_.c_str();
2139 bool EWebView::SaveAsPdf(int width, int height, const std::string& filename) {
2142 rwhva()->host()->PrintToPdf(width, height, base::FilePath(filename));
2146 bool EWebView::GetMHTMLData(Ewk_View_MHTML_Data_Get_Callback callback,
2148 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
2149 if (!render_view_host)
2152 MHTMLCallbackDetails* callback_details = new MHTMLCallbackDetails;
2153 callback_details->Set(callback, user_data);
2154 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
2155 int mhtml_callback_id = mhtml_callback_map_.Add(callback_details);
2156 return render_view_host->Send(new EwkViewMsg_GetMHTMLData(
2157 render_view_host->GetRoutingID(), mhtml_callback_id));
2163 void EWebView::OnMHTMLContentGet(const std::string& mhtml_content,
2165 MHTMLCallbackDetails* callback_details =
2166 mhtml_callback_map_.Lookup(callback_id);
2167 callback_details->Run(evas_object(), mhtml_content.c_str());
2168 mhtml_callback_map_.Remove(callback_id);
2171 bool EWebView::SavePageAsMHTML(const std::string& path,
2172 Ewk_View_Save_Page_Callback callback,
2177 GURL url(web_contents_->GetLastCommittedURL());
2178 std::u16string title(web_contents_->GetTitle());
2180 // Post function that has file access to blocking task runner.
2181 return base::PostTaskAndReplyWithResult(
2182 base::ThreadPool::CreateSequencedTaskRunner(
2183 {base::MayBlock(), base::TaskPriority::BEST_EFFORT,
2184 base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})
2187 base::BindOnce(&GenerateMHTMLFilePath, url, base::UTF16ToUTF8(title),
2189 base::BindOnce(&EWebView::GenerateMHTML, base::Unretained(this), callback,
2193 void EWebView::GenerateMHTML(Ewk_View_Save_Page_Callback callback,
2195 const base::FilePath& file_path) {
2196 if (file_path.empty()) {
2197 LOG(ERROR) << "Generating file path was failed";
2198 callback(evas_object_, nullptr, user_data);
2202 MHTMLGenerationParams params(file_path);
2203 web_contents_->GenerateMHTML(
2204 params, base::BindOnce(&EWebView::MHTMLGenerated, base::Unretained(this),
2205 callback, user_data, file_path));
2208 void EWebView::MHTMLGenerated(Ewk_View_Save_Page_Callback callback,
2210 const base::FilePath& file_path,
2211 int64_t file_size) {
2212 callback(evas_object_, file_size > 0 ? file_path.value().c_str() : nullptr,
2216 bool EWebView::GetBackgroundColor(
2217 Ewk_View_Background_Color_Get_Callback callback,
2221 BackgroundColorGetCallback* cb =
2222 new BackgroundColorGetCallback(callback, user_data);
2223 int callback_id = background_color_get_callback_map_.Add(cb);
2225 rwhva()->host()->RequestBackgroundColor(callback_id);
2229 void EWebView::OnGetBackgroundColor(int callback_id, SkColor bg_color) {
2230 BackgroundColorGetCallback* cb =
2231 background_color_get_callback_map_.Lookup(callback_id);
2236 cb->Run(evas_object(), SkColorGetR(bg_color), SkColorGetG(bg_color),
2237 SkColorGetB(bg_color), SkColorGetA(bg_color));
2238 background_color_get_callback_map_.Remove(callback_id);
2241 bool EWebView::IsFullscreen() {
2242 return web_contents_delegate_->IsFullscreenForTabOrPending(
2243 web_contents_.get());
2246 void EWebView::ExitFullscreen() {
2247 WebContentsImpl* wci = static_cast<WebContentsImpl*>(web_contents_.get());
2248 wci->ExitFullscreen(false);
2251 double EWebView::GetScale() {
2252 return page_scale_factor_;
2255 void EWebView::DidChangePageScaleFactor(double scale_factor) {
2256 page_scale_factor_ = scale_factor;
2257 wcva()->wcva_helper()->SetPageScaleFactor(scale_factor);
2258 SetScaledContentsSize();
2260 // Notify app about the scale change.
2261 scale_changed_cb_.Run(evas_object_, scale_factor);
2264 inline JavaScriptDialogManagerEfl* EWebView::GetJavaScriptDialogManagerEfl() {
2265 return static_cast<JavaScriptDialogManagerEfl*>(
2266 web_contents_delegate_->GetJavaScriptDialogManager(web_contents_.get()));
2269 void EWebView::SetJavaScriptAlertCallback(
2270 Ewk_View_JavaScript_Alert_Callback callback,
2272 GetJavaScriptDialogManagerEfl()->SetAlertCallback(callback, user_data);
2275 void EWebView::JavaScriptAlertReply() {
2276 GetJavaScriptDialogManagerEfl()->ExecuteDialogClosedCallBack(true,
2278 SmartCallback<EWebViewCallbacks::PopupReplyWaitFinish>().call(0);
2281 void EWebView::SetJavaScriptConfirmCallback(
2282 Ewk_View_JavaScript_Confirm_Callback callback,
2284 GetJavaScriptDialogManagerEfl()->SetConfirmCallback(callback, user_data);
2287 void EWebView::JavaScriptConfirmReply(bool result) {
2288 GetJavaScriptDialogManagerEfl()->ExecuteDialogClosedCallBack(result,
2290 SmartCallback<EWebViewCallbacks::PopupReplyWaitFinish>().call(0);
2293 void EWebView::SetJavaScriptPromptCallback(
2294 Ewk_View_JavaScript_Prompt_Callback callback,
2296 GetJavaScriptDialogManagerEfl()->SetPromptCallback(callback, user_data);
2299 void EWebView::JavaScriptPromptReply(const char* result) {
2300 GetJavaScriptDialogManagerEfl()->ExecuteDialogClosedCallBack(
2301 true, (std::string(result)));
2302 SmartCallback<EWebViewCallbacks::PopupReplyWaitFinish>().call(0);
2305 void EWebView::GetPageScaleRange(double* min_scale, double* max_scale) {
2306 auto prefs = web_contents_->GetOrCreateWebPreferences();
2308 *min_scale = prefs.default_minimum_page_scale_factor;
2310 *max_scale = prefs.default_maximum_page_scale_factor;
2313 void EWebView::SetDrawsTransparentBackground(bool enabled) {
2314 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
2315 if (!render_view_host)
2317 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
2318 render_view_host->Send(new EwkViewMsg_SetDrawsTransparentBackground(
2319 render_view_host->GetRoutingID(), enabled));
2323 void EWebView::GetSessionData(const char** data, unsigned* length) const {
2324 static const int MAX_SESSION_ENTRY_SIZE = std::numeric_limits<int>::max();
2326 NavigationController& navigationController = web_contents_->GetController();
2327 base::Pickle sessionPickle;
2328 const int itemCount = navigationController.GetEntryCount();
2330 sessionPickle.WriteInt(itemCount);
2331 sessionPickle.WriteInt(navigationController.GetCurrentEntryIndex());
2333 for (int i = 0; i < itemCount; i++) {
2334 NavigationEntry* navigationEntry = navigationController.GetEntryAtIndex(i);
2335 sessions::SerializedNavigationEntry serializedEntry =
2336 sessions::ContentSerializedNavigationBuilder::FromNavigationEntry(
2337 i, navigationEntry);
2338 serializedEntry.WriteToPickle(MAX_SESSION_ENTRY_SIZE, &sessionPickle);
2341 if (sessionPickle.size() <= 0 ||
2343 static_cast<char*>(malloc(sizeof(char) * sessionPickle.size())))) {
2344 LOG(ERROR) << "Failed to get session data";
2348 memcpy(const_cast<char*>(*data), sessionPickle.data(), sessionPickle.size());
2349 *length = sessionPickle.size();
2352 bool EWebView::RestoreFromSessionData(const char* data, unsigned length) {
2353 base::Pickle sessionPickle(data, length);
2354 base::PickleIterator pickleIterator(sessionPickle);
2358 if (!pickleIterator.ReadInt(&entryCount))
2360 if (!pickleIterator.ReadInt(¤tEntry))
2363 std::vector<sessions::SerializedNavigationEntry> serializedEntries;
2364 serializedEntries.resize(entryCount);
2365 for (int i = 0; i < entryCount; ++i) {
2366 if (!serializedEntries.at(i).ReadFromPickle(&pickleIterator))
2376 std::vector<std::unique_ptr<content::NavigationEntry>> scopedEntries =
2377 sessions::ContentSerializedNavigationBuilder::ToNavigationEntries(
2378 serializedEntries, context()->browser_context());
2380 NavigationController& navigationController = web_contents_->GetController();
2382 if (currentEntry < 0)
2385 if (currentEntry >= static_cast<int>(scopedEntries.size()))
2386 currentEntry = scopedEntries.size() - 1;
2388 navigationController.Restore(currentEntry, RestoreType::kRestored,
2393 void EWebView::SetBrowserFont() {
2394 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
2395 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
2396 if (render_view_host) {
2397 IPC::Message* message =
2398 new EwkViewMsg_SetBrowserFont(render_view_host->GetRoutingID());
2400 if (render_view_host->IsRenderViewLive())
2401 render_view_host->Send(message);
2403 delayed_messages_.push_back(message);
2408 bool EWebView::IsDragging() const {
2409 return wcva()->wcva_helper()->IsDragging();
2412 void EWebView::ShowFileChooser(content::RenderFrameHost* render_frame_host,
2413 const blink::mojom::FileChooserParams& params) {
2414 if (!IsMobileProfile() && !IsWearableProfile())
2417 #if !defined(EWK_BRINGUP) // FIXME: m71 bringup
2418 if (params.capture) {
2419 const std::string capture_types[] = {"video/*", "audio/*", "image/*"};
2420 unsigned int capture_types_num =
2421 sizeof(capture_types) / sizeof(*capture_types);
2422 for (unsigned int i = 0; i < capture_types_num; ++i) {
2423 for (unsigned int j = 0; j < params.accept_types.size(); ++j) {
2424 if (UTF16ToUTF8(params.accept_types[j]) == capture_types[i]) {
2425 filechooser_mode_ = params.mode;
2426 LaunchCamera(params.accept_types[j]);
2432 file_chooser_.reset(
2433 new content::FileChooserControllerEfl(render_frame_host, ¶ms));
2434 file_chooser_->Open();
2438 #if !defined(EWK_BRINGUP) // FIXME: m67 bringup
2439 void EWebView::SetViewMode(blink::WebViewMode view_mode) {
2440 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
2441 if (!render_view_host)
2444 IPC::Message* message =
2445 new ViewMsg_SetViewMode(render_view_host->GetRoutingID(), view_mode);
2446 if (render_view_host->IsRenderViewLive()) {
2447 render_view_host->Send(message);
2449 delayed_messages_.push_back(message);
2454 gfx::Point EWebView::GetContextMenuPosition() const {
2455 return context_menu_position_;
2458 void EWebView::ShowContentsDetectedPopup(const char* message) {
2459 popup_controller_.reset(new PopupControllerEfl(this));
2460 popup_controller_->openPopup(message);
2463 void EWebView::RequestColorPicker(int r, int g, int b, int a) {
2464 input_picker_.reset(
2465 new InputPicker(this, web_contents_.get(), evas_object()));
2466 input_picker_->ShowColorPicker(r, g, b, a);
2469 bool EWebView::SetColorPickerColor(int r, int g, int b, int a) {
2470 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
2471 web_contents_->DidChooseColorInColorChooser(SkColorSetARGB(a, r, g, b));
2476 void EWebView::InputPickerShow(ui::TextInputType input_type,
2478 content::DateTimeChooserEfl* date_time_chooser) {
2479 input_picker_.reset(new InputPicker(this, web_contents_.get(), evas_object(),
2480 date_time_chooser));
2481 input_picker_->ShowDatePicker(input_type, input_value);
2484 void EWebView::LoadNotFoundErrorPage(const std::string& invalidUrl) {
2485 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
2486 RenderFrameHost* render_frame_host = web_contents_->GetPrimaryMainFrame();
2487 if (render_frame_host)
2488 render_frame_host->Send(new EwkFrameMsg_LoadNotFoundErrorPage(
2489 render_frame_host->GetRoutingID(), invalidUrl));
2493 std::string EWebView::GetPlatformLocale() {
2494 char* local_default = setlocale(LC_CTYPE, 0);
2496 return std::string("en-US");
2497 std::string locale = std::string(local_default);
2498 size_t position = locale.find('_');
2499 if (position != std::string::npos)
2500 locale.replace(position, 1, "-");
2501 position = locale.find('.');
2502 if (position != std::string::npos)
2503 locale = locale.substr(0, position);
2507 int EWebView::StartInspectorServer(int port) {
2508 #if BUILDFLAG(IS_TIZEN_TV)
2510 use_early_rwi_ = false;
2511 rwi_info_showed_ = false;
2513 if (!context_->GetImpl()->GetInspectorServerState()) {
2515 if (!devtools_http_handler::DevToolsPortManager::GetInstance()
2516 ->GetValidPort(validPort))
2522 return context_->InspectorServerStart(port);
2525 bool EWebView::StopInspectorServer() {
2526 #if BUILDFLAG(IS_TIZEN_TV)
2528 use_early_rwi_ = false;
2529 rwi_info_showed_ = false;
2532 return context_->InspectorServerStop();
2535 void EWebView::InvokeWebProcessCrashedCallback() {
2536 DCHECK_CURRENTLY_ON(BrowserThread::UI);
2537 const GURL last_url = GetURL();
2538 bool callback_handled = false;
2539 SmartCallback<EWebViewCallbacks::WebProcessCrashed>().call(&callback_handled);
2540 if (!callback_handled)
2541 LoadHTMLString(kRendererCrashedHTMLMessage, NULL,
2542 last_url.possibly_invalid_spec().c_str());
2545 void EWebView::SyncAcceptLanguages(const std::string& accept_languages) {
2546 web_contents_->GetMutableRendererPrefs()->accept_languages = accept_languages;
2547 web_contents_->SyncRendererPrefs();
2548 BrowserContext* browser_context = web_contents_->GetBrowserContext();
2549 if (!browser_context)
2552 auto* storage_partition = browser_context->GetDefaultStoragePartition();
2553 if (!storage_partition)
2556 if (auto* network_context = storage_partition->GetNetworkContext())
2557 network_context->SetAcceptLanguage(accept_languages);
2560 void EWebView::HandleRendererProcessCrash() {
2561 content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
2562 base::BindOnce(&EWebView::InvokeWebProcessCrashedCallback,
2563 base::Unretained(this)));
2566 void EWebView::InitializeContent() {
2567 LOG(INFO) << "eweb_view.cc InitializeContent" ;
2568 #if BUILDFLAG(IS_TIZEN_TV)
2569 // When initialize content init inspector server
2570 InitInspectorServer();
2572 WebContents* new_contents = create_new_window_web_contents_cb_.Run(this);
2573 if (!new_contents) {
2574 WebContents::CreateParams params(context_->browser_context());
2575 web_contents_.reset(
2576 new WebContentsImplEfl(context_->browser_context(), this));
2577 static_cast<WebContentsImpl*>(web_contents_.get())
2578 ->Init(params, blink::FramePolicy());
2580 web_contents_.reset(new_contents);
2582 // When a new webview is created in response to a request from the
2583 // engine, the BrowserContext instance of the originator WebContents
2584 // is used by the newly created WebContents object.
2585 // See more in WebContentsImplEfl::HandleNewWebContentsCreate.
2587 // Hence, if as part of the WebView creation, the embedding APP
2588 // passes in a Ewk_Context instance that wraps a different instance of
2589 // BrowserContext than the one the originator WebContents holds,
2590 // undefined behavior can be seen.
2592 // This is a snippet code that illustrate the scenario:
2595 // evas_object_smart_callback_add(web_view_, "create,window",
2596 // &OnNewWindowRequest, this);
2599 // void OnNewWindowRequest(void *data, Evas_Object*, void* out_view) {
2601 // EvasObject* new_web_view = ewk_view_add_with_context(GetEvas(),
2602 // ewk_context_new());
2603 // *static_cast<Evas_Object**>(out_view) = new_web_view;
2607 // The new Ewk_Context object created and passed in as parameter to
2608 // ewk_view_add_with_context wraps a different instance of BrowserContext
2609 // than the one the new WebContents object will hold.
2611 // CHECK below aims at catching misuse of this API.
2612 bool should_crash = context_->GetImpl()->browser_context() !=
2613 web_contents_->GetBrowserContext();
2616 << "BrowserContext of new WebContents does not match EWebView's. "
2617 << "Please see 'ewk_view_add*' documentation. "
2618 << "Aborting execution ...";
2621 web_contents_delegate_.reset(new WebContentsDelegateEfl(this));
2622 web_contents_->SetDelegate(web_contents_delegate_.get());
2623 WebContentsImplEfl* wc_efl =
2624 static_cast<WebContentsImplEfl*>(web_contents_.get());
2625 wc_efl->SetEflDelegate(new WebContentsEflDelegateEwk(this));
2626 wcva()->wcva_helper()->SetEflDelegate(wc_efl->GetEflDelegate());
2628 back_forward_list_.reset(new _Ewk_Back_Forward_List(web_contents_.get()));
2630 permission_popup_manager_.reset(new PermissionPopupManager(evas_object_));
2631 gin_native_bridge_dispatcher_host_.reset(
2632 new content::GinNativeBridgeDispatcherHost(web_contents_.get()));
2635 static_cast<WebContentsImplEfl*>(web_contents_.get())->GetEflNativeView();
2636 evas_object_smart_member_add(native_view_, evas_object_);
2637 static_cast<WebContentsImpl*>(web_contents_.get())
2638 ->set_ewk_view(evas_object_);
2639 InitializeWindowTreeHost();
2642 #if BUILDFLAG(IS_TIZEN_TV)
2643 void EWebView::OnDialogClosed() {
2644 if (!use_early_rwi_)
2647 use_early_rwi_ = false;
2648 LOG(INFO) << "[FAST RWI] SetURL Restore [" << rwi_gurl_.spec()
2649 << "] from [about:blank]";
2652 rwi_info_showed_ = true;
2655 void EWebView::InitInspectorServer() {
2656 if (devtools_http_handler::DevToolsPortManager::GetInstance()
2657 ->ProcessCompare()) {
2658 int res = StartInspectorServer(0);
2660 LOG(INFO) << "InitInspectorServer SetPort";
2661 devtools_http_handler::DevToolsPortManager::GetInstance()->SetPort(res);
2667 void EWebView::InitializeWindowTreeHost() {
2668 CHECK(aura::Env::GetInstance());
2670 int x, y, width, height;
2672 ecore_evas_ecore_evas_get(evas_object_evas_get(native_view_));
2673 ecore_evas_geometry_get(ee, &x, &y, &width, &height);
2675 gfx::Rect bounds(x, y, width, height);
2676 ui::PlatformWindowInitProperties properties;
2677 properties.bounds = bounds;
2679 host_ = aura::WindowTreeHost::Create(std::move(properties));
2681 host_->window()->Show();
2684 std::make_unique<aura::test::TestFocusClient>(host_->window());
2685 window_parenting_client_ =
2686 std::make_unique<aura::test::TestWindowParentingClient>(host_->window());
2687 compositor_observer_ = std::make_unique<ui::CompositorObserverEfl>(
2688 host_->compositor(), web_contents_.get());
2690 aura::Window* content = web_contents_->GetNativeView();
2691 aura::Window* parent = host_->window();
2692 if (!parent->Contains(content)) {
2693 parent->AddChild(content);
2696 content->SetBounds(bounds);
2697 RenderWidgetHostView* host_view = web_contents_->GetRenderWidgetHostView();
2699 host_view->SetSize(bounds.size());
2702 #if BUILDFLAG(IS_TIZEN) && !defined(EWK_BRINGUP)
2703 void EWebView::cameraResultCb(service_h request,
2705 service_result_e result,
2707 if (!IsMobileProfile() && !IsWearableProfile())
2710 EWebView* webview = static_cast<EWebView*>(data);
2711 RenderViewHost* render_view_host =
2712 webview->web_contents_->GetRenderViewHost();
2713 if (result == SERVICE_RESULT_SUCCEEDED) {
2717 ret = service_get_extra_data_array(reply, SERVICE_DATA_SELECTED,
2718 &filesarray, &number);
2720 for (int i = 0; i < number; i++) {
2721 std::vector<ui::SelectedFileInfo> files;
2722 if (!render_view_host) {
2725 if (filesarray[i]) {
2726 GURL url(filesarray[i]);
2727 if (!url.is_valid()) {
2728 base::FilePath path(url.SchemeIsFile() ? url.path()
2730 files.push_back(ui::SelectedFileInfo(path, base::FilePath()));
2733 render_view_host->FilesSelectedInChooser(files,
2734 webview->filechooser_mode_);
2738 std::vector<ui::SelectedFileInfo> files;
2739 if (render_view_host) {
2740 render_view_host->FilesSelectedInChooser(files,
2741 webview->filechooser_mode_);
2746 bool EWebView::LaunchCamera(std::u16string mimetype) {
2747 service_h svcHandle = 0;
2748 if (service_create(&svcHandle) < 0 || !svcHandle) {
2749 LOG(ERROR) << __FUNCTION__ << " Service Creation Failed ";
2752 service_set_operation(svcHandle, SERVICE_OPERATION_CREATE_CONTENT);
2753 service_set_mime(svcHandle, UTF16ToUTF8(mimetype).c_str());
2754 service_add_extra_data(svcHandle, "CALLER", "Browser");
2756 int ret = service_send_launch_request(svcHandle, cameraResultCb, this);
2757 if (ret != SERVICE_ERROR_NONE) {
2758 LOG(ERROR) << __FUNCTION__ << " Service Launch Failed ";
2759 service_destroy(svcHandle);
2762 service_destroy(svcHandle);
2767 void EWebView::UrlRequestSet(
2769 content::NavigationController::LoadURLType loadtype,
2773 content::NavigationController::LoadURLParams params(gurl);
2774 params.load_type = loadtype;
2775 params.override_user_agent = NavigationController::UA_OVERRIDE_TRUE;
2778 std::string s(body);
2780 network::ResourceRequestBody::CreateFromBytes(s.data(), s.size());
2783 net::HttpRequestHeaders header;
2785 Eina_Iterator* it = eina_hash_iterator_tuple_new(headers);
2787 while (eina_iterator_next(it, reinterpret_cast<void**>(&t))) {
2789 const char* value_str =
2790 t->data ? static_cast<const char*>(t->data) : "";
2791 base::StringPiece name = static_cast<const char*>(t->key);
2792 base::StringPiece value = value_str;
2793 header.SetHeader(name, value);
2794 // net::HttpRequestHeaders.ToString() returns string with newline
2795 params.extra_headers += header.ToString();
2798 eina_iterator_free(it);
2801 web_contents_->GetController().LoadURLWithParams(params);
2804 #if defined(TIZEN_VIDEO_HOLE)
2805 void EWebView::SetVideoHoleSupport(bool enable) {
2806 if (!web_contents_->GetPrimaryMainFrame() ||
2807 !web_contents_->GetPrimaryMainFrame()->IsRenderFrameLive() || !rwhva()) {
2808 pending_video_hole_setting_ = enable;
2812 rwhva()->host()->SetVideoHoleForRender(enable);
2816 bool EWebView::HandleShow() {
2824 bool EWebView::HandleHide() {
2832 bool EWebView::HandleMove(int x, int y) {
2835 evas_object_move(native_view_, x, y);
2837 #if defined(TIZEN_VIDEO_HOLE) && !defined(EWK_BRINGUP)
2839 rwhva()->offscreen_helper()->DidMoveWebView();
2843 context_menu_->Move(x, y);
2848 bool EWebView::HandleResize(int width, int height) {
2851 evas_object_resize(native_view_, width, height);
2853 if (select_picker_) {
2854 AdjustViewPortHeightToPopupMenu(true /* is_popup_menu_visible */);
2855 ScrollFocusedNodeIntoView();
2858 #if defined(USE_AURA) && BUILDFLAG(IS_TIZEN_TV)
2861 evas_object_geometry_get(native_view_, &x, &y, nullptr, nullptr);
2862 gfx::Rect bounds(x, y, width, height);
2863 host_->SetBoundsInPixels(bounds);
2870 bool EWebView::HandleTextSelectionDown(int x, int y) {
2871 if (!GetSelectionController())
2873 return GetSelectionController()->TextSelectionDown(x, y);
2876 bool EWebView::HandleTextSelectionUp(int x, int y) {
2877 if (!GetSelectionController())
2879 return GetSelectionController()->TextSelectionUp(x, y);
2882 void EWebView::HandleTapGestureForSelection(bool is_content_editable) {
2883 if (!GetSelectionController())
2886 GetSelectionController()->PostHandleTapGesture(is_content_editable);
2889 void EWebView::HandleZoomGesture(blink::WebGestureEvent& event) {
2890 blink::WebInputEvent::Type event_type = event.GetType();
2891 if (event_type == blink::WebInputEvent::Type::kGestureDoubleTap ||
2892 event_type == blink::WebInputEvent::Type::kGesturePinchBegin) {
2893 SmartCallback<EWebViewCallbacks::ZoomStarted>().call();
2895 if (event_type == blink::WebInputEvent::Type::kGestureDoubleTap ||
2896 event_type == blink::WebInputEvent::Type::kGesturePinchEnd) {
2897 SmartCallback<EWebViewCallbacks::ZoomFinished>().call();
2901 bool EWebView::GetHorizontalPanningHold() const {
2904 return rwhva()->offscreen_helper()->GetHorizontalPanningHold();
2907 void EWebView::SetHorizontalPanningHold(bool hold) {
2909 rwhva()->offscreen_helper()->SetHorizontalPanningHold(hold);
2912 bool EWebView::GetVerticalPanningHold() const {
2915 return rwhva()->offscreen_helper()->GetVerticalPanningHold();
2918 void EWebView::SetVerticalPanningHold(bool hold) {
2920 rwhva()->offscreen_helper()->SetVerticalPanningHold(hold);
2923 void EWebView::SendDelayedMessages(RenderViewHost* render_view_host) {
2924 DCHECK(render_view_host);
2926 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
2927 content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
2928 base::BindOnce(&EWebView::SendDelayedMessages, base::Unretained(this),
2933 for (auto iter = delayed_messages_.begin(); iter != delayed_messages_.end();
2935 IPC::Message* message = *iter;
2936 message->set_routing_id(render_view_host->GetRoutingID());
2937 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
2938 render_view_host->Send(message);
2942 delayed_messages_.clear();
2945 void EWebView::ClosePage() {
2946 web_contents_->ClosePage();
2949 bool EWebView::SetMainFrameScrollbarVisible(bool visible) {
2950 if (web_contents_->GetPrimaryMainFrame()->IsRenderFrameLive() && rwhva())
2951 rwhva()->host()->SetMainFrameScrollbarVisible(visible);
2955 bool EWebView::GetMainFrameScrollbarVisible(
2956 Ewk_View_Main_Frame_Scrollbar_Visible_Get_Callback callback,
2961 MainFrameScrollbarVisibleGetCallback* callback_ptr =
2962 new MainFrameScrollbarVisibleGetCallback;
2963 callback_ptr->Set(callback, user_data);
2965 main_frame_scrollbar_visible_callback_map_.Add(callback_ptr);
2966 rwhva()->host()->RequestMainFrameScrollbarVisible(callback_id);
2970 void EWebView::InvokeMainFrameScrollbarVisibleCallback(int callback_id,
2972 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
2973 content::GetUIThreadTaskRunner({})->PostTask(
2975 base::BindOnce(&EWebView::InvokeMainFrameScrollbarVisibleCallback,
2976 base::Unretained(this), visible, callback_id));
2980 MainFrameScrollbarVisibleGetCallback* callback =
2981 main_frame_scrollbar_visible_callback_map_.Lookup(callback_id);
2985 main_frame_scrollbar_visible_callback_map_.Remove(callback_id);
2986 callback->Run(evas_object(), visible);
2987 main_frame_scrollbar_visible_callback_map_.Remove(callback_id);
2990 void EWebView::OnOverscrolled(const gfx::Vector2dF& accumulated_overscroll,
2991 const gfx::Vector2dF& latest_overscroll_delta) {
2992 const gfx::Vector2dF old_overscroll =
2993 accumulated_overscroll - latest_overscroll_delta;
2995 if (latest_overscroll_delta.x() && !old_overscroll.x()) {
2996 latest_overscroll_delta.x() < 0
2997 ? SmartCallback<EWebViewCallbacks::OverscrolledLeft>().call()
2998 : SmartCallback<EWebViewCallbacks::OverscrolledRight>().call();
3000 if (latest_overscroll_delta.y() && !old_overscroll.y()) {
3001 latest_overscroll_delta.y() < 0
3002 ? SmartCallback<EWebViewCallbacks::OverscrolledTop>().call()
3003 : SmartCallback<EWebViewCallbacks::OverscrolledBottom>().call();
3007 void EWebView::SetDidChangeThemeColorCallback(
3008 Ewk_View_Did_Change_Theme_Color_Callback callback,
3010 did_change_theme_color_callback_.Set(callback, user_data);
3013 void EWebView::DidChangeThemeColor(const SkColor& color) {
3014 did_change_theme_color_callback_.Run(evas_object_, color);
3017 #if BUILDFLAG(IS_TIZEN_TV)
3018 void EWebView::DrawLabel(Evas_Object* image, Eina_Rectangle rect) {
3020 rwhva()->offscreen_helper()->DrawLabel(image, rect);
3023 void EWebView::DeactivateAtk(bool deactivated) {
3024 EWebAccessibilityUtil::GetInstance()->Deactivate(deactivated);
3027 void EWebView::ClearLabels() {
3029 rwhva()->offscreen_helper()->ClearLabels();
3033 void EWebView::RequestManifest(Ewk_View_Request_Manifest_Callback callback,
3035 web_contents_delegate_->RequestManifestInfo(callback, user_data);
3038 void EWebView::DidRespondRequestManifest(
3039 _Ewk_View_Request_Manifest* manifest,
3040 Ewk_View_Request_Manifest_Callback callback,
3042 callback(evas_object_, manifest, user_data);
3045 void EWebView::SetSessionTimeout(uint64_t timeout) {
3046 if (web_contents_->GetPrimaryMainFrame()->IsRenderFrameLive() && rwhva())
3047 rwhva()->host()->SetLongPollingGlobalTimeout(timeout);
3050 void EWebView::SetBeforeUnloadConfirmPanelCallback(
3051 Ewk_View_Before_Unload_Confirm_Panel_Callback callback,
3053 GetJavaScriptDialogManagerEfl()->SetBeforeUnloadConfirmPanelCallback(
3054 callback, user_data);
3057 void EWebView::ReplyBeforeUnloadConfirmPanel(Eina_Bool result) {
3058 GetJavaScriptDialogManagerEfl()->ReplyBeforeUnloadConfirmPanel(result);
3061 void EWebView::SetExceededIndexedDatabaseQuotaCallback(
3062 Ewk_View_Exceeded_Indexed_Database_Quota_Callback callback,
3064 exceeded_indexed_db_quota_callback_.Set(callback, user_data);
3065 content::BrowserContextEfl* browser_context =
3066 static_cast<content::BrowserContextEfl*>(
3067 web_contents_->GetBrowserContext());
3068 if (browser_context) {
3069 browser_context->GetSpecialStoragePolicyEfl()->SetQuotaExceededCallback(
3070 base::BindOnce(&EWebView::InvokeExceededIndexedDatabaseQuotaCallback,
3071 base::Unretained(this)));
3075 void EWebView::InvokeExceededIndexedDatabaseQuotaCallback(
3077 int64_t current_quota) {
3078 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
3079 content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
3080 base::BindOnce(&EWebView::InvokeExceededIndexedDatabaseQuotaCallback,
3081 base::Unretained(this), origin, current_quota));
3084 LOG(INFO) << __func__ << "()" << origin << ", " << current_quota;
3085 CHECK(!exceeded_indexed_db_quota_origin_.get());
3086 exceeded_indexed_db_quota_origin_.reset(new Ewk_Security_Origin(origin));
3087 exceeded_indexed_db_quota_callback_.Run(
3088 evas_object_, exceeded_indexed_db_quota_origin_.get(), current_quota);
3091 void EWebView::ExceededIndexedDatabaseQuotaReply(bool allow) {
3092 if (!exceeded_indexed_db_quota_origin_.get()) {
3093 LOG(WARNING) << __func__ << "() : callback is not invoked!";
3096 LOG(INFO) << __func__ << "()" << exceeded_indexed_db_quota_origin_->GetURL()
3098 content::BrowserContextEfl* browser_context =
3099 static_cast<content::BrowserContextEfl*>(
3100 web_contents_->GetBrowserContext());
3101 if (browser_context) {
3102 browser_context->GetSpecialStoragePolicyEfl()->SetUnlimitedStoragePolicy(
3103 exceeded_indexed_db_quota_origin_->GetURL(), allow);
3105 exceeded_indexed_db_quota_origin_.reset();
3108 bool EWebView::ShouldIgnoreNavigation(
3109 content::NavigationHandle* navigation_handle) {
3110 if (!navigation_handle->GetURL().is_valid() ||
3111 !navigation_handle->GetURL().SchemeIs("appcontrol") ||
3112 (!navigation_handle->HasUserGesture() &&
3113 !navigation_handle->WasServerRedirect())) {
3117 _Ewk_App_Control app_control(
3118 this, navigation_handle->GetURL().possibly_invalid_spec());
3119 return app_control.Proceed();
3122 bool EWebView::SetVisibility(bool enable) {
3127 web_contents_->WasShown();
3129 web_contents_->WasHidden();
3134 void EWebView::SetDoNotTrack(Eina_Bool enable) {
3135 // enable: 0 User tend to allow tracking on the target site.
3136 // enable: 1 User tend to not be tracked on the target site.
3137 if (web_contents_->GetMutableRendererPrefs()->enable_do_not_track == enable)
3140 // Set navigator.doNotTrack attribute
3141 web_contents_->GetMutableRendererPrefs()->enable_do_not_track = enable;
3142 web_contents_->SyncRendererPrefs();
3144 // Set or remove DNT HTTP header, the effects will depend on design of target
3150 context()->HTTPCustomHeaderAdd("DNT", "1");
3152 context()->HTTPCustomHeaderRemove("DNT");
3155 #if defined(TIZEN_ATK_SUPPORT)
3156 void EWebView::UpdateSpatialNavigationStatus(Eina_Bool enable) {
3157 if (settings_->getPreferences().spatial_navigation_enabled == enable)
3160 settings_->getPreferences().spatial_navigation_enabled = enable;
3161 WebContentsImpl* wc = static_cast<WebContentsImpl*>(web_contents_.get());
3163 wc->SetSpatialNavigationEnabled(enable);
3166 void EWebView::UpdateAccessibilityStatus(Eina_Bool enable) {
3167 if (settings_->getPreferences().atk_enabled == enable)
3170 settings_->getPreferences().atk_enabled = enable;
3171 WebContentsImpl* wc = static_cast<WebContentsImpl*>(web_contents_.get());
3173 wc->SetAtkEnabled(enable);
3176 void EWebView::InitAtk() {
3177 EWebAccessibilityUtil::GetInstance()->ToggleAtk(lazy_initialize_atk_);
3180 /* LCOV_EXCL_START */
3181 bool EWebView::GetAtkStatus() {
3182 auto state = content::BrowserAccessibilityStateImpl::GetInstance();
3185 return state->IsAccessibleBrowser();
3187 /* LCOV_EXCL_STOP */