1 // Copyright 2014-2020 Samsung Electronics. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
7 #include <Ecore_Evas.h>
9 #include <Elementary.h>
11 #include "base/bind.h"
12 #include "base/command_line.h"
13 #include "base/files/file_path.h"
14 #include "base/files/file_util.h"
15 #include "base/json/json_string_value_serializer.h"
16 #include "base/logging.h"
17 #include "base/pickle.h"
18 #include "base/strings/escape.h"
19 #include "base/strings/utf_string_conversions.h"
20 #include "base/task/task_runner_util.h"
21 #include "browser/javascript_dialog_manager_efl.h"
22 #include "browser/javascript_interface/gin_native_bridge_dispatcher_host.h"
23 #include "browser/navigation_policy_handler_efl.h"
24 #include "browser/quota_permission_context_efl.h"
25 #include "browser/scoped_allow_wait_for_legacy_web_view_api.h"
26 #include "browser/select_picker/select_picker_mobile.h"
27 #include "browser/select_picker/select_picker_tv.h"
28 #include "browser/web_view_browser_message_filter.h"
29 #include "browser/web_view_evas_handler.h"
30 #include "browser_context_efl.h"
31 #include "common/content_client_efl.h"
32 #include "common/render_messages_ewk.h"
33 #include "common/version_info.h"
34 #include "common/web_contents_utils.h"
35 #include "components/sessions/content/content_serialized_navigation_builder.h"
36 #include "components/sessions/core/serialized_navigation_entry.h"
37 #include "content/browser/renderer_host/render_view_host_impl.h"
38 #include "content/browser/renderer_host/render_widget_host_view_aura.h"
39 #include "content/browser/renderer_host/ui_events_helper.h"
40 #include "content/browser/web_contents/web_contents_impl_efl.h"
41 #include "content/browser/web_contents/web_contents_view.h"
42 #include "content/browser/web_contents/web_contents_view_aura.h"
43 #include "content/browser/web_contents/web_contents_view_aura_helper_efl.h"
44 #include "content/common/content_client_export.h"
45 #include "content/public/browser/browser_message_filter.h"
46 #include "content/public/browser/browser_task_traits.h"
47 #include "content/public/browser/browser_thread.h"
48 #include "content/public/browser/host_zoom_map.h"
49 #include "content/public/browser/navigation_controller.h"
50 #include "content/public/browser/navigation_entry.h"
51 #include "content/public/browser/navigation_handle.h"
52 #include "content/public/common/content_client.h"
53 #include "content/public/common/content_switches.h"
54 #include "content/public/common/mhtml_generation_params.h"
55 #include "content/public/common/user_agent.h"
56 #include "net/base/filename_util.h"
57 #include "permission_popup_manager.cc"
58 #include "private/ewk_app_control_private.h"
59 #include "private/ewk_back_forward_list_private.h"
60 #include "private/ewk_context_private.h"
61 #include "private/ewk_frame_private.h"
62 #include "private/ewk_policy_decision_private.h"
63 #include "private/ewk_quota_permission_request_private.h"
64 #include "private/ewk_settings_private.h"
65 #include "private/webview_delegate_ewk.h"
66 #include "public/ewk_hit_test_internal.h"
67 #include "services/network/public/cpp/features.h"
68 #include "services/network/public/cpp/resource_request_body.h"
69 #include "services/network/public/mojom/network_context.mojom.h"
70 #include "skia/ext/platform_canvas.h"
71 #include "third_party/blink/public/common/page/page_zoom.h"
72 #include "third_party/blink/public/platform/web_string.h"
73 #include "tizen/system_info.h"
74 #include "ui/aura/env.h"
75 #include "ui/aura/test/test_focus_client.h"
76 #include "ui/aura/test/test_window_parenting_client.h"
77 #include "ui/aura/window.h"
78 #include "ui/base/clipboard/clipboard_helper_efl.h"
79 #include "ui/base/l10n/l10n_util.h"
80 #include "ui/compositor/compositor_observer_efl.h"
81 #include "ui/display/screen.h"
82 #include "ui/events/event_switches.h"
83 #include "ui/gfx/geometry/dip_util.h"
84 #include "ui/gfx/geometry/vector2d_f.h"
85 #include "ui/ozone/platform/efl/efl_event_handler.h"
86 #include "ui/platform_window/platform_window_init_properties.h"
87 #include "web_contents_delegate_efl.h"
88 #include "web_contents_efl_delegate_ewk.h"
92 #if defined(TIZEN_ATK_SUPPORT)
93 #include "content/browser/accessibility/browser_accessibility_state_impl.h"
94 #include "eweb_accessibility.h"
95 #include "eweb_accessibility_util.h"
98 #if defined(TIZEN_AUTOFILL_FW)
99 #include "browser/autofill/autofill_request_manager.h"
100 #include "components/autofill/core/common/autofill_switches.h"
103 #if BUILDFLAG(IS_TIZEN_TV)
104 #include "common/application_type.h"
105 #include "devtools_port_manager.h"
106 #include "public/ewk_media_downloadable_font_info.h"
107 #include "browser/mixed_content_observer.h"
110 #if defined(TIZEN_PEPPER_EXTENSIONS)
111 #include "efl/window_factory.h"
112 #include "ewk/efl_integration/ewk_privilege_checker.h"
113 #endif // defined(TIZEN_PEPPER_EXTENSIONS)
115 #if defined(USE_WAYLAND) && defined(TIZEN_PEPPER_EXTENSIONS)
116 #include <Ecore_Wayland.h>
117 #endif // defined(USE_WAYLAND)
119 #if defined(TIZEN_TBM_SUPPORT)
120 #include "ui/compositor/compositor.h"
123 using namespace content;
124 using web_contents_utils::WebViewFromWebContents;
128 const int kTitleLengthMax = 80;
129 const base::FilePath::CharType kMHTMLFileNameExtension[] =
130 FILE_PATH_LITERAL(".mhtml");
131 const base::FilePath::CharType kMHTMLExtension[] = FILE_PATH_LITERAL("mhtml");
132 const base::FilePath::CharType kDefaultFileName[] =
133 FILE_PATH_LITERAL("saved_page");
134 const char kReplaceChars[] = " ";
135 const char kReplaceWith[] = "_";
137 static const char* kRendererCrashedHTMLMessage =
138 "<html><body><h1>Renderer process has crashed!</h1></body></html>";
140 // "visible,content,changed" is an email-app specific signal which informs
141 // that the web view is only partially visible.
142 static const char* kVisibleContentChangedSignalName = "visible,content,changed";
144 // email-app specific signal which informs that custom scrolling is started.
145 const char* kCustomScrollBeginSignalName = "custom,scroll,begin";
147 // email-app specific signal which informs that custom scrolling is finished.
148 const char* kCustomScrollEndSignalName = "custom,scroll,end";
150 const float kDelayShowContextMenuTime = 0.2f;
152 inline void SetDefaultStringIfNull(const char*& variable,
153 const char* default_string) {
155 variable = default_string;
159 void GetEinaRectFromGfxRect(const gfx::Rect& gfx_rect,
160 Eina_Rectangle* eina_rect) {
161 eina_rect->x = gfx_rect.x();
162 eina_rect->y = gfx_rect.y();
163 eina_rect->w = gfx_rect.width();
164 eina_rect->h = gfx_rect.height();
167 #if BUILDFLAG(IS_TIZEN)
168 static Eina_Bool RotateWindowCb(void* data, int type, void* event) {
169 auto wv = static_cast<EWebView*>(data);
171 ecore_evas_rotation_get(ecore_evas_ecore_evas_get(wv->GetEvas())));
172 return ECORE_CALLBACK_PASS_ON;
176 static content::WebContents* NullCreateWebContents(void*) {
180 base::FilePath GenerateMHTMLFilePath(const GURL& url,
181 const std::string& title,
182 const std::string& base_path) {
183 base::FilePath file_path(base_path);
185 if (base::DirectoryExists(file_path)) {
186 std::string title_part(title.substr(0, kTitleLengthMax));
187 base::ReplaceChars(title_part, kReplaceChars, kReplaceWith, &title_part);
188 base::FilePath file_name =
189 net::GenerateFileName(url, std::string(), std::string(), title_part,
190 std::string(), kDefaultFileName);
191 DCHECK(!file_name.empty());
192 file_path = file_path.Append(file_name);
195 if (file_path.Extension().empty())
196 file_path = file_path.AddExtension(kMHTMLExtension);
197 else if (!file_path.MatchesExtension(kMHTMLFileNameExtension))
198 file_path = file_path.ReplaceExtension(kMHTMLExtension);
200 if (!base::PathExists(file_path))
203 int uniquifier = base::GetUniquePathNumber(file_path);
204 if (uniquifier > 0) {
205 return file_path.InsertBeforeExtensionASCII(
206 base::StringPrintf(" (%d)", uniquifier));
209 return base::FilePath();
212 SelectPickerBase* CreateSelectPicker(
215 std::vector<blink::mojom::MenuItemPtr> items,
216 bool is_multiple_selection,
217 const gfx::Rect& bounds) {
218 SelectPickerBase* picker;
221 new SelectPickerTv(web_view, selected_index, is_multiple_selection);
224 new SelectPickerMobile(web_view, selected_index, is_multiple_selection);
226 // Create two separate Elm_Genlist_Item_Class classes, because EFL cannot swap
227 // item_style at runtime.
228 picker->InitializeItemClass();
229 picker->InitializeGroupClass();
230 picker->Init(std::move(items), bounds);
236 class WebViewAsyncRequestHitTestDataCallback {
238 WebViewAsyncRequestHitTestDataCallback(int x, int y, Ewk_Hit_Test_Mode mode)
239 : x_(x), y_(y), mode_(mode) {}
240 virtual ~WebViewAsyncRequestHitTestDataCallback(){};
242 virtual void Run(_Ewk_Hit_Test* hit_test, EWebView* web_view) = 0;
245 int GetX() const { return x_; }
246 int GetY() const { return y_; }
247 Ewk_Hit_Test_Mode GetMode() const { return mode_; }
252 Ewk_Hit_Test_Mode mode_;
255 class WebViewAsyncRequestHitTestDataUserCallback
256 : public WebViewAsyncRequestHitTestDataCallback {
258 WebViewAsyncRequestHitTestDataUserCallback(
261 Ewk_Hit_Test_Mode mode,
262 Ewk_View_Hit_Test_Request_Callback callback,
264 : WebViewAsyncRequestHitTestDataCallback(x, y, mode),
266 user_data_(user_data) {}
268 void Run(_Ewk_Hit_Test* hit_test, EWebView* web_view) override {
270 callback_(web_view->evas_object(), GetX(), GetY(), GetMode(), hit_test,
275 Ewk_View_Hit_Test_Request_Callback callback_;
279 #if defined(TIZEN_ATK_SUPPORT)
280 class EWebAccessibilityObserver : public EWebAccessibility::Observer {
282 explicit EWebAccessibilityObserver(EWebView* webview) : webview_(webview) {}
283 virtual ~EWebAccessibilityObserver() {}
285 // EWebAccessibility::Observer implementation
286 void OnSpatialNavigationStatusChanged(Eina_Bool enable) override {
287 webview_->UpdateSpatialNavigationStatus(enable);
290 void OnAccessibilityStatusChanged(Eina_Bool enable) override {
291 webview_->UpdateAccessibilityStatus(enable);
299 int EWebView::find_request_id_counter_ = 0;
300 content::WebContentsEflDelegate::WebContentsCreateCallback
301 EWebView::create_new_window_web_contents_cb_ =
302 base::BindRepeating(&NullCreateWebContents);
304 EWebView* EWebView::FromEvasObject(Evas_Object* eo) {
305 return WebViewDelegateEwk::GetInstance().GetWebViewFromEvasObject(eo);
308 void EWebView::OnViewFocusIn(void* data, Evas*, Evas_Object*, void*) {
309 auto view = static_cast<EWebView*>(data);
310 view->SetFocus(EINA_TRUE);
313 void EWebView::OnViewFocusOut(void* data, Evas*, Evas_Object*, void*) {
314 auto view = static_cast<EWebView*>(data);
315 view->SetFocus(EINA_FALSE);
318 void EWebView::VisibleContentChangedCallback(void* user_data,
319 Evas_Object* /*object*/,
321 auto view = static_cast<EWebView*>(user_data);
322 auto rect = static_cast<Eina_Rectangle*>(event_info);
323 view->GetSelectionController()->SetCustomVisibleViewRect(
324 gfx::Rect(rect->x, rect->y, rect->w, rect->h));
327 void EWebView::OnCustomScrollBeginCallback(void* user_data,
328 Evas_Object* /*object*/,
329 void* /*event_info*/) {
330 auto* view = static_cast<EWebView*>(user_data);
331 if (auto* selection_controller = view->GetSelectionController())
332 selection_controller->SetControlsTemporarilyHidden(true,true);
335 void EWebView::OnCustomScrollEndCallback(void* user_data,
336 Evas_Object* /*object*/,
337 void* /*event_info*/) {
338 auto* view = static_cast<EWebView*>(user_data);
339 if (auto* selection_controller = view->GetSelectionController())
340 selection_controller->SetControlsTemporarilyHidden(false,true);
343 EWebView::EWebView(Ewk_Context* context, Evas_Object* object)
345 evas_object_(object),
346 native_view_(object),
347 mouse_events_enabled_(false),
348 text_zoom_factor_(1.0),
349 current_find_request_id_(find_request_id_counter_++),
351 hit_test_completion_(base::WaitableEvent::ResetPolicy::AUTOMATIC,
352 base::WaitableEvent::InitialState::NOT_SIGNALED),
353 page_scale_factor_(1.0),
356 #if BUILDFLAG(IS_TIZEN_TV)
357 is_processing_edge_scroll_(false),
358 use_early_rwi_(false),
359 rwi_info_showed_(false),
361 is_initialized_(false) {
362 LOG(INFO) << "EWebView: " << this;
364 evas_object_smart_callback_add(evas_object_,
365 kVisibleContentChangedSignalName,
366 VisibleContentChangedCallback, this);
368 evas_object_smart_callback_add(evas_object_, kCustomScrollBeginSignalName,
369 OnCustomScrollBeginCallback, this);
370 evas_object_smart_callback_add(evas_object_, kCustomScrollEndSignalName,
371 OnCustomScrollEndCallback, this);
372 evas_object_event_callback_add(evas_object_, EVAS_CALLBACK_FOCUS_IN,
373 OnViewFocusIn, this);
374 evas_object_event_callback_add(evas_object_, EVAS_CALLBACK_FOCUS_OUT,
375 OnViewFocusOut, this);
376 #if BUILDFLAG(IS_TIZEN)
377 window_rotate_handler_ = ecore_event_handler_add(
378 ECORE_WL2_EVENT_WINDOW_ROTATE, RotateWindowCb, this);
383 void EWebView::Initialize() {
384 if (is_initialized_) {
390 evas_event_handler_ = new WebViewEvasEventHandler(this);
392 scroll_detector_.reset(new ScrollDetector(this));
394 #if defined(TIZEN_PEPPER_EXTENSIONS)
395 InitializePepperExtensionSystem();
397 DCHECK(web_contents_->GetRenderViewHost());
398 // Settings (content::WebPreferences) will be initalized by
399 // RenderViewHostImpl::ComputeWebkitPrefs() based on command line switches.
400 settings_.reset(new Ewk_Settings(evas_object_,
401 web_contents_->GetOrCreateWebPreferences()));
402 #if defined(TIZEN_ATK_SUPPORT)
403 std::unique_ptr<EWebAccessibilityObserver> observer(
404 new EWebAccessibilityObserver(this));
405 eweb_accessibility_.reset(new EWebAccessibility(
406 evas_object_, web_contents_.get(), std::move(observer)));
407 lazy_initialize_atk_ = true;
410 base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess();
411 if (cmdline->HasSwitch(switches::kTouchEventFeatureDetection)) {
412 SetTouchEventsEnabled(
413 cmdline->GetSwitchValueASCII(switches::kTouchEventFeatureDetection) ==
414 switches::kTouchEventFeatureDetectionEnabled);
416 SetMouseEventsEnabled(true);
419 std::string user_agent =
420 EflWebView::VersionInfo::GetInstance()->DefaultUserAgent();
421 web_contents_->SetUserAgentOverride(
422 blink::UserAgentOverride::UserAgentOnly(user_agent),
423 false /* override_in_new_tabs */);
425 elm_object_tree_focus_allow_set(native_view_, EINA_TRUE);
426 is_initialized_ = true;
427 evas_object_event_callback_add(native_view_, EVAS_CALLBACK_RESIZE,
428 EWebView::NativeViewResize, this);
430 auto cbce = static_cast<ContentBrowserClientEfl*>(
431 content::GetContentClientExport()->browser());
432 // Initialize accept languages
433 SyncAcceptLanguages(cbce->GetAcceptLangs(nullptr));
434 accept_langs_changed_callback_ =
435 base::BindOnce(&EWebView::SyncAcceptLanguages, base::Unretained(this));
436 cbce->AddAcceptLangsChangedCallback(
437 std::move(accept_langs_changed_callback_));
439 // If EWebView is created by window.open, RenderView is already created
440 // before initializing WebContents. So we should manually invoke
441 // EWebView::RenderViewReady here.
442 if (web_contents_->GetPrimaryMainFrame() &&
443 web_contents_->GetPrimaryMainFrame()->IsRenderFrameLive()) {
448 EWebView::~EWebView() {
449 LOG(INFO) << "EWebView: " << this;
450 auto cbce = static_cast<ContentBrowserClientEfl*>(
451 content::GetContentClientExport()->browser());
452 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
453 cbce->RemoveAcceptLangsChangedCallback(
454 std::move(accept_langs_changed_callback_));
456 #if defined(TIZEN_PEPPER_EXTENSIONS)
457 UnregisterPepperExtensionDelegate();
460 evas_object_event_callback_del(native_view_, EVAS_CALLBACK_RESIZE,
461 EWebView::NativeViewResize);
462 #if defined(USE_WAYLAND)
463 if (GetSettings()->getClipboardEnabled())
464 ClipboardHelperEfl::GetInstance()->MaybeInvalidateActiveWebview(this);
467 std::map<int64_t, WebViewAsyncRequestHitTestDataCallback*>::iterator
468 hit_test_callback_iterator;
469 for (hit_test_callback_iterator = hit_test_callback_.begin();
470 hit_test_callback_iterator != hit_test_callback_.end();
471 hit_test_callback_iterator++)
472 delete hit_test_callback_iterator->second;
473 hit_test_callback_.clear();
475 for (auto iter = delayed_messages_.begin(); iter != delayed_messages_.end();
479 delayed_messages_.clear();
481 if (!is_initialized_) {
485 #if defined(TIZEN_ATK_SUPPORT)
486 eweb_accessibility_.reset();
489 #if defined(TIZEN_AUTOFILL_FW)
490 if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
491 autofill::switches::kDisableAutofill)) {
492 autofill::AutofillRequestManager::GetInstance()->RemoveRequest(
497 select_picker_.reset();
498 context_menu_.reset();
499 mhtml_callback_map_.Clear();
501 compositor_observer_.reset();
503 // Release manually those scoped pointers to
504 // make sure they are released in correct order
505 web_contents_.reset();
506 web_contents_delegate_.reset();
508 // This code must be executed after WebContents deletion
509 // because WebContents depends on BrowserContext which
510 // is deleted along with EwkContext.
511 CHECK(!web_contents_);
513 permission_popup_manager_.reset();
515 gin_native_bridge_dispatcher_host_.reset();
518 evas_object_event_callback_del(evas_object_, EVAS_CALLBACK_FOCUS_IN,
520 evas_object_event_callback_del(evas_object_, EVAS_CALLBACK_FOCUS_OUT,
522 evas_object_smart_callback_del(evas_object_,
523 kVisibleContentChangedSignalName,
524 VisibleContentChangedCallback);
525 evas_object_smart_callback_del(evas_object_, kCustomScrollBeginSignalName,
526 OnCustomScrollBeginCallback);
527 evas_object_smart_callback_del(evas_object_, kCustomScrollEndSignalName,
528 OnCustomScrollEndCallback);
529 #if BUILDFLAG(IS_TIZEN)
530 if (window_rotate_handler_)
531 ecore_event_handler_del(window_rotate_handler_);
536 content::RenderWidgetHostViewAura* EWebView::rwhva() const {
537 return static_cast<content::RenderWidgetHostViewAura*>(
538 web_contents_->GetRenderWidgetHostView());
541 content::WebContentsViewAura* EWebView::wcva() const {
542 WebContentsImpl* wc = static_cast<WebContentsImpl*>(web_contents_.get());
543 return static_cast<WebContentsViewAura*>(wc->GetView());
546 void EWebView::NativeViewResize(void* data,
550 auto thiz = static_cast<EWebView*>(data);
551 if (!thiz->context_menu_)
553 int native_view_x, native_view_y, native_view_width, native_view_height;
554 evas_object_geometry_get(obj, &native_view_x, &native_view_y,
555 &native_view_width, &native_view_height);
556 gfx::Rect webview_rect(native_view_x, native_view_y, native_view_width,
558 thiz->context_menu_->Resize(webview_rect);
561 void EWebView::ResetContextMenuController() {
562 return context_menu_.reset();
565 #if BUILDFLAG(IS_TIZEN_TV)
566 void EWebView::RunPendingSetFocus(Eina_Bool focus) {
567 if (!web_contents_ || !rwhva() || (HasFocus() == focus))
569 rwhva()->offscreen_helper()->Focus(focus);
573 void EWebView::SetFocus(Eina_Bool focus) {
574 if (!web_contents_ || !rwhva() || (HasFocus() == focus))
577 #if BUILDFLAG(IS_TIZEN_TV)
578 if (web_contents_->GetPrimaryMainFrame()->IsRenderFrameLive()) {
579 rwhva()->offscreen_helper()->Focus(focus);
581 if (pending_setfocus_closure_)
582 pending_setfocus_closure_.Reset();
584 LOG(ERROR) << "SEND DELAY SET FOCUS BIND";
585 pending_setfocus_closure_ = base::BindOnce(&EWebView::RunPendingSetFocus,
586 base::Unretained(this), focus);
589 rwhva()->offscreen_helper()->Focus(focus);
593 Eina_Bool EWebView::HasFocus() const {
597 return rwhva()->offscreen_helper()->HasFocus() ? EINA_TRUE : EINA_FALSE;
600 Eina_Bool EWebView::AddJavaScriptMessageHandler(
602 Ewk_View_Script_Message_Cb callback,
604 if (!gin_native_bridge_dispatcher_host_)
607 return gin_native_bridge_dispatcher_host_->AddNamedObject(view, callback,
611 bool EWebView::SetPageVisibility(
612 Ewk_Page_Visibility_State page_visibility_state) {
616 // TODO: We should able to set 'prerender' or 'unloaded' as visibility state.
617 // http://www.w3.org/TR/page-visibility/#dom-document-visibilitystate
618 switch (page_visibility_state) {
619 case EWK_PAGE_VISIBILITY_STATE_VISIBLE:
620 rwhva()->offscreen_helper()->SetPageVisibility(true);
622 case EWK_PAGE_VISIBILITY_STATE_HIDDEN:
623 rwhva()->offscreen_helper()->SetPageVisibility(false);
625 case EWK_PAGE_VISIBILITY_STATE_PRERENDER:
635 bool EWebView::CreateNewWindow(
636 content::WebContentsEflDelegate::WebContentsCreateCallback cb) {
637 create_new_window_web_contents_cb_ = cb;
638 Evas_Object* new_object = NULL;
639 SmartCallback<EWebViewCallbacks::CreateNewWindow>().call(&new_object);
640 create_new_window_web_contents_cb_ =
641 base::BindRepeating(&NullCreateWebContents);
646 Evas_Object* EWebView::GetHostWindowDelegate(const content::WebContents* wc) {
647 EWebView* thiz = WebViewFromWebContents(wc);
648 DCHECK(thiz->evas_object_);
649 Evas_Object* parent = evas_object_above_get(thiz->evas_object_);
651 LOG(WARNING) << "Could not find and visual parents for EWK smart object!.";
652 return thiz->evas_object_;
655 if (elm_object_widget_check(parent)) {
656 Evas_Object* elm_parent = elm_object_top_widget_get(parent);
662 LOG(WARNING) << "Could not find elementary parent for WebView object!";
663 return thiz->evas_object_;
666 Evas_Object* EWebView::GetElmWindow() const {
667 Evas_Object* parent = elm_object_parent_widget_get(evas_object_);
668 return parent ? elm_object_top_widget_get(parent) : nullptr;
671 void EWebView::SetURL(const GURL& url, bool from_api) {
672 NavigationController::LoadURLParams params(url);
675 params.transition_type = ui::PageTransitionFromInt(
676 ui::PAGE_TRANSITION_LINK | ui::PAGE_TRANSITION_FROM_API);
679 #if BUILDFLAG(IS_TIZEN_TV)
680 if (use_early_rwi_) {
681 LOG(INFO) << "[FAST RWI] SetURL Replace [" << url.spec()
682 << "] to [about:blank]";
684 params.url = GURL("about:blank");
688 params.override_user_agent = NavigationController::UA_OVERRIDE_TRUE;
689 web_contents_->GetController().LoadURLWithParams(params);
692 const GURL& EWebView::GetURL() const {
693 return web_contents_->GetVisibleURL();
696 const GURL& EWebView::GetOriginalURL() const {
697 const auto entry = web_contents_->GetController().GetVisibleEntry();
699 return entry->GetOriginalRequestURL();
701 return web_contents_->GetVisibleURL();
704 void EWebView::Reload() {
705 web_contents_->GetController().Reload(content::ReloadType::NORMAL, true);
708 void EWebView::ReloadBypassingCache() {
709 web_contents_->GetController().Reload(content::ReloadType::BYPASSING_CACHE,
713 Eina_Bool EWebView::CanGoBack() {
714 return web_contents_->GetController().CanGoBack();
717 Eina_Bool EWebView::CanGoForward() {
718 return web_contents_->GetController().CanGoForward();
721 Eina_Bool EWebView::GoBack() {
722 if (!web_contents_->GetController().CanGoBack())
725 #if defined(TIZEN_AUTOFILL_FW)
726 if (web_contents_delegate_)
727 web_contents_delegate_->ResetLastInteractedElements();
730 web_contents_->GetController().GoBack();
734 Eina_Bool EWebView::GoForward() {
735 if (!web_contents_->GetController().CanGoForward())
738 web_contents_->GetController().GoForward();
742 void EWebView::Stop() {
743 if (web_contents_->IsLoading())
744 web_contents_->Stop();
747 void EWebView::Suspend() {
748 CHECK(web_contents_);
749 #if BUILDFLAG(IS_TIZEN)
750 if (IsMobileProfile() && web_contents_->IsFullscreen())
751 web_contents_->ExitFullscreen(true);
753 RenderViewHost* rvh = web_contents_->GetRenderViewHost();
754 RenderFrameHost* rfh = web_contents_->GetPrimaryMainFrame();
757 #if !defined(EWK_BRINGUP) // FIXME: m69 bringup
758 rfh->BlockRequestsForFrame();
761 content::GetIOThreadTaskRunner({})->PostTask(FROM_HERE, base::BindOnce(
762 &content::ResourceDispatcherHost::BlockRequestsForFrameFromUI, rfh));
765 rvh->Send(new EwkViewMsg_SuspendScheduledTask(rvh->GetRoutingID()));
769 void EWebView::Resume() {
770 CHECK(web_contents_);
771 RenderViewHost* rvh = web_contents_->GetRenderViewHost();
772 RenderFrameHost* rfh = web_contents_->GetPrimaryMainFrame();
775 #if !defined(EWK_BRINGUP) // FIXME: m69 bringup
776 rfh->ResumeBlockedRequestsForFrame();
779 content::GetIOThreadTaskRunner({})->PostTask(FROM_HERE, base::BindOnce(
780 &content::ResourceDispatcherHost::ResumeBlockedRequestsForFrameFromUI,
784 rvh->Send(new EwkViewMsg_ResumeScheduledTasks(rvh->GetRoutingID()));
788 #if BUILDFLAG(IS_TIZEN_TV)
789 void EWebView::SetFloatVideoWindowState(bool enabled) {
790 RenderWidgetHostImpl* rwhi = static_cast<RenderWidgetHostImpl*>(
791 web_contents_->GetRenderViewHost()->GetWidget());
793 rwhi->SetFloatVideoWindowState(enabled);
795 #endif // IS_TIZEN_TV
797 double EWebView::GetTextZoomFactor() const {
798 if (text_zoom_factor_ < 0.0)
801 return text_zoom_factor_;
804 void EWebView::SetTextZoomFactor(double text_zoom_factor) {
805 if (text_zoom_factor_ == text_zoom_factor || text_zoom_factor < 0.0)
808 text_zoom_factor_ = text_zoom_factor;
809 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
810 if (!render_view_host)
812 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
813 render_view_host->Send(new ViewMsg_SetTextZoomFactor(
814 render_view_host->GetRoutingID(), text_zoom_factor));
818 double EWebView::GetPageZoomFactor() const {
819 return blink::PageZoomLevelToZoomFactor(
820 content::HostZoomMap::GetZoomLevel(web_contents_.get()));
823 void EWebView::SetPageZoomFactor(double page_zoom_factor) {
824 content::HostZoomMap::SetZoomLevel(
825 web_contents_.get(), blink::PageZoomFactorToZoomLevel(page_zoom_factor));
828 void EWebView::ExecuteEditCommand(const char* command, const char* value) {
829 EINA_SAFETY_ON_NULL_RETURN(command);
831 absl::optional<std::u16string> optional_value;
833 optional_value = absl::make_optional(base::ASCIIToUTF16(value));
835 WebContentsImpl* wc = static_cast<WebContentsImpl*>(web_contents_.get());
836 if (wc && wc->GetFocusedFrameWidgetInputHandler()) {
837 wc->GetFocusedFrameWidgetInputHandler()->ExecuteEditCommand(
838 std::string(command), optional_value);
842 #if BUILDFLAG(IS_TIZEN)
843 void EWebView::EnterDragState() {
844 if (IsMobileProfile()) {
845 if (RenderViewHost* render_view_host = web_contents_->GetRenderViewHost())
846 web_contents_->EnterDragState(render_view_host);
851 void EWebView::SetOrientation(int orientation) {
852 if (GetOrientation() == orientation)
855 if (orientation == 0 || orientation == 90 || orientation == 180 ||
856 orientation == 270) {
857 #if !defined(USE_AURA)
858 GetWebContentsViewEfl()->SetOrientation(orientation);
862 const Ecore_Evas* ee =
863 ecore_evas_ecore_evas_get(evas_object_evas_get(evas_object_));
864 ecore_evas_screen_geometry_get(ee, nullptr, nullptr, &width, &height);
865 if (orientation == 90 || orientation == 270)
866 std::swap(width, height);
868 if (popup_controller_)
869 popup_controller_->SetPopupSize(width, height);
870 if (JavaScriptDialogManagerEfl* dialogMG = GetJavaScriptDialogManagerEfl())
871 dialogMG->SetPopupSize(width, height);
875 int EWebView::GetOrientation() {
876 #if !defined(USE_AURA)
877 return GetWebContentsViewEfl()->GetOrientation();
883 void EWebView::Show() {
884 evas_object_show(native_view_);
885 web_contents_->WasShown();
888 void EWebView::Hide() {
889 LOG(INFO) << "EWebView: " << this;
890 evas_object_hide(native_view_);
893 web_contents_->WasHidden();
896 void EWebView::SetViewAuthCallback(Ewk_View_Authentication_Callback callback,
898 authentication_cb_.Set(callback, user_data);
901 void EWebView::InvokeAuthCallback(LoginDelegateEfl* login_delegate,
903 const std::string& realm) {
904 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
906 auth_challenge_.reset(new _Ewk_Auth_Challenge(login_delegate, url, realm));
907 authentication_cb_.Run(evas_object_, auth_challenge_.get());
909 if (!auth_challenge_->is_decided && !auth_challenge_->is_suspended) {
910 auth_challenge_->is_decided = true;
911 auth_challenge_->login_delegate->Cancel();
915 void EWebView::InvokePolicyResponseCallback(
916 _Ewk_Policy_Decision* policy_decision,
918 SmartCallback<EWebViewCallbacks::PolicyResponseDecide>().call(
921 if (policy_decision->isSuspended()) {
926 if (!policy_decision->isDecided())
927 policy_decision->Use();
929 policy_decision->SelfDeleteIfNecessary();
932 void EWebView::InvokePolicyNavigationCallback(
933 const NavigationPolicyParams& params,
935 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
937 SmartCallback<EWebViewCallbacks::SaveSessionData>().call();
939 std::unique_ptr<_Ewk_Policy_Decision> policy_decision(
940 new _Ewk_Policy_Decision(params));
942 SmartCallback<EWebViewCallbacks::NavigationPolicyDecision>().call(
943 policy_decision.get());
945 CHECK(!policy_decision->isSuspended());
947 // TODO: Navigation can't be suspended
948 // this aproach is synchronous and requires immediate response
949 // Maybe there is different approach (like resource throttle response
950 // mechanism) that allows us to
951 // suspend navigation
952 if (!policy_decision->isDecided())
953 policy_decision->Use();
955 *handled = policy_decision->GetNavigationPolicyHandler()->GetDecision() ==
956 NavigationPolicyHandlerEfl::Handled;
959 void EWebView::HandleTouchEvents(Ewk_Touch_Event_Type type,
960 const Eina_List* points,
961 const Evas_Modifier* modifiers) {
965 if (GetSettings()->touchFocusEnabled() &&
966 (type == EWK_TOUCH_START && eina_list_count(points) == 1)) {
970 EINA_LIST_FOREACH(points, l, data) {
971 const Ewk_Touch_Point* point = static_cast<Ewk_Touch_Point*>(data);
972 if (point->state == EVAS_TOUCH_POINT_STILL) {
973 // Chromium doesn't expect (and doesn't like) these events.
982 evas_object_geometry_get(evas_object(), nullptr, &delta_y, nullptr,
984 ui::TouchEvent touch_event =
985 ui::MakeTouchEvent(pt, point->state, point->id, 0, delta_y);
986 rwhva()->OnTouchEvent(&touch_event);
991 bool EWebView::TouchEventsEnabled() const {
992 return rwhva()->offscreen_helper()->TouchEventsEnabled();
995 // TODO: Touch events use the same mouse events in EFL API.
996 // Figure out how to distinguish touch and mouse events on touch&mice devices.
997 // Currently mouse and touch support is mutually exclusive.
998 void EWebView::SetTouchEventsEnabled(bool enabled) {
999 if (!rwhva() || !rwhva()->offscreen_helper()) {
1000 LOG(WARNING) << "RWHV is not created yet!";
1004 if (rwhva()->offscreen_helper()->TouchEventsEnabled() == enabled)
1007 rwhva()->offscreen_helper()->SetTouchEventsEnabled(enabled);
1009 GetSettings()->getPreferences().touch_event_feature_detection_enabled =
1011 GetSettings()->getPreferences().double_tap_to_zoom_enabled = enabled;
1012 GetSettings()->getPreferences().editing_behavior =
1013 enabled ? blink::mojom::EditingBehavior::kEditingAndroidBehavior
1014 : blink::mojom::EditingBehavior::kEditingUnixBehavior,
1015 UpdateWebKitPreferences();
1018 bool EWebView::MouseEventsEnabled() const {
1019 return mouse_events_enabled_;
1022 void EWebView::SetMouseEventsEnabled(bool enabled) {
1023 if (!rwhva() || !rwhva()->offscreen_helper()) {
1024 LOG(WARNING) << "RWHV is not created yet!";
1028 if (mouse_events_enabled_ == enabled)
1031 mouse_events_enabled_ = enabled;
1032 rwhva()->offscreen_helper()->SetTouchEventsEnabled(!enabled);
1037 class JavaScriptCallbackDetails {
1039 JavaScriptCallbackDetails(Ewk_View_Script_Execute_Callback callback_func,
1042 : callback_func_(callback_func), user_data_(user_data), view_(view) {}
1044 Ewk_View_Script_Execute_Callback callback_func_;
1049 void JavaScriptComplete(JavaScriptCallbackDetails* script_callback_data,
1050 base::Value result) {
1051 if (!script_callback_data->callback_func_)
1054 std::string return_string;
1055 if (result.is_string()) {
1056 // We don't want to serialize strings with JSONStringValueSerializer
1057 // to avoid quotation marks.
1058 return_string = result.GetString();
1059 } else if (result.is_none()) {
1060 // Value::TYPE_NULL is for lack of value, undefined, null
1063 JSONStringValueSerializer serializer(&return_string);
1064 serializer.Serialize(result);
1067 script_callback_data->callback_func_(script_callback_data->view_,
1068 return_string.c_str(),
1069 script_callback_data->user_data_);
1074 bool EWebView::ExecuteJavaScript(const char* script,
1075 Ewk_View_Script_Execute_Callback callback,
1077 LOG(INFO) << __FUNCTION__;
1078 if (!web_contents_) {
1079 LOG(ERROR) << __FUNCTION__ << "web_contents_ is null";
1083 RenderFrameHost* render_frame_host = web_contents_->GetPrimaryMainFrame();
1084 if (!render_frame_host) {
1085 LOG(ERROR) << __FUNCTION__ << " render_frame_host is null";
1089 // Note: M37. Execute JavaScript, |script| with
1090 // |RenderFrameHost::ExecuteJavaScript|.
1091 // @see also https://codereview.chromium.org/188893005 for more details.
1092 std::u16string js_script;
1093 base::UTF8ToUTF16(script, strlen(script), &js_script);
1095 JavaScriptCallbackDetails* script_callback_data =
1096 new JavaScriptCallbackDetails(callback, userdata, evas_object_);
1097 RenderFrameHost::JavaScriptResultCallback js_callback =
1098 base::BindOnce(&JavaScriptComplete, base::Owned(script_callback_data));
1099 // In M47, it isn't possible anymore to execute javascript in the generic
1100 // case. We need to call ExecuteJavaScriptForTests to keep the behaviour
1101 // unchanged @see https://codereview.chromium.org/1123783002
1102 render_frame_host->ExecuteJavaScriptWithUserGestureForTests(
1103 js_script, std::move(js_callback));
1105 // We use ExecuteJavaScriptWithUserGestureForTests instead of
1106 // ExecuteJavaScript because
1107 // ExecuteJavaScriptWithUserGestureForTests sets user_gesture to true. This
1109 // behaviour is m34, and we want to keep it that way.
1110 render_frame_host->ExecuteJavaScriptWithUserGestureForTests(
1111 js_script, base::NullCallback());
1117 bool EWebView::SetUserAgent(const char* userAgent) {
1118 content::NavigationController& controller = web_contents_->GetController();
1119 bool override = userAgent && strlen(userAgent);
1120 for (int i = 0; i < controller.GetEntryCount(); ++i)
1121 controller.GetEntryAtIndex(i)->SetIsOverridingUserAgent(override);
1122 // TODO: Check if override_in_new_tabs has to be true.
1123 web_contents_->SetUserAgentOverride(
1124 blink::UserAgentOverride::UserAgentOnly(userAgent),
1125 false /* override_in_new_tabs */);
1129 bool EWebView::SetUserAgentAppName(const char* application_name) {
1130 EflWebView::VersionInfo::GetInstance()->UpdateUserAgentWithAppName(
1131 application_name ? application_name : "");
1132 std::string user_agent =
1133 EflWebView::VersionInfo::GetInstance()->DefaultUserAgent();
1134 web_contents_->SetUserAgentOverride(
1135 blink::UserAgentOverride::UserAgentOnly(user_agent),
1136 false /* override_in_new_tabs */);
1140 #if BUILDFLAG(IS_TIZEN)
1141 bool EWebView::SetPrivateBrowsing(bool incognito) {
1142 if (context_->GetImpl()->browser_context()->IsOffTheRecord() == incognito)
1144 context_->GetImpl()->browser_context()->SetOffTheRecord(incognito);
1148 bool EWebView::GetPrivateBrowsing() const {
1149 return context_->GetImpl()->browser_context()->IsOffTheRecord();
1153 const char* EWebView::GetUserAgent() const {
1154 std::string user_agent =
1155 web_contents_->GetUserAgentOverride().ua_string_override;
1156 if (user_agent.empty())
1157 user_agent_ = content::GetContentClientExport()->browser()->GetUserAgent();
1159 user_agent_ = user_agent;
1161 return user_agent_.c_str();
1164 const char* EWebView::GetUserAgentAppName() const {
1165 user_agent_app_name_ = EflWebView::VersionInfo::GetInstance()->AppName();
1166 return user_agent_app_name_.c_str();
1169 const char* EWebView::CacheSelectedText() {
1173 selected_text_cached_ = base::UTF16ToUTF8(rwhva()->GetSelectedText());
1174 return selected_text_cached_.c_str();
1177 _Ewk_Frame* EWebView::GetMainFrame() {
1178 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1181 frame_.reset(new _Ewk_Frame(web_contents_->GetPrimaryMainFrame()));
1183 return frame_.get();
1186 void EWebView::UpdateWebKitPreferences() {
1187 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1189 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1190 if (!render_view_host)
1193 web_contents_delegate_->OnUpdateSettings(settings_.get());
1194 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
1195 render_view_host->UpdateWebkitPreferences(settings_->getPreferences());
1197 UpdateWebkitPreferencesEfl(render_view_host);
1200 void EWebView::UpdateWebkitPreferencesEfl(RenderViewHost* render_view_host) {
1201 DCHECK(render_view_host);
1202 #if !defined(EWK_BRINGUP) // FIXME: m108 bringup
1203 IPC::Message* message = new EwkSettingsMsg_UpdateWebKitPreferencesEfl(
1204 render_view_host->GetRoutingID(), settings_->getPreferencesEfl());
1206 if (render_view_host->IsRenderViewLive()) {
1207 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
1208 render_view_host->Send(message);
1211 delayed_messages_.push_back(message);
1216 void EWebView::SetContentSecurityPolicy(const char* policy,
1217 Ewk_CSP_Header_Type type) {
1218 web_contents_delegate_->SetContentSecurityPolicy(
1219 (policy ? policy : std::string()), type);
1222 void EWebView::LoadHTMLString(const char* html,
1223 const char* base_uri,
1224 const char* unreachable_uri) {
1225 LoadData(html, std::string::npos, NULL, NULL, base_uri, unreachable_uri);
1228 void EWebView::LoadPlainTextString(const char* plain_text) {
1229 LoadData(plain_text, std::string::npos, "text/plain", NULL, NULL, NULL);
1232 void EWebView::LoadHTMLStringOverridingCurrentEntry(
1234 const char* base_uri,
1235 const char* unreachable_url) {
1236 LoadData(html, std::string::npos, NULL, NULL, base_uri, unreachable_url,
1240 void EWebView::LoadData(const char* data,
1242 const char* mime_type,
1243 const char* encoding,
1244 const char* base_uri,
1245 const char* unreachable_uri,
1246 bool should_replace_current_entry) {
1247 SetDefaultStringIfNull(mime_type, "text/html");
1248 SetDefaultStringIfNull(encoding, "utf-8");
1249 SetDefaultStringIfNull(base_uri, "about:blank"); // Webkit2 compatible
1250 SetDefaultStringIfNull(unreachable_uri, "");
1252 std::string str_data = data;
1254 if (size < str_data.length())
1255 str_data = str_data.substr(0, size);
1257 std::string url_str("data:");
1258 url_str.append(mime_type);
1259 url_str.append(";charset=");
1260 url_str.append(encoding);
1261 url_str.append(",");
1263 // GURL constructor performs canonicalization of url string, but this is not
1264 // enough for correctly escaping contents of "data:" url.
1265 url_str.append(base::EscapeUrlEncodedData(str_data, false));
1267 NavigationController::LoadURLParams data_params(GURL(url_str.c_str()));
1269 data_params.base_url_for_data_url = GURL(base_uri);
1270 data_params.virtual_url_for_data_url = GURL(unreachable_uri);
1272 data_params.load_type = NavigationController::LOAD_TYPE_DATA;
1273 data_params.should_replace_current_entry = should_replace_current_entry;
1274 data_params.override_user_agent = NavigationController::UA_OVERRIDE_TRUE;
1275 web_contents_->GetController().LoadURLWithParams(data_params);
1278 void EWebView::InvokeLoadError(const GURL& url,
1280 bool is_cancellation) {
1281 _Ewk_Error err(error_code, is_cancellation,
1282 url.possibly_invalid_spec().c_str());
1284 SmartCallback<EWebViewCallbacks::LoadError>().call(&err);
1287 void EWebView::SetViewLoadErrorPageCallback(
1288 Ewk_View_Error_Page_Load_Callback callback,
1290 load_error_page_cb_.Set(callback, user_data);
1293 // Remove below code while ewk_error_cancellation_get has been implemented.
1294 const char* EWebView::InvokeViewLoadErrorPageCallback(
1297 const std::string& error_description) {
1298 std::unique_ptr<_Ewk_Error> err(
1299 new _Ewk_Error(error_code, url.possibly_invalid_spec().c_str(),
1300 error_description.c_str()));
1301 _Ewk_Error_Page error_page;
1303 LOG(INFO) << "EWebView::InvokeLoadErrorPageCallback url: "
1304 << url.spec().c_str() << ", error_code: " << error_code;
1306 load_error_page_cb_.Run(evas_object_, err.get(), &error_page);
1307 return error_page.content;
1310 bool EWebView::IsLoadErrorPageCallbackSet() const {
1311 return load_error_page_cb_.IsCallbackSet();
1313 void EWebView::HandlePopupMenu(std::vector<blink::mojom::MenuItemPtr> items,
1316 const gfx::Rect& bounds) {
1317 if (!select_picker_) {
1318 select_picker_.reset(CreateSelectPicker(
1319 this, selectedIndex, std::move(items), multiple, bounds));
1321 // Picker has been shown on top of webview and the page content gets
1322 // partially overlapped. Decrease viewport while showing picker.
1323 AdjustViewPortHeightToPopupMenu(true /* is_popup_menu_visible */);
1324 #if BUILDFLAG(IS_TIZEN_TV)
1325 SmartCallback<EWebViewCallbacks::PopupMenuShow>().call();
1328 select_picker_->UpdatePickerData(selectedIndex, std::move(items), multiple);
1331 select_picker_->Show();
1334 void EWebView::HidePopupMenu() {
1335 if (!select_picker_)
1338 AdjustViewPortHeightToPopupMenu(false /* is_popup_menu_visible */);
1339 #if BUILDFLAG(IS_TIZEN_TV)
1340 SmartCallback<EWebViewCallbacks::PopupMenuHide>().call();
1342 select_picker_.reset();
1345 void EWebView::DidSelectPopupMenuItems(std::vector<int>& indices) {
1346 wcva()->wcva_helper()->DidSelectPopupMenuItems(indices);
1349 void EWebView::DidCancelPopupMenu() {
1350 wcva()->wcva_helper()->DidCancelPopupMenu();
1353 void EWebView::HandleLongPressGesture(
1354 const content::ContextMenuParams& params) {
1355 // This menu is created in renderer process and it does not now anything about
1356 // view scaling factor and it has another calling sequence, so coordinates is
1358 if (settings_ && !settings_->getPreferences().long_press_enabled)
1361 content::ContextMenuParams convertedParams = params;
1362 gfx::Point convertedPoint =
1363 rwhva()->offscreen_helper()->ConvertPointInViewPix(
1364 gfx::Point(params.x, params.y));
1365 convertedParams.x = convertedPoint.x();
1366 convertedParams.y = convertedPoint.y();
1369 evas_object_geometry_get(evas_object(), &x, &y, 0, 0);
1370 convertedParams.x += x;
1371 convertedParams.y += y;
1373 if (GetSelectionController() && GetSelectionController()->GetLongPressed()) {
1374 bool show_context_menu_now =
1375 !GetSelectionController()->HandleLongPressEvent(convertedPoint,
1377 if (show_context_menu_now)
1378 ShowContextMenuInternal(convertedParams);
1382 void EWebView::ShowContextMenu(const content::ContextMenuParams& params) {
1386 // This menu is created in renderer process and it does not now anything about
1387 // view scaling factor and it has another calling sequence, so coordinates is
1389 content::ContextMenuParams convertedParams = params;
1390 gfx::Point convertedPoint =
1391 rwhva()->offscreen_helper()->ConvertPointInViewPix(
1392 gfx::Point(params.x, params.y));
1393 convertedParams.x = convertedPoint.x();
1394 convertedParams.y = convertedPoint.y();
1397 evas_object_geometry_get(evas_object(), &x, &y, 0, 0);
1398 convertedParams.x += x;
1399 convertedParams.y += y;
1401 context_menu_position_ = gfx::Point(convertedParams.x, convertedParams.y);
1403 ShowContextMenuInternal(convertedParams);
1406 void EWebView::ShowContextMenuInternal(
1407 const content::ContextMenuParams& params) {
1408 // We don't want to show 'cut' or 'copy' for inputs of type 'password' in
1409 // selection context menu, but params.input_field_type might not be set
1410 // correctly, because in some cases params is received from SelectionBoxEfl,
1411 // not from FrameHostMsg_ContextMenu message. In SelectionBoxEfl
1412 // ContextMenuParams is constructed on our side with limited information and
1413 // input_field_type is not set.
1415 // To work around this, we query for input type and set it separately. In
1416 // response to EwkViewMsg_QueryInputType we run ::UpdateContextMenu with
1417 // information about input's type.
1419 // FIXME: the way we get ContextMenuParams for context menu is flawed in some
1420 // cases. This should be fixed by restructuring context menu code.
1421 // Context menu creation should be unified to always have
1422 // ContextMenuParams received from FrameHostMsg_ContextMenu.
1423 // Tracked at: http://suprem.sec.samsung.net/jira/browse/TWF-1640
1424 if (params.is_editable) {
1425 saved_context_menu_params_ = params;
1427 rwhva()->host()->QueryInputType();
1429 UpdateContextMenuWithParams(params);
1433 void EWebView::UpdateContextMenu(bool is_password_input) {
1434 if (is_password_input) {
1435 saved_context_menu_params_.input_field_type =
1436 blink::mojom::ContextMenuDataInputFieldType::kPassword;
1438 UpdateContextMenuWithParams(saved_context_menu_params_);
1441 void EWebView::UpdateContextMenuWithParams(
1442 const content::ContextMenuParams& params) {
1443 context_menu_.reset(
1444 new content::ContextMenuControllerEfl(this, *web_contents_.get()));
1446 if (IsMobileProfile()) {
1447 if (delayed_show_context_menu_timer_) {
1448 ecore_timer_del(delayed_show_context_menu_timer_);
1449 delayed_show_context_menu_timer_ = nullptr;
1451 saved_context_menu_params_ = params;
1452 delayed_show_context_menu_timer_ = ecore_timer_add(
1453 kDelayShowContextMenuTime, DelayedPopulateAndShowContextMenu, this);
1455 if (!context_menu_->PopulateAndShowContextMenu(params)) {
1456 context_menu_.reset();
1457 if (GetSelectionController())
1458 GetSelectionController()->HideHandles();
1463 Eina_Bool EWebView::DelayedPopulateAndShowContextMenu(void* data) {
1464 if (IsMobileProfile) {
1465 EWebView* view = static_cast<EWebView*>(data);
1467 if (view->context_menu_ &&
1468 !(view->context_menu_->PopulateAndShowContextMenu(
1469 view->saved_context_menu_params_))) {
1470 view->context_menu_.reset();
1472 view->delayed_show_context_menu_timer_ = nullptr;
1475 return ECORE_CALLBACK_CANCEL;
1478 void EWebView::CancelContextMenu(int request_id) {
1480 context_menu_->HideContextMenu();
1483 void EWebView::Find(const char* text, Ewk_Find_Options ewk_find_options) {
1484 std::u16string find_text = base::UTF8ToUTF16(text);
1485 bool find_next = (previous_text_ == find_text);
1488 current_find_request_id_ = find_request_id_counter_++;
1489 previous_text_ = find_text;
1492 auto find_options = blink::mojom::FindOptions::New();
1493 find_options->forward = !(ewk_find_options & EWK_FIND_OPTIONS_BACKWARDS);
1494 find_options->match_case =
1495 !(ewk_find_options & EWK_FIND_OPTIONS_CASE_INSENSITIVE);
1497 web_contents_->Find(current_find_request_id_, find_text,
1498 std::move(find_options));
1501 void EWebView::SetScale(double scale_factor) {
1502 // Do not cache |scale_factor| here as it may be discarded by Blink's
1503 // minimumPageScaleFactor and maximumPageScaleFactor.
1504 // |scale_factor| is cached as responde to DidChangePageScaleFactor.
1505 WebContentsImpl* wci = static_cast<WebContentsImpl*>(web_contents_.get());
1506 wci->GetPrimaryMainFrame()->GetAssociatedLocalMainFrame()->SetScaleFactor(
1510 void EWebView::ScrollFocusedNodeIntoView() {
1511 if (RenderViewHost* render_view_host = web_contents_->GetRenderViewHost()) {
1512 if (auto& broadcast = static_cast<RenderViewHostImpl*>(render_view_host)
1513 ->GetAssociatedPageBroadcast())
1514 broadcast->ScrollFocusedNodeIntoView();
1518 void EWebView::AdjustViewPortHeightToPopupMenu(bool is_popup_menu_visible) {
1519 if (!rwhva() || !IsMobileProfile() ||
1520 settings_->getPreferences().TizenCompatibilityModeEnabled()) {
1524 int picker_height = select_picker_->GetGeometryDIP().height();
1525 gfx::Rect screen_rect =
1526 display::Screen::GetScreen()->GetPrimaryDisplay().bounds();
1527 gfx::Rect view_rect = rwhva()->offscreen_helper()->GetViewBounds();
1529 screen_rect.height() - (view_rect.y() + view_rect.height());
1531 rwhva()->offscreen_helper()->SetCustomViewportSize(
1532 is_popup_menu_visible
1533 ? gfx::Size(view_rect.width(),
1534 view_rect.height() - picker_height + bottom_height)
1538 void EWebView::SetScaleChangedCallback(Ewk_View_Scale_Changed_Callback callback,
1540 scale_changed_cb_.Set(callback, user_data);
1543 bool EWebView::GetScrollPosition(int* x, int* y) const {
1545 LOG(ERROR) << "rwhva() returns nullptr";
1548 if (scroll_detector_->IsScrollOffsetChanged()) {
1550 *x = previous_scroll_position_.x();
1552 *y = previous_scroll_position_.y();
1554 const gfx::Vector2d scroll_position_dip =
1555 scroll_detector_->GetLastScrollPosition();
1556 const float device_scale_factor = display::Screen::GetScreen()
1557 ->GetPrimaryDisplay()
1558 .device_scale_factor();
1560 *x = base::ClampRound((scroll_position_dip.x() - x_delta_) *
1561 device_scale_factor);
1564 *y = base::ClampRound((scroll_position_dip.y() - y_delta_) *
1565 device_scale_factor);
1571 void EWebView::ChangeScroll(int& x, int& y) {
1573 LOG(ERROR) << "rwhva() returns nullptr";
1578 GetScrollSize(&max_x, &max_y);
1579 previous_scroll_position_.set_x(std::min(std::max(x, 0), max_x));
1580 previous_scroll_position_.set_y(std::min(std::max(y, 0), max_y));
1582 const float device_scale_factor = display::Screen::GetScreen()
1583 ->GetPrimaryDisplay()
1584 .device_scale_factor();
1588 x = base::ClampCeil(x / device_scale_factor);
1589 y = base::ClampCeil(y / device_scale_factor);
1591 x_delta_ = x - (x_input / device_scale_factor);
1592 y_delta_ = y - (y_input / device_scale_factor);
1594 scroll_detector_->SetScrollOffsetChanged();
1597 void EWebView::SetScroll(int x, int y) {
1598 if (auto* render_view_host = web_contents_->GetRenderViewHost()) {
1599 if (auto& broadcast = static_cast<RenderViewHostImpl*>(render_view_host)
1600 ->GetAssociatedPageBroadcast()) {
1602 broadcast->SetScrollOffset(x, y);
1607 void EWebView::UseSettingsFont() {
1608 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
1609 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1610 if (render_view_host)
1611 render_view_host->Send(
1612 new EwkViewMsg_UseSettingsFont(render_view_host->GetRoutingID()));
1616 void EWebView::DidChangeContentsSize(int width, int height) {
1617 contents_size_ = gfx::Size(width, height);
1618 SmartCallback<EWebViewCallbacks::ContentsSizeChanged>().call();
1619 SetScaledContentsSize();
1622 const Eina_Rectangle EWebView::GetContentsSize() const {
1623 Eina_Rectangle rect;
1624 EINA_RECTANGLE_SET(&rect, 0, 0, contents_size_.width(),
1625 contents_size_.height());
1629 void EWebView::SetScaledContentsSize() {
1631 return; // LCOV_EXCL_LINE
1633 const float device_scale_factor =
1634 display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
1635 gfx::SizeF scaled_contents_size = gfx::ConvertSizeToPixels(
1636 contents_size_, device_scale_factor * page_scale_factor_);
1637 rwhva()->offscreen_helper()->SetScaledContentSize(scaled_contents_size);
1640 void EWebView::GetScrollSize(int* width, int* height) {
1643 *width = (rwhva() &&
1644 (w = rwhva()->offscreen_helper()->GetScrollableSize().width()))
1649 *height = (rwhva() &&
1650 (h = rwhva()->offscreen_helper()->GetScrollableSize().height()))
1656 void EWebView::MoveCaret(const gfx::Point& point) {
1658 rwhva()->offscreen_helper()->MoveCaret(point);
1661 SelectionControllerEfl* EWebView::GetSelectionController() const {
1662 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1663 RenderWidgetHostViewAura* view = static_cast<RenderWidgetHostViewAura*>(
1664 render_view_host->GetWidget()->GetView());
1665 return view ? view->offscreen_helper()->GetSelectionController() : 0;
1668 void EWebView::SelectFocusedLink() {
1669 rwhva()->host()->SelectFocusedLink();
1672 bool EWebView::GetSelectionRange(Eina_Rectangle* left_rect,
1673 Eina_Rectangle* right_rect) {
1674 if (left_rect && right_rect) {
1675 gfx::Rect left, right;
1676 if (GetSelectionController()) {
1677 GetSelectionController()->GetSelectionBounds(&left, &right);
1678 GetEinaRectFromGfxRect(left, left_rect);
1679 GetEinaRectFromGfxRect(right, right_rect);
1686 void EWebView::OnSelectionRectReceived(const gfx::Rect& selection_rect) const {
1688 context_menu_->OnSelectionRectReceived(selection_rect);
1691 Eina_Bool EWebView::ClearSelection() {
1695 ResetContextMenuController();
1696 rwhva()->SelectionChanged(std::u16string(), 0, gfx::Range());
1698 if (GetSelectionController())
1699 return GetSelectionController()->ClearSelectionViaEWebView();
1704 _Ewk_Hit_Test* EWebView::RequestHitTestDataAt(int x,
1706 Ewk_Hit_Test_Mode mode) {
1707 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1710 EvasToBlinkCords(x, y, &view_x, &view_y);
1712 return RequestHitTestDataAtBlinkCoords(view_x, view_y, mode);
1715 Eina_Bool EWebView::AsyncRequestHitTestDataAt(
1718 Ewk_Hit_Test_Mode mode,
1719 Ewk_View_Hit_Test_Request_Callback callback,
1722 EvasToBlinkCords(x, y, &view_x, &view_y);
1723 return AsyncRequestHitTestDataAtBlinkCords(
1724 view_x, view_y, mode,
1725 new WebViewAsyncRequestHitTestDataUserCallback(x, y, mode, callback,
1729 Eina_Bool EWebView::AsyncRequestHitTestDataAtBlinkCords(
1732 Ewk_Hit_Test_Mode mode,
1733 Ewk_View_Hit_Test_Request_Callback callback,
1735 return AsyncRequestHitTestDataAtBlinkCords(
1737 new WebViewAsyncRequestHitTestDataUserCallback(x, y, mode, callback,
1741 Eina_Bool EWebView::AsyncRequestHitTestDataAtBlinkCords(
1744 Ewk_Hit_Test_Mode mode,
1745 WebViewAsyncRequestHitTestDataCallback* cb) {
1746 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1749 static int64_t request_id = 1;
1752 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1753 DCHECK(render_view_host);
1755 if (render_view_host) {
1756 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
1757 render_view_host->Send(new EwkViewMsg_DoHitTestAsync(
1758 render_view_host->GetRoutingID(), x, y, mode, request_id));
1760 hit_test_callback_[request_id] = cb;
1766 // if failed we delete callback as it is not needed anymore
1771 void EWebView::DispatchAsyncHitTestData(const Hit_Test_Params& params,
1772 int64_t request_id) {
1773 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1775 std::map<int64_t, WebViewAsyncRequestHitTestDataCallback*>::iterator it =
1776 hit_test_callback_.find(request_id);
1778 if (it == hit_test_callback_.end())
1780 std::unique_ptr<_Ewk_Hit_Test> hit_test(new _Ewk_Hit_Test(params));
1782 it->second->Run(hit_test.get(), this);
1784 hit_test_callback_.erase(it);
1787 _Ewk_Hit_Test* EWebView::RequestHitTestDataAtBlinkCoords(
1790 Ewk_Hit_Test_Mode mode) {
1791 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1793 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1795 if (render_view_host) {
1796 // We wait on UI thread till hit test data is updated.
1797 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
1798 render_view_host->Send(
1799 new EwkViewMsg_DoHitTest(render_view_host->GetRoutingID(), x, y, mode));
1801 hit_test_completion_.Wait();
1802 return new _Ewk_Hit_Test(hit_test_params_);
1808 void EWebView::EvasToBlinkCords(int x, int y, int* view_x, int* view_y) {
1809 DCHECK(display::Screen::GetScreen());
1813 gfx::Rect view_bounds = rwhva()->offscreen_helper()->GetViewBoundsInPix();
1816 *view_x = x - view_bounds.x();
1818 display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
1822 *view_y = y - view_bounds.y();
1824 display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
1828 void EWebView::UpdateHitTestData(const Hit_Test_Params& params) {
1829 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
1830 hit_test_params_ = params;
1831 hit_test_completion_.Signal();
1834 void EWebView::OnCopyFromBackingStore(bool success, const SkBitmap& bitmap) {}
1836 void EWebView::OnFocusIn() {
1837 SmartCallback<EWebViewCallbacks::FocusIn>().call();
1838 #if defined(USE_WAYLAND)
1839 if (!rwhva() || !rwhva()->offscreen_helper())
1841 if (GetSettings()->getClipboardEnabled()) {
1842 ClipboardHelperEfl::GetInstance()->OnWebviewFocusIn(
1843 this, rwhva()->offscreen_helper()->content_image_elm_host(),
1844 rwhva()->offscreen_helper()->IsFocusedNodeContentEditable(),
1845 base::BindRepeating(&EWebView::ExecuteEditCommand,
1846 base::Unretained(this)));
1851 void EWebView::OnFocusOut() {
1852 SmartCallback<EWebViewCallbacks::FocusOut>().call();
1853 #if defined(USE_WAYLAND)
1854 if (GetSettings()->getClipboardEnabled())
1855 ClipboardHelperEfl::GetInstance()->MaybeInvalidateActiveWebview(this);
1859 void EWebView::RenderViewReady() {
1861 rwhva()->offscreen_helper()->SetFocusInOutCallbacks(
1862 base::BindRepeating(&EWebView::OnFocusIn, base::Unretained(this)),
1863 base::BindRepeating(&EWebView::OnFocusOut, base::Unretained(this)));
1866 #if defined(TIZEN_VIDEO_HOLE)
1867 if (rwhva() && pending_video_hole_setting_) {
1868 EnableVideoHoleSupportInternal();
1869 pending_video_hole_setting_ = false;
1873 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1875 SendDelayedMessages(render_view_host);
1876 UpdateWebkitPreferencesEfl(render_view_host);
1878 if (render_view_host) {
1879 WebContents* content = WebContents::FromRenderViewHost(render_view_host);
1881 RenderProcessHost* host = render_view_host->GetProcess();
1883 host->AddFilter(new WebViewBrowserMessageFilter(content));
1888 void EWebView::SetQuotaPermissionRequestCallback(
1889 Ewk_Quota_Permission_Request_Callback callback,
1891 quota_request_callback_.Set(callback, user_data);
1894 void EWebView::InvokeQuotaPermissionRequest(
1895 _Ewk_Quota_Permission_Request* request,
1896 content::QuotaPermissionContext::PermissionCallback cb) {
1897 quota_permission_request_map_[request] = std::move(cb);
1898 request->setView(evas_object());
1899 if (quota_request_callback_.IsCallbackSet())
1900 quota_request_callback_.Run(evas_object(), request);
1902 QuotaRequestCancel(request);
1905 void EWebView::QuotaRequestReply(const _Ewk_Quota_Permission_Request* request,
1907 DCHECK(quota_permission_request_map_.find(request) !=
1908 quota_permission_request_map_.end());
1910 QuotaPermissionContextEfl::DispatchCallback(
1911 std::move(quota_permission_request_map_[request]),
1912 (allow ? QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_ALLOW
1913 : QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_DISALLOW));
1915 quota_permission_request_map_.erase(request);
1919 void EWebView::QuotaRequestCancel(
1920 const _Ewk_Quota_Permission_Request* request) {
1921 DCHECK(quota_permission_request_map_.find(request) !=
1922 quota_permission_request_map_.end());
1924 QuotaPermissionContextEfl::DispatchCallback(
1925 std::move(quota_permission_request_map_[request]),
1926 QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_CANCELLED);
1927 quota_permission_request_map_.erase(request);
1931 bool EWebView::GetLinkMagnifierEnabled() const {
1932 #if !defined(EWK_BRINGUP) // FIXME: m71 bringup
1933 return web_contents_->GetMutableRendererPrefs()
1934 ->tap_multiple_targets_strategy ==
1935 TAP_MULTIPLE_TARGETS_STRATEGY_POPUP;
1941 void EWebView::SetLinkMagnifierEnabled(bool enabled) {
1942 #if !defined(EWK_BRINGUP) // FIXME: m71 bringup
1943 web_contents_->GetMutableRendererPrefs()->tap_multiple_targets_strategy =
1944 enabled ? TAP_MULTIPLE_TARGETS_STRATEGY_POPUP
1945 : TAP_MULTIPLE_TARGETS_STRATEGY_NONE;
1947 web_contents_->SyncRendererPrefs();
1950 bool EWebView::GetSnapshotAsync(
1951 Eina_Rectangle rect,
1952 Ewk_Web_App_Screenshot_Captured_Callback callback,
1954 float scale_factor) {
1955 if (!rwhva() || !rwhva()->offscreen_helper())
1958 rwhva()->offscreen_helper()->RequestSnapshotAsync(
1959 gfx::Rect(rect.x, rect.y, rect.w, rect.h), callback, user_data,
1964 Evas_Object* EWebView::GetSnapshot(Eina_Rectangle rect, float scale_factor) {
1965 if (!rwhva() || !rwhva()->offscreen_helper())
1968 return rwhva()->offscreen_helper()->GetSnapshot(
1969 gfx::Rect(rect.x, rect.y, rect.w, rect.h), scale_factor);
1972 void EWebView::BackForwardListClear() {
1973 content::NavigationController& controller = web_contents_->GetController();
1975 int entry_count = controller.GetEntryCount();
1976 bool entry_removed = false;
1978 for (int i = 0; i < entry_count; i++) {
1979 if (controller.RemoveEntryAtIndex(i)) {
1980 entry_removed = true;
1981 entry_count = controller.GetEntryCount();
1986 if (entry_removed) {
1987 back_forward_list_->ClearCache();
1988 InvokeBackForwardListChangedCallback();
1992 _Ewk_Back_Forward_List* EWebView::GetBackForwardList() const {
1993 return back_forward_list_.get();
1996 void EWebView::InvokeBackForwardListChangedCallback() {
1997 SmartCallback<EWebViewCallbacks::BackForwardListChange>().call();
2000 _Ewk_History* EWebView::GetBackForwardHistory() const {
2001 return new _Ewk_History(web_contents_->GetController());
2004 bool EWebView::WebAppCapableGet(Ewk_Web_App_Capable_Get_Callback callback,
2006 RenderViewHost* renderViewHost = web_contents_->GetRenderViewHost();
2007 if (!renderViewHost) {
2010 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
2011 WebApplicationCapableGetCallback* cb =
2012 new WebApplicationCapableGetCallback(callback, userData);
2013 int callbackId = web_app_capable_get_callback_map_.Add(cb);
2014 return renderViewHost->Send(new EwkViewMsg_WebAppCapableGet(
2015 renderViewHost->GetRoutingID(), callbackId));
2021 bool EWebView::WebAppIconUrlGet(Ewk_Web_App_Icon_URL_Get_Callback callback,
2023 RenderViewHost* renderViewHost = web_contents_->GetRenderViewHost();
2024 if (!renderViewHost) {
2027 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
2028 WebApplicationIconUrlGetCallback* cb =
2029 new WebApplicationIconUrlGetCallback(callback, userData);
2030 int callbackId = web_app_icon_url_get_callback_map_.Add(cb);
2031 return renderViewHost->Send(new EwkViewMsg_WebAppIconUrlGet(
2032 renderViewHost->GetRoutingID(), callbackId));
2038 bool EWebView::WebAppIconUrlsGet(Ewk_Web_App_Icon_URLs_Get_Callback callback,
2040 RenderViewHost* renderViewHost = web_contents_->GetRenderViewHost();
2041 if (!renderViewHost) {
2044 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
2045 WebApplicationIconUrlsGetCallback* cb =
2046 new WebApplicationIconUrlsGetCallback(callback, userData);
2047 int callbackId = web_app_icon_urls_get_callback_map_.Add(cb);
2048 return renderViewHost->Send(new EwkViewMsg_WebAppIconUrlsGet(
2049 renderViewHost->GetRoutingID(), callbackId));
2055 void EWebView::InvokeWebAppCapableGetCallback(bool capable, int callbackId) {
2056 WebApplicationCapableGetCallback* callback =
2057 web_app_capable_get_callback_map_.Lookup(callbackId);
2060 callback->Run(capable);
2061 web_app_capable_get_callback_map_.Remove(callbackId);
2064 void EWebView::InvokeWebAppIconUrlGetCallback(const std::string& iconUrl,
2066 WebApplicationIconUrlGetCallback* callback =
2067 web_app_icon_url_get_callback_map_.Lookup(callbackId);
2070 callback->Run(iconUrl);
2071 web_app_icon_url_get_callback_map_.Remove(callbackId);
2074 void EWebView::InvokeWebAppIconUrlsGetCallback(const StringMap& iconUrls,
2076 WebApplicationIconUrlsGetCallback* callback =
2077 web_app_icon_urls_get_callback_map_.Lookup(callbackId);
2081 callback->Run(iconUrls);
2082 web_app_icon_urls_get_callback_map_.Remove(callbackId);
2085 void EWebView::SetNotificationPermissionCallback(
2086 Ewk_View_Notification_Permission_Callback callback,
2088 notification_permission_callback_.Set(callback, user_data);
2091 bool EWebView::IsNotificationPermissionCallbackSet() const {
2092 return notification_permission_callback_.IsCallbackSet();
2095 bool EWebView::InvokeNotificationPermissionCallback(
2096 Ewk_Notification_Permission_Request* request) {
2097 Eina_Bool ret = EINA_FALSE;
2098 notification_permission_callback_.Run(evas_object_, request, &ret);
2102 int EWebView::SetEwkViewPlainTextGetCallback(
2103 Ewk_View_Plain_Text_Get_Callback callback,
2105 EwkViewPlainTextGetCallback* view_plain_text_callback_ptr =
2106 new EwkViewPlainTextGetCallback;
2107 view_plain_text_callback_ptr->Set(callback, user_data);
2108 return plain_text_get_callback_map_.Add(view_plain_text_callback_ptr);
2111 bool EWebView::PlainTextGet(Ewk_View_Plain_Text_Get_Callback callback,
2113 auto* render_frame_host = web_contents_->GetPrimaryMainFrame();
2114 if (!render_frame_host)
2117 auto callback_id = SetEwkViewPlainTextGetCallback(callback, user_data);
2118 return render_frame_host->Send(new EwkFrameMsg_GetPlainText(
2119 render_frame_host->GetRoutingID(), callback_id));
2122 void EWebView::InvokePlainTextGetCallback(const std::string& content_text,
2123 int plain_text_get_callback_id) {
2124 EwkViewPlainTextGetCallback* view_plain_text_callback_invoke_ptr =
2125 plain_text_get_callback_map_.Lookup(plain_text_get_callback_id);
2126 view_plain_text_callback_invoke_ptr->Run(evas_object(), content_text.c_str());
2127 plain_text_get_callback_map_.Remove(plain_text_get_callback_id);
2130 void EWebView::SetViewGeolocationPermissionCallback(
2131 Ewk_View_Geolocation_Permission_Callback callback,
2133 geolocation_permission_cb_.Set(callback, user_data);
2136 bool EWebView::InvokeViewGeolocationPermissionCallback(
2137 _Ewk_Geolocation_Permission_Request* permission_context,
2138 Eina_Bool* callback_result) {
2139 return geolocation_permission_cb_.Run(evas_object_, permission_context,
2143 void EWebView::SetViewUserMediaPermissionCallback(
2144 Ewk_View_User_Media_Permission_Callback callback,
2146 user_media_permission_cb_.Set(callback, user_data);
2149 bool EWebView::InvokeViewUserMediaPermissionCallback(
2150 _Ewk_User_Media_Permission_Request* permission_context,
2151 Eina_Bool* callback_result) {
2152 return user_media_permission_cb_.Run(evas_object_, permission_context,
2156 void EWebView::SetViewUserMediaPermissionQueryCallback(
2157 Ewk_View_User_Media_Permission_Query_Callback callback,
2159 user_media_permission_query_cb_.Set(callback, user_data);
2162 Ewk_User_Media_Permission_Query_Result
2163 EWebView::InvokeViewUserMediaPermissionQueryCallback(
2164 _Ewk_User_Media_Permission_Query* permission_context) {
2165 return user_media_permission_query_cb_.Run(evas_object_, permission_context);
2168 void EWebView::SetViewUnfocusAllowCallback(
2169 Ewk_View_Unfocus_Allow_Callback callback,
2171 unfocus_allow_cb_.Set(callback, user_data);
2174 bool EWebView::InvokeViewUnfocusAllowCallback(Ewk_Unfocus_Direction direction,
2175 Eina_Bool* callback_result) {
2176 return unfocus_allow_cb_.Run(evas_object_, direction, callback_result);
2179 void EWebView::StopFinding() {
2180 web_contents_->StopFinding(content::STOP_FIND_ACTION_CLEAR_SELECTION);
2183 void EWebView::SetProgressValue(double progress) {
2184 progress_ = progress;
2187 double EWebView::GetProgressValue() {
2191 const char* EWebView::GetTitle() {
2192 title_ = base::UTF16ToUTF8(web_contents_->GetTitle());
2193 return title_.c_str();
2196 bool EWebView::SaveAsPdf(int width, int height, const std::string& filename) {
2199 rwhva()->host()->PrintToPdf(width, height, base::FilePath(filename));
2203 bool EWebView::GetMHTMLData(Ewk_View_MHTML_Data_Get_Callback callback,
2205 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
2206 if (!render_view_host)
2209 MHTMLCallbackDetails* callback_details = new MHTMLCallbackDetails;
2210 callback_details->Set(callback, user_data);
2211 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
2212 int mhtml_callback_id = mhtml_callback_map_.Add(callback_details);
2213 return render_view_host->Send(new EwkViewMsg_GetMHTMLData(
2214 render_view_host->GetRoutingID(), mhtml_callback_id));
2220 void EWebView::OnMHTMLContentGet(const std::string& mhtml_content,
2222 MHTMLCallbackDetails* callback_details =
2223 mhtml_callback_map_.Lookup(callback_id);
2224 callback_details->Run(evas_object(), mhtml_content.c_str());
2225 mhtml_callback_map_.Remove(callback_id);
2228 bool EWebView::SavePageAsMHTML(const std::string& path,
2229 Ewk_View_Save_Page_Callback callback,
2234 GURL url(web_contents_->GetLastCommittedURL());
2235 std::u16string title(web_contents_->GetTitle());
2237 // Post function that has file access to blocking task runner.
2238 return base::PostTaskAndReplyWithResult(
2239 base::ThreadPool::CreateSequencedTaskRunner(
2240 {base::MayBlock(), base::TaskPriority::BEST_EFFORT,
2241 base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})
2244 base::BindOnce(&GenerateMHTMLFilePath, url, base::UTF16ToUTF8(title),
2246 base::BindOnce(&EWebView::GenerateMHTML, base::Unretained(this), callback,
2250 void EWebView::GenerateMHTML(Ewk_View_Save_Page_Callback callback,
2252 const base::FilePath& file_path) {
2253 if (file_path.empty()) {
2254 LOG(ERROR) << "Generating file path was failed";
2255 callback(evas_object_, nullptr, user_data);
2259 MHTMLGenerationParams params(file_path);
2260 web_contents_->GenerateMHTML(
2261 params, base::BindOnce(&EWebView::MHTMLGenerated, base::Unretained(this),
2262 callback, user_data, file_path));
2265 void EWebView::MHTMLGenerated(Ewk_View_Save_Page_Callback callback,
2267 const base::FilePath& file_path,
2268 int64_t file_size) {
2269 callback(evas_object_, file_size > 0 ? file_path.value().c_str() : nullptr,
2273 bool EWebView::GetBackgroundColor(
2274 Ewk_View_Background_Color_Get_Callback callback,
2278 BackgroundColorGetCallback* cb =
2279 new BackgroundColorGetCallback(callback, user_data);
2280 int callback_id = background_color_get_callback_map_.Add(cb);
2282 rwhva()->host()->RequestBackgroundColor(callback_id);
2286 void EWebView::OnGetBackgroundColor(int callback_id, SkColor bg_color) {
2287 BackgroundColorGetCallback* cb =
2288 background_color_get_callback_map_.Lookup(callback_id);
2293 cb->Run(evas_object(), SkColorGetR(bg_color), SkColorGetG(bg_color),
2294 SkColorGetB(bg_color), SkColorGetA(bg_color));
2295 background_color_get_callback_map_.Remove(callback_id);
2298 bool EWebView::IsFullscreen() {
2299 return web_contents_delegate_->IsFullscreenForTabOrPending(
2300 web_contents_.get());
2303 void EWebView::ExitFullscreen() {
2304 WebContentsImpl* wci = static_cast<WebContentsImpl*>(web_contents_.get());
2305 wci->ExitFullscreen(false);
2308 double EWebView::GetScale() {
2309 return page_scale_factor_;
2312 void EWebView::DidChangePageScaleFactor(double scale_factor) {
2313 page_scale_factor_ = scale_factor;
2314 wcva()->wcva_helper()->SetPageScaleFactor(scale_factor);
2315 SetScaledContentsSize();
2317 // Notify app about the scale change.
2318 scale_changed_cb_.Run(evas_object_, scale_factor);
2321 inline JavaScriptDialogManagerEfl* EWebView::GetJavaScriptDialogManagerEfl() {
2322 return static_cast<JavaScriptDialogManagerEfl*>(
2323 web_contents_delegate_->GetJavaScriptDialogManager(web_contents_.get()));
2326 void EWebView::SetJavaScriptAlertCallback(
2327 Ewk_View_JavaScript_Alert_Callback callback,
2329 GetJavaScriptDialogManagerEfl()->SetAlertCallback(callback, user_data);
2332 void EWebView::JavaScriptAlertReply() {
2333 GetJavaScriptDialogManagerEfl()->ExecuteDialogClosedCallBack(true,
2335 SmartCallback<EWebViewCallbacks::PopupReplyWaitFinish>().call(0);
2338 void EWebView::SetJavaScriptConfirmCallback(
2339 Ewk_View_JavaScript_Confirm_Callback callback,
2341 GetJavaScriptDialogManagerEfl()->SetConfirmCallback(callback, user_data);
2344 void EWebView::JavaScriptConfirmReply(bool result) {
2345 GetJavaScriptDialogManagerEfl()->ExecuteDialogClosedCallBack(result,
2347 SmartCallback<EWebViewCallbacks::PopupReplyWaitFinish>().call(0);
2350 void EWebView::SetJavaScriptPromptCallback(
2351 Ewk_View_JavaScript_Prompt_Callback callback,
2353 GetJavaScriptDialogManagerEfl()->SetPromptCallback(callback, user_data);
2356 void EWebView::JavaScriptPromptReply(const char* result) {
2357 GetJavaScriptDialogManagerEfl()->ExecuteDialogClosedCallBack(
2358 true, (std::string(result)));
2359 SmartCallback<EWebViewCallbacks::PopupReplyWaitFinish>().call(0);
2362 void EWebView::GetPageScaleRange(double* min_scale, double* max_scale) {
2363 auto prefs = web_contents_->GetOrCreateWebPreferences();
2365 *min_scale = prefs.default_minimum_page_scale_factor;
2367 *max_scale = prefs.default_maximum_page_scale_factor;
2370 content::WebContentsViewAura* EWebView::GetWebContentsViewAura() const {
2371 WebContentsImpl* wc = static_cast<WebContentsImpl*>(web_contents_.get());
2372 return static_cast<WebContentsViewAura*>(wc->GetView());
2375 bool EWebView::SetDrawsTransparentBackground(bool enabled) {
2376 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
2377 if (!render_view_host || !rwhva())
2380 #if BUILDFLAG(IS_EFL)
2381 if (!rwhva()->offscreen_helper())
2383 elm_object_style_set(rwhva()->offscreen_helper()->content_image_elm_host(),
2384 enabled ? "transparent" : "default");
2385 evas_object_image_alpha_set(rwhva()->offscreen_helper()->content_image(),
2389 GetWebContentsViewAura()->SetBackgroundColor(enabled ? SK_ColorTRANSPARENT
2391 static_cast<RenderViewHostImpl*>(render_view_host)
2393 ->GetAssociatedFrameWidget()
2394 ->SetDrawsTransparentBackground(enabled);
2395 rwhva()->SetBackgroundColor(enabled ? SK_ColorTRANSPARENT : SK_ColorWHITE);
2400 bool EWebView::GetDrawsTransparentBackground() {
2401 return GetWebContentsViewAura()->GetBackgroundColor() == SK_ColorTRANSPARENT;
2404 bool EWebView::SetBackgroundColor(int red, int green, int blue, int alpha) {
2406 return SetDrawsTransparentBackground(true);
2408 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
2409 if (!render_view_host || !rwhva())
2412 #if BUILDFLAG(IS_EFL)
2413 if (!rwhva()->offscreen_helper())
2415 elm_object_style_set(rwhva()->offscreen_helper()->content_image_elm_host(),
2416 alpha < 255 ? "transparent" : "default");
2417 evas_object_image_alpha_set(rwhva()->offscreen_helper()->content_image(),
2421 GetWebContentsViewAura()->SetBackgroundColor(
2422 SkColorSetARGB(alpha, red, green, blue));
2423 static_cast<RenderViewHostImpl*>(render_view_host)
2425 ->GetAssociatedFrameWidget()
2426 ->SetBackgroundColor(red, green, blue, alpha);
2427 rwhva()->SetBackgroundColor(SkColorSetARGB(alpha, red, green, blue));
2432 void EWebView::GetSessionData(const char** data, unsigned* length) const {
2433 static const int MAX_SESSION_ENTRY_SIZE = std::numeric_limits<int>::max();
2435 NavigationController& navigationController = web_contents_->GetController();
2436 base::Pickle sessionPickle;
2437 const int itemCount = navigationController.GetEntryCount();
2439 sessionPickle.WriteInt(itemCount);
2440 sessionPickle.WriteInt(navigationController.GetCurrentEntryIndex());
2442 for (int i = 0; i < itemCount; i++) {
2443 NavigationEntry* navigationEntry = navigationController.GetEntryAtIndex(i);
2444 sessions::SerializedNavigationEntry serializedEntry =
2445 sessions::ContentSerializedNavigationBuilder::FromNavigationEntry(
2446 i, navigationEntry);
2447 serializedEntry.WriteToPickle(MAX_SESSION_ENTRY_SIZE, &sessionPickle);
2450 if (sessionPickle.size() <= 0 ||
2452 static_cast<char*>(malloc(sizeof(char) * sessionPickle.size())))) {
2453 LOG(ERROR) << "Failed to get session data";
2457 memcpy(const_cast<char*>(*data), sessionPickle.data(), sessionPickle.size());
2458 *length = sessionPickle.size();
2461 bool EWebView::RestoreFromSessionData(const char* data, unsigned length) {
2462 base::Pickle sessionPickle(data, length);
2463 base::PickleIterator pickleIterator(sessionPickle);
2467 if (!pickleIterator.ReadInt(&entryCount))
2469 if (!pickleIterator.ReadInt(¤tEntry))
2472 std::vector<sessions::SerializedNavigationEntry> serializedEntries;
2473 serializedEntries.resize(entryCount);
2474 for (int i = 0; i < entryCount; ++i) {
2475 if (!serializedEntries.at(i).ReadFromPickle(&pickleIterator))
2485 std::vector<std::unique_ptr<content::NavigationEntry>> scopedEntries =
2486 sessions::ContentSerializedNavigationBuilder::ToNavigationEntries(
2487 serializedEntries, context()->browser_context());
2489 NavigationController& navigationController = web_contents_->GetController();
2491 if (currentEntry < 0)
2494 if (currentEntry >= static_cast<int>(scopedEntries.size()))
2495 currentEntry = scopedEntries.size() - 1;
2497 navigationController.Restore(currentEntry, RestoreType::kRestored,
2502 void EWebView::SetBrowserFont() {
2503 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
2504 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
2505 if (render_view_host) {
2506 IPC::Message* message =
2507 new EwkViewMsg_SetBrowserFont(render_view_host->GetRoutingID());
2509 if (render_view_host->IsRenderViewLive())
2510 render_view_host->Send(message);
2512 delayed_messages_.push_back(message);
2517 bool EWebView::IsDragging() const {
2518 return wcva()->wcva_helper()->IsDragging();
2521 void EWebView::ShowFileChooser(content::RenderFrameHost* render_frame_host,
2522 const blink::mojom::FileChooserParams& params) {
2523 if (!IsMobileProfile() && !IsWearableProfile())
2526 #if !defined(EWK_BRINGUP) // FIXME: m71 bringup
2527 if (params.capture) {
2528 const std::string capture_types[] = {"video/*", "audio/*", "image/*"};
2529 unsigned int capture_types_num =
2530 sizeof(capture_types) / sizeof(*capture_types);
2531 for (unsigned int i = 0; i < capture_types_num; ++i) {
2532 for (unsigned int j = 0; j < params.accept_types.size(); ++j) {
2533 if (UTF16ToUTF8(params.accept_types[j]) == capture_types[i]) {
2534 filechooser_mode_ = params.mode;
2535 LaunchCamera(params.accept_types[j]);
2541 file_chooser_.reset(
2542 new content::FileChooserControllerEfl(render_frame_host, ¶ms));
2543 file_chooser_->Open();
2547 #if !defined(EWK_BRINGUP) // FIXME: m67 bringup
2548 void EWebView::SetViewMode(blink::WebViewMode view_mode) {
2549 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
2550 if (!render_view_host)
2553 IPC::Message* message =
2554 new ViewMsg_SetViewMode(render_view_host->GetRoutingID(), view_mode);
2555 if (render_view_host->IsRenderViewLive()) {
2556 render_view_host->Send(message);
2558 delayed_messages_.push_back(message);
2563 gfx::Point EWebView::GetContextMenuPosition() const {
2564 return context_menu_position_;
2567 void EWebView::ShowContentsDetectedPopup(const char* message) {
2568 popup_controller_.reset(new PopupControllerEfl(this));
2569 popup_controller_->openPopup(message);
2572 void EWebView::RequestColorPicker(int r, int g, int b, int a) {
2573 input_picker_.reset(
2574 new InputPicker(this, web_contents_.get(), evas_object()));
2575 input_picker_->ShowColorPicker(r, g, b, a);
2578 bool EWebView::SetColorPickerColor(int r, int g, int b, int a) {
2579 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
2580 web_contents_->DidChooseColorInColorChooser(SkColorSetARGB(a, r, g, b));
2585 void EWebView::InputPickerShow(ui::TextInputType input_type,
2587 content::DateTimeChooserEfl* date_time_chooser) {
2588 input_picker_.reset(new InputPicker(this, web_contents_.get(), evas_object(),
2589 date_time_chooser));
2590 input_picker_->ShowDatePicker(input_type, input_value);
2593 void EWebView::LoadNotFoundErrorPage(const std::string& invalidUrl) {
2594 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
2595 RenderFrameHost* render_frame_host = web_contents_->GetPrimaryMainFrame();
2596 if (render_frame_host)
2597 render_frame_host->Send(new EwkFrameMsg_LoadNotFoundErrorPage(
2598 render_frame_host->GetRoutingID(), invalidUrl));
2602 std::string EWebView::GetPlatformLocale() {
2603 char* local_default = setlocale(LC_CTYPE, 0);
2605 return std::string("en-US");
2606 std::string locale = std::string(local_default);
2607 size_t position = locale.find('_');
2608 if (position != std::string::npos)
2609 locale.replace(position, 1, "-");
2610 position = locale.find('.');
2611 if (position != std::string::npos)
2612 locale = locale.substr(0, position);
2616 int EWebView::StartInspectorServer(int port) {
2617 #if BUILDFLAG(IS_TIZEN_TV)
2619 use_early_rwi_ = false;
2620 rwi_info_showed_ = false;
2622 if (!context_->GetImpl()->GetInspectorServerState()) {
2624 if (!devtools_http_handler::DevToolsPortManager::GetInstance()
2625 ->GetValidPort(validPort))
2631 return context_->InspectorServerStart(port);
2634 bool EWebView::StopInspectorServer() {
2635 #if BUILDFLAG(IS_TIZEN_TV)
2637 use_early_rwi_ = false;
2638 rwi_info_showed_ = false;
2641 return context_->InspectorServerStop();
2644 void EWebView::InvokeWebProcessCrashedCallback() {
2645 DCHECK_CURRENTLY_ON(BrowserThread::UI);
2646 const GURL last_url = GetURL();
2647 bool callback_handled = false;
2648 SmartCallback<EWebViewCallbacks::WebProcessCrashed>().call(&callback_handled);
2649 if (!callback_handled)
2650 LoadHTMLString(kRendererCrashedHTMLMessage, NULL,
2651 last_url.possibly_invalid_spec().c_str());
2654 void EWebView::SyncAcceptLanguages(const std::string& accept_languages) {
2655 web_contents_->GetMutableRendererPrefs()->accept_languages = accept_languages;
2656 web_contents_->SyncRendererPrefs();
2657 BrowserContext* browser_context = web_contents_->GetBrowserContext();
2658 if (!browser_context)
2661 auto* storage_partition = browser_context->GetDefaultStoragePartition();
2662 if (!storage_partition)
2665 if (auto* network_context = storage_partition->GetNetworkContext())
2666 network_context->SetAcceptLanguage(accept_languages);
2669 #if BUILDFLAG(IS_TIZEN_TV)
2670 bool EWebView::EdgeScrollBy(int delta_x, int delta_y) {
2671 if ((delta_x == 0 && delta_y == 0) || is_processing_edge_scroll_)
2674 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
2675 if (!render_view_host)
2681 gfx::Point offset = gfx::Point(delta_x, delta_y);
2682 gfx::Point mouse_position;
2683 GetMousePosition(mouse_position);
2684 is_processing_edge_scroll_ = true;
2686 static_cast<RenderViewHostImpl*>(render_view_host)
2688 ->GetAssociatedFrameWidget()
2689 ->EdgeScrollBy(offset, mouse_position);
2693 void EWebView::GetMousePosition(gfx::Point& mouse_position) {
2694 int mouse_x, mouse_y;
2695 evas_pointer_output_xy_get(GetEvas(), &mouse_x, &mouse_y);
2696 Evas_Coord x, y, width, height;
2697 evas_object_geometry_get(evas_object(), &x, &y, &width, &height);
2701 else if (mouse_y > y + height)
2702 mouse_y = y + height - 1;
2705 else if (mouse_x > x + width)
2706 mouse_x = x + width - 1;
2712 display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
2714 display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
2716 mouse_position.set_x(mouse_x);
2717 mouse_position.set_y(mouse_y);
2720 void EWebView::InvokeEdgeScrollByCallback(const gfx::Point& offset,
2722 is_processing_edge_scroll_ = false;
2725 SmartCallback<EWebViewCallbacks::EdgeScrollLeft>().call(&handled);
2726 else if (offset.x() > 0)
2727 SmartCallback<EWebViewCallbacks::EdgeScrollRight>().call(&handled);
2730 SmartCallback<EWebViewCallbacks::EdgeScrollTop>().call(&handled);
2731 else if (offset.y() > 0)
2732 SmartCallback<EWebViewCallbacks::EdgeScrollBottom>().call(&handled);
2736 void EWebView::HandleRendererProcessCrash() {
2737 content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
2738 base::BindOnce(&EWebView::InvokeWebProcessCrashedCallback,
2739 base::Unretained(this)));
2742 void EWebView::InitializeContent() {
2743 LOG(INFO) << "eweb_view.cc InitializeContent" ;
2744 #if BUILDFLAG(IS_TIZEN_TV)
2745 // When initialize content init inspector server
2746 InitInspectorServer();
2748 WebContents* new_contents = create_new_window_web_contents_cb_.Run(this);
2749 if (!new_contents) {
2750 WebContents::CreateParams params(context_->browser_context());
2751 web_contents_.reset(
2752 new WebContentsImplEfl(context_->browser_context(), this));
2753 static_cast<WebContentsImpl*>(web_contents_.get())
2754 ->Init(params, blink::FramePolicy());
2756 web_contents_.reset(new_contents);
2758 // When a new webview is created in response to a request from the
2759 // engine, the BrowserContext instance of the originator WebContents
2760 // is used by the newly created WebContents object.
2761 // See more in WebContentsImplEfl::HandleNewWebContentsCreate.
2763 // Hence, if as part of the WebView creation, the embedding APP
2764 // passes in a Ewk_Context instance that wraps a different instance of
2765 // BrowserContext than the one the originator WebContents holds,
2766 // undefined behavior can be seen.
2768 // This is a snippet code that illustrate the scenario:
2771 // evas_object_smart_callback_add(web_view_, "create,window",
2772 // &OnNewWindowRequest, this);
2775 // void OnNewWindowRequest(void *data, Evas_Object*, void* out_view) {
2777 // EvasObject* new_web_view = ewk_view_add_with_context(GetEvas(),
2778 // ewk_context_new());
2779 // *static_cast<Evas_Object**>(out_view) = new_web_view;
2783 // The new Ewk_Context object created and passed in as parameter to
2784 // ewk_view_add_with_context wraps a different instance of BrowserContext
2785 // than the one the new WebContents object will hold.
2787 // CHECK below aims at catching misuse of this API.
2788 bool should_crash = context_->GetImpl()->browser_context() !=
2789 web_contents_->GetBrowserContext();
2792 << "BrowserContext of new WebContents does not match EWebView's. "
2793 << "Please see 'ewk_view_add*' documentation. "
2794 << "Aborting execution ...";
2797 web_contents_delegate_.reset(new WebContentsDelegateEfl(this));
2798 web_contents_->SetDelegate(web_contents_delegate_.get());
2799 WebContentsImplEfl* wc_efl =
2800 static_cast<WebContentsImplEfl*>(web_contents_.get());
2801 wc_efl->SetEflDelegate(new WebContentsEflDelegateEwk(this));
2802 wcva()->wcva_helper()->SetEflDelegate(wc_efl->GetEflDelegate());
2804 back_forward_list_.reset(new _Ewk_Back_Forward_List(web_contents_.get()));
2806 permission_popup_manager_.reset(new PermissionPopupManager(evas_object_));
2807 gin_native_bridge_dispatcher_host_.reset(
2808 new content::GinNativeBridgeDispatcherHost(web_contents_.get()));
2811 static_cast<WebContentsImplEfl*>(web_contents_.get())->GetEflNativeView();
2812 evas_object_smart_member_add(native_view_, evas_object_);
2813 static_cast<WebContentsImpl*>(web_contents_.get())
2814 ->set_ewk_view(evas_object_);
2815 InitializeWindowTreeHost();
2818 #if BUILDFLAG(IS_TIZEN_TV)
2819 void EWebView::OnDialogClosed() {
2820 if (!use_early_rwi_)
2823 use_early_rwi_ = false;
2824 LOG(INFO) << "[FAST RWI] SetURL Restore [" << rwi_gurl_.spec()
2825 << "] from [about:blank]";
2828 rwi_info_showed_ = true;
2831 void EWebView::InitInspectorServer() {
2832 if (devtools_http_handler::DevToolsPortManager::GetInstance()
2833 ->ProcessCompare()) {
2834 int res = StartInspectorServer(0);
2836 LOG(INFO) << "InitInspectorServer SetPort";
2837 devtools_http_handler::DevToolsPortManager::GetInstance()->SetPort(res);
2843 #if defined(TIZEN_TBM_SUPPORT)
2844 void EWebView::SetOffscreenRendering(bool enable) {
2846 host_->compositor()->SetUseTbmSuraceForOffscreenRendering(enable);
2850 void EWebView::InitializeWindowTreeHost() {
2851 CHECK(aura::Env::GetInstance());
2853 int x, y, width, height;
2855 ecore_evas_ecore_evas_get(evas_object_evas_get(native_view_));
2856 ecore_evas_geometry_get(ee, &x, &y, &width, &height);
2858 gfx::Rect bounds(x, y, width, height);
2859 ui::PlatformWindowInitProperties properties;
2860 properties.bounds = bounds;
2862 host_ = aura::WindowTreeHost::Create(std::move(properties));
2864 host_->window()->Show();
2867 std::make_unique<aura::test::TestFocusClient>(host_->window());
2868 window_parenting_client_ =
2869 std::make_unique<aura::test::TestWindowParentingClient>(host_->window());
2870 compositor_observer_ = std::make_unique<ui::CompositorObserverEfl>(
2871 host_->compositor(), web_contents_.get());
2873 aura::Window* content = web_contents_->GetNativeView();
2874 aura::Window* parent = host_->window();
2875 if (!parent->Contains(content)) {
2876 parent->AddChild(content);
2879 content->SetBounds(bounds);
2880 RenderWidgetHostView* host_view = web_contents_->GetRenderWidgetHostView();
2882 host_view->SetSize(bounds.size());
2885 #if BUILDFLAG(IS_TIZEN) && !defined(EWK_BRINGUP)
2886 void EWebView::cameraResultCb(service_h request,
2888 service_result_e result,
2890 if (!IsMobileProfile() && !IsWearableProfile())
2893 EWebView* webview = static_cast<EWebView*>(data);
2894 RenderViewHost* render_view_host =
2895 webview->web_contents_->GetRenderViewHost();
2896 if (result == SERVICE_RESULT_SUCCEEDED) {
2900 ret = service_get_extra_data_array(reply, SERVICE_DATA_SELECTED,
2901 &filesarray, &number);
2903 for (int i = 0; i < number; i++) {
2904 std::vector<ui::SelectedFileInfo> files;
2905 if (!render_view_host) {
2908 if (filesarray[i]) {
2909 GURL url(filesarray[i]);
2910 if (!url.is_valid()) {
2911 base::FilePath path(url.SchemeIsFile() ? url.path()
2913 files.push_back(ui::SelectedFileInfo(path, base::FilePath()));
2916 render_view_host->FilesSelectedInChooser(files,
2917 webview->filechooser_mode_);
2921 std::vector<ui::SelectedFileInfo> files;
2922 if (render_view_host) {
2923 render_view_host->FilesSelectedInChooser(files,
2924 webview->filechooser_mode_);
2929 bool EWebView::LaunchCamera(std::u16string mimetype) {
2930 service_h svcHandle = 0;
2931 if (service_create(&svcHandle) < 0 || !svcHandle) {
2932 LOG(ERROR) << __FUNCTION__ << " Service Creation Failed ";
2935 service_set_operation(svcHandle, SERVICE_OPERATION_CREATE_CONTENT);
2936 service_set_mime(svcHandle, UTF16ToUTF8(mimetype).c_str());
2937 service_add_extra_data(svcHandle, "CALLER", "Browser");
2939 int ret = service_send_launch_request(svcHandle, cameraResultCb, this);
2940 if (ret != SERVICE_ERROR_NONE) {
2941 LOG(ERROR) << __FUNCTION__ << " Service Launch Failed ";
2942 service_destroy(svcHandle);
2945 service_destroy(svcHandle);
2950 void EWebView::UrlRequestSet(
2952 content::NavigationController::LoadURLType loadtype,
2956 content::NavigationController::LoadURLParams params(gurl);
2957 params.load_type = loadtype;
2958 params.override_user_agent = NavigationController::UA_OVERRIDE_TRUE;
2961 std::string s(body);
2963 network::ResourceRequestBody::CreateFromBytes(s.data(), s.size());
2966 net::HttpRequestHeaders header;
2968 Eina_Iterator* it = eina_hash_iterator_tuple_new(headers);
2970 while (eina_iterator_next(it, reinterpret_cast<void**>(&t))) {
2972 const char* value_str =
2973 t->data ? static_cast<const char*>(t->data) : "";
2974 base::StringPiece name = static_cast<const char*>(t->key);
2975 base::StringPiece value = value_str;
2976 header.SetHeader(name, value);
2977 // net::HttpRequestHeaders.ToString() returns string with newline
2978 params.extra_headers += header.ToString();
2981 eina_iterator_free(it);
2984 web_contents_->GetController().LoadURLWithParams(params);
2987 #if defined(TIZEN_VIDEO_HOLE)
2988 void EWebView::EnableVideoHoleSupport() {
2989 if (!web_contents_->GetPrimaryMainFrame() ||
2990 !web_contents_->GetPrimaryMainFrame()->IsRenderFrameLive() || !rwhva()) {
2991 pending_video_hole_setting_ = true;
2995 EnableVideoHoleSupportInternal();
2998 void EWebView::EnableVideoHoleSupportInternal() {
2999 if (settings_->getPreferences().video_hole_enabled)
3001 settings_->getPreferences().video_hole_enabled = true;
3002 UpdateWebKitPreferences();
3006 bool EWebView::HandleShow() {
3014 bool EWebView::HandleHide() {
3022 bool EWebView::HandleMove(int x, int y) {
3025 evas_object_move(native_view_, x, y);
3027 #if defined(TIZEN_VIDEO_HOLE) && !defined(EWK_BRINGUP)
3029 rwhva()->offscreen_helper()->DidMoveWebView();
3033 context_menu_->Move(x, y);
3038 bool EWebView::HandleResize(int width, int height) {
3041 evas_object_resize(native_view_, width, height);
3043 if (select_picker_) {
3044 AdjustViewPortHeightToPopupMenu(true /* is_popup_menu_visible */);
3045 ScrollFocusedNodeIntoView();
3048 #if defined(USE_AURA) && BUILDFLAG(IS_TIZEN_TV)
3051 evas_object_geometry_get(native_view_, &x, &y, nullptr, nullptr);
3052 gfx::Rect bounds(x, y, width, height);
3053 host_->SetBoundsInPixels(bounds);
3060 bool EWebView::HandleTextSelectionDown(int x, int y) {
3061 if (!GetSelectionController())
3063 return GetSelectionController()->TextSelectionDown(x, y);
3066 bool EWebView::HandleTextSelectionUp(int x, int y) {
3067 if (!GetSelectionController())
3069 return GetSelectionController()->TextSelectionUp(x, y);
3072 void EWebView::HandleTapGestureForSelection(bool is_content_editable) {
3073 if (!GetSelectionController())
3076 GetSelectionController()->PostHandleTapGesture(is_content_editable);
3079 void EWebView::HandleZoomGesture(blink::WebGestureEvent& event) {
3080 blink::WebInputEvent::Type event_type = event.GetType();
3081 if (event_type == blink::WebInputEvent::Type::kGestureDoubleTap ||
3082 event_type == blink::WebInputEvent::Type::kGesturePinchBegin) {
3083 SmartCallback<EWebViewCallbacks::ZoomStarted>().call();
3085 if (event_type == blink::WebInputEvent::Type::kGestureDoubleTap ||
3086 event_type == blink::WebInputEvent::Type::kGesturePinchEnd) {
3087 SmartCallback<EWebViewCallbacks::ZoomFinished>().call();
3091 bool EWebView::GetHorizontalPanningHold() const {
3094 return rwhva()->offscreen_helper()->GetHorizontalPanningHold();
3097 void EWebView::SetHorizontalPanningHold(bool hold) {
3099 rwhva()->offscreen_helper()->SetHorizontalPanningHold(hold);
3102 bool EWebView::GetVerticalPanningHold() const {
3105 return rwhva()->offscreen_helper()->GetVerticalPanningHold();
3108 void EWebView::SetVerticalPanningHold(bool hold) {
3110 rwhva()->offscreen_helper()->SetVerticalPanningHold(hold);
3113 void EWebView::SendDelayedMessages(RenderViewHost* render_view_host) {
3114 DCHECK(render_view_host);
3116 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
3117 content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
3118 base::BindOnce(&EWebView::SendDelayedMessages, base::Unretained(this),
3123 for (auto iter = delayed_messages_.begin(); iter != delayed_messages_.end();
3125 IPC::Message* message = *iter;
3126 message->set_routing_id(render_view_host->GetRoutingID());
3127 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
3128 render_view_host->Send(message);
3132 delayed_messages_.clear();
3135 void EWebView::ClosePage() {
3136 web_contents_->ClosePage();
3139 bool EWebView::SetMainFrameScrollbarVisible(bool visible) {
3140 if (web_contents_->GetPrimaryMainFrame()->IsRenderFrameLive() && rwhva())
3141 rwhva()->host()->SetMainFrameScrollbarVisible(visible);
3145 bool EWebView::GetMainFrameScrollbarVisible(
3146 Ewk_View_Main_Frame_Scrollbar_Visible_Get_Callback callback,
3151 MainFrameScrollbarVisibleGetCallback* callback_ptr =
3152 new MainFrameScrollbarVisibleGetCallback;
3153 callback_ptr->Set(callback, user_data);
3155 main_frame_scrollbar_visible_callback_map_.Add(callback_ptr);
3156 rwhva()->host()->RequestMainFrameScrollbarVisible(callback_id);
3160 void EWebView::InvokeMainFrameScrollbarVisibleCallback(int callback_id,
3162 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
3163 content::GetUIThreadTaskRunner({})->PostTask(
3165 base::BindOnce(&EWebView::InvokeMainFrameScrollbarVisibleCallback,
3166 base::Unretained(this), visible, callback_id));
3170 MainFrameScrollbarVisibleGetCallback* callback =
3171 main_frame_scrollbar_visible_callback_map_.Lookup(callback_id);
3175 main_frame_scrollbar_visible_callback_map_.Remove(callback_id);
3176 callback->Run(evas_object(), visible);
3177 main_frame_scrollbar_visible_callback_map_.Remove(callback_id);
3180 void EWebView::OnOverscrolled(const gfx::Vector2dF& accumulated_overscroll,
3181 const gfx::Vector2dF& latest_overscroll_delta) {
3182 const gfx::Vector2dF old_overscroll =
3183 accumulated_overscroll - latest_overscroll_delta;
3185 if (latest_overscroll_delta.x() && !old_overscroll.x()) {
3186 latest_overscroll_delta.x() < 0
3187 ? SmartCallback<EWebViewCallbacks::OverscrolledLeft>().call()
3188 : SmartCallback<EWebViewCallbacks::OverscrolledRight>().call();
3190 if (latest_overscroll_delta.y() && !old_overscroll.y()) {
3191 latest_overscroll_delta.y() < 0
3192 ? SmartCallback<EWebViewCallbacks::OverscrolledTop>().call()
3193 : SmartCallback<EWebViewCallbacks::OverscrolledBottom>().call();
3197 void EWebView::SetDidChangeThemeColorCallback(
3198 Ewk_View_Did_Change_Theme_Color_Callback callback,
3200 did_change_theme_color_callback_.Set(callback, user_data);
3203 void EWebView::DidChangeThemeColor(const SkColor& color) {
3204 did_change_theme_color_callback_.Run(evas_object_, color);
3207 #if BUILDFLAG(IS_TIZEN_TV)
3208 void EWebView::DrawLabel(Evas_Object* image, Eina_Rectangle rect) {
3210 rwhva()->offscreen_helper()->DrawLabel(image, rect);
3213 void EWebView::DeactivateAtk(bool deactivated) {
3214 EWebAccessibilityUtil::GetInstance()->Deactivate(deactivated);
3217 void EWebView::ClearLabels() {
3219 rwhva()->offscreen_helper()->ClearLabels();
3223 void EWebView::RequestManifest(Ewk_View_Request_Manifest_Callback callback,
3225 web_contents_delegate_->RequestManifestInfo(callback, user_data);
3228 void EWebView::DidRespondRequestManifest(
3229 _Ewk_View_Request_Manifest* manifest,
3230 Ewk_View_Request_Manifest_Callback callback,
3232 callback(evas_object_, manifest, user_data);
3235 void EWebView::SetSessionTimeout(uint64_t timeout) {
3236 if (web_contents_->GetPrimaryMainFrame()->IsRenderFrameLive() && rwhva())
3237 rwhva()->host()->SetLongPollingGlobalTimeout(timeout);
3240 void EWebView::SetBeforeUnloadConfirmPanelCallback(
3241 Ewk_View_Before_Unload_Confirm_Panel_Callback callback,
3243 GetJavaScriptDialogManagerEfl()->SetBeforeUnloadConfirmPanelCallback(
3244 callback, user_data);
3247 void EWebView::ReplyBeforeUnloadConfirmPanel(Eina_Bool result) {
3248 GetJavaScriptDialogManagerEfl()->ReplyBeforeUnloadConfirmPanel(result);
3251 #if defined(TIZEN_PEPPER_EXTENSIONS)
3252 void EWebView::InitializePepperExtensionSystem() {
3253 RegisterPepperExtensionDelegate();
3257 EwkExtensionSystemDelegate* EWebView::GetExtensionDelegate() {
3258 RenderFrameHost* render_frame_host = web_contents_->GetPrimaryMainFrame();
3259 if (!render_frame_host)
3262 ExtensionSystemDelegateManager::RenderFrameID id;
3263 id.render_process_id = render_frame_host->GetProcess()->GetID();
3264 id.render_frame_id = render_frame_host->GetRoutingID();
3265 return static_cast<EwkExtensionSystemDelegate*>(
3266 ExtensionSystemDelegateManager::GetInstance()->GetDelegateForFrame(id));
3269 void EWebView::SetWindowId() {
3270 EwkExtensionSystemDelegate* delegate = GetExtensionDelegate();
3272 LOG(WARNING) << "No delegate is available to set window id";
3275 Evas_Object* main_wind =
3276 efl::WindowFactory::GetHostWindow(web_contents_.get());
3278 LOG(ERROR) << "Can`t get main window";
3281 delegate->SetWindowId(main_wind);
3284 void EWebView::SetPepperExtensionWidgetInfo(Ewk_Value widget_pepper_ext_info) {
3285 EwkExtensionSystemDelegate* delegate = GetExtensionDelegate();
3287 LOG(WARNING) << "No delegate is available to set extension info";
3290 delegate->SetExtensionInfo(widget_pepper_ext_info);
3293 void EWebView::SetPepperExtensionCallback(Generic_Sync_Call_Callback cb,
3295 EwkExtensionSystemDelegate* delegate = GetExtensionDelegate();
3297 LOG(WARNING) << "No delegate is available to set generic callback";
3300 delegate->SetGenericSyncCallback(cb, data);
3303 void EWebView::RegisterPepperExtensionDelegate() {
3304 RenderFrameHost* render_frame_host = web_contents_->GetPrimaryMainFrame();
3305 if (!render_frame_host) {
3306 LOG(WARNING) << "render_frame_host is nullptr, can't register delegate";
3310 ExtensionSystemDelegateManager::RenderFrameID id;
3311 id.render_process_id = render_frame_host->GetProcess()->GetID();
3312 id.render_frame_id = render_frame_host->GetRoutingID();
3314 EwkExtensionSystemDelegate* delegate = new EwkExtensionSystemDelegate;
3315 ExtensionSystemDelegateManager::GetInstance()->RegisterDelegate(
3316 id, std::unique_ptr<EwkExtensionSystemDelegate>{delegate});
3319 void EWebView::UnregisterPepperExtensionDelegate() {
3320 if (!web_contents_) {
3321 LOG(WARNING) << "web_contents_ is nullptr, can't unregister delegate";
3324 RenderFrameHost* render_frame_host = web_contents_->GetPrimaryMainFrame();
3325 if (!render_frame_host) {
3326 LOG(WARNING) << "render_frame_host is nullptr, can't unregister delegate";
3330 ExtensionSystemDelegateManager::RenderFrameID id;
3331 id.render_process_id = render_frame_host->GetProcess()->GetID();
3332 id.render_frame_id = render_frame_host->GetRoutingID();
3334 if (!ExtensionSystemDelegateManager::GetInstance()->UnregisterDelegate(id))
3335 LOG(WARNING) << "Unregistering pepper extension delegate failed";
3337 #endif // defined(TIZEN_PEPPER_EXTENSIONS)
3339 void EWebView::SetExceededIndexedDatabaseQuotaCallback(
3340 Ewk_View_Exceeded_Indexed_Database_Quota_Callback callback,
3342 exceeded_indexed_db_quota_callback_.Set(callback, user_data);
3343 content::BrowserContextEfl* browser_context =
3344 static_cast<content::BrowserContextEfl*>(
3345 web_contents_->GetBrowserContext());
3346 if (browser_context) {
3347 browser_context->GetSpecialStoragePolicyEfl()->SetQuotaExceededCallback(
3348 base::BindOnce(&EWebView::InvokeExceededIndexedDatabaseQuotaCallback,
3349 base::Unretained(this)));
3353 void EWebView::InvokeExceededIndexedDatabaseQuotaCallback(
3355 int64_t current_quota) {
3356 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
3357 content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
3358 base::BindOnce(&EWebView::InvokeExceededIndexedDatabaseQuotaCallback,
3359 base::Unretained(this), origin, current_quota));
3362 LOG(INFO) << __func__ << "()" << origin << ", " << current_quota;
3363 CHECK(!exceeded_indexed_db_quota_origin_.get());
3364 exceeded_indexed_db_quota_origin_.reset(new Ewk_Security_Origin(origin));
3365 exceeded_indexed_db_quota_callback_.Run(
3366 evas_object_, exceeded_indexed_db_quota_origin_.get(), current_quota);
3369 void EWebView::ExceededIndexedDatabaseQuotaReply(bool allow) {
3370 if (!exceeded_indexed_db_quota_origin_.get()) {
3371 LOG(WARNING) << __func__ << "() : callback is not invoked!";
3374 LOG(INFO) << __func__ << "()" << exceeded_indexed_db_quota_origin_->GetURL()
3376 content::BrowserContextEfl* browser_context =
3377 static_cast<content::BrowserContextEfl*>(
3378 web_contents_->GetBrowserContext());
3379 if (browser_context) {
3380 browser_context->GetSpecialStoragePolicyEfl()->SetUnlimitedStoragePolicy(
3381 exceeded_indexed_db_quota_origin_->GetURL(), allow);
3383 exceeded_indexed_db_quota_origin_.reset();
3386 bool EWebView::ShouldIgnoreNavigation(
3387 content::NavigationHandle* navigation_handle) {
3388 if (!navigation_handle->GetURL().is_valid() ||
3389 !navigation_handle->GetURL().SchemeIs("appcontrol") ||
3390 (!navigation_handle->HasUserGesture() &&
3391 !navigation_handle->WasServerRedirect())) {
3395 _Ewk_App_Control app_control(
3396 this, navigation_handle->GetURL().possibly_invalid_spec());
3397 return app_control.Proceed();
3400 #if BUILDFLAG(IS_TIZEN_TV)
3401 void EWebView::AddDynamicCertificatePath(const std::string& host,
3402 const std::string& cert_path) {
3403 web_contents_->AddDynamicCertificatePath(host, cert_path);
3407 bool EWebView::SetVisibility(bool enable) {
3412 web_contents_->WasShown();
3414 web_contents_->WasHidden();
3419 void EWebView::SetDoNotTrack(Eina_Bool enable) {
3420 // enable: 0 User tend to allow tracking on the target site.
3421 // enable: 1 User tend to not be tracked on the target site.
3422 if (web_contents_->GetMutableRendererPrefs()->enable_do_not_track == enable)
3425 // Set navigator.doNotTrack attribute
3426 web_contents_->GetMutableRendererPrefs()->enable_do_not_track = enable;
3427 web_contents_->SyncRendererPrefs();
3429 // Set or remove DNT HTTP header, the effects will depend on design of target
3435 context()->HTTPCustomHeaderAdd("DNT", "1");
3437 context()->HTTPCustomHeaderRemove("DNT");
3440 #if defined(TIZEN_ATK_SUPPORT)
3441 void EWebView::UpdateSpatialNavigationStatus(Eina_Bool enable) {
3442 if (settings_->getPreferences().spatial_navigation_enabled == enable)
3445 settings_->getPreferences().spatial_navigation_enabled = enable;
3446 WebContentsImpl* wc = static_cast<WebContentsImpl*>(web_contents_.get());
3448 wc->SetSpatialNavigationEnabled(enable);
3451 void EWebView::UpdateAccessibilityStatus(Eina_Bool enable) {
3452 if (settings_->getPreferences().atk_enabled == enable)
3455 settings_->getPreferences().atk_enabled = enable;
3456 WebContentsImpl* wc = static_cast<WebContentsImpl*>(web_contents_.get());
3458 wc->SetAtkEnabled(enable);
3461 void EWebView::InitAtk() {
3462 EWebAccessibilityUtil::GetInstance()->ToggleAtk(lazy_initialize_atk_);
3465 /* LCOV_EXCL_START */
3466 bool EWebView::GetAtkStatus() {
3467 auto state = content::BrowserAccessibilityStateImpl::GetInstance();
3470 return state->IsAccessibleBrowser();
3472 /* LCOV_EXCL_STOP */
3475 #if BUILDFLAG(IS_TIZEN_TV)
3476 bool EWebView::SetMixedContents(bool allow) {
3477 MixedContentObserver* mixed_content_observer =
3478 MixedContentObserver::FromWebContents(web_contents_.get());
3479 return mixed_content_observer->MixedContentReply(allow);