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 using namespace content;
99 using web_contents_utils::WebViewFromWebContents;
103 const int kTitleLengthMax = 80;
104 const base::FilePath::CharType kMHTMLFileNameExtension[] =
105 FILE_PATH_LITERAL(".mhtml");
106 const base::FilePath::CharType kMHTMLExtension[] = FILE_PATH_LITERAL("mhtml");
107 const base::FilePath::CharType kDefaultFileName[] =
108 FILE_PATH_LITERAL("saved_page");
109 const char kReplaceChars[] = " ";
110 const char kReplaceWith[] = "_";
112 static const char* kRendererCrashedHTMLMessage =
113 "<html><body><h1>Renderer process has crashed!</h1></body></html>";
115 // "visible,content,changed" is an email-app specific signal which informs
116 // that the web view is only partially visible.
117 static const char* kVisibleContentChangedSignalName = "visible,content,changed";
119 // email-app specific signal which informs that custom scrolling is started.
120 const char* kCustomScrollBeginSignalName = "custom,scroll,begin";
122 // email-app specific signal which informs that custom scrolling is finished.
123 const char* kCustomScrollEndSignalName = "custom,scroll,end";
125 const float kDelayShowContextMenuTime = 0.2f;
127 inline void SetDefaultStringIfNull(const char*& variable,
128 const char* default_string) {
130 variable = default_string;
134 void GetEinaRectFromGfxRect(const gfx::Rect& gfx_rect,
135 Eina_Rectangle* eina_rect) {
136 eina_rect->x = gfx_rect.x();
137 eina_rect->y = gfx_rect.y();
138 eina_rect->w = gfx_rect.width();
139 eina_rect->h = gfx_rect.height();
142 #if BUILDFLAG(IS_TIZEN)
143 static Eina_Bool RotateWindowCb(void* data, int type, void* event) {
144 auto wv = static_cast<EWebView*>(data);
146 ecore_evas_rotation_get(ecore_evas_ecore_evas_get(wv->GetEvas())));
147 return ECORE_CALLBACK_PASS_ON;
151 static content::WebContents* NullCreateWebContents(void*) {
155 base::FilePath GenerateMHTMLFilePath(const GURL& url,
156 const std::string& title,
157 const std::string& base_path) {
158 base::FilePath file_path(base_path);
160 if (base::DirectoryExists(file_path)) {
161 std::string title_part(title.substr(0, kTitleLengthMax));
162 base::ReplaceChars(title_part, kReplaceChars, kReplaceWith, &title_part);
163 base::FilePath file_name =
164 net::GenerateFileName(url, std::string(), std::string(), title_part,
165 std::string(), kDefaultFileName);
166 DCHECK(!file_name.empty());
167 file_path = file_path.Append(file_name);
170 if (file_path.Extension().empty())
171 file_path = file_path.AddExtension(kMHTMLExtension);
172 else if (!file_path.MatchesExtension(kMHTMLFileNameExtension))
173 file_path = file_path.ReplaceExtension(kMHTMLExtension);
175 if (!base::PathExists(file_path))
178 int uniquifier = base::GetUniquePathNumber(file_path);
179 if (uniquifier > 0) {
180 return file_path.InsertBeforeExtensionASCII(
181 base::StringPrintf(" (%d)", uniquifier));
184 return base::FilePath();
187 SelectPickerBase* CreateSelectPicker(
190 std::vector<blink::mojom::MenuItemPtr> items,
191 bool is_multiple_selection,
192 const gfx::Rect& bounds) {
193 SelectPickerBase* picker;
196 new SelectPickerTv(web_view, selected_index, is_multiple_selection);
199 new SelectPickerMobile(web_view, selected_index, is_multiple_selection);
201 // Create two separate Elm_Genlist_Item_Class classes, because EFL cannot swap
202 // item_style at runtime.
203 picker->InitializeItemClass();
204 picker->InitializeGroupClass();
205 picker->Init(std::move(items), bounds);
211 class WebViewAsyncRequestHitTestDataCallback {
213 WebViewAsyncRequestHitTestDataCallback(int x, int y, Ewk_Hit_Test_Mode mode)
214 : x_(x), y_(y), mode_(mode) {}
215 virtual ~WebViewAsyncRequestHitTestDataCallback(){};
217 virtual void Run(_Ewk_Hit_Test* hit_test, EWebView* web_view) = 0;
220 int GetX() const { return x_; }
221 int GetY() const { return y_; }
222 Ewk_Hit_Test_Mode GetMode() const { return mode_; }
227 Ewk_Hit_Test_Mode mode_;
230 class WebViewAsyncRequestHitTestDataUserCallback
231 : public WebViewAsyncRequestHitTestDataCallback {
233 WebViewAsyncRequestHitTestDataUserCallback(
236 Ewk_Hit_Test_Mode mode,
237 Ewk_View_Hit_Test_Request_Callback callback,
239 : WebViewAsyncRequestHitTestDataCallback(x, y, mode),
241 user_data_(user_data) {}
243 void Run(_Ewk_Hit_Test* hit_test, EWebView* web_view) override {
245 callback_(web_view->evas_object(), GetX(), GetY(), GetMode(), hit_test,
250 Ewk_View_Hit_Test_Request_Callback callback_;
254 #if defined(TIZEN_ATK_SUPPORT)
255 class EWebAccessibilityObserver : public EWebAccessibility::Observer {
257 explicit EWebAccessibilityObserver(EWebView* webview) : webview_(webview) {}
258 virtual ~EWebAccessibilityObserver() {}
260 // EWebAccessibility::Observer implementation
261 void OnSpatialNavigationStatusChanged(Eina_Bool enable) override {
262 webview_->UpdateSpatialNavigationStatus(enable);
265 void OnAccessibilityStatusChanged(Eina_Bool enable) override {
266 webview_->UpdateAccessibilityStatus(enable);
274 int EWebView::find_request_id_counter_ = 0;
275 content::WebContentsEflDelegate::WebContentsCreateCallback
276 EWebView::create_new_window_web_contents_cb_ =
277 base::BindRepeating(&NullCreateWebContents);
279 EWebView* EWebView::FromEvasObject(Evas_Object* eo) {
280 return WebViewDelegateEwk::GetInstance().GetWebViewFromEvasObject(eo);
283 void EWebView::OnViewFocusIn(void* data, Evas*, Evas_Object*, void*) {
284 auto view = static_cast<EWebView*>(data);
285 view->SetFocus(EINA_TRUE);
288 void EWebView::OnViewFocusOut(void* data, Evas*, Evas_Object*, void*) {
289 auto view = static_cast<EWebView*>(data);
290 view->SetFocus(EINA_FALSE);
293 void EWebView::VisibleContentChangedCallback(void* user_data,
294 Evas_Object* /*object*/,
296 auto view = static_cast<EWebView*>(user_data);
297 auto rect = static_cast<Eina_Rectangle*>(event_info);
298 view->GetSelectionController()->SetCustomVisibleViewRect(
299 gfx::Rect(rect->x, rect->y, rect->w, rect->h));
302 void EWebView::OnCustomScrollBeginCallback(void* user_data,
303 Evas_Object* /*object*/,
304 void* /*event_info*/) {
305 auto* view = static_cast<EWebView*>(user_data);
306 if (auto* selection_controller = view->GetSelectionController())
307 selection_controller->SetControlsTemporarilyHidden(true,true);
310 void EWebView::OnCustomScrollEndCallback(void* user_data,
311 Evas_Object* /*object*/,
312 void* /*event_info*/) {
313 auto* view = static_cast<EWebView*>(user_data);
314 if (auto* selection_controller = view->GetSelectionController())
315 selection_controller->SetControlsTemporarilyHidden(false,true);
318 EWebView::EWebView(Ewk_Context* context, Evas_Object* object)
320 evas_object_(object),
321 native_view_(object),
322 mouse_events_enabled_(false),
323 text_zoom_factor_(1.0),
324 current_find_request_id_(find_request_id_counter_++),
326 hit_test_completion_(base::WaitableEvent::ResetPolicy::AUTOMATIC,
327 base::WaitableEvent::InitialState::NOT_SIGNALED),
328 page_scale_factor_(1.0),
331 is_initialized_(false) {
333 evas_object_smart_callback_add(evas_object_,
334 kVisibleContentChangedSignalName,
335 VisibleContentChangedCallback, this);
337 evas_object_smart_callback_add(evas_object_, kCustomScrollBeginSignalName,
338 OnCustomScrollBeginCallback, this);
339 evas_object_smart_callback_add(evas_object_, kCustomScrollEndSignalName,
340 OnCustomScrollEndCallback, this);
341 evas_object_event_callback_add(evas_object_, EVAS_CALLBACK_FOCUS_IN,
342 OnViewFocusIn, this);
343 evas_object_event_callback_add(evas_object_, EVAS_CALLBACK_FOCUS_OUT,
344 OnViewFocusOut, this);
345 #if BUILDFLAG(IS_TIZEN)
346 window_rotate_handler_ = ecore_event_handler_add(
347 ECORE_WL2_EVENT_WINDOW_ROTATE, RotateWindowCb, this);
352 void EWebView::Initialize() {
353 if (is_initialized_) {
359 evas_event_handler_ = new WebViewEvasEventHandler(this);
361 scroll_detector_.reset(new ScrollDetector(this));
363 DCHECK(web_contents_->GetRenderViewHost());
364 // Settings (content::WebPreferences) will be initalized by
365 // RenderViewHostImpl::ComputeWebkitPrefs() based on command line switches.
366 settings_.reset(new Ewk_Settings(evas_object_,
367 web_contents_->GetOrCreateWebPreferences()));
368 #if defined(TIZEN_ATK_SUPPORT)
369 std::unique_ptr<EWebAccessibilityObserver> observer(
370 new EWebAccessibilityObserver(this));
371 eweb_accessibility_.reset(new EWebAccessibility(
372 evas_object_, web_contents_.get(), std::move(observer)));
373 lazy_initialize_atk_ = true;
376 base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess();
377 if (cmdline->HasSwitch(switches::kTouchEventFeatureDetection)) {
378 SetTouchEventsEnabled(
379 cmdline->GetSwitchValueASCII(switches::kTouchEventFeatureDetection) ==
380 switches::kTouchEventFeatureDetectionEnabled);
382 SetMouseEventsEnabled(true);
385 std::string user_agent =
386 EflWebView::VersionInfo::GetInstance()->DefaultUserAgent();
387 web_contents_->SetUserAgentOverride(
388 blink::UserAgentOverride::UserAgentOnly(user_agent),
389 false /* override_in_new_tabs */);
391 elm_object_tree_focus_allow_set(native_view_, EINA_TRUE);
392 is_initialized_ = true;
393 evas_object_event_callback_add(native_view_, EVAS_CALLBACK_RESIZE,
394 EWebView::NativeViewResize, this);
396 auto cbce = static_cast<ContentBrowserClientEfl*>(
397 content::GetContentClientExport()->browser());
398 // Initialize accept languages
399 SyncAcceptLanguages(cbce->GetAcceptLangs(nullptr));
400 accept_langs_changed_callback_ =
401 base::BindOnce(&EWebView::SyncAcceptLanguages, base::Unretained(this));
402 cbce->AddAcceptLangsChangedCallback(
403 std::move(accept_langs_changed_callback_));
405 // If EWebView is created by window.open, RenderView is already created
406 // before initializing WebContents. So we should manually invoke
407 // EWebView::RenderViewReady here.
408 if (web_contents_->GetPrimaryMainFrame() &&
409 web_contents_->GetPrimaryMainFrame()->IsRenderFrameLive()) {
414 EWebView::~EWebView() {
415 auto cbce = static_cast<ContentBrowserClientEfl*>(
416 content::GetContentClientExport()->browser());
417 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
418 cbce->RemoveAcceptLangsChangedCallback(
419 std::move(accept_langs_changed_callback_));
422 evas_object_event_callback_del(native_view_, EVAS_CALLBACK_RESIZE,
423 EWebView::NativeViewResize);
424 #if defined(USE_WAYLAND)
425 if (GetSettings()->getClipboardEnabled())
426 ClipboardHelperEfl::GetInstance()->MaybeInvalidateActiveWebview(this);
429 std::map<int64_t, WebViewAsyncRequestHitTestDataCallback*>::iterator
430 hit_test_callback_iterator;
431 for (hit_test_callback_iterator = hit_test_callback_.begin();
432 hit_test_callback_iterator != hit_test_callback_.end();
433 hit_test_callback_iterator++)
434 delete hit_test_callback_iterator->second;
435 hit_test_callback_.clear();
437 for (auto iter = delayed_messages_.begin(); iter != delayed_messages_.end();
441 delayed_messages_.clear();
443 if (!is_initialized_) {
447 #if defined(TIZEN_ATK_SUPPORT)
448 eweb_accessibility_.reset();
451 select_picker_.reset();
452 context_menu_.reset();
453 mhtml_callback_map_.Clear();
455 compositor_observer_.reset();
457 // Release manually those scoped pointers to
458 // make sure they are released in correct order
459 web_contents_.reset();
460 web_contents_delegate_.reset();
462 // This code must be executed after WebContents deletion
463 // because WebContents depends on BrowserContext which
464 // is deleted along with EwkContext.
465 CHECK(!web_contents_);
467 permission_popup_manager_.reset();
469 gin_native_bridge_dispatcher_host_.reset();
472 evas_object_event_callback_del(evas_object_, EVAS_CALLBACK_FOCUS_IN,
474 evas_object_event_callback_del(evas_object_, EVAS_CALLBACK_FOCUS_OUT,
476 evas_object_smart_callback_del(evas_object_,
477 kVisibleContentChangedSignalName,
478 VisibleContentChangedCallback);
479 evas_object_smart_callback_del(evas_object_, kCustomScrollBeginSignalName,
480 OnCustomScrollBeginCallback);
481 evas_object_smart_callback_del(evas_object_, kCustomScrollEndSignalName,
482 OnCustomScrollEndCallback);
486 content::RenderWidgetHostViewAura* EWebView::rwhva() const {
487 return static_cast<content::RenderWidgetHostViewAura*>(
488 web_contents_->GetRenderWidgetHostView());
491 content::WebContentsViewAura* EWebView::wcva() const {
492 WebContentsImpl* wc = static_cast<WebContentsImpl*>(web_contents_.get());
493 return static_cast<WebContentsViewAura*>(wc->GetView());
496 void EWebView::NativeViewResize(void* data,
500 auto thiz = static_cast<EWebView*>(data);
501 if (!thiz->context_menu_)
503 int native_view_x, native_view_y, native_view_width, native_view_height;
504 evas_object_geometry_get(obj, &native_view_x, &native_view_y,
505 &native_view_width, &native_view_height);
506 gfx::Rect webview_rect(native_view_x, native_view_y, native_view_width,
508 thiz->context_menu_->Resize(webview_rect);
511 void EWebView::ResetContextMenuController() {
512 return context_menu_.reset();
515 void EWebView::SetFocus(Eina_Bool focus) {
516 if (!web_contents_ || !rwhva() || (HasFocus() == focus))
519 rwhva()->offscreen_helper()->Focus(focus);
522 Eina_Bool EWebView::HasFocus() const {
526 return rwhva()->offscreen_helper()->HasFocus() ? EINA_TRUE : EINA_FALSE;
529 Eina_Bool EWebView::AddJavaScriptMessageHandler(
531 Ewk_View_Script_Message_Cb callback,
533 if (!gin_native_bridge_dispatcher_host_)
536 return gin_native_bridge_dispatcher_host_->AddNamedObject(view, callback,
540 bool EWebView::SetPageVisibility(
541 Ewk_Page_Visibility_State page_visibility_state) {
545 // TODO: We should able to set 'prerender' or 'unloaded' as visibility state.
546 // http://www.w3.org/TR/page-visibility/#dom-document-visibilitystate
547 switch (page_visibility_state) {
548 case EWK_PAGE_VISIBILITY_STATE_VISIBLE:
549 rwhva()->offscreen_helper()->SetPageVisibility(true);
551 case EWK_PAGE_VISIBILITY_STATE_HIDDEN:
552 rwhva()->offscreen_helper()->SetPageVisibility(false);
554 case EWK_PAGE_VISIBILITY_STATE_PRERENDER:
564 bool EWebView::CreateNewWindow(
565 content::WebContentsEflDelegate::WebContentsCreateCallback cb) {
566 create_new_window_web_contents_cb_ = cb;
567 Evas_Object* new_object = NULL;
568 SmartCallback<EWebViewCallbacks::CreateNewWindow>().call(&new_object);
569 create_new_window_web_contents_cb_ =
570 base::BindRepeating(&NullCreateWebContents);
575 Evas_Object* EWebView::GetHostWindowDelegate(const content::WebContents* wc) {
576 EWebView* thiz = WebViewFromWebContents(wc);
577 DCHECK(thiz->evas_object_);
578 Evas_Object* parent = evas_object_above_get(thiz->evas_object_);
580 LOG(WARNING) << "Could not find and visual parents for EWK smart object!.";
581 return thiz->evas_object_;
584 if (elm_object_widget_check(parent)) {
585 Evas_Object* elm_parent = elm_object_top_widget_get(parent);
591 LOG(WARNING) << "Could not find elementary parent for WebView object!";
592 return thiz->evas_object_;
595 Evas_Object* EWebView::GetElmWindow() const {
596 Evas_Object* parent = elm_object_parent_widget_get(evas_object_);
597 return parent ? elm_object_top_widget_get(parent) : nullptr;
600 void EWebView::SetURL(const GURL& url, bool from_api) {
601 NavigationController::LoadURLParams params(url);
604 params.transition_type = ui::PageTransitionFromInt(
605 ui::PAGE_TRANSITION_LINK | ui::PAGE_TRANSITION_FROM_API);
608 params.override_user_agent = NavigationController::UA_OVERRIDE_TRUE;
609 web_contents_->GetController().LoadURLWithParams(params);
612 const GURL& EWebView::GetURL() const {
613 return web_contents_->GetVisibleURL();
616 const GURL& EWebView::GetOriginalURL() const {
617 const auto entry = web_contents_->GetController().GetVisibleEntry();
619 return entry->GetOriginalRequestURL();
621 return web_contents_->GetVisibleURL();
624 void EWebView::Reload() {
625 web_contents_->GetController().Reload(content::ReloadType::NORMAL, true);
628 void EWebView::ReloadBypassingCache() {
629 web_contents_->GetController().Reload(content::ReloadType::BYPASSING_CACHE,
633 Eina_Bool EWebView::CanGoBack() {
634 return web_contents_->GetController().CanGoBack();
637 Eina_Bool EWebView::CanGoForward() {
638 return web_contents_->GetController().CanGoForward();
641 Eina_Bool EWebView::GoBack() {
642 if (!web_contents_->GetController().CanGoBack())
645 web_contents_->GetController().GoBack();
649 Eina_Bool EWebView::GoForward() {
650 if (!web_contents_->GetController().CanGoForward())
653 web_contents_->GetController().GoForward();
657 void EWebView::Stop() {
658 if (web_contents_->IsLoading())
659 web_contents_->Stop();
662 void EWebView::Suspend() {
663 CHECK(web_contents_);
664 #if BUILDFLAG(IS_TIZEN)
665 if (IsMobileProfile() && web_contents_->IsFullscreen())
666 web_contents_->ExitFullscreen(true);
668 RenderViewHost* rvh = web_contents_->GetRenderViewHost();
669 RenderFrameHost* rfh = web_contents_->GetPrimaryMainFrame();
672 #if !defined(EWK_BRINGUP) // FIXME: m69 bringup
673 rfh->BlockRequestsForFrame();
676 content::GetIOThreadTaskRunner({})->PostTask(FROM_HERE, base::BindOnce(
677 &content::ResourceDispatcherHost::BlockRequestsForFrameFromUI, rfh));
680 rvh->Send(new EwkViewMsg_SuspendScheduledTask(rvh->GetRoutingID()));
684 void EWebView::Resume() {
685 CHECK(web_contents_);
686 RenderViewHost* rvh = web_contents_->GetRenderViewHost();
687 RenderFrameHost* rfh = web_contents_->GetPrimaryMainFrame();
690 #if !defined(EWK_BRINGUP) // FIXME: m69 bringup
691 rfh->ResumeBlockedRequestsForFrame();
694 content::GetIOThreadTaskRunner({})->PostTask(FROM_HERE, base::BindOnce(
695 &content::ResourceDispatcherHost::ResumeBlockedRequestsForFrameFromUI,
699 rvh->Send(new EwkViewMsg_ResumeScheduledTasks(rvh->GetRoutingID()));
703 double EWebView::GetTextZoomFactor() const {
704 if (text_zoom_factor_ < 0.0)
707 return text_zoom_factor_;
710 void EWebView::SetTextZoomFactor(double text_zoom_factor) {
711 if (text_zoom_factor_ == text_zoom_factor || text_zoom_factor < 0.0)
714 text_zoom_factor_ = text_zoom_factor;
715 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
716 if (!render_view_host)
718 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
719 render_view_host->Send(new ViewMsg_SetTextZoomFactor(
720 render_view_host->GetRoutingID(), text_zoom_factor));
724 double EWebView::GetPageZoomFactor() const {
725 return blink::PageZoomLevelToZoomFactor(
726 content::HostZoomMap::GetZoomLevel(web_contents_.get()));
729 void EWebView::SetPageZoomFactor(double page_zoom_factor) {
730 content::HostZoomMap::SetZoomLevel(
731 web_contents_.get(), blink::PageZoomFactorToZoomLevel(page_zoom_factor));
734 void EWebView::ExecuteEditCommand(const char* command, const char* value) {
735 EINA_SAFETY_ON_NULL_RETURN(command);
737 absl::optional<std::u16string> optional_value;
738 if (value == nullptr)
739 optional_value = absl::nullopt;
741 optional_value = absl::make_optional(base::ASCIIToUTF16(value));
743 WebContentsImpl* wc = static_cast<WebContentsImpl*>(web_contents_.get());
745 wc->GetFocusedFrameWidgetInputHandler()->ExecuteEditCommand(
746 std::string(command), optional_value);
750 #if BUILDFLAG(IS_TIZEN)
751 void EWebView::EnterDragState() {
752 if (IsMobileProfile()) {
753 if (RenderViewHost* render_view_host = web_contents_->GetRenderViewHost())
754 web_contents_->EnterDragState(render_view_host);
759 void EWebView::SetOrientation(int orientation) {
760 if (GetOrientation() == orientation)
763 if (orientation == 0 || orientation == 90 || orientation == 180 ||
764 orientation == 270) {
765 #if !defined(USE_AURA)
766 GetWebContentsViewEfl()->SetOrientation(orientation);
770 const Ecore_Evas* ee =
771 ecore_evas_ecore_evas_get(evas_object_evas_get(evas_object_));
772 ecore_evas_screen_geometry_get(ee, nullptr, nullptr, &width, &height);
773 if (orientation == 90 || orientation == 270)
774 std::swap(width, height);
776 if (popup_controller_)
777 popup_controller_->SetPopupSize(width, height);
778 if (JavaScriptDialogManagerEfl* dialogMG = GetJavaScriptDialogManagerEfl())
779 dialogMG->SetPopupSize(width, height);
783 int EWebView::GetOrientation() {
784 #if !defined(USE_AURA)
785 return GetWebContentsViewEfl()->GetOrientation();
791 void EWebView::Show() {
792 evas_object_show(native_view_);
793 web_contents_->WasShown();
796 void EWebView::Hide() {
797 evas_object_hide(native_view_);
798 web_contents_->WasHidden();
801 void EWebView::SetViewAuthCallback(Ewk_View_Authentication_Callback callback,
803 authentication_cb_.Set(callback, user_data);
806 void EWebView::InvokeAuthCallback(LoginDelegateEfl* login_delegate,
808 const std::string& realm) {
809 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
811 auth_challenge_.reset(new _Ewk_Auth_Challenge(login_delegate, url, realm));
812 authentication_cb_.Run(evas_object_, auth_challenge_.get());
814 if (!auth_challenge_->is_decided && !auth_challenge_->is_suspended) {
815 auth_challenge_->is_decided = true;
816 auth_challenge_->login_delegate->Cancel();
820 void EWebView::InvokePolicyResponseCallback(
821 _Ewk_Policy_Decision* policy_decision,
823 SmartCallback<EWebViewCallbacks::PolicyResponseDecide>().call(
826 if (policy_decision->isSuspended()) {
831 if (!policy_decision->isDecided())
832 policy_decision->Use();
834 policy_decision->SelfDeleteIfNecessary();
837 void EWebView::InvokePolicyNavigationCallback(
838 const NavigationPolicyParams& params,
840 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
842 SmartCallback<EWebViewCallbacks::SaveSessionData>().call();
844 std::unique_ptr<_Ewk_Policy_Decision> policy_decision(
845 new _Ewk_Policy_Decision(params));
847 SmartCallback<EWebViewCallbacks::NavigationPolicyDecision>().call(
848 policy_decision.get());
850 CHECK(!policy_decision->isSuspended());
852 // TODO: Navigation can't be suspended
853 // this aproach is synchronous and requires immediate response
854 // Maybe there is different approach (like resource throttle response
855 // mechanism) that allows us to
856 // suspend navigation
857 if (!policy_decision->isDecided())
858 policy_decision->Use();
860 *handled = policy_decision->GetNavigationPolicyHandler()->GetDecision() ==
861 NavigationPolicyHandlerEfl::Handled;
864 void EWebView::HandleTouchEvents(Ewk_Touch_Event_Type type,
865 const Eina_List* points,
866 const Evas_Modifier* modifiers) {
870 if (GetSettings()->touchFocusEnabled() &&
871 (type == EWK_TOUCH_START && eina_list_count(points) == 1)) {
875 EINA_LIST_FOREACH(points, l, data) {
876 const Ewk_Touch_Point* point = static_cast<Ewk_Touch_Point*>(data);
877 if (point->state == EVAS_TOUCH_POINT_STILL) {
878 // Chromium doesn't expect (and doesn't like) these events.
887 evas_object_geometry_get(evas_object(), nullptr, &delta_y, nullptr,
889 ui::TouchEvent touch_event =
890 ui::MakeTouchEvent(pt, point->state, point->id, 0, delta_y);
891 rwhva()->OnTouchEvent(&touch_event);
896 bool EWebView::TouchEventsEnabled() const {
897 return rwhva()->offscreen_helper()->TouchEventsEnabled();
900 // TODO: Touch events use the same mouse events in EFL API.
901 // Figure out how to distinguish touch and mouse events on touch&mice devices.
902 // Currently mouse and touch support is mutually exclusive.
903 void EWebView::SetTouchEventsEnabled(bool enabled) {
904 if (!rwhva() || !rwhva()->offscreen_helper()) {
905 LOG(WARNING) << "RWHV is not created yet!";
909 if (rwhva()->offscreen_helper()->TouchEventsEnabled() == enabled)
912 rwhva()->offscreen_helper()->SetTouchEventsEnabled(enabled);
914 GetSettings()->getPreferences().touch_event_feature_detection_enabled =
916 GetSettings()->getPreferences().double_tap_to_zoom_enabled = enabled;
917 GetSettings()->getPreferences().editing_behavior =
918 enabled ? blink::mojom::EditingBehavior::kEditingAndroidBehavior
919 : blink::mojom::EditingBehavior::kEditingUnixBehavior,
920 UpdateWebKitPreferences();
923 bool EWebView::MouseEventsEnabled() const {
924 return mouse_events_enabled_;
927 void EWebView::SetMouseEventsEnabled(bool enabled) {
928 if (!rwhva() || !rwhva()->offscreen_helper()) {
929 LOG(WARNING) << "RWHV is not created yet!";
933 if (mouse_events_enabled_ == enabled)
936 mouse_events_enabled_ = enabled;
937 rwhva()->offscreen_helper()->SetTouchEventsEnabled(!enabled);
942 class JavaScriptCallbackDetails {
944 JavaScriptCallbackDetails(Ewk_View_Script_Execute_Callback callback_func,
947 : callback_func_(callback_func), user_data_(user_data), view_(view) {}
949 Ewk_View_Script_Execute_Callback callback_func_;
954 void JavaScriptComplete(JavaScriptCallbackDetails* script_callback_data,
955 base::Value result) {
956 if (!script_callback_data->callback_func_)
959 std::string return_string;
960 if (result.is_string()) {
961 // We don't want to serialize strings with JSONStringValueSerializer
962 // to avoid quotation marks.
963 return_string = result.GetString();
964 } else if (result.is_none()) {
965 // Value::TYPE_NULL is for lack of value, undefined, null
968 JSONStringValueSerializer serializer(&return_string);
969 serializer.Serialize(result);
972 script_callback_data->callback_func_(script_callback_data->view_,
973 return_string.c_str(),
974 script_callback_data->user_data_);
979 bool EWebView::ExecuteJavaScript(const char* script,
980 Ewk_View_Script_Execute_Callback callback,
982 LOG(INFO) << __FUNCTION__;
983 if (!web_contents_) {
984 LOG(ERROR) << __FUNCTION__ << "web_contents_ is null";
988 RenderFrameHost* render_frame_host = web_contents_->GetPrimaryMainFrame();
989 if (!render_frame_host) {
990 LOG(ERROR) << __FUNCTION__ << " render_frame_host is null";
994 // Note: M37. Execute JavaScript, |script| with
995 // |RenderFrameHost::ExecuteJavaScript|.
996 // @see also https://codereview.chromium.org/188893005 for more details.
997 std::u16string js_script;
998 base::UTF8ToUTF16(script, strlen(script), &js_script);
1000 JavaScriptCallbackDetails* script_callback_data =
1001 new JavaScriptCallbackDetails(callback, userdata, evas_object_);
1002 RenderFrameHost::JavaScriptResultCallback js_callback =
1003 base::BindOnce(&JavaScriptComplete, base::Owned(script_callback_data));
1004 // In M47, it isn't possible anymore to execute javascript in the generic
1005 // case. We need to call ExecuteJavaScriptForTests to keep the behaviour
1006 // unchanged @see https://codereview.chromium.org/1123783002
1007 render_frame_host->ExecuteJavaScriptWithUserGestureForTests(
1008 js_script, std::move(js_callback));
1010 // We use ExecuteJavaScriptWithUserGestureForTests instead of
1011 // ExecuteJavaScript because
1012 // ExecuteJavaScriptWithUserGestureForTests sets user_gesture to true. This
1014 // behaviour is m34, and we want to keep it that way.
1015 render_frame_host->ExecuteJavaScriptWithUserGestureForTests(
1016 js_script, base::NullCallback());
1022 bool EWebView::SetUserAgent(const char* userAgent) {
1023 content::NavigationController& controller = web_contents_->GetController();
1024 bool override = userAgent && strlen(userAgent);
1025 for (int i = 0; i < controller.GetEntryCount(); ++i)
1026 controller.GetEntryAtIndex(i)->SetIsOverridingUserAgent(override);
1027 // TODO: Check if override_in_new_tabs has to be true.
1028 web_contents_->SetUserAgentOverride(
1029 blink::UserAgentOverride::UserAgentOnly(userAgent),
1030 false /* override_in_new_tabs */);
1034 bool EWebView::SetUserAgentAppName(const char* application_name) {
1035 EflWebView::VersionInfo::GetInstance()->UpdateUserAgentWithAppName(
1036 application_name ? application_name : "");
1037 std::string user_agent =
1038 EflWebView::VersionInfo::GetInstance()->DefaultUserAgent();
1039 web_contents_->SetUserAgentOverride(
1040 blink::UserAgentOverride::UserAgentOnly(user_agent),
1041 false /* override_in_new_tabs */);
1045 #if BUILDFLAG(IS_TIZEN)
1046 bool EWebView::SetPrivateBrowsing(bool incognito) {
1047 if (context_->GetImpl()->browser_context()->IsOffTheRecord() == incognito)
1049 context_->GetImpl()->browser_context()->SetOffTheRecord(incognito);
1053 bool EWebView::GetPrivateBrowsing() const {
1054 return context_->GetImpl()->browser_context()->IsOffTheRecord();
1058 const char* EWebView::GetUserAgent() const {
1059 std::string user_agent =
1060 web_contents_->GetUserAgentOverride().ua_string_override;
1061 if (user_agent.empty())
1062 user_agent_ = content::GetContentClientExport()->browser()->GetUserAgent();
1064 user_agent_ = user_agent;
1066 return user_agent_.c_str();
1069 const char* EWebView::GetUserAgentAppName() const {
1070 user_agent_app_name_ = EflWebView::VersionInfo::GetInstance()->AppName();
1071 return user_agent_app_name_.c_str();
1074 const char* EWebView::CacheSelectedText() {
1078 selected_text_cached_ = base::UTF16ToUTF8(rwhva()->GetSelectedText());
1079 return selected_text_cached_.c_str();
1082 _Ewk_Frame* EWebView::GetMainFrame() {
1083 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1086 frame_.reset(new _Ewk_Frame(web_contents_->GetPrimaryMainFrame()));
1088 return frame_.get();
1091 void EWebView::UpdateWebKitPreferences() {
1092 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1094 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1095 if (!render_view_host)
1098 web_contents_delegate_->OnUpdateSettings(settings_.get());
1099 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
1100 render_view_host->UpdateWebkitPreferences(settings_->getPreferences());
1102 UpdateWebkitPreferencesEfl(render_view_host);
1105 void EWebView::UpdateWebkitPreferencesEfl(RenderViewHost* render_view_host) {
1106 DCHECK(render_view_host);
1107 #if !defined(EWK_BRINGUP) // FIXME: m108 bringup
1108 IPC::Message* message = new EwkSettingsMsg_UpdateWebKitPreferencesEfl(
1109 render_view_host->GetRoutingID(), settings_->getPreferencesEfl());
1111 if (render_view_host->IsRenderViewLive()) {
1112 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
1113 render_view_host->Send(message);
1116 delayed_messages_.push_back(message);
1121 void EWebView::SetContentSecurityPolicy(const char* policy,
1122 Ewk_CSP_Header_Type type) {
1123 web_contents_delegate_->SetContentSecurityPolicy(
1124 (policy ? policy : std::string()), type);
1127 void EWebView::LoadHTMLString(const char* html,
1128 const char* base_uri,
1129 const char* unreachable_uri) {
1130 LoadData(html, std::string::npos, NULL, NULL, base_uri, unreachable_uri);
1133 void EWebView::LoadPlainTextString(const char* plain_text) {
1134 LoadData(plain_text, std::string::npos, "text/plain", NULL, NULL, NULL);
1137 void EWebView::LoadData(const char* data,
1139 const char* mime_type,
1140 const char* encoding,
1141 const char* base_uri,
1142 const char* unreachable_uri) {
1143 SetDefaultStringIfNull(mime_type, "text/html");
1144 SetDefaultStringIfNull(encoding, "utf-8");
1145 SetDefaultStringIfNull(base_uri, "about:blank"); // Webkit2 compatible
1146 SetDefaultStringIfNull(unreachable_uri, "");
1148 std::string str_data = data;
1150 if (size < str_data.length())
1151 str_data = str_data.substr(0, size);
1153 std::string url_str("data:");
1154 url_str.append(mime_type);
1155 url_str.append(";charset=");
1156 url_str.append(encoding);
1157 url_str.append(",");
1159 // GURL constructor performs canonicalization of url string, but this is not
1160 // enough for correctly escaping contents of "data:" url.
1161 url_str.append(base::EscapeUrlEncodedData(str_data, false));
1163 NavigationController::LoadURLParams data_params(GURL(url_str.c_str()));
1165 data_params.base_url_for_data_url = GURL(base_uri);
1166 data_params.virtual_url_for_data_url = GURL(unreachable_uri);
1168 data_params.load_type = NavigationController::LOAD_TYPE_DATA;
1169 data_params.should_replace_current_entry = false;
1170 data_params.override_user_agent = NavigationController::UA_OVERRIDE_TRUE;
1171 web_contents_->GetController().LoadURLWithParams(data_params);
1174 void EWebView::InvokeLoadError(const GURL& url,
1176 bool is_cancellation) {
1177 _Ewk_Error err(error_code, is_cancellation,
1178 url.possibly_invalid_spec().c_str());
1180 SmartCallback<EWebViewCallbacks::LoadError>().call(&err);
1183 void EWebView::SetViewLoadErrorPageCallback(
1184 Ewk_View_Error_Page_Load_Callback callback,
1186 load_error_page_cb_.Set(callback, user_data);
1189 // Remove below code while ewk_error_cancellation_get has been implemented.
1190 const char* EWebView::InvokeViewLoadErrorPageCallback(
1193 const std::string& error_description) {
1194 std::unique_ptr<_Ewk_Error> err(
1195 new _Ewk_Error(error_code, url.possibly_invalid_spec().c_str(),
1196 error_description.c_str()));
1197 _Ewk_Error_Page error_page;
1199 LOG(INFO) << "EWebView::InvokeLoadErrorPageCallback url: "
1200 << url.spec().c_str() << ", error_code: " << error_code;
1202 load_error_page_cb_.Run(evas_object_, err.get(), &error_page);
1203 return error_page.content;
1206 bool EWebView::IsLoadErrorPageCallbackSet() const {
1207 return load_error_page_cb_.IsCallbackSet();
1209 void EWebView::HandlePopupMenu(std::vector<blink::mojom::MenuItemPtr> items,
1212 const gfx::Rect& bounds) {
1213 if (!select_picker_) {
1214 select_picker_.reset(CreateSelectPicker(
1215 this, selectedIndex, std::move(items), multiple, bounds));
1217 // Picker has been shown on top of webview and the page content gets
1218 // partially overlapped. Decrease viewport while showing picker.
1219 AdjustViewPortHeightToPopupMenu(true /* is_popup_menu_visible */);
1220 #if BUILDFLAG(IS_TIZEN_TV)
1221 SmartCallback<EWebViewCallbacks::PopupMenuShow>().call();
1224 select_picker_->UpdatePickerData(selectedIndex, std::move(items), multiple);
1227 select_picker_->Show();
1230 void EWebView::HidePopupMenu() {
1231 if (!select_picker_)
1234 AdjustViewPortHeightToPopupMenu(false /* is_popup_menu_visible */);
1235 #if BUILDFLAG(IS_TIZEN_TV)
1236 SmartCallback<EWebViewCallbacks::PopupMenuHide>().call();
1238 select_picker_.reset();
1241 void EWebView::DidSelectPopupMenuItems(std::vector<int>& indices) {
1242 wcva()->wcva_helper()->DidSelectPopupMenuItems(indices);
1245 void EWebView::DidCancelPopupMenu() {
1246 wcva()->wcva_helper()->DidCancelPopupMenu();
1249 void EWebView::HandleLongPressGesture(
1250 const content::ContextMenuParams& params) {
1251 // This menu is created in renderer process and it does not now anything about
1252 // view scaling factor and it has another calling sequence, so coordinates is
1254 if (settings_ && !settings_->getPreferences().long_press_enabled)
1257 content::ContextMenuParams convertedParams = params;
1258 gfx::Point convertedPoint =
1259 rwhva()->offscreen_helper()->ConvertPointInViewPix(
1260 gfx::Point(params.x, params.y));
1261 convertedParams.x = convertedPoint.x();
1262 convertedParams.y = convertedPoint.y();
1265 evas_object_geometry_get(evas_object(), &x, &y, 0, 0);
1266 convertedParams.x += x;
1267 convertedParams.y += y;
1269 if (GetSelectionController() && GetSelectionController()->GetLongPressed()) {
1270 bool show_context_menu_now =
1271 !GetSelectionController()->HandleLongPressEvent(convertedPoint,
1273 if (show_context_menu_now)
1274 ShowContextMenuInternal(convertedParams);
1278 void EWebView::ShowContextMenu(const content::ContextMenuParams& params) {
1282 // This menu is created in renderer process and it does not now anything about
1283 // view scaling factor and it has another calling sequence, so coordinates is
1285 content::ContextMenuParams convertedParams = params;
1286 gfx::Point convertedPoint =
1287 rwhva()->offscreen_helper()->ConvertPointInViewPix(
1288 gfx::Point(params.x, params.y));
1289 convertedParams.x = convertedPoint.x();
1290 convertedParams.y = convertedPoint.y();
1293 evas_object_geometry_get(evas_object(), &x, &y, 0, 0);
1294 convertedParams.x += x;
1295 convertedParams.y += y;
1297 context_menu_position_ = gfx::Point(convertedParams.x, convertedParams.y);
1299 ShowContextMenuInternal(convertedParams);
1302 void EWebView::ShowContextMenuInternal(
1303 const content::ContextMenuParams& params) {
1304 // We don't want to show 'cut' or 'copy' for inputs of type 'password' in
1305 // selection context menu, but params.input_field_type might not be set
1306 // correctly, because in some cases params is received from SelectionBoxEfl,
1307 // not from FrameHostMsg_ContextMenu message. In SelectionBoxEfl
1308 // ContextMenuParams is constructed on our side with limited information and
1309 // input_field_type is not set.
1311 // To work around this, we query for input type and set it separately. In
1312 // response to EwkViewMsg_QueryInputType we run ::UpdateContextMenu with
1313 // information about input's type.
1315 // FIXME: the way we get ContextMenuParams for context menu is flawed in some
1316 // cases. This should be fixed by restructuring context menu code.
1317 // Context menu creation should be unified to always have
1318 // ContextMenuParams received from FrameHostMsg_ContextMenu.
1319 // Tracked at: http://suprem.sec.samsung.net/jira/browse/TWF-1640
1320 if (params.is_editable) {
1321 saved_context_menu_params_ = params;
1323 rwhva()->host()->QueryInputType();
1325 UpdateContextMenuWithParams(params);
1329 void EWebView::UpdateContextMenu(bool is_password_input) {
1330 if (is_password_input) {
1331 saved_context_menu_params_.input_field_type =
1332 blink::mojom::ContextMenuDataInputFieldType::kPassword;
1334 UpdateContextMenuWithParams(saved_context_menu_params_);
1337 void EWebView::UpdateContextMenuWithParams(
1338 const content::ContextMenuParams& params) {
1339 context_menu_.reset(
1340 new content::ContextMenuControllerEfl(this, *web_contents_.get()));
1342 if (IsMobileProfile()) {
1343 if (delayed_show_context_menu_timer_) {
1344 ecore_timer_del(delayed_show_context_menu_timer_);
1345 delayed_show_context_menu_timer_ = nullptr;
1347 saved_context_menu_params_ = params;
1348 delayed_show_context_menu_timer_ = ecore_timer_add(
1349 kDelayShowContextMenuTime, DelayedPopulateAndShowContextMenu, this);
1351 if (!context_menu_->PopulateAndShowContextMenu(params)) {
1352 context_menu_.reset();
1353 if (GetSelectionController())
1354 GetSelectionController()->HideHandles();
1359 Eina_Bool EWebView::DelayedPopulateAndShowContextMenu(void* data) {
1360 if (IsMobileProfile) {
1361 EWebView* view = static_cast<EWebView*>(data);
1363 if (view->context_menu_ &&
1364 !(view->context_menu_->PopulateAndShowContextMenu(
1365 view->saved_context_menu_params_))) {
1366 view->context_menu_.reset();
1368 view->delayed_show_context_menu_timer_ = nullptr;
1371 return ECORE_CALLBACK_CANCEL;
1374 void EWebView::CancelContextMenu(int request_id) {
1376 context_menu_->HideContextMenu();
1379 void EWebView::Find(const char* text, Ewk_Find_Options ewk_find_options) {
1380 std::u16string find_text = base::UTF8ToUTF16(text);
1381 bool find_next = (previous_text_ == find_text);
1384 current_find_request_id_ = find_request_id_counter_++;
1385 previous_text_ = find_text;
1388 auto find_options = blink::mojom::FindOptions::New();
1389 find_options->forward = !(ewk_find_options & EWK_FIND_OPTIONS_BACKWARDS);
1390 find_options->match_case =
1391 !(ewk_find_options & EWK_FIND_OPTIONS_CASE_INSENSITIVE);
1393 web_contents_->Find(current_find_request_id_, find_text,
1394 std::move(find_options));
1397 void EWebView::SetScale(double scale_factor) {
1398 // Do not cache |scale_factor| here as it may be discarded by Blink's
1399 // minimumPageScaleFactor and maximumPageScaleFactor.
1400 // |scale_factor| is cached as responde to DidChangePageScaleFactor.
1401 WebContentsImpl* wci = static_cast<WebContentsImpl*>(web_contents_.get());
1402 wci->GetPrimaryMainFrame()->GetAssociatedLocalMainFrame()->SetScaleFactor(
1406 void EWebView::ScrollFocusedNodeIntoView() {
1407 if (RenderViewHost* render_view_host = web_contents_->GetRenderViewHost()) {
1408 if (auto& broadcast = static_cast<RenderViewHostImpl*>(render_view_host)
1409 ->GetAssociatedPageBroadcast())
1410 broadcast->ScrollFocusedNodeIntoView();
1414 void EWebView::AdjustViewPortHeightToPopupMenu(bool is_popup_menu_visible) {
1415 if (!rwhva() || !IsMobileProfile() ||
1416 settings_->getPreferences().TizenCompatibilityModeEnabled()) {
1420 int picker_height = select_picker_->GetGeometryDIP().height();
1421 gfx::Rect screen_rect =
1422 display::Screen::GetScreen()->GetPrimaryDisplay().bounds();
1423 gfx::Rect view_rect = rwhva()->offscreen_helper()->GetViewBounds();
1425 screen_rect.height() - (view_rect.y() + view_rect.height());
1427 rwhva()->offscreen_helper()->SetCustomViewportSize(
1428 is_popup_menu_visible
1429 ? gfx::Size(view_rect.width(),
1430 view_rect.height() - picker_height + bottom_height)
1434 void EWebView::SetScaleChangedCallback(Ewk_View_Scale_Changed_Callback callback,
1436 scale_changed_cb_.Set(callback, user_data);
1439 bool EWebView::GetScrollPosition(int* x, int* y) const {
1441 LOG(ERROR) << "rwhva() returns nullptr";
1444 if (scroll_detector_->IsScrollOffsetChanged()) {
1446 *x = previous_scroll_position_.x();
1448 *y = previous_scroll_position_.y();
1450 const gfx::Vector2d scroll_position_dip =
1451 scroll_detector_->GetLastScrollPosition();
1452 const float device_scale_factor = display::Screen::GetScreen()
1453 ->GetPrimaryDisplay()
1454 .device_scale_factor();
1456 *x = base::ClampRound((scroll_position_dip.x() - x_delta_) *
1457 device_scale_factor);
1460 *y = base::ClampRound((scroll_position_dip.y() - y_delta_) *
1461 device_scale_factor);
1467 void EWebView::ChangeScroll(int& x, int& y) {
1469 LOG(ERROR) << "rwhva() returns nullptr";
1474 GetScrollSize(&max_x, &max_y);
1475 previous_scroll_position_.set_x(std::min(std::max(x, 0), max_x));
1476 previous_scroll_position_.set_y(std::min(std::max(y, 0), max_y));
1478 const float device_scale_factor = display::Screen::GetScreen()
1479 ->GetPrimaryDisplay()
1480 .device_scale_factor();
1484 x = base::ClampCeil(x / device_scale_factor);
1485 y = base::ClampCeil(y / device_scale_factor);
1487 x_delta_ = x - (x_input / device_scale_factor);
1488 y_delta_ = y - (y_input / device_scale_factor);
1490 scroll_detector_->SetScrollOffsetChanged();
1493 void EWebView::SetScroll(int x, int y) {
1494 if (auto* render_view_host = web_contents_->GetRenderViewHost()) {
1495 if (auto& broadcast = static_cast<RenderViewHostImpl*>(render_view_host)
1496 ->GetAssociatedPageBroadcast()) {
1498 broadcast->SetScrollOffset(x, y);
1503 void EWebView::UseSettingsFont() {
1504 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
1505 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1506 if (render_view_host)
1507 render_view_host->Send(
1508 new EwkViewMsg_UseSettingsFont(render_view_host->GetRoutingID()));
1512 void EWebView::DidChangeContentsSize(int width, int height) {
1513 contents_size_ = gfx::Size(width, height);
1514 SmartCallback<EWebViewCallbacks::ContentsSizeChanged>().call();
1515 SetScaledContentsSize();
1518 const Eina_Rectangle EWebView::GetContentsSize() const {
1519 Eina_Rectangle rect;
1520 EINA_RECTANGLE_SET(&rect, 0, 0, contents_size_.width(),
1521 contents_size_.height());
1525 void EWebView::SetScaledContentsSize() {
1527 return; // LCOV_EXCL_LINE
1529 const float device_scale_factor =
1530 display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
1531 gfx::SizeF scaled_contents_size = gfx::ConvertSizeToPixels(
1532 contents_size_, device_scale_factor * page_scale_factor_);
1533 rwhva()->offscreen_helper()->SetScaledContentSize(scaled_contents_size);
1536 void EWebView::GetScrollSize(int* width, int* height) {
1539 *width = (rwhva() &&
1540 (w = rwhva()->offscreen_helper()->GetScrollableSize().width()))
1545 *height = (rwhva() &&
1546 (h = rwhva()->offscreen_helper()->GetScrollableSize().height()))
1552 void EWebView::MoveCaret(const gfx::Point& point) {
1554 rwhva()->offscreen_helper()->MoveCaret(point);
1557 SelectionControllerEfl* EWebView::GetSelectionController() const {
1558 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1559 RenderWidgetHostViewAura* view = static_cast<RenderWidgetHostViewAura*>(
1560 render_view_host->GetWidget()->GetView());
1561 return view ? view->offscreen_helper()->GetSelectionController() : 0;
1564 void EWebView::SelectFocusedLink() {
1565 rwhva()->host()->SelectFocusedLink();
1568 bool EWebView::GetSelectionRange(Eina_Rectangle* left_rect,
1569 Eina_Rectangle* right_rect) {
1570 if (left_rect && right_rect) {
1571 gfx::Rect left, right;
1572 if (GetSelectionController()) {
1573 GetSelectionController()->GetSelectionBounds(&left, &right);
1574 GetEinaRectFromGfxRect(left, left_rect);
1575 GetEinaRectFromGfxRect(right, right_rect);
1582 void EWebView::OnSelectionRectReceived(const gfx::Rect& selection_rect) const {
1584 context_menu_->OnSelectionRectReceived(selection_rect);
1587 Eina_Bool EWebView::ClearSelection() {
1591 ResetContextMenuController();
1592 rwhva()->offscreen_helper()->SelectionChanged(std::u16string(), 0,
1595 if (GetSelectionController())
1596 return GetSelectionController()->ClearSelectionViaEWebView();
1601 _Ewk_Hit_Test* EWebView::RequestHitTestDataAt(int x,
1603 Ewk_Hit_Test_Mode mode) {
1604 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1607 EvasToBlinkCords(x, y, &view_x, &view_y);
1609 return RequestHitTestDataAtBlinkCoords(view_x, view_y, mode);
1612 Eina_Bool EWebView::AsyncRequestHitTestDataAt(
1615 Ewk_Hit_Test_Mode mode,
1616 Ewk_View_Hit_Test_Request_Callback callback,
1619 EvasToBlinkCords(x, y, &view_x, &view_y);
1620 return AsyncRequestHitTestDataAtBlinkCords(
1621 view_x, view_y, mode,
1622 new WebViewAsyncRequestHitTestDataUserCallback(x, y, mode, callback,
1626 Eina_Bool EWebView::AsyncRequestHitTestDataAtBlinkCords(
1629 Ewk_Hit_Test_Mode mode,
1630 Ewk_View_Hit_Test_Request_Callback callback,
1632 return AsyncRequestHitTestDataAtBlinkCords(
1634 new WebViewAsyncRequestHitTestDataUserCallback(x, y, mode, callback,
1638 Eina_Bool EWebView::AsyncRequestHitTestDataAtBlinkCords(
1641 Ewk_Hit_Test_Mode mode,
1642 WebViewAsyncRequestHitTestDataCallback* cb) {
1643 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1646 static int64_t request_id = 1;
1649 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1650 DCHECK(render_view_host);
1652 if (render_view_host) {
1653 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
1654 render_view_host->Send(new EwkViewMsg_DoHitTestAsync(
1655 render_view_host->GetRoutingID(), x, y, mode, request_id));
1657 hit_test_callback_[request_id] = cb;
1663 // if failed we delete callback as it is not needed anymore
1668 void EWebView::DispatchAsyncHitTestData(const Hit_Test_Params& params,
1669 int64_t request_id) {
1670 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1672 std::map<int64_t, WebViewAsyncRequestHitTestDataCallback*>::iterator it =
1673 hit_test_callback_.find(request_id);
1675 if (it == hit_test_callback_.end())
1677 std::unique_ptr<_Ewk_Hit_Test> hit_test(new _Ewk_Hit_Test(params));
1679 it->second->Run(hit_test.get(), this);
1681 hit_test_callback_.erase(it);
1684 _Ewk_Hit_Test* EWebView::RequestHitTestDataAtBlinkCoords(
1687 Ewk_Hit_Test_Mode mode) {
1688 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1690 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1692 if (render_view_host) {
1693 // We wait on UI thread till hit test data is updated.
1694 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
1695 render_view_host->Send(
1696 new EwkViewMsg_DoHitTest(render_view_host->GetRoutingID(), x, y, mode));
1698 hit_test_completion_.Wait();
1699 return new _Ewk_Hit_Test(hit_test_params_);
1705 void EWebView::EvasToBlinkCords(int x, int y, int* view_x, int* view_y) {
1706 DCHECK(display::Screen::GetScreen());
1710 gfx::Rect view_bounds = rwhva()->offscreen_helper()->GetViewBoundsInPix();
1713 *view_x = x - view_bounds.x();
1715 display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
1719 *view_y = y - view_bounds.y();
1721 display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
1725 void EWebView::UpdateHitTestData(const Hit_Test_Params& params) {
1726 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
1727 hit_test_params_ = params;
1728 hit_test_completion_.Signal();
1731 void EWebView::OnCopyFromBackingStore(bool success, const SkBitmap& bitmap) {}
1733 void EWebView::OnFocusIn() {
1734 SmartCallback<EWebViewCallbacks::FocusIn>().call();
1735 #if defined(USE_WAYLAND)
1736 if (!rwhva() || !rwhva()->offscreen_helper())
1738 if (GetSettings()->getClipboardEnabled()) {
1739 ClipboardHelperEfl::GetInstance()->OnWebviewFocusIn(
1740 this, rwhva()->offscreen_helper()->content_image_elm_host(),
1741 rwhva()->offscreen_helper()->IsFocusedNodeContentEditable(),
1742 base::BindRepeating(&EWebView::ExecuteEditCommand,
1743 base::Unretained(this)));
1748 void EWebView::OnFocusOut() {
1749 SmartCallback<EWebViewCallbacks::FocusOut>().call();
1750 #if defined(USE_WAYLAND)
1751 if (GetSettings()->getClipboardEnabled())
1752 ClipboardHelperEfl::GetInstance()->MaybeInvalidateActiveWebview(this);
1756 void EWebView::RenderViewReady() {
1758 rwhva()->offscreen_helper()->SetFocusInOutCallbacks(
1759 base::BindRepeating(&EWebView::OnFocusIn, base::Unretained(this)),
1760 base::BindRepeating(&EWebView::OnFocusOut, base::Unretained(this)));
1763 #if defined(TIZEN_VIDEO_HOLE)
1764 if (rwhva() && pending_video_hole_setting_) {
1765 rwhva()->host()->SetVideoHoleForRender(pending_video_hole_setting_);
1766 pending_video_hole_setting_ = false;
1770 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1772 SendDelayedMessages(render_view_host);
1773 UpdateWebkitPreferencesEfl(render_view_host);
1775 if (render_view_host) {
1776 WebContents* content = WebContents::FromRenderViewHost(render_view_host);
1778 RenderProcessHost* host = render_view_host->GetProcess();
1780 host->AddFilter(new WebViewBrowserMessageFilter(content));
1785 void EWebView::SetQuotaPermissionRequestCallback(
1786 Ewk_Quota_Permission_Request_Callback callback,
1788 quota_request_callback_.Set(callback, user_data);
1791 void EWebView::InvokeQuotaPermissionRequest(
1792 _Ewk_Quota_Permission_Request* request,
1793 content::QuotaPermissionContext::PermissionCallback cb) {
1794 quota_permission_request_map_[request] = std::move(cb);
1795 request->setView(evas_object());
1796 if (quota_request_callback_.IsCallbackSet())
1797 quota_request_callback_.Run(evas_object(), request);
1799 QuotaRequestCancel(request);
1802 void EWebView::QuotaRequestReply(const _Ewk_Quota_Permission_Request* request,
1804 DCHECK(quota_permission_request_map_.find(request) !=
1805 quota_permission_request_map_.end());
1807 QuotaPermissionContextEfl::DispatchCallback(
1808 std::move(quota_permission_request_map_[request]),
1809 (allow ? QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_ALLOW
1810 : QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_DISALLOW));
1812 quota_permission_request_map_.erase(request);
1816 void EWebView::QuotaRequestCancel(
1817 const _Ewk_Quota_Permission_Request* request) {
1818 DCHECK(quota_permission_request_map_.find(request) !=
1819 quota_permission_request_map_.end());
1821 QuotaPermissionContextEfl::DispatchCallback(
1822 std::move(quota_permission_request_map_[request]),
1823 QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_CANCELLED);
1824 quota_permission_request_map_.erase(request);
1828 bool EWebView::GetLinkMagnifierEnabled() const {
1829 #if !defined(EWK_BRINGUP) // FIXME: m71 bringup
1830 return web_contents_->GetMutableRendererPrefs()
1831 ->tap_multiple_targets_strategy ==
1832 TAP_MULTIPLE_TARGETS_STRATEGY_POPUP;
1838 void EWebView::SetLinkMagnifierEnabled(bool enabled) {
1839 #if !defined(EWK_BRINGUP) // FIXME: m71 bringup
1840 web_contents_->GetMutableRendererPrefs()->tap_multiple_targets_strategy =
1841 enabled ? TAP_MULTIPLE_TARGETS_STRATEGY_POPUP
1842 : TAP_MULTIPLE_TARGETS_STRATEGY_NONE;
1844 web_contents_->SyncRendererPrefs();
1847 bool EWebView::GetSnapshotAsync(
1848 Eina_Rectangle rect,
1849 Ewk_Web_App_Screenshot_Captured_Callback callback,
1851 float scale_factor) {
1852 if (!rwhva() || !rwhva()->offscreen_helper())
1855 rwhva()->offscreen_helper()->RequestSnapshotAsync(
1856 gfx::Rect(rect.x, rect.y, rect.w, rect.h), callback, user_data,
1861 Evas_Object* EWebView::GetSnapshot(Eina_Rectangle rect, float scale_factor) {
1862 if (!rwhva() || !rwhva()->offscreen_helper())
1865 return rwhva()->offscreen_helper()->GetSnapshot(
1866 gfx::Rect(rect.x, rect.y, rect.w, rect.h), scale_factor);
1869 void EWebView::BackForwardListClear() {
1870 content::NavigationController& controller = web_contents_->GetController();
1872 int entry_count = controller.GetEntryCount();
1873 bool entry_removed = false;
1875 for (int i = 0; i < entry_count; i++) {
1876 if (controller.RemoveEntryAtIndex(i)) {
1877 entry_removed = true;
1878 entry_count = controller.GetEntryCount();
1883 if (entry_removed) {
1884 back_forward_list_->ClearCache();
1885 InvokeBackForwardListChangedCallback();
1889 _Ewk_Back_Forward_List* EWebView::GetBackForwardList() const {
1890 return back_forward_list_.get();
1893 void EWebView::InvokeBackForwardListChangedCallback() {
1894 SmartCallback<EWebViewCallbacks::BackForwardListChange>().call();
1897 _Ewk_History* EWebView::GetBackForwardHistory() const {
1898 return new _Ewk_History(web_contents_->GetController());
1901 bool EWebView::WebAppCapableGet(Ewk_Web_App_Capable_Get_Callback callback,
1903 RenderViewHost* renderViewHost = web_contents_->GetRenderViewHost();
1904 if (!renderViewHost) {
1907 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
1908 WebApplicationCapableGetCallback* cb =
1909 new WebApplicationCapableGetCallback(callback, userData);
1910 int callbackId = web_app_capable_get_callback_map_.Add(cb);
1911 return renderViewHost->Send(new EwkViewMsg_WebAppCapableGet(
1912 renderViewHost->GetRoutingID(), callbackId));
1918 bool EWebView::WebAppIconUrlGet(Ewk_Web_App_Icon_URL_Get_Callback callback,
1920 RenderViewHost* renderViewHost = web_contents_->GetRenderViewHost();
1921 if (!renderViewHost) {
1924 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
1925 WebApplicationIconUrlGetCallback* cb =
1926 new WebApplicationIconUrlGetCallback(callback, userData);
1927 int callbackId = web_app_icon_url_get_callback_map_.Add(cb);
1928 return renderViewHost->Send(new EwkViewMsg_WebAppIconUrlGet(
1929 renderViewHost->GetRoutingID(), callbackId));
1935 bool EWebView::WebAppIconUrlsGet(Ewk_Web_App_Icon_URLs_Get_Callback callback,
1937 RenderViewHost* renderViewHost = web_contents_->GetRenderViewHost();
1938 if (!renderViewHost) {
1941 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
1942 WebApplicationIconUrlsGetCallback* cb =
1943 new WebApplicationIconUrlsGetCallback(callback, userData);
1944 int callbackId = web_app_icon_urls_get_callback_map_.Add(cb);
1945 return renderViewHost->Send(new EwkViewMsg_WebAppIconUrlsGet(
1946 renderViewHost->GetRoutingID(), callbackId));
1952 void EWebView::InvokeWebAppCapableGetCallback(bool capable, int callbackId) {
1953 WebApplicationCapableGetCallback* callback =
1954 web_app_capable_get_callback_map_.Lookup(callbackId);
1957 callback->Run(capable);
1958 web_app_capable_get_callback_map_.Remove(callbackId);
1961 void EWebView::InvokeWebAppIconUrlGetCallback(const std::string& iconUrl,
1963 WebApplicationIconUrlGetCallback* callback =
1964 web_app_icon_url_get_callback_map_.Lookup(callbackId);
1967 callback->Run(iconUrl);
1968 web_app_icon_url_get_callback_map_.Remove(callbackId);
1971 void EWebView::InvokeWebAppIconUrlsGetCallback(const StringMap& iconUrls,
1973 WebApplicationIconUrlsGetCallback* callback =
1974 web_app_icon_urls_get_callback_map_.Lookup(callbackId);
1978 callback->Run(iconUrls);
1979 web_app_icon_urls_get_callback_map_.Remove(callbackId);
1982 void EWebView::SetNotificationPermissionCallback(
1983 Ewk_View_Notification_Permission_Callback callback,
1985 notification_permission_callback_.Set(callback, user_data);
1988 bool EWebView::IsNotificationPermissionCallbackSet() const {
1989 return notification_permission_callback_.IsCallbackSet();
1992 bool EWebView::InvokeNotificationPermissionCallback(
1993 Ewk_Notification_Permission_Request* request) {
1994 Eina_Bool ret = EINA_FALSE;
1995 notification_permission_callback_.Run(evas_object_, request, &ret);
1999 int EWebView::SetEwkViewPlainTextGetCallback(
2000 Ewk_View_Plain_Text_Get_Callback callback,
2002 EwkViewPlainTextGetCallback* view_plain_text_callback_ptr =
2003 new EwkViewPlainTextGetCallback;
2004 view_plain_text_callback_ptr->Set(callback, user_data);
2005 return plain_text_get_callback_map_.Add(view_plain_text_callback_ptr);
2008 bool EWebView::PlainTextGet(Ewk_View_Plain_Text_Get_Callback callback,
2010 auto* render_frame_host = web_contents_->GetPrimaryMainFrame();
2011 if (!render_frame_host)
2014 auto callback_id = SetEwkViewPlainTextGetCallback(callback, user_data);
2015 return render_frame_host->Send(new EwkFrameMsg_GetPlainText(
2016 render_frame_host->GetRoutingID(), callback_id));
2019 void EWebView::InvokePlainTextGetCallback(const std::string& content_text,
2020 int plain_text_get_callback_id) {
2021 EwkViewPlainTextGetCallback* view_plain_text_callback_invoke_ptr =
2022 plain_text_get_callback_map_.Lookup(plain_text_get_callback_id);
2023 view_plain_text_callback_invoke_ptr->Run(evas_object(), content_text.c_str());
2024 plain_text_get_callback_map_.Remove(plain_text_get_callback_id);
2027 void EWebView::SetViewGeolocationPermissionCallback(
2028 Ewk_View_Geolocation_Permission_Callback callback,
2030 geolocation_permission_cb_.Set(callback, user_data);
2033 bool EWebView::InvokeViewGeolocationPermissionCallback(
2034 _Ewk_Geolocation_Permission_Request* permission_context,
2035 Eina_Bool* callback_result) {
2036 return geolocation_permission_cb_.Run(evas_object_, permission_context,
2040 void EWebView::SetViewUserMediaPermissionCallback(
2041 Ewk_View_User_Media_Permission_Callback callback,
2043 user_media_permission_cb_.Set(callback, user_data);
2046 bool EWebView::InvokeViewUserMediaPermissionCallback(
2047 _Ewk_User_Media_Permission_Request* permission_context,
2048 Eina_Bool* callback_result) {
2049 return user_media_permission_cb_.Run(evas_object_, permission_context,
2053 void EWebView::SetViewUserMediaPermissionQueryCallback(
2054 Ewk_View_User_Media_Permission_Query_Callback callback,
2056 user_media_permission_query_cb_.Set(callback, user_data);
2059 Ewk_User_Media_Permission_Query_Result
2060 EWebView::InvokeViewUserMediaPermissionQueryCallback(
2061 _Ewk_User_Media_Permission_Query* permission_context) {
2062 return user_media_permission_query_cb_.Run(evas_object_, permission_context);
2065 void EWebView::SetViewUnfocusAllowCallback(
2066 Ewk_View_Unfocus_Allow_Callback callback,
2068 unfocus_allow_cb_.Set(callback, user_data);
2071 bool EWebView::InvokeViewUnfocusAllowCallback(Ewk_Unfocus_Direction direction,
2072 Eina_Bool* callback_result) {
2073 return unfocus_allow_cb_.Run(evas_object_, direction, callback_result);
2076 void EWebView::StopFinding() {
2077 web_contents_->StopFinding(content::STOP_FIND_ACTION_CLEAR_SELECTION);
2080 void EWebView::SetProgressValue(double progress) {
2081 progress_ = progress;
2084 double EWebView::GetProgressValue() {
2088 const char* EWebView::GetTitle() {
2089 title_ = base::UTF16ToUTF8(web_contents_->GetTitle());
2090 return title_.c_str();
2093 bool EWebView::SaveAsPdf(int width, int height, const std::string& filename) {
2096 rwhva()->host()->PrintToPdf(width, height, base::FilePath(filename));
2100 bool EWebView::GetMHTMLData(Ewk_View_MHTML_Data_Get_Callback callback,
2102 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
2103 if (!render_view_host)
2106 MHTMLCallbackDetails* callback_details = new MHTMLCallbackDetails;
2107 callback_details->Set(callback, user_data);
2108 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
2109 int mhtml_callback_id = mhtml_callback_map_.Add(callback_details);
2110 return render_view_host->Send(new EwkViewMsg_GetMHTMLData(
2111 render_view_host->GetRoutingID(), mhtml_callback_id));
2117 void EWebView::OnMHTMLContentGet(const std::string& mhtml_content,
2119 MHTMLCallbackDetails* callback_details =
2120 mhtml_callback_map_.Lookup(callback_id);
2121 callback_details->Run(evas_object(), mhtml_content.c_str());
2122 mhtml_callback_map_.Remove(callback_id);
2125 bool EWebView::SavePageAsMHTML(const std::string& path,
2126 Ewk_View_Save_Page_Callback callback,
2131 GURL url(web_contents_->GetLastCommittedURL());
2132 std::u16string title(web_contents_->GetTitle());
2134 // Post function that has file access to blocking task runner.
2135 return base::PostTaskAndReplyWithResult(
2136 base::ThreadPool::CreateSequencedTaskRunner(
2137 {base::MayBlock(), base::TaskPriority::BEST_EFFORT,
2138 base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})
2141 base::BindOnce(&GenerateMHTMLFilePath, url, base::UTF16ToUTF8(title),
2143 base::BindOnce(&EWebView::GenerateMHTML, base::Unretained(this), callback,
2147 void EWebView::GenerateMHTML(Ewk_View_Save_Page_Callback callback,
2149 const base::FilePath& file_path) {
2150 if (file_path.empty()) {
2151 LOG(ERROR) << "Generating file path was failed";
2152 callback(evas_object_, nullptr, user_data);
2156 MHTMLGenerationParams params(file_path);
2157 web_contents_->GenerateMHTML(
2158 params, base::BindOnce(&EWebView::MHTMLGenerated, base::Unretained(this),
2159 callback, user_data, file_path));
2162 void EWebView::MHTMLGenerated(Ewk_View_Save_Page_Callback callback,
2164 const base::FilePath& file_path,
2165 int64_t file_size) {
2166 callback(evas_object_, file_size > 0 ? file_path.value().c_str() : nullptr,
2170 bool EWebView::GetBackgroundColor(
2171 Ewk_View_Background_Color_Get_Callback callback,
2175 BackgroundColorGetCallback* cb =
2176 new BackgroundColorGetCallback(callback, user_data);
2177 int callback_id = background_color_get_callback_map_.Add(cb);
2179 rwhva()->host()->RequestBackgroundColor(callback_id);
2183 void EWebView::OnGetBackgroundColor(int callback_id, SkColor bg_color) {
2184 BackgroundColorGetCallback* cb =
2185 background_color_get_callback_map_.Lookup(callback_id);
2190 cb->Run(evas_object(), SkColorGetR(bg_color), SkColorGetG(bg_color),
2191 SkColorGetB(bg_color), SkColorGetA(bg_color));
2192 background_color_get_callback_map_.Remove(callback_id);
2195 bool EWebView::IsFullscreen() {
2196 return web_contents_delegate_->IsFullscreenForTabOrPending(
2197 web_contents_.get());
2200 void EWebView::ExitFullscreen() {
2201 WebContentsImpl* wci = static_cast<WebContentsImpl*>(web_contents_.get());
2202 wci->ExitFullscreen(false);
2205 double EWebView::GetScale() {
2206 return page_scale_factor_;
2209 void EWebView::DidChangePageScaleFactor(double scale_factor) {
2210 page_scale_factor_ = scale_factor;
2211 wcva()->wcva_helper()->SetPageScaleFactor(scale_factor);
2212 SetScaledContentsSize();
2214 // Notify app about the scale change.
2215 scale_changed_cb_.Run(evas_object_, scale_factor);
2218 inline JavaScriptDialogManagerEfl* EWebView::GetJavaScriptDialogManagerEfl() {
2219 return static_cast<JavaScriptDialogManagerEfl*>(
2220 web_contents_delegate_->GetJavaScriptDialogManager(web_contents_.get()));
2223 void EWebView::SetJavaScriptAlertCallback(
2224 Ewk_View_JavaScript_Alert_Callback callback,
2226 GetJavaScriptDialogManagerEfl()->SetAlertCallback(callback, user_data);
2229 void EWebView::JavaScriptAlertReply() {
2230 GetJavaScriptDialogManagerEfl()->ExecuteDialogClosedCallBack(true,
2232 SmartCallback<EWebViewCallbacks::PopupReplyWaitFinish>().call(0);
2235 void EWebView::SetJavaScriptConfirmCallback(
2236 Ewk_View_JavaScript_Confirm_Callback callback,
2238 GetJavaScriptDialogManagerEfl()->SetConfirmCallback(callback, user_data);
2241 void EWebView::JavaScriptConfirmReply(bool result) {
2242 GetJavaScriptDialogManagerEfl()->ExecuteDialogClosedCallBack(result,
2244 SmartCallback<EWebViewCallbacks::PopupReplyWaitFinish>().call(0);
2247 void EWebView::SetJavaScriptPromptCallback(
2248 Ewk_View_JavaScript_Prompt_Callback callback,
2250 GetJavaScriptDialogManagerEfl()->SetPromptCallback(callback, user_data);
2253 void EWebView::JavaScriptPromptReply(const char* result) {
2254 GetJavaScriptDialogManagerEfl()->ExecuteDialogClosedCallBack(
2255 true, (std::string(result)));
2256 SmartCallback<EWebViewCallbacks::PopupReplyWaitFinish>().call(0);
2259 void EWebView::GetPageScaleRange(double* min_scale, double* max_scale) {
2260 auto prefs = web_contents_->GetOrCreateWebPreferences();
2262 *min_scale = prefs.default_minimum_page_scale_factor;
2264 *max_scale = prefs.default_maximum_page_scale_factor;
2267 void EWebView::SetDrawsTransparentBackground(bool enabled) {
2268 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
2269 if (!render_view_host)
2271 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
2272 render_view_host->Send(new EwkViewMsg_SetDrawsTransparentBackground(
2273 render_view_host->GetRoutingID(), enabled));
2277 void EWebView::GetSessionData(const char** data, unsigned* length) const {
2278 static const int MAX_SESSION_ENTRY_SIZE = std::numeric_limits<int>::max();
2280 NavigationController& navigationController = web_contents_->GetController();
2281 base::Pickle sessionPickle;
2282 const int itemCount = navigationController.GetEntryCount();
2284 sessionPickle.WriteInt(itemCount);
2285 sessionPickle.WriteInt(navigationController.GetCurrentEntryIndex());
2287 for (int i = 0; i < itemCount; i++) {
2288 NavigationEntry* navigationEntry = navigationController.GetEntryAtIndex(i);
2289 sessions::SerializedNavigationEntry serializedEntry =
2290 sessions::ContentSerializedNavigationBuilder::FromNavigationEntry(
2291 i, navigationEntry);
2292 serializedEntry.WriteToPickle(MAX_SESSION_ENTRY_SIZE, &sessionPickle);
2295 if (sessionPickle.size() <= 0 ||
2297 static_cast<char*>(malloc(sizeof(char) * sessionPickle.size())))) {
2298 LOG(ERROR) << "Failed to get session data";
2302 memcpy(const_cast<char*>(*data), sessionPickle.data(), sessionPickle.size());
2303 *length = sessionPickle.size();
2306 bool EWebView::RestoreFromSessionData(const char* data, unsigned length) {
2307 base::Pickle sessionPickle(data, length);
2308 base::PickleIterator pickleIterator(sessionPickle);
2312 if (!pickleIterator.ReadInt(&entryCount))
2314 if (!pickleIterator.ReadInt(¤tEntry))
2317 std::vector<sessions::SerializedNavigationEntry> serializedEntries;
2318 serializedEntries.resize(entryCount);
2319 for (int i = 0; i < entryCount; ++i) {
2320 if (!serializedEntries.at(i).ReadFromPickle(&pickleIterator))
2330 std::vector<std::unique_ptr<content::NavigationEntry>> scopedEntries =
2331 sessions::ContentSerializedNavigationBuilder::ToNavigationEntries(
2332 serializedEntries, context()->browser_context());
2334 NavigationController& navigationController = web_contents_->GetController();
2336 if (currentEntry < 0)
2339 if (currentEntry >= static_cast<int>(scopedEntries.size()))
2340 currentEntry = scopedEntries.size() - 1;
2342 navigationController.Restore(currentEntry, RestoreType::kRestored,
2347 void EWebView::SetBrowserFont() {
2348 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
2349 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
2350 if (render_view_host) {
2351 IPC::Message* message =
2352 new EwkViewMsg_SetBrowserFont(render_view_host->GetRoutingID());
2354 if (render_view_host->IsRenderViewLive())
2355 render_view_host->Send(message);
2357 delayed_messages_.push_back(message);
2362 bool EWebView::IsDragging() const {
2363 return wcva()->wcva_helper()->IsDragging();
2366 void EWebView::ShowFileChooser(content::RenderFrameHost* render_frame_host,
2367 const blink::mojom::FileChooserParams& params) {
2368 if (!IsMobileProfile() && !IsWearableProfile())
2371 #if !defined(EWK_BRINGUP) // FIXME: m71 bringup
2372 if (params.capture) {
2373 const std::string capture_types[] = {"video/*", "audio/*", "image/*"};
2374 unsigned int capture_types_num =
2375 sizeof(capture_types) / sizeof(*capture_types);
2376 for (unsigned int i = 0; i < capture_types_num; ++i) {
2377 for (unsigned int j = 0; j < params.accept_types.size(); ++j) {
2378 if (UTF16ToUTF8(params.accept_types[j]) == capture_types[i]) {
2379 filechooser_mode_ = params.mode;
2380 LaunchCamera(params.accept_types[j]);
2386 file_chooser_.reset(
2387 new content::FileChooserControllerEfl(render_frame_host, ¶ms));
2388 file_chooser_->Open();
2392 #if !defined(EWK_BRINGUP) // FIXME: m67 bringup
2393 void EWebView::SetViewMode(blink::WebViewMode view_mode) {
2394 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
2395 if (!render_view_host)
2398 IPC::Message* message =
2399 new ViewMsg_SetViewMode(render_view_host->GetRoutingID(), view_mode);
2400 if (render_view_host->IsRenderViewLive()) {
2401 render_view_host->Send(message);
2403 delayed_messages_.push_back(message);
2408 gfx::Point EWebView::GetContextMenuPosition() const {
2409 return context_menu_position_;
2412 void EWebView::ShowContentsDetectedPopup(const char* message) {
2413 popup_controller_.reset(new PopupControllerEfl(this));
2414 popup_controller_->openPopup(message);
2417 void EWebView::RequestColorPicker(int r, int g, int b, int a) {
2418 input_picker_.reset(new InputPicker(this));
2419 input_picker_->ShowColorPicker(r, g, b, a);
2422 bool EWebView::SetColorPickerColor(int r, int g, int b, int a) {
2423 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
2424 web_contents_->DidChooseColorInColorChooser(SkColorSetARGB(a, r, g, b));
2429 void EWebView::InputPickerShow(ui::TextInputType input_type,
2431 content::DateTimeChooserEfl* date_time_chooser) {
2432 input_picker_.reset(new InputPicker(this));
2433 date_time_chooser_ = date_time_chooser;
2434 input_picker_->ShowDatePicker(input_type, input_value);
2437 void EWebView::LoadNotFoundErrorPage(const std::string& invalidUrl) {
2438 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
2439 RenderFrameHost* render_frame_host = web_contents_->GetPrimaryMainFrame();
2440 if (render_frame_host)
2441 render_frame_host->Send(new EwkFrameMsg_LoadNotFoundErrorPage(
2442 render_frame_host->GetRoutingID(), invalidUrl));
2446 std::string EWebView::GetPlatformLocale() {
2447 char* local_default = setlocale(LC_CTYPE, 0);
2449 return std::string("en-US");
2450 std::string locale = std::string(local_default);
2451 size_t position = locale.find('_');
2452 if (position != std::string::npos)
2453 locale.replace(position, 1, "-");
2454 position = locale.find('.');
2455 if (position != std::string::npos)
2456 locale = locale.substr(0, position);
2460 int EWebView::StartInspectorServer(int port) {
2461 return context_->InspectorServerStart(port);
2464 bool EWebView::StopInspectorServer() {
2465 return context_->InspectorServerStop();
2468 void EWebView::InvokeWebProcessCrashedCallback() {
2469 DCHECK_CURRENTLY_ON(BrowserThread::UI);
2470 const GURL last_url = GetURL();
2471 bool callback_handled = false;
2472 SmartCallback<EWebViewCallbacks::WebProcessCrashed>().call(&callback_handled);
2473 if (!callback_handled)
2474 LoadHTMLString(kRendererCrashedHTMLMessage, NULL,
2475 last_url.possibly_invalid_spec().c_str());
2478 void EWebView::SyncAcceptLanguages(const std::string& accept_languages) {
2479 web_contents_->GetMutableRendererPrefs()->accept_languages = accept_languages;
2480 web_contents_->SyncRendererPrefs();
2481 BrowserContext* browser_context = web_contents_->GetBrowserContext();
2482 if (!browser_context)
2485 auto* storage_partition = browser_context->GetDefaultStoragePartition();
2486 if (!storage_partition)
2489 if (auto* network_context = storage_partition->GetNetworkContext())
2490 network_context->SetAcceptLanguage(accept_languages);
2493 void EWebView::HandleRendererProcessCrash() {
2494 content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
2495 base::BindOnce(&EWebView::InvokeWebProcessCrashedCallback,
2496 base::Unretained(this)));
2499 void EWebView::InitializeContent() {
2500 WebContents* new_contents = create_new_window_web_contents_cb_.Run(this);
2501 if (!new_contents) {
2502 WebContents::CreateParams params(context_->browser_context());
2503 web_contents_.reset(
2504 new WebContentsImplEfl(context_->browser_context(), this));
2505 static_cast<WebContentsImpl*>(web_contents_.get())
2506 ->Init(params, blink::FramePolicy());
2508 web_contents_.reset(new_contents);
2510 // When a new webview is created in response to a request from the
2511 // engine, the BrowserContext instance of the originator WebContents
2512 // is used by the newly created WebContents object.
2513 // See more in WebContentsImplEfl::HandleNewWebContentsCreate.
2515 // Hence, if as part of the WebView creation, the embedding APP
2516 // passes in a Ewk_Context instance that wraps a different instance of
2517 // BrowserContext than the one the originator WebContents holds,
2518 // undefined behavior can be seen.
2520 // This is a snippet code that illustrate the scenario:
2523 // evas_object_smart_callback_add(web_view_, "create,window",
2524 // &OnNewWindowRequest, this);
2527 // void OnNewWindowRequest(void *data, Evas_Object*, void* out_view) {
2529 // EvasObject* new_web_view = ewk_view_add_with_context(GetEvas(),
2530 // ewk_context_new());
2531 // *static_cast<Evas_Object**>(out_view) = new_web_view;
2535 // The new Ewk_Context object created and passed in as parameter to
2536 // ewk_view_add_with_context wraps a different instance of BrowserContext
2537 // than the one the new WebContents object will hold.
2539 // CHECK below aims at catching misuse of this API.
2540 bool should_crash = context_->GetImpl()->browser_context() !=
2541 web_contents_->GetBrowserContext();
2544 << "BrowserContext of new WebContents does not match EWebView's. "
2545 << "Please see 'ewk_view_add*' documentation. "
2546 << "Aborting execution ...";
2549 web_contents_delegate_.reset(new WebContentsDelegateEfl(this));
2550 web_contents_->SetDelegate(web_contents_delegate_.get());
2551 WebContentsImplEfl* wc_efl =
2552 static_cast<WebContentsImplEfl*>(web_contents_.get());
2553 wc_efl->SetEflDelegate(new WebContentsEflDelegateEwk(this));
2554 wcva()->wcva_helper()->SetEflDelegate(wc_efl->GetEflDelegate());
2556 back_forward_list_.reset(new _Ewk_Back_Forward_List(web_contents_.get()));
2558 permission_popup_manager_.reset(new PermissionPopupManager(evas_object_));
2559 gin_native_bridge_dispatcher_host_.reset(
2560 new content::GinNativeBridgeDispatcherHost(web_contents_.get()));
2563 static_cast<WebContentsImplEfl*>(web_contents_.get())->GetEflNativeView();
2564 evas_object_smart_member_add(native_view_, evas_object_);
2565 static_cast<WebContentsImpl*>(web_contents_.get())
2566 ->set_ewk_view(evas_object_);
2567 InitializeWindowTreeHost();
2570 void EWebView::InitializeWindowTreeHost() {
2571 CHECK(aura::Env::GetInstance());
2573 int x, y, width, height;
2575 ecore_evas_ecore_evas_get(evas_object_evas_get(native_view_));
2576 ecore_evas_geometry_get(ee, &x, &y, &width, &height);
2578 gfx::Rect bounds(x, y, width, height);
2579 ui::PlatformWindowInitProperties properties;
2580 properties.bounds = bounds;
2582 host_ = aura::WindowTreeHost::Create(std::move(properties));
2584 host_->window()->Show();
2587 std::make_unique<aura::test::TestFocusClient>(host_->window());
2588 window_parenting_client_ =
2589 std::make_unique<aura::test::TestWindowParentingClient>(host_->window());
2590 compositor_observer_ = std::make_unique<ui::CompositorObserverEfl>(
2591 host_->compositor(), web_contents_.get());
2593 aura::Window* content = web_contents_->GetNativeView();
2594 aura::Window* parent = host_->window();
2595 if (!parent->Contains(content)) {
2596 parent->AddChild(content);
2599 content->SetBounds(bounds);
2600 RenderWidgetHostView* host_view = web_contents_->GetRenderWidgetHostView();
2602 host_view->SetSize(bounds.size());
2605 #if BUILDFLAG(IS_TIZEN) && !defined(EWK_BRINGUP)
2606 void EWebView::cameraResultCb(service_h request,
2608 service_result_e result,
2610 if (!IsMobileProfile() && !IsWearableProfile())
2613 EWebView* webview = static_cast<EWebView*>(data);
2614 RenderViewHost* render_view_host =
2615 webview->web_contents_->GetRenderViewHost();
2616 if (result == SERVICE_RESULT_SUCCEEDED) {
2620 ret = service_get_extra_data_array(reply, SERVICE_DATA_SELECTED,
2621 &filesarray, &number);
2623 for (int i = 0; i < number; i++) {
2624 std::vector<ui::SelectedFileInfo> files;
2625 if (!render_view_host) {
2628 if (filesarray[i]) {
2629 GURL url(filesarray[i]);
2630 if (!url.is_valid()) {
2631 base::FilePath path(url.SchemeIsFile() ? url.path()
2633 files.push_back(ui::SelectedFileInfo(path, base::FilePath()));
2636 render_view_host->FilesSelectedInChooser(files,
2637 webview->filechooser_mode_);
2641 std::vector<ui::SelectedFileInfo> files;
2642 if (render_view_host) {
2643 render_view_host->FilesSelectedInChooser(files,
2644 webview->filechooser_mode_);
2649 bool EWebView::LaunchCamera(std::u16string mimetype) {
2650 service_h svcHandle = 0;
2651 if (service_create(&svcHandle) < 0 || !svcHandle) {
2652 LOG(ERROR) << __FUNCTION__ << " Service Creation Failed ";
2655 service_set_operation(svcHandle, SERVICE_OPERATION_CREATE_CONTENT);
2656 service_set_mime(svcHandle, UTF16ToUTF8(mimetype).c_str());
2657 service_add_extra_data(svcHandle, "CALLER", "Browser");
2659 int ret = service_send_launch_request(svcHandle, cameraResultCb, this);
2660 if (ret != SERVICE_ERROR_NONE) {
2661 LOG(ERROR) << __FUNCTION__ << " Service Launch Failed ";
2662 service_destroy(svcHandle);
2665 service_destroy(svcHandle);
2670 void EWebView::UrlRequestSet(
2672 content::NavigationController::LoadURLType loadtype,
2676 content::NavigationController::LoadURLParams params(gurl);
2677 params.load_type = loadtype;
2678 params.override_user_agent = NavigationController::UA_OVERRIDE_TRUE;
2681 std::string s(body);
2683 network::ResourceRequestBody::CreateFromBytes(s.data(), s.size());
2686 net::HttpRequestHeaders header;
2688 Eina_Iterator* it = eina_hash_iterator_tuple_new(headers);
2690 while (eina_iterator_next(it, reinterpret_cast<void**>(&t))) {
2692 const char* value_str =
2693 t->data ? static_cast<const char*>(t->data) : "";
2694 base::StringPiece name = static_cast<const char*>(t->key);
2695 base::StringPiece value = value_str;
2696 header.SetHeader(name, value);
2697 // net::HttpRequestHeaders.ToString() returns string with newline
2698 params.extra_headers += header.ToString();
2701 eina_iterator_free(it);
2704 web_contents_->GetController().LoadURLWithParams(params);
2707 #if defined(TIZEN_VIDEO_HOLE)
2708 void EWebView::SetVideoHoleSupport(bool enable) {
2709 if (!web_contents_->GetPrimaryMainFrame() ||
2710 !web_contents_->GetPrimaryMainFrame()->IsRenderFrameLive() || !rwhva()) {
2711 pending_video_hole_setting_ = enable;
2715 rwhva()->host()->SetVideoHoleForRender(enable);
2719 bool EWebView::HandleShow() {
2727 bool EWebView::HandleHide() {
2735 bool EWebView::HandleMove(int x, int y) {
2738 evas_object_move(native_view_, x, y);
2740 #if defined(TIZEN_VIDEO_HOLE) && !defined(EWK_BRINGUP)
2742 rwhva()->offscreen_helper()->DidMoveWebView();
2746 context_menu_->Move(x, y);
2751 bool EWebView::HandleResize(int width, int height) {
2754 evas_object_resize(native_view_, width, height);
2756 if (select_picker_) {
2757 AdjustViewPortHeightToPopupMenu(true /* is_popup_menu_visible */);
2758 ScrollFocusedNodeIntoView();
2764 bool EWebView::HandleTextSelectionDown(int x, int y) {
2765 if (!GetSelectionController())
2767 return GetSelectionController()->TextSelectionDown(x, y);
2770 bool EWebView::HandleTextSelectionUp(int x, int y) {
2771 if (!GetSelectionController())
2773 return GetSelectionController()->TextSelectionUp(x, y);
2776 void EWebView::HandleTapGestureForSelection(bool is_content_editable) {
2777 if (!GetSelectionController())
2780 GetSelectionController()->PostHandleTapGesture(is_content_editable);
2783 void EWebView::HandleZoomGesture(blink::WebGestureEvent& event) {
2784 blink::WebInputEvent::Type event_type = event.GetType();
2785 if (event_type == blink::WebInputEvent::Type::kGestureDoubleTap ||
2786 event_type == blink::WebInputEvent::Type::kGesturePinchBegin) {
2787 SmartCallback<EWebViewCallbacks::ZoomStarted>().call();
2789 if (event_type == blink::WebInputEvent::Type::kGestureDoubleTap ||
2790 event_type == blink::WebInputEvent::Type::kGesturePinchEnd) {
2791 SmartCallback<EWebViewCallbacks::ZoomFinished>().call();
2795 bool EWebView::GetHorizontalPanningHold() const {
2798 return rwhva()->offscreen_helper()->GetHorizontalPanningHold();
2801 void EWebView::SetHorizontalPanningHold(bool hold) {
2803 rwhva()->offscreen_helper()->SetHorizontalPanningHold(hold);
2806 bool EWebView::GetVerticalPanningHold() const {
2809 return rwhva()->offscreen_helper()->GetVerticalPanningHold();
2812 void EWebView::SetVerticalPanningHold(bool hold) {
2814 rwhva()->offscreen_helper()->SetVerticalPanningHold(hold);
2817 void EWebView::SendDelayedMessages(RenderViewHost* render_view_host) {
2818 DCHECK(render_view_host);
2820 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
2821 content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
2822 base::BindOnce(&EWebView::SendDelayedMessages, base::Unretained(this),
2827 for (auto iter = delayed_messages_.begin(); iter != delayed_messages_.end();
2829 IPC::Message* message = *iter;
2830 message->set_routing_id(render_view_host->GetRoutingID());
2831 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
2832 render_view_host->Send(message);
2836 delayed_messages_.clear();
2839 void EWebView::ClosePage() {
2840 web_contents_->ClosePage();
2843 bool EWebView::SetMainFrameScrollbarVisible(bool visible) {
2844 if (web_contents_->GetPrimaryMainFrame()->IsRenderFrameLive() && rwhva())
2845 rwhva()->host()->SetMainFrameScrollbarVisible(visible);
2849 bool EWebView::GetMainFrameScrollbarVisible(
2850 Ewk_View_Main_Frame_Scrollbar_Visible_Get_Callback callback,
2855 MainFrameScrollbarVisibleGetCallback* callback_ptr =
2856 new MainFrameScrollbarVisibleGetCallback;
2857 callback_ptr->Set(callback, user_data);
2859 main_frame_scrollbar_visible_callback_map_.Add(callback_ptr);
2860 rwhva()->host()->RequestMainFrameScrollbarVisible(callback_id);
2864 void EWebView::InvokeMainFrameScrollbarVisibleCallback(int callback_id,
2866 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
2867 content::GetUIThreadTaskRunner({})->PostTask(
2869 base::BindOnce(&EWebView::InvokeMainFrameScrollbarVisibleCallback,
2870 base::Unretained(this), visible, callback_id));
2874 MainFrameScrollbarVisibleGetCallback* callback =
2875 main_frame_scrollbar_visible_callback_map_.Lookup(callback_id);
2879 main_frame_scrollbar_visible_callback_map_.Remove(callback_id);
2880 callback->Run(evas_object(), visible);
2881 main_frame_scrollbar_visible_callback_map_.Remove(callback_id);
2884 void EWebView::OnOverscrolled(const gfx::Vector2dF& accumulated_overscroll,
2885 const gfx::Vector2dF& latest_overscroll_delta) {
2886 const gfx::Vector2dF old_overscroll =
2887 accumulated_overscroll - latest_overscroll_delta;
2889 if (latest_overscroll_delta.x() && !old_overscroll.x()) {
2890 latest_overscroll_delta.x() < 0
2891 ? SmartCallback<EWebViewCallbacks::OverscrolledLeft>().call()
2892 : SmartCallback<EWebViewCallbacks::OverscrolledRight>().call();
2894 if (latest_overscroll_delta.y() && !old_overscroll.y()) {
2895 latest_overscroll_delta.y() < 0
2896 ? SmartCallback<EWebViewCallbacks::OverscrolledTop>().call()
2897 : SmartCallback<EWebViewCallbacks::OverscrolledBottom>().call();
2901 void EWebView::SetDidChangeThemeColorCallback(
2902 Ewk_View_Did_Change_Theme_Color_Callback callback,
2904 did_change_theme_color_callback_.Set(callback, user_data);
2907 void EWebView::DidChangeThemeColor(const SkColor& color) {
2908 did_change_theme_color_callback_.Run(evas_object_, color);
2911 #if BUILDFLAG(IS_TIZEN_TV)
2912 void EWebView::DrawLabel(Evas_Object* image, Eina_Rectangle rect) {
2914 rwhva()->offscreen_helper()->DrawLabel(image, rect);
2917 void EWebView::DeactivateAtk(bool deactivated) {
2918 EWebAccessibilityUtil::GetInstance()->Deactivate(deactivated);
2921 void EWebView::ClearLabels() {
2923 rwhva()->offscreen_helper()->ClearLabels();
2927 void EWebView::RequestManifest(Ewk_View_Request_Manifest_Callback callback,
2929 web_contents_delegate_->RequestManifestInfo(callback, user_data);
2932 void EWebView::DidRespondRequestManifest(
2933 _Ewk_View_Request_Manifest* manifest,
2934 Ewk_View_Request_Manifest_Callback callback,
2936 callback(evas_object_, manifest, user_data);
2939 void EWebView::SetSessionTimeout(uint64_t timeout) {
2940 if (web_contents_->GetPrimaryMainFrame()->IsRenderFrameLive() && rwhva())
2941 rwhva()->host()->SetLongPollingGlobalTimeout(timeout);
2944 void EWebView::SetBeforeUnloadConfirmPanelCallback(
2945 Ewk_View_Before_Unload_Confirm_Panel_Callback callback,
2947 GetJavaScriptDialogManagerEfl()->SetBeforeUnloadConfirmPanelCallback(
2948 callback, user_data);
2951 void EWebView::ReplyBeforeUnloadConfirmPanel(Eina_Bool result) {
2952 GetJavaScriptDialogManagerEfl()->ReplyBeforeUnloadConfirmPanel(result);
2955 void EWebView::SetExceededIndexedDatabaseQuotaCallback(
2956 Ewk_View_Exceeded_Indexed_Database_Quota_Callback callback,
2958 exceeded_indexed_db_quota_callback_.Set(callback, user_data);
2959 content::BrowserContextEfl* browser_context =
2960 static_cast<content::BrowserContextEfl*>(
2961 web_contents_->GetBrowserContext());
2962 if (browser_context) {
2963 browser_context->GetSpecialStoragePolicyEfl()->SetQuotaExceededCallback(
2964 base::BindOnce(&EWebView::InvokeExceededIndexedDatabaseQuotaCallback,
2965 base::Unretained(this)));
2969 void EWebView::InvokeExceededIndexedDatabaseQuotaCallback(
2971 int64_t current_quota) {
2972 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
2973 content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
2974 base::BindOnce(&EWebView::InvokeExceededIndexedDatabaseQuotaCallback,
2975 base::Unretained(this), origin, current_quota));
2978 LOG(INFO) << __func__ << "()" << origin << ", " << current_quota;
2979 CHECK(!exceeded_indexed_db_quota_origin_.get());
2980 exceeded_indexed_db_quota_origin_.reset(new Ewk_Security_Origin(origin));
2981 exceeded_indexed_db_quota_callback_.Run(
2982 evas_object_, exceeded_indexed_db_quota_origin_.get(), current_quota);
2985 void EWebView::ExceededIndexedDatabaseQuotaReply(bool allow) {
2986 if (!exceeded_indexed_db_quota_origin_.get()) {
2987 LOG(WARNING) << __func__ << "() : callback is not invoked!";
2990 LOG(INFO) << __func__ << "()" << exceeded_indexed_db_quota_origin_->GetURL()
2992 content::BrowserContextEfl* browser_context =
2993 static_cast<content::BrowserContextEfl*>(
2994 web_contents_->GetBrowserContext());
2995 if (browser_context) {
2996 browser_context->GetSpecialStoragePolicyEfl()->SetUnlimitedStoragePolicy(
2997 exceeded_indexed_db_quota_origin_->GetURL(), allow);
2999 exceeded_indexed_db_quota_origin_.reset();
3002 bool EWebView::ShouldIgnoreNavigation(
3003 content::NavigationHandle* navigation_handle) {
3004 if (!navigation_handle->GetURL().is_valid() ||
3005 !navigation_handle->GetURL().SchemeIs("appcontrol") ||
3006 (!navigation_handle->HasUserGesture() &&
3007 !navigation_handle->WasServerRedirect())) {
3011 _Ewk_App_Control app_control(
3012 this, navigation_handle->GetURL().possibly_invalid_spec());
3013 return app_control.Proceed();
3016 bool EWebView::SetVisibility(bool enable) {
3021 web_contents_->WasShown();
3023 web_contents_->WasHidden();
3028 void EWebView::SetDoNotTrack(Eina_Bool enable) {
3029 // enable: 0 User tend to allow tracking on the target site.
3030 // enable: 1 User tend to not be tracked on the target site.
3031 if (web_contents_->GetMutableRendererPrefs()->enable_do_not_track == enable)
3034 // Set navigator.doNotTrack attribute
3035 web_contents_->GetMutableRendererPrefs()->enable_do_not_track = enable;
3036 web_contents_->SyncRendererPrefs();
3038 // Set or remove DNT HTTP header, the effects will depend on design of target
3044 context()->HTTPCustomHeaderAdd("DNT", "1");
3046 context()->HTTPCustomHeaderRemove("DNT");
3049 #if defined(TIZEN_ATK_SUPPORT)
3050 void EWebView::UpdateSpatialNavigationStatus(Eina_Bool enable) {
3051 if (settings_->getPreferences().spatial_navigation_enabled == enable)
3054 settings_->getPreferences().spatial_navigation_enabled = enable;
3055 WebContentsImpl* wc = static_cast<WebContentsImpl*>(web_contents_.get());
3057 wc->SetSpatialNavigationEnabled(enable);
3060 void EWebView::UpdateAccessibilityStatus(Eina_Bool enable) {
3061 if (settings_->getPreferences().atk_enabled == enable)
3064 settings_->getPreferences().atk_enabled = enable;
3065 WebContentsImpl* wc = static_cast<WebContentsImpl*>(web_contents_.get());
3067 wc->SetAtkEnabled(enable);
3070 void EWebView::InitAtk() {
3071 EWebAccessibilityUtil::GetInstance()->ToggleAtk(lazy_initialize_atk_);
3074 /* LCOV_EXCL_START */
3075 bool EWebView::GetAtkStatus() {
3076 auto state = content::BrowserAccessibilityStateImpl::GetInstance();
3079 return state->IsAccessibleBrowser();
3081 /* LCOV_EXCL_STOP */