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/command_line.h"
12 #include "base/files/file_path.h"
13 #include "base/files/file_util.h"
14 #include "base/functional/bind.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/thread_pool.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/scoped_allow_wait_for_legacy_web_view_api.h"
25 #include "browser/select_picker/select_picker_mobile.h"
26 #include "browser/select_picker/select_picker_tv.h"
27 #include "browser/web_view_browser_message_filter.h"
28 #include "browser/web_view_evas_handler.h"
29 #include "browser_context_efl.h"
30 #include "common/content_client_efl.h"
31 #include "common/render_messages_ewk.h"
32 #include "common/version_info.h"
33 #include "common/web_contents_utils.h"
34 #include "components/sessions/content/content_serialized_navigation_builder.h"
35 #include "components/sessions/core/serialized_navigation_entry.h"
36 #include "content/browser/renderer_host/render_view_host_impl.h"
37 #include "content/browser/renderer_host/render_widget_host_view_aura.h"
38 #include "content/browser/renderer_host/ui_events_helper.h"
39 #include "content/browser/web_contents/web_contents_impl_efl.h"
40 #include "content/browser/web_contents/web_contents_view.h"
41 #include "content/browser/web_contents/web_contents_view_aura.h"
42 #include "content/browser/web_contents/web_contents_view_aura_helper_efl.h"
43 #include "content/common/content_client_export.h"
44 #include "content/public/browser/browser_message_filter.h"
45 #include "content/public/browser/browser_task_traits.h"
46 #include "content/public/browser/browser_thread.h"
47 #include "content/public/browser/host_zoom_map.h"
48 #include "content/public/browser/navigation_controller.h"
49 #include "content/public/browser/navigation_entry.h"
50 #include "content/public/browser/navigation_handle.h"
51 #include "content/public/common/content_client.h"
52 #include "content/public/common/content_switches.h"
53 #include "content/public/common/mhtml_generation_params.h"
54 #include "content/public/common/user_agent.h"
55 #include "net/base/filename_util.h"
56 #include "permission_popup_manager.cc"
57 #include "private/ewk_app_control_private.h"
58 #include "private/ewk_back_forward_list_private.h"
59 #include "private/ewk_context_private.h"
60 #include "private/ewk_frame_private.h"
61 #include "private/ewk_policy_decision_private.h"
62 #include "private/ewk_quota_permission_request_private.h"
63 #include "private/ewk_settings_private.h"
64 #include "private/webview_delegate_ewk.h"
65 #include "public/ewk_hit_test_internal.h"
66 #include "services/network/public/cpp/features.h"
67 #include "services/network/public/cpp/resource_request_body.h"
68 #include "services/network/public/mojom/network_context.mojom.h"
69 #include "skia/ext/platform_canvas.h"
70 #include "third_party/blink/public/common/page/page_zoom.h"
71 #include "third_party/blink/public/platform/web_string.h"
72 #include "tizen/system_info.h"
73 #include "ui/aura/env.h"
74 #include "ui/aura/test/test_focus_client.h"
75 #include "ui/aura/test/test_window_parenting_client.h"
76 #include "ui/aura/window.h"
77 #include "ui/base/clipboard/clipboard_helper_efl.h"
78 #include "ui/base/l10n/l10n_util.h"
79 #include "ui/compositor/compositor_observer_efl.h"
80 #include "ui/display/screen.h"
81 #include "ui/events/event_switches.h"
82 #include "ui/gfx/geometry/dip_util.h"
83 #include "ui/gfx/geometry/vector2d_f.h"
84 #include "ui/ozone/platform/efl/efl_event_handler.h"
85 #include "ui/platform_window/platform_window_init_properties.h"
86 #include "web_contents_delegate_efl.h"
87 #include "webview_delegate_efl.h"
91 #if defined(TIZEN_ATK_SUPPORT)
92 #include "content/browser/accessibility/browser_accessibility_state_impl.h"
93 #include "eweb_accessibility.h"
94 #include "eweb_accessibility_util.h"
97 #if defined(TIZEN_AUTOFILL_FW)
98 #include "browser/autofill/autofill_request_manager.h"
99 #include "components/autofill/core/common/autofill_switches.h"
102 #if BUILDFLAG(IS_TIZEN_TV)
103 #include "common/application_type.h"
104 #include "devtools_port_manager.h"
105 #include "public/ewk_media_downloadable_font_info.h"
106 #include "browser/mixed_content_observer.h"
109 #if defined(TIZEN_PEPPER_EXTENSIONS)
110 #include "efl/window_factory.h"
111 #include "ewk/efl_integration/ewk_privilege_checker.h"
112 #endif // defined(TIZEN_PEPPER_EXTENSIONS)
114 #if defined(USE_WAYLAND) && defined(TIZEN_PEPPER_EXTENSIONS)
115 #include <Ecore_Wayland.h>
116 #endif // defined(USE_WAYLAND)
118 #if defined(TIZEN_TBM_SUPPORT)
119 #include "ui/compositor/compositor.h"
122 using namespace content;
123 using web_contents_utils::WebViewFromWebContents;
127 const int kTitleLengthMax = 80;
128 const base::FilePath::CharType kMHTMLFileNameExtension[] =
129 FILE_PATH_LITERAL(".mhtml");
130 const base::FilePath::CharType kMHTMLExtension[] = FILE_PATH_LITERAL("mhtml");
131 const base::FilePath::CharType kDefaultFileName[] =
132 FILE_PATH_LITERAL("saved_page");
133 const char kReplaceChars[] = " ";
134 const char kReplaceWith[] = "_";
136 static const char* kRendererCrashedHTMLMessage =
137 "<html><body><h1>Renderer process has crashed!</h1></body></html>";
139 // "visible,content,changed" is an email-app specific signal which informs
140 // that the web view is only partially visible.
141 static const char* kVisibleContentChangedSignalName = "visible,content,changed";
143 // email-app specific signal which informs that custom scrolling is started.
144 const char* kCustomScrollBeginSignalName = "custom,scroll,begin";
146 // email-app specific signal which informs that custom scrolling is finished.
147 const char* kCustomScrollEndSignalName = "custom,scroll,end";
149 const float kDelayShowContextMenuTime = 0.2f;
151 inline void SetDefaultStringIfNull(const char*& variable,
152 const char* default_string) {
154 variable = default_string;
158 void GetEinaRectFromGfxRect(const gfx::Rect& gfx_rect,
159 Eina_Rectangle* eina_rect) {
160 eina_rect->x = gfx_rect.x();
161 eina_rect->y = gfx_rect.y();
162 eina_rect->w = gfx_rect.width();
163 eina_rect->h = gfx_rect.height();
166 #if BUILDFLAG(IS_TIZEN)
167 static Eina_Bool RotateWindowCb(void* data, int type, void* event) {
168 auto wv = static_cast<EWebView*>(data);
170 ecore_evas_rotation_get(ecore_evas_ecore_evas_get(wv->GetEvas())));
171 return ECORE_CALLBACK_PASS_ON;
175 static content::WebContents* NullCreateWebContents(void*) {
179 base::FilePath GenerateMHTMLFilePath(const GURL& url,
180 const std::string& title,
181 const std::string& base_path) {
182 base::FilePath file_path(base_path);
184 if (base::DirectoryExists(file_path)) {
185 std::string title_part(title.substr(0, kTitleLengthMax));
186 base::ReplaceChars(title_part, kReplaceChars, kReplaceWith, &title_part);
187 base::FilePath file_name =
188 net::GenerateFileName(url, std::string(), std::string(), title_part,
189 std::string(), kDefaultFileName);
190 DCHECK(!file_name.empty());
191 file_path = file_path.Append(file_name);
194 if (file_path.Extension().empty())
195 file_path = file_path.AddExtension(kMHTMLExtension);
196 else if (!file_path.MatchesExtension(kMHTMLFileNameExtension))
197 file_path = file_path.ReplaceExtension(kMHTMLExtension);
199 if (!base::PathExists(file_path))
202 int uniquifier = base::GetUniquePathNumber(file_path);
203 if (uniquifier > 0) {
204 return file_path.InsertBeforeExtensionASCII(
205 base::StringPrintf(" (%d)", uniquifier));
208 return base::FilePath();
211 SelectPickerBase* CreateSelectPicker(
214 std::vector<blink::mojom::MenuItemPtr> items,
215 bool is_multiple_selection,
216 const gfx::Rect& bounds) {
217 SelectPickerBase* picker;
220 new SelectPickerTv(web_view, selected_index, is_multiple_selection);
223 new SelectPickerMobile(web_view, selected_index, is_multiple_selection);
225 // Create two separate Elm_Genlist_Item_Class classes, because EFL cannot swap
226 // item_style at runtime.
227 picker->InitializeItemClass();
228 picker->InitializeGroupClass();
229 picker->Init(std::move(items), bounds);
235 class WebViewAsyncRequestHitTestDataCallback {
237 WebViewAsyncRequestHitTestDataCallback(int x, int y, Ewk_Hit_Test_Mode mode)
238 : x_(x), y_(y), mode_(mode) {}
239 virtual ~WebViewAsyncRequestHitTestDataCallback(){};
241 virtual void Run(_Ewk_Hit_Test* hit_test, EWebView* web_view) = 0;
244 int GetX() const { return x_; }
245 int GetY() const { return y_; }
246 Ewk_Hit_Test_Mode GetMode() const { return mode_; }
251 Ewk_Hit_Test_Mode mode_;
254 class WebViewAsyncRequestHitTestDataUserCallback
255 : public WebViewAsyncRequestHitTestDataCallback {
257 WebViewAsyncRequestHitTestDataUserCallback(
260 Ewk_Hit_Test_Mode mode,
261 Ewk_View_Hit_Test_Request_Callback callback,
263 : WebViewAsyncRequestHitTestDataCallback(x, y, mode),
265 user_data_(user_data) {}
267 void Run(_Ewk_Hit_Test* hit_test, EWebView* web_view) override {
269 callback_(web_view->evas_object(), GetX(), GetY(), GetMode(), hit_test,
274 Ewk_View_Hit_Test_Request_Callback callback_;
278 #if defined(TIZEN_ATK_SUPPORT)
279 class EWebAccessibilityObserver : public EWebAccessibility::Observer {
281 explicit EWebAccessibilityObserver(EWebView* webview) : webview_(webview) {}
282 virtual ~EWebAccessibilityObserver() {}
284 // EWebAccessibility::Observer implementation
285 void OnSpatialNavigationStatusChanged(Eina_Bool enable) override {
286 webview_->UpdateSpatialNavigationStatus(enable);
289 void OnAccessibilityStatusChanged(Eina_Bool enable) override {
290 webview_->UpdateAccessibilityStatus(enable);
298 int EWebView::find_request_id_counter_ = 0;
299 content::WebViewDelegate::WebContentsCreateCallback
300 EWebView::create_new_window_web_contents_cb_ =
301 base::BindRepeating(&NullCreateWebContents);
303 EWebView* EWebView::FromEvasObject(Evas_Object* eo) {
304 return WebViewDelegateEwk::GetInstance().GetWebViewFromEvasObject(eo);
307 void EWebView::OnViewFocusIn(void* data, Evas*, Evas_Object*, void*) {
308 auto view = static_cast<EWebView*>(data);
309 view->SetFocus(EINA_TRUE);
312 void EWebView::OnViewFocusOut(void* data, Evas*, Evas_Object*, void*) {
313 auto view = static_cast<EWebView*>(data);
314 view->SetFocus(EINA_FALSE);
317 void EWebView::VisibleContentChangedCallback(void* user_data,
318 Evas_Object* /*object*/,
320 auto view = static_cast<EWebView*>(user_data);
321 auto rect = static_cast<Eina_Rectangle*>(event_info);
322 view->GetSelectionController()->SetCustomVisibleViewRect(
323 gfx::Rect(rect->x, rect->y, rect->w, rect->h));
326 void EWebView::OnCustomScrollBeginCallback(void* user_data,
327 Evas_Object* /*object*/,
328 void* /*event_info*/) {
329 auto* view = static_cast<EWebView*>(user_data);
330 if (auto* selection_controller = view->GetSelectionController())
331 selection_controller->SetControlsTemporarilyHidden(true,true);
334 void EWebView::OnCustomScrollEndCallback(void* user_data,
335 Evas_Object* /*object*/,
336 void* /*event_info*/) {
337 auto* view = static_cast<EWebView*>(user_data);
338 if (auto* selection_controller = view->GetSelectionController())
339 selection_controller->SetControlsTemporarilyHidden(false,true);
342 EWebView::EWebView(Ewk_Context* context, Evas_Object* object)
344 evas_object_(object),
345 native_view_(object),
346 mouse_events_enabled_(false),
347 text_zoom_factor_(1.0),
348 current_find_request_id_(find_request_id_counter_++),
350 hit_test_completion_(base::WaitableEvent::ResetPolicy::AUTOMATIC,
351 base::WaitableEvent::InitialState::NOT_SIGNALED),
352 page_scale_factor_(1.0),
355 #if BUILDFLAG(IS_TIZEN_TV)
356 is_processing_edge_scroll_(false),
357 use_early_rwi_(false),
358 rwi_info_showed_(false),
360 #if defined(TIZEN_PEPPER_EXTENSIONS)
361 render_frame_id_{0, 0},
363 is_initialized_(false) {
364 LOG(INFO) << "EWebView: " << this;
366 evas_object_smart_callback_add(evas_object_,
367 kVisibleContentChangedSignalName,
368 VisibleContentChangedCallback, this);
370 evas_object_smart_callback_add(evas_object_, kCustomScrollBeginSignalName,
371 OnCustomScrollBeginCallback, this);
372 evas_object_smart_callback_add(evas_object_, kCustomScrollEndSignalName,
373 OnCustomScrollEndCallback, this);
374 evas_object_event_callback_add(evas_object_, EVAS_CALLBACK_FOCUS_IN,
375 OnViewFocusIn, this);
376 evas_object_event_callback_add(evas_object_, EVAS_CALLBACK_FOCUS_OUT,
377 OnViewFocusOut, this);
378 #if BUILDFLAG(IS_TIZEN)
379 window_rotate_handler_ = ecore_event_handler_add(
380 ECORE_WL2_EVENT_WINDOW_ROTATE, RotateWindowCb, this);
385 void EWebView::Initialize() {
386 if (is_initialized_) {
392 evas_event_handler_ = new WebViewEvasEventHandler(this);
394 scroll_detector_.reset(new ScrollDetector(this));
396 #if defined(TIZEN_PEPPER_EXTENSIONS)
397 InitializePepperExtensionSystem();
399 DCHECK(web_contents_->GetRenderViewHost());
400 // Settings (content::WebPreferences) will be initalized by
401 // RenderViewHostImpl::ComputeWebkitPrefs() based on command line switches.
402 settings_.reset(new Ewk_Settings(evas_object_,
403 web_contents_->GetOrCreateWebPreferences()));
404 #if defined(TIZEN_ATK_SUPPORT)
405 std::unique_ptr<EWebAccessibilityObserver> observer(
406 new EWebAccessibilityObserver(this));
407 eweb_accessibility_.reset(new EWebAccessibility(
408 evas_object_, web_contents_.get(), std::move(observer)));
409 lazy_initialize_atk_ = true;
412 base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess();
413 if (cmdline->HasSwitch(switches::kTouchEventFeatureDetection)) {
414 SetTouchEventsEnabled(
415 cmdline->GetSwitchValueASCII(switches::kTouchEventFeatureDetection) ==
416 switches::kTouchEventFeatureDetectionEnabled);
418 SetMouseEventsEnabled(true);
421 std::string user_agent =
422 EflWebView::VersionInfo::GetInstance()->DefaultUserAgent();
423 web_contents_->SetUserAgentOverride(
424 blink::UserAgentOverride::UserAgentOnly(user_agent),
425 false /* override_in_new_tabs */);
427 elm_object_tree_focus_allow_set(native_view_, EINA_TRUE);
428 is_initialized_ = true;
429 evas_object_event_callback_add(native_view_, EVAS_CALLBACK_RESIZE,
430 EWebView::NativeViewResize, this);
432 auto cbce = static_cast<ContentBrowserClientEfl*>(
433 content::GetContentClientExport()->browser());
434 // Initialize accept languages
435 SyncAcceptLanguages(cbce->GetAcceptLangs(nullptr));
436 accept_langs_changed_callback_ = base::BindRepeating(
437 &EWebView::SyncAcceptLanguages, base::Unretained(this));
438 cbce->AddAcceptLangsChangedCallback(accept_langs_changed_callback_);
440 // If EWebView is created by window.open, RenderView is already created
441 // before initializing WebContents. So we should manually invoke
442 // EWebView::RenderViewReady here.
443 if (web_contents_->GetPrimaryMainFrame() &&
444 web_contents_->GetPrimaryMainFrame()->IsRenderFrameLive()) {
449 EWebView::~EWebView() {
450 LOG(INFO) << "EWebView: " << this;
451 auto cbce = static_cast<ContentBrowserClientEfl*>(
452 content::GetContentClientExport()->browser());
453 cbce->RemoveAcceptLangsChangedCallback(accept_langs_changed_callback_);
454 #if defined(TIZEN_PEPPER_EXTENSIONS)
455 UnregisterPepperExtensionDelegate();
458 evas_object_event_callback_del(native_view_, EVAS_CALLBACK_RESIZE,
459 EWebView::NativeViewResize);
460 #if defined(USE_WAYLAND)
461 if (GetSettings()->getClipboardEnabled())
462 ClipboardHelperEfl::GetInstance()->MaybeInvalidateActiveWebview(this);
465 std::map<int64_t, WebViewAsyncRequestHitTestDataCallback*>::iterator
466 hit_test_callback_iterator;
467 for (hit_test_callback_iterator = hit_test_callback_.begin();
468 hit_test_callback_iterator != hit_test_callback_.end();
469 hit_test_callback_iterator++)
470 delete hit_test_callback_iterator->second;
471 hit_test_callback_.clear();
473 for (auto iter = delayed_messages_.begin(); iter != delayed_messages_.end();
477 delayed_messages_.clear();
479 if (!is_initialized_) {
483 #if defined(TIZEN_ATK_SUPPORT)
484 eweb_accessibility_.reset();
487 #if defined(TIZEN_AUTOFILL_FW)
488 if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
489 autofill::switches::kDisableAutofill)) {
490 autofill::AutofillRequestManager::GetInstance()->RemoveRequest(
495 select_picker_.reset();
496 context_menu_.reset();
497 mhtml_callback_map_.Clear();
499 compositor_observer_.reset();
501 // Release manually those scoped pointers to
502 // make sure they are released in correct order
503 web_contents_.reset();
504 web_contents_delegate_.reset();
506 // This code must be executed after WebContents deletion
507 // because WebContents depends on BrowserContext which
508 // is deleted along with EwkContext.
509 CHECK(!web_contents_);
511 permission_popup_manager_.reset();
513 gin_native_bridge_dispatcher_host_.reset();
516 evas_object_event_callback_del(evas_object_, EVAS_CALLBACK_FOCUS_IN,
518 evas_object_event_callback_del(evas_object_, EVAS_CALLBACK_FOCUS_OUT,
520 evas_object_smart_callback_del(evas_object_,
521 kVisibleContentChangedSignalName,
522 VisibleContentChangedCallback);
523 evas_object_smart_callback_del(evas_object_, kCustomScrollBeginSignalName,
524 OnCustomScrollBeginCallback);
525 evas_object_smart_callback_del(evas_object_, kCustomScrollEndSignalName,
526 OnCustomScrollEndCallback);
527 #if BUILDFLAG(IS_TIZEN)
528 if (window_rotate_handler_)
529 ecore_event_handler_del(window_rotate_handler_);
534 content::RenderWidgetHostViewAura* EWebView::rwhva() const {
535 return static_cast<content::RenderWidgetHostViewAura*>(
536 web_contents_->GetRenderWidgetHostView());
539 content::WebContentsViewAura* EWebView::wcva() const {
540 WebContentsImpl* wc = static_cast<WebContentsImpl*>(web_contents_.get());
541 return static_cast<WebContentsViewAura*>(wc->GetView());
544 void EWebView::NativeViewResize(void* data,
548 auto thiz = static_cast<EWebView*>(data);
549 if (!thiz->context_menu_)
551 int native_view_x, native_view_y, native_view_width, native_view_height;
552 evas_object_geometry_get(obj, &native_view_x, &native_view_y,
553 &native_view_width, &native_view_height);
554 gfx::Rect webview_rect(native_view_x, native_view_y, native_view_width,
556 thiz->context_menu_->Resize(webview_rect);
559 void EWebView::ResetContextMenuController() {
560 return context_menu_.reset();
563 #if BUILDFLAG(IS_TIZEN_TV)
564 void EWebView::RunPendingSetFocus(Eina_Bool focus) {
565 if (!web_contents_ || !rwhva() || (HasFocus() == focus))
567 rwhva()->offscreen_helper()->Focus(focus);
571 void EWebView::SetFocus(Eina_Bool focus) {
572 if (!web_contents_ || !rwhva() || (HasFocus() == focus))
575 #if BUILDFLAG(IS_TIZEN_TV)
576 if (web_contents_->GetPrimaryMainFrame()->IsRenderFrameLive()) {
577 rwhva()->offscreen_helper()->Focus(focus);
579 if (pending_setfocus_closure_)
580 pending_setfocus_closure_.Reset();
582 LOG(ERROR) << "SEND DELAY SET FOCUS BIND";
583 pending_setfocus_closure_ = base::BindOnce(&EWebView::RunPendingSetFocus,
584 base::Unretained(this), focus);
587 rwhva()->offscreen_helper()->Focus(focus);
591 Eina_Bool EWebView::HasFocus() const {
595 return rwhva()->offscreen_helper()->HasFocus() ? EINA_TRUE : EINA_FALSE;
598 Eina_Bool EWebView::AddJavaScriptMessageHandler(
600 Ewk_View_Script_Message_Cb callback,
602 if (!gin_native_bridge_dispatcher_host_)
605 return gin_native_bridge_dispatcher_host_->AddNamedObject(view, callback,
609 bool EWebView::SetPageVisibility(
610 Ewk_Page_Visibility_State page_visibility_state) {
614 // TODO: We should able to set 'prerender' or 'unloaded' as visibility state.
615 // http://www.w3.org/TR/page-visibility/#dom-document-visibilitystate
616 switch (page_visibility_state) {
617 case EWK_PAGE_VISIBILITY_STATE_VISIBLE:
618 rwhva()->offscreen_helper()->SetPageVisibility(true);
620 case EWK_PAGE_VISIBILITY_STATE_HIDDEN:
621 rwhva()->offscreen_helper()->SetPageVisibility(false);
623 case EWK_PAGE_VISIBILITY_STATE_PRERENDER:
633 bool EWebView::CreateNewWindow(
634 content::WebViewDelegate::WebContentsCreateCallback cb) {
635 create_new_window_web_contents_cb_ = cb;
636 Evas_Object* new_object = NULL;
637 SmartCallback<EWebViewCallbacks::CreateNewWindow>().call(&new_object);
638 create_new_window_web_contents_cb_ =
639 base::BindRepeating(&NullCreateWebContents);
644 Evas_Object* EWebView::GetHostWindowDelegate(const content::WebContents* wc) {
645 EWebView* thiz = WebViewFromWebContents(wc);
646 DCHECK(thiz->evas_object_);
647 Evas_Object* parent = evas_object_above_get(thiz->evas_object_);
649 LOG(WARNING) << "Could not find and visual parents for EWK smart object!.";
650 return thiz->evas_object_;
653 if (elm_object_widget_check(parent)) {
654 Evas_Object* elm_parent = elm_object_top_widget_get(parent);
660 LOG(WARNING) << "Could not find elementary parent for WebView object!";
661 return thiz->evas_object_;
664 Evas_Object* EWebView::GetElmWindow() const {
665 Evas_Object* parent = elm_object_parent_widget_get(evas_object_);
666 return parent ? elm_object_top_widget_get(parent) : nullptr;
669 void EWebView::SetURL(const GURL& url, bool from_api) {
670 NavigationController::LoadURLParams params(url);
673 params.transition_type = ui::PageTransitionFromInt(
674 ui::PAGE_TRANSITION_LINK | ui::PAGE_TRANSITION_FROM_API);
677 #if BUILDFLAG(IS_TIZEN_TV)
678 if (use_early_rwi_) {
679 LOG(INFO) << "[FAST RWI] SetURL Replace [" << url.spec()
680 << "] to [about:blank]";
682 params.url = GURL("about:blank");
686 params.override_user_agent = NavigationController::UA_OVERRIDE_TRUE;
687 web_contents_->GetController().LoadURLWithParams(params);
690 const GURL& EWebView::GetURL() const {
691 return web_contents_->GetVisibleURL();
694 const GURL& EWebView::GetOriginalURL() const {
695 const auto entry = web_contents_->GetController().GetVisibleEntry();
697 return entry->GetOriginalRequestURL();
699 return web_contents_->GetVisibleURL();
702 void EWebView::Reload() {
703 web_contents_->GetController().Reload(content::ReloadType::NORMAL, true);
706 void EWebView::ReloadBypassingCache() {
707 web_contents_->GetController().Reload(content::ReloadType::BYPASSING_CACHE,
711 Eina_Bool EWebView::CanGoBack() {
712 return web_contents_->GetController().CanGoBack();
715 Eina_Bool EWebView::CanGoForward() {
716 return web_contents_->GetController().CanGoForward();
719 Eina_Bool EWebView::GoBack() {
720 if (!web_contents_->GetController().CanGoBack())
723 #if defined(TIZEN_AUTOFILL_FW)
724 if (web_contents_delegate_)
725 web_contents_delegate_->ResetLastInteractedElements();
728 web_contents_->GetController().GoBack();
732 Eina_Bool EWebView::GoForward() {
733 if (!web_contents_->GetController().CanGoForward())
736 web_contents_->GetController().GoForward();
740 void EWebView::Stop() {
741 if (web_contents_->IsLoading())
742 web_contents_->Stop();
745 void EWebView::Suspend() {
746 #if BUILDFLAG(IS_TIZEN)
747 CHECK(web_contents_);
748 if (IsMobileProfile() && web_contents_->IsFullscreen())
749 web_contents_->ExitFullscreen(true);
750 RenderViewHost* rvh = web_contents_->GetRenderViewHost();
751 RenderFrameHost* rfh = web_contents_->GetPrimaryMainFrame();
754 if (rvh->IsRenderViewLive()) {
755 RenderWidgetHostImpl* rwhi = static_cast<RenderWidgetHostImpl*>(rvh->GetWidget());
756 rwhi->PauseScheduledTasks();
761 void EWebView::Resume() {
762 #if BUILDFLAG(IS_TIZEN)
763 CHECK(web_contents_);
764 RenderViewHost* rvh = web_contents_->GetRenderViewHost();
765 RenderFrameHost* rfh = web_contents_->GetPrimaryMainFrame();
768 if (rvh->IsRenderViewLive() && rwhva())
769 rwhva()->host()->UnPauseScheduledTasks();
773 #if BUILDFLAG(IS_TIZEN_TV)
774 void EWebView::SetFloatVideoWindowState(bool enabled) {
775 RenderWidgetHostImpl* rwhi = static_cast<RenderWidgetHostImpl*>(
776 web_contents_->GetRenderViewHost()->GetWidget());
778 rwhi->SetFloatVideoWindowState(enabled);
780 #endif // IS_TIZEN_TV
782 double EWebView::GetTextZoomFactor() const {
783 if (text_zoom_factor_ < 0.0)
786 return text_zoom_factor_;
789 void EWebView::SetTextZoomFactor(double text_zoom_factor) {
790 if (text_zoom_factor_ == text_zoom_factor || text_zoom_factor < 0.0)
793 text_zoom_factor_ = text_zoom_factor;
794 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
795 if (!render_view_host)
797 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
798 render_view_host->Send(new ViewMsg_SetTextZoomFactor(
799 render_view_host->GetRoutingID(), text_zoom_factor));
803 double EWebView::GetPageZoomFactor() const {
804 return blink::PageZoomLevelToZoomFactor(
805 content::HostZoomMap::GetZoomLevel(web_contents_.get()));
808 void EWebView::SetPageZoomFactor(double page_zoom_factor) {
809 content::HostZoomMap::SetZoomLevel(
810 web_contents_.get(), blink::PageZoomFactorToZoomLevel(page_zoom_factor));
813 void EWebView::ExecuteEditCommand(const char* command, const char* value) {
814 EINA_SAFETY_ON_NULL_RETURN(command);
816 absl::optional<std::u16string> optional_value;
818 optional_value = absl::make_optional(base::ASCIIToUTF16(value));
820 WebContentsImpl* wc = static_cast<WebContentsImpl*>(web_contents_.get());
821 if (!wc || !wc->GetFocusedFrameWidgetInputHandler())
824 wc->GetFocusedFrameWidgetInputHandler()->ExecuteEditCommand(
825 std::string(command), optional_value);
828 #if BUILDFLAG(IS_TIZEN)
829 void EWebView::EnterDragState() {
830 if (IsMobileProfile()) {
831 if (RenderViewHost* render_view_host = web_contents_->GetRenderViewHost())
832 web_contents_->EnterDragState(render_view_host);
837 void EWebView::SetOrientation(int orientation) {
838 if (GetOrientation() == orientation)
841 if (orientation == 0 || orientation == 90 || orientation == 180 ||
842 orientation == 270) {
843 #if !defined(USE_AURA)
844 GetWebContentsViewEfl()->SetOrientation(orientation);
848 const Ecore_Evas* ee =
849 ecore_evas_ecore_evas_get(evas_object_evas_get(evas_object_));
850 ecore_evas_screen_geometry_get(ee, nullptr, nullptr, &width, &height);
851 if (orientation == 90 || orientation == 270)
852 std::swap(width, height);
854 if (popup_controller_)
855 popup_controller_->SetPopupSize(width, height);
856 if (JavaScriptDialogManagerEfl* dialogMG = GetJavaScriptDialogManagerEfl())
857 dialogMG->SetPopupSize(width, height);
861 int EWebView::GetOrientation() {
862 #if !defined(USE_AURA)
863 return GetWebContentsViewEfl()->GetOrientation();
869 void EWebView::Show() {
870 evas_object_show(native_view_);
871 web_contents_->WasShown();
874 void EWebView::Hide() {
875 LOG(INFO) << "EWebView: " << this;
876 evas_object_hide(native_view_);
879 web_contents_->WasHidden();
882 void EWebView::SetViewAuthCallback(Ewk_View_Authentication_Callback callback,
884 authentication_cb_.Set(callback, user_data);
887 void EWebView::InvokeAuthCallback(LoginDelegateEfl* login_delegate,
889 const std::string& realm) {
890 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
892 auth_challenge_.reset(new _Ewk_Auth_Challenge(login_delegate, url, realm));
893 authentication_cb_.Run(evas_object_, auth_challenge_.get());
895 if (!auth_challenge_->is_decided && !auth_challenge_->is_suspended) {
896 auth_challenge_->is_decided = true;
897 auth_challenge_->login_delegate->Cancel();
901 void EWebView::InvokePolicyResponseCallback(
902 _Ewk_Policy_Decision* policy_decision,
904 SmartCallback<EWebViewCallbacks::PolicyResponseDecide>().call(
907 if (policy_decision->isSuspended()) {
912 if (!policy_decision->isDecided())
913 policy_decision->Use();
915 policy_decision->SelfDeleteIfNecessary();
918 void EWebView::InvokePolicyNavigationCallback(
919 const NavigationPolicyParams& params,
921 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
923 SmartCallback<EWebViewCallbacks::SaveSessionData>().call();
925 std::unique_ptr<_Ewk_Policy_Decision> policy_decision(
926 new _Ewk_Policy_Decision(params));
928 SmartCallback<EWebViewCallbacks::NavigationPolicyDecision>().call(
929 policy_decision.get());
931 CHECK(!policy_decision->isSuspended());
933 // TODO: Navigation can't be suspended
934 // this aproach is synchronous and requires immediate response
935 // Maybe there is different approach (like resource throttle response
936 // mechanism) that allows us to
937 // suspend navigation
938 if (!policy_decision->isDecided())
939 policy_decision->Use();
941 *handled = policy_decision->GetNavigationPolicyHandler()->GetDecision() ==
942 NavigationPolicyHandlerEfl::Handled;
945 void EWebView::HandleTouchEvents(Ewk_Touch_Event_Type type,
946 const Eina_List* points,
947 const Evas_Modifier* modifiers) {
951 if (GetSettings()->touchFocusEnabled() &&
952 (type == EWK_TOUCH_START && eina_list_count(points) == 1)) {
956 EINA_LIST_FOREACH(points, l, data) {
957 const Ewk_Touch_Point* point = static_cast<Ewk_Touch_Point*>(data);
958 if (point->state == EVAS_TOUCH_POINT_STILL) {
959 // Chromium doesn't expect (and doesn't like) these events.
968 evas_object_geometry_get(evas_object(), nullptr, &delta_y, nullptr,
970 ui::TouchEvent touch_event =
971 ui::MakeTouchEvent(pt, point->state, point->id, 0, delta_y);
972 rwhva()->OnTouchEvent(&touch_event);
977 bool EWebView::TouchEventsEnabled() const {
978 return rwhva()->offscreen_helper()->TouchEventsEnabled();
981 // TODO: Touch events use the same mouse events in EFL API.
982 // Figure out how to distinguish touch and mouse events on touch&mice devices.
983 // Currently mouse and touch support is mutually exclusive.
984 void EWebView::SetTouchEventsEnabled(bool enabled) {
985 if (!rwhva() || !rwhva()->offscreen_helper()) {
986 LOG(WARNING) << "RWHV is not created yet!";
990 if (rwhva()->offscreen_helper()->TouchEventsEnabled() == enabled)
993 rwhva()->offscreen_helper()->SetTouchEventsEnabled(enabled);
995 GetSettings()->getPreferences().touch_event_feature_detection_enabled =
997 GetSettings()->getPreferences().double_tap_to_zoom_enabled = enabled;
998 GetSettings()->getPreferences().editing_behavior =
999 enabled ? blink::mojom::EditingBehavior::kEditingAndroidBehavior
1000 : blink::mojom::EditingBehavior::kEditingUnixBehavior,
1001 UpdateWebKitPreferences();
1004 bool EWebView::MouseEventsEnabled() const {
1005 return mouse_events_enabled_;
1008 void EWebView::SetMouseEventsEnabled(bool enabled) {
1009 if (!rwhva() || !rwhva()->offscreen_helper()) {
1010 LOG(WARNING) << "RWHV is not created yet!";
1014 if (mouse_events_enabled_ == enabled)
1017 mouse_events_enabled_ = enabled;
1018 rwhva()->offscreen_helper()->SetTouchEventsEnabled(!enabled);
1023 class JavaScriptCallbackDetails {
1025 JavaScriptCallbackDetails(Ewk_View_Script_Execute_Callback callback_func,
1028 : callback_func_(callback_func), user_data_(user_data), view_(view) {}
1030 Ewk_View_Script_Execute_Callback callback_func_;
1035 void JavaScriptComplete(JavaScriptCallbackDetails* script_callback_data,
1036 base::Value result) {
1037 if (!script_callback_data->callback_func_)
1040 std::string return_string;
1041 if (result.is_string()) {
1042 // We don't want to serialize strings with JSONStringValueSerializer
1043 // to avoid quotation marks.
1044 return_string = result.GetString();
1045 } else if (result.is_none()) {
1046 // Value::TYPE_NULL is for lack of value, undefined, null
1049 JSONStringValueSerializer serializer(&return_string);
1050 serializer.Serialize(result);
1053 script_callback_data->callback_func_(script_callback_data->view_,
1054 return_string.c_str(),
1055 script_callback_data->user_data_);
1060 bool EWebView::ExecuteJavaScript(const char* script,
1061 Ewk_View_Script_Execute_Callback callback,
1063 LOG(INFO) << __FUNCTION__;
1064 if (!web_contents_) {
1065 LOG(ERROR) << __FUNCTION__ << "web_contents_ is null";
1069 RenderFrameHost* render_frame_host = web_contents_->GetPrimaryMainFrame();
1070 if (!render_frame_host) {
1071 LOG(ERROR) << __FUNCTION__ << " render_frame_host is null";
1075 // Note: M37. Execute JavaScript, |script| with
1076 // |RenderFrameHost::ExecuteJavaScript|.
1077 // @see also https://codereview.chromium.org/188893005 for more details.
1078 std::u16string js_script;
1079 base::UTF8ToUTF16(script, strlen(script), &js_script);
1081 JavaScriptCallbackDetails* script_callback_data =
1082 new JavaScriptCallbackDetails(callback, userdata, evas_object_);
1083 RenderFrameHost::JavaScriptResultCallback js_callback =
1084 base::BindOnce(&JavaScriptComplete, base::Owned(script_callback_data));
1085 // In M47, it isn't possible anymore to execute javascript in the generic
1086 // case. We need to call ExecuteJavaScriptForTests to keep the behaviour
1087 // unchanged @see https://codereview.chromium.org/1123783002
1088 render_frame_host->ExecuteJavaScriptWithUserGestureForTests(
1089 js_script, std::move(js_callback));
1091 // We use ExecuteJavaScriptWithUserGestureForTests instead of
1092 // ExecuteJavaScript because
1093 // ExecuteJavaScriptWithUserGestureForTests sets user_gesture to true. This
1095 // behaviour is m34, and we want to keep it that way.
1096 render_frame_host->ExecuteJavaScriptWithUserGestureForTests(
1097 js_script, base::NullCallback());
1103 bool EWebView::SetUserAgent(const char* userAgent) {
1104 content::NavigationController& controller = web_contents_->GetController();
1105 bool override = userAgent && strlen(userAgent);
1106 for (int i = 0; i < controller.GetEntryCount(); ++i)
1107 controller.GetEntryAtIndex(i)->SetIsOverridingUserAgent(override);
1108 // TODO: Check if override_in_new_tabs has to be true.
1109 web_contents_->SetUserAgentOverride(
1110 blink::UserAgentOverride::UserAgentOnly(userAgent),
1111 false /* override_in_new_tabs */);
1115 bool EWebView::SetUserAgentAppName(const char* application_name) {
1116 EflWebView::VersionInfo::GetInstance()->UpdateUserAgentWithAppName(
1117 application_name ? application_name : "");
1118 std::string user_agent =
1119 EflWebView::VersionInfo::GetInstance()->DefaultUserAgent();
1120 web_contents_->SetUserAgentOverride(
1121 blink::UserAgentOverride::UserAgentOnly(user_agent),
1122 false /* override_in_new_tabs */);
1126 #if BUILDFLAG(IS_TIZEN)
1127 bool EWebView::SetPrivateBrowsing(bool incognito) {
1128 if (context_->GetImpl()->browser_context()->IsOffTheRecord() == incognito)
1130 context_->GetImpl()->browser_context()->SetOffTheRecord(incognito);
1134 bool EWebView::GetPrivateBrowsing() const {
1135 return context_->GetImpl()->browser_context()->IsOffTheRecord();
1139 const char* EWebView::GetUserAgent() const {
1140 std::string user_agent =
1141 web_contents_->GetUserAgentOverride().ua_string_override;
1142 if (user_agent.empty())
1143 user_agent_ = content::GetContentClientExport()->browser()->GetUserAgent();
1145 user_agent_ = user_agent;
1147 return user_agent_.c_str();
1150 const char* EWebView::GetUserAgentAppName() const {
1151 user_agent_app_name_ = EflWebView::VersionInfo::GetInstance()->AppName();
1152 return user_agent_app_name_.c_str();
1155 const char* EWebView::CacheSelectedText() {
1159 selected_text_cached_ = base::UTF16ToUTF8(rwhva()->GetSelectedText());
1160 return selected_text_cached_.c_str();
1163 _Ewk_Frame* EWebView::GetMainFrame() {
1164 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1167 frame_.reset(new _Ewk_Frame(web_contents_->GetPrimaryMainFrame()));
1169 return frame_.get();
1172 void EWebView::UpdateWebKitPreferences() {
1173 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1175 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1176 if (!render_view_host)
1179 web_contents_delegate_->OnUpdateSettings(settings_.get());
1180 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
1181 render_view_host->UpdateWebkitPreferences(settings_->getPreferences());
1183 UpdateWebkitPreferencesEfl(render_view_host);
1186 void EWebView::UpdateWebkitPreferencesEfl(RenderViewHost* render_view_host) {
1187 DCHECK(render_view_host);
1188 #if !defined(EWK_BRINGUP) // FIXME: m108 bringup
1189 IPC::Message* message = new EwkSettingsMsg_UpdateWebKitPreferencesEfl(
1190 render_view_host->GetRoutingID(), settings_->getPreferencesEfl());
1192 if (render_view_host->IsRenderViewLive()) {
1193 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
1194 render_view_host->Send(message);
1197 delayed_messages_.push_back(message);
1202 void EWebView::SetContentSecurityPolicy(const char* policy,
1203 Ewk_CSP_Header_Type type) {
1204 web_contents_delegate_->SetContentSecurityPolicy(
1205 (policy ? policy : std::string()), type);
1208 void EWebView::LoadHTMLString(const char* html,
1209 const char* base_uri,
1210 const char* unreachable_uri) {
1211 LoadData(html, std::string::npos, NULL, NULL, base_uri, unreachable_uri);
1214 void EWebView::LoadPlainTextString(const char* plain_text) {
1215 LoadData(plain_text, std::string::npos, "text/plain", NULL, NULL, NULL);
1218 void EWebView::LoadHTMLStringOverridingCurrentEntry(
1220 const char* base_uri,
1221 const char* unreachable_url) {
1222 LoadData(html, std::string::npos, NULL, NULL, base_uri, unreachable_url,
1226 void EWebView::LoadData(const char* data,
1228 const char* mime_type,
1229 const char* encoding,
1230 const char* base_uri,
1231 const char* unreachable_uri,
1232 bool should_replace_current_entry) {
1233 SetDefaultStringIfNull(mime_type, "text/html");
1234 SetDefaultStringIfNull(encoding, "utf-8");
1235 SetDefaultStringIfNull(base_uri, "about:blank"); // Webkit2 compatible
1236 SetDefaultStringIfNull(unreachable_uri, "");
1238 std::string str_data = data;
1240 if (size < str_data.length())
1241 str_data = str_data.substr(0, size);
1243 std::string url_str("data:");
1244 url_str.append(mime_type);
1245 url_str.append(";charset=");
1246 url_str.append(encoding);
1247 url_str.append(",");
1249 // GURL constructor performs canonicalization of url string, but this is not
1250 // enough for correctly escaping contents of "data:" url.
1251 url_str.append(base::EscapeUrlEncodedData(str_data, false));
1253 NavigationController::LoadURLParams data_params(GURL(url_str.c_str()));
1255 data_params.base_url_for_data_url = GURL(base_uri);
1256 data_params.virtual_url_for_data_url = GURL(unreachable_uri);
1258 data_params.load_type = NavigationController::LOAD_TYPE_DATA;
1259 data_params.should_replace_current_entry = should_replace_current_entry;
1260 data_params.override_user_agent = NavigationController::UA_OVERRIDE_TRUE;
1261 web_contents_->GetController().LoadURLWithParams(data_params);
1264 void EWebView::InvokeLoadError(const GURL& url,
1266 bool is_cancellation) {
1267 _Ewk_Error err(error_code, is_cancellation,
1268 url.possibly_invalid_spec().c_str());
1270 SmartCallback<EWebViewCallbacks::LoadError>().call(&err);
1273 void EWebView::SetViewLoadErrorPageCallback(
1274 Ewk_View_Error_Page_Load_Callback callback,
1276 load_error_page_cb_.Set(callback, user_data);
1279 // Remove below code while ewk_error_cancellation_get has been implemented.
1280 const char* EWebView::InvokeViewLoadErrorPageCallback(
1283 const std::string& error_description) {
1284 std::unique_ptr<_Ewk_Error> err(
1285 new _Ewk_Error(error_code, url.possibly_invalid_spec().c_str(),
1286 error_description.c_str()));
1287 _Ewk_Error_Page error_page;
1289 LOG(INFO) << "EWebView::InvokeLoadErrorPageCallback url: "
1290 << url.spec().c_str() << ", error_code: " << error_code;
1292 load_error_page_cb_.Run(evas_object_, err.get(), &error_page);
1293 return error_page.content;
1296 bool EWebView::IsLoadErrorPageCallbackSet() const {
1297 return load_error_page_cb_.IsCallbackSet();
1299 void EWebView::HandlePopupMenu(std::vector<blink::mojom::MenuItemPtr> items,
1302 const gfx::Rect& bounds) {
1303 if (!select_picker_) {
1304 select_picker_.reset(CreateSelectPicker(
1305 this, selectedIndex, std::move(items), multiple, bounds));
1307 // Picker has been shown on top of webview and the page content gets
1308 // partially overlapped. Decrease viewport while showing picker.
1309 AdjustViewPortHeightToPopupMenu(true /* is_popup_menu_visible */);
1310 #if BUILDFLAG(IS_TIZEN_TV)
1311 SmartCallback<EWebViewCallbacks::PopupMenuShow>().call();
1314 select_picker_->UpdatePickerData(selectedIndex, std::move(items), multiple);
1317 select_picker_->Show();
1320 void EWebView::HidePopupMenu() {
1321 if (!select_picker_)
1324 AdjustViewPortHeightToPopupMenu(false /* is_popup_menu_visible */);
1325 #if BUILDFLAG(IS_TIZEN_TV)
1326 SmartCallback<EWebViewCallbacks::PopupMenuHide>().call();
1328 select_picker_.reset();
1331 void EWebView::DidSelectPopupMenuItems(std::vector<int>& indices) {
1332 wcva()->wcva_helper()->DidSelectPopupMenuItems(indices);
1335 void EWebView::DidCancelPopupMenu() {
1336 wcva()->wcva_helper()->DidCancelPopupMenu();
1339 void EWebView::HandleLongPressGesture(
1340 const content::ContextMenuParams& params) {
1341 // This menu is created in renderer process and it does not now anything about
1342 // view scaling factor and it has another calling sequence, so coordinates is
1344 if (settings_ && !settings_->getPreferences().long_press_enabled)
1347 content::ContextMenuParams convertedParams = params;
1348 gfx::Point convertedPoint =
1349 rwhva()->offscreen_helper()->ConvertPointInViewPix(
1350 gfx::Point(params.x, params.y));
1351 convertedParams.x = convertedPoint.x();
1352 convertedParams.y = convertedPoint.y();
1355 evas_object_geometry_get(evas_object(), &x, &y, 0, 0);
1356 convertedParams.x += x;
1357 convertedParams.y += y;
1359 if (GetSelectionController() && GetSelectionController()->GetLongPressed()) {
1360 bool show_context_menu_now =
1361 !GetSelectionController()->HandleLongPressEvent(convertedPoint,
1363 if (show_context_menu_now)
1364 ShowContextMenuInternal(convertedParams);
1368 void EWebView::ShowContextMenu(const content::ContextMenuParams& params) {
1372 // This menu is created in renderer process and it does not now anything about
1373 // view scaling factor and it has another calling sequence, so coordinates is
1375 content::ContextMenuParams convertedParams = params;
1376 gfx::Point convertedPoint =
1377 rwhva()->offscreen_helper()->ConvertPointInViewPix(
1378 gfx::Point(params.x, params.y));
1379 convertedParams.x = convertedPoint.x();
1380 convertedParams.y = convertedPoint.y();
1383 evas_object_geometry_get(evas_object(), &x, &y, 0, 0);
1384 convertedParams.x += x;
1385 convertedParams.y += y;
1387 context_menu_position_ = gfx::Point(convertedParams.x, convertedParams.y);
1389 ShowContextMenuInternal(convertedParams);
1392 void EWebView::ShowContextMenuInternal(
1393 const content::ContextMenuParams& params) {
1394 // We don't want to show 'cut' or 'copy' for inputs of type 'password' in
1395 // selection context menu, but params.input_field_type might not be set
1396 // correctly, because in some cases params is received from SelectionBoxEfl,
1397 // not from FrameHostMsg_ContextMenu message. In SelectionBoxEfl
1398 // ContextMenuParams is constructed on our side with limited information and
1399 // input_field_type is not set.
1401 // To work around this, we query for input type and set it separately. In
1402 // response to EwkViewMsg_QueryInputType we run ::UpdateContextMenu with
1403 // information about input's type.
1405 // FIXME: the way we get ContextMenuParams for context menu is flawed in some
1406 // cases. This should be fixed by restructuring context menu code.
1407 // Context menu creation should be unified to always have
1408 // ContextMenuParams received from FrameHostMsg_ContextMenu.
1409 // Tracked at: http://suprem.sec.samsung.net/jira/browse/TWF-1640
1410 if (params.is_editable) {
1411 saved_context_menu_params_ = params;
1413 rwhva()->host()->QueryInputType();
1415 UpdateContextMenuWithParams(params);
1419 void EWebView::UpdateContextMenu(bool is_password_input) {
1420 if (is_password_input) {
1421 saved_context_menu_params_.form_control_type =
1422 blink::mojom::FormControlType::kInputPassword;
1424 UpdateContextMenuWithParams(saved_context_menu_params_);
1427 void EWebView::UpdateContextMenuWithParams(
1428 const content::ContextMenuParams& params) {
1429 context_menu_.reset(
1430 new content::ContextMenuControllerEfl(this, *web_contents_.get()));
1432 if (IsMobileProfile()) {
1433 if (delayed_show_context_menu_timer_) {
1434 ecore_timer_del(delayed_show_context_menu_timer_);
1435 delayed_show_context_menu_timer_ = nullptr;
1437 saved_context_menu_params_ = params;
1438 delayed_show_context_menu_timer_ = ecore_timer_add(
1439 kDelayShowContextMenuTime, DelayedPopulateAndShowContextMenu, this);
1441 if (!context_menu_->PopulateAndShowContextMenu(params)) {
1442 context_menu_.reset();
1443 if (GetSelectionController())
1444 GetSelectionController()->HideHandles();
1449 Eina_Bool EWebView::DelayedPopulateAndShowContextMenu(void* data) {
1450 if (IsMobileProfile) {
1451 EWebView* view = static_cast<EWebView*>(data);
1453 if (view->context_menu_ &&
1454 !(view->context_menu_->PopulateAndShowContextMenu(
1455 view->saved_context_menu_params_))) {
1456 view->context_menu_.reset();
1458 view->delayed_show_context_menu_timer_ = nullptr;
1461 return ECORE_CALLBACK_CANCEL;
1464 void EWebView::CancelContextMenu(int request_id) {
1466 context_menu_->HideContextMenu();
1469 void EWebView::Find(const char* text, Ewk_Find_Options ewk_find_options) {
1470 std::u16string find_text = base::UTF8ToUTF16(text);
1471 bool find_next = (previous_text_ == find_text);
1474 current_find_request_id_ = find_request_id_counter_++;
1475 previous_text_ = find_text;
1478 auto find_options = blink::mojom::FindOptions::New();
1479 find_options->forward = !(ewk_find_options & EWK_FIND_OPTIONS_BACKWARDS);
1480 find_options->match_case =
1481 !(ewk_find_options & EWK_FIND_OPTIONS_CASE_INSENSITIVE);
1483 web_contents_->Find(current_find_request_id_, find_text,
1484 std::move(find_options));
1487 void EWebView::SetScale(double scale_factor) {
1488 // Do not cache |scale_factor| here as it may be discarded by Blink's
1489 // minimumPageScaleFactor and maximumPageScaleFactor.
1490 // |scale_factor| is cached as responde to DidChangePageScaleFactor.
1491 WebContentsImpl* wci = static_cast<WebContentsImpl*>(web_contents_.get());
1492 wci->GetPrimaryMainFrame()->GetAssociatedLocalMainFrame()->SetScaleFactor(
1496 void EWebView::ScrollFocusedNodeIntoView() {
1497 if (RenderViewHost* render_view_host = web_contents_->GetRenderViewHost()) {
1498 if (auto& broadcast = static_cast<RenderViewHostImpl*>(render_view_host)
1499 ->GetAssociatedPageBroadcast())
1500 broadcast->ScrollFocusedNodeIntoView();
1504 void EWebView::AdjustViewPortHeightToPopupMenu(bool is_popup_menu_visible) {
1505 if (!rwhva() || !IsMobileProfile() ||
1506 settings_->getPreferences().TizenCompatibilityModeEnabled()) {
1510 int picker_height = select_picker_->GetGeometryDIP().height();
1511 gfx::Rect screen_rect =
1512 display::Screen::GetScreen()->GetPrimaryDisplay().bounds();
1513 gfx::Rect view_rect = rwhva()->offscreen_helper()->GetViewBounds();
1515 screen_rect.height() - (view_rect.y() + view_rect.height());
1517 rwhva()->offscreen_helper()->SetCustomViewportSize(
1518 is_popup_menu_visible
1519 ? gfx::Size(view_rect.width(),
1520 view_rect.height() - picker_height + bottom_height)
1524 void EWebView::SetScaleChangedCallback(Ewk_View_Scale_Changed_Callback callback,
1526 scale_changed_cb_.Set(callback, user_data);
1529 bool EWebView::GetScrollPosition(int* x, int* y) const {
1531 LOG(ERROR) << "rwhva() returns nullptr";
1534 if (scroll_detector_->IsScrollOffsetChanged()) {
1536 *x = previous_scroll_position_.x();
1538 *y = previous_scroll_position_.y();
1540 const gfx::Vector2d scroll_position_dip =
1541 scroll_detector_->GetLastScrollPosition();
1542 const float device_scale_factor = display::Screen::GetScreen()
1543 ->GetPrimaryDisplay()
1544 .device_scale_factor();
1546 *x = base::ClampRound((scroll_position_dip.x() - x_delta_) *
1547 device_scale_factor);
1550 *y = base::ClampRound((scroll_position_dip.y() - y_delta_) *
1551 device_scale_factor);
1557 void EWebView::ChangeScroll(int& x, int& y) {
1559 LOG(ERROR) << "rwhva() returns nullptr";
1564 GetScrollSize(&max_x, &max_y);
1565 previous_scroll_position_.set_x(std::min(std::max(x, 0), max_x));
1566 previous_scroll_position_.set_y(std::min(std::max(y, 0), max_y));
1568 const float device_scale_factor = display::Screen::GetScreen()
1569 ->GetPrimaryDisplay()
1570 .device_scale_factor();
1574 x = base::ClampCeil(x / device_scale_factor);
1575 y = base::ClampCeil(y / device_scale_factor);
1577 x_delta_ = x - (x_input / device_scale_factor);
1578 y_delta_ = y - (y_input / device_scale_factor);
1580 scroll_detector_->SetScrollOffsetChanged();
1583 void EWebView::SetScroll(int x, int y) {
1584 if (auto* render_view_host = web_contents_->GetRenderViewHost()) {
1585 if (auto& broadcast = static_cast<RenderViewHostImpl*>(render_view_host)
1586 ->GetAssociatedPageBroadcast()) {
1588 broadcast->SetScrollOffset(x, y);
1593 void EWebView::UseSettingsFont() {
1594 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
1595 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1596 if (render_view_host)
1597 render_view_host->Send(
1598 new EwkViewMsg_UseSettingsFont(render_view_host->GetRoutingID()));
1602 void EWebView::DidChangeContentsSize(int width, int height) {
1603 contents_size_ = gfx::Size(width, height);
1604 SmartCallback<EWebViewCallbacks::ContentsSizeChanged>().call();
1605 SetScaledContentsSize();
1608 const Eina_Rectangle EWebView::GetContentsSize() const {
1609 Eina_Rectangle rect;
1610 EINA_RECTANGLE_SET(&rect, 0, 0, contents_size_.width(),
1611 contents_size_.height());
1615 void EWebView::SetScaledContentsSize() {
1617 return; // LCOV_EXCL_LINE
1619 const float device_scale_factor =
1620 display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
1621 gfx::SizeF scaled_contents_size = gfx::ConvertSizeToPixels(
1622 contents_size_, device_scale_factor * page_scale_factor_);
1623 rwhva()->offscreen_helper()->SetScaledContentSize(scaled_contents_size);
1626 void EWebView::GetScrollSize(int* width, int* height) {
1629 *width = (rwhva() &&
1630 (w = rwhva()->offscreen_helper()->GetScrollableSize().width()))
1635 *height = (rwhva() &&
1636 (h = rwhva()->offscreen_helper()->GetScrollableSize().height()))
1642 void EWebView::MoveCaret(const gfx::Point& point) {
1644 rwhva()->offscreen_helper()->MoveCaret(point);
1647 SelectionControllerEfl* EWebView::GetSelectionController() const {
1648 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1649 RenderWidgetHostViewAura* view = static_cast<RenderWidgetHostViewAura*>(
1650 render_view_host->GetWidget()->GetView());
1651 return view ? view->offscreen_helper()->GetSelectionController() : 0;
1654 void EWebView::SelectFocusedLink() {
1655 rwhva()->host()->SelectFocusedLink();
1658 bool EWebView::GetSelectionRange(Eina_Rectangle* left_rect,
1659 Eina_Rectangle* right_rect) {
1660 if (left_rect && right_rect) {
1661 gfx::Rect left, right;
1662 if (GetSelectionController()) {
1663 GetSelectionController()->GetSelectionBounds(&left, &right);
1664 GetEinaRectFromGfxRect(left, left_rect);
1665 GetEinaRectFromGfxRect(right, right_rect);
1672 void EWebView::OnSelectionRectReceived(const gfx::Rect& selection_rect) const {
1674 context_menu_->OnSelectionRectReceived(selection_rect);
1677 Eina_Bool EWebView::ClearSelection() {
1681 ResetContextMenuController();
1682 rwhva()->SelectionChanged(std::u16string(), 0, gfx::Range());
1684 if (GetSelectionController())
1685 return GetSelectionController()->ClearSelectionViaEWebView();
1690 _Ewk_Hit_Test* EWebView::RequestHitTestDataAt(int x,
1692 Ewk_Hit_Test_Mode mode) {
1693 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1696 EvasToBlinkCords(x, y, &view_x, &view_y);
1698 return RequestHitTestDataAtBlinkCoords(view_x, view_y, mode);
1701 Eina_Bool EWebView::AsyncRequestHitTestDataAt(
1704 Ewk_Hit_Test_Mode mode,
1705 Ewk_View_Hit_Test_Request_Callback callback,
1708 EvasToBlinkCords(x, y, &view_x, &view_y);
1709 return AsyncRequestHitTestDataAtBlinkCords(
1710 view_x, view_y, mode,
1711 new WebViewAsyncRequestHitTestDataUserCallback(x, y, mode, callback,
1715 Eina_Bool EWebView::AsyncRequestHitTestDataAtBlinkCords(
1718 Ewk_Hit_Test_Mode mode,
1719 Ewk_View_Hit_Test_Request_Callback callback,
1721 return AsyncRequestHitTestDataAtBlinkCords(
1723 new WebViewAsyncRequestHitTestDataUserCallback(x, y, mode, callback,
1727 Eina_Bool EWebView::AsyncRequestHitTestDataAtBlinkCords(
1730 Ewk_Hit_Test_Mode mode,
1731 WebViewAsyncRequestHitTestDataCallback* cb) {
1732 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1735 static int64_t request_id = 1;
1738 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1739 DCHECK(render_view_host);
1741 if (render_view_host) {
1742 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
1743 render_view_host->Send(new EwkViewMsg_DoHitTestAsync(
1744 render_view_host->GetRoutingID(), x, y, mode, request_id));
1746 hit_test_callback_[request_id] = cb;
1752 // if failed we delete callback as it is not needed anymore
1757 void EWebView::DispatchAsyncHitTestData(const Hit_Test_Params& params,
1758 int64_t request_id) {
1759 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1761 std::map<int64_t, WebViewAsyncRequestHitTestDataCallback*>::iterator it =
1762 hit_test_callback_.find(request_id);
1764 if (it == hit_test_callback_.end())
1766 std::unique_ptr<_Ewk_Hit_Test> hit_test(new _Ewk_Hit_Test(params));
1768 it->second->Run(hit_test.get(), this);
1770 hit_test_callback_.erase(it);
1773 _Ewk_Hit_Test* EWebView::RequestHitTestDataAtBlinkCoords(
1776 Ewk_Hit_Test_Mode mode) {
1777 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1779 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1781 if (render_view_host) {
1782 // We wait on UI thread till hit test data is updated.
1783 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
1784 render_view_host->Send(
1785 new EwkViewMsg_DoHitTest(render_view_host->GetRoutingID(), x, y, mode));
1787 hit_test_completion_.Wait();
1788 return new _Ewk_Hit_Test(hit_test_params_);
1794 void EWebView::EvasToBlinkCords(int x, int y, int* view_x, int* view_y) {
1795 DCHECK(display::Screen::GetScreen());
1799 gfx::Rect view_bounds = rwhva()->offscreen_helper()->GetViewBoundsInPix();
1802 *view_x = x - view_bounds.x();
1804 display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
1808 *view_y = y - view_bounds.y();
1810 display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
1814 void EWebView::UpdateHitTestData(const Hit_Test_Params& params) {
1815 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
1816 hit_test_params_ = params;
1817 hit_test_completion_.Signal();
1820 void EWebView::OnCopyFromBackingStore(bool success, const SkBitmap& bitmap) {}
1822 void EWebView::OnFocusIn() {
1823 SmartCallback<EWebViewCallbacks::FocusIn>().call();
1824 #if defined(USE_WAYLAND)
1825 if (!rwhva() || !rwhva()->offscreen_helper())
1827 if (GetSettings()->getClipboardEnabled()) {
1828 ClipboardHelperEfl::GetInstance()->OnWebviewFocusIn(
1829 this, rwhva()->offscreen_helper()->content_image_elm_host(),
1830 rwhva()->offscreen_helper()->IsFocusedNodeContentEditable(),
1831 base::BindRepeating(&EWebView::ExecuteEditCommand,
1832 base::Unretained(this)));
1837 void EWebView::OnFocusOut() {
1838 #if defined(TIZEN_ATK_SUPPORT)
1839 if (IsMobileProfile())
1840 eweb_accessibility_->OnFocusOut();
1842 SmartCallback<EWebViewCallbacks::FocusOut>().call();
1843 #if defined(USE_WAYLAND)
1844 if (GetSettings()->getClipboardEnabled())
1845 ClipboardHelperEfl::GetInstance()->MaybeInvalidateActiveWebview(this);
1849 void EWebView::RenderViewReady() {
1851 rwhva()->offscreen_helper()->SetFocusInOutCallbacks(
1852 base::BindRepeating(&EWebView::OnFocusIn, base::Unretained(this)),
1853 base::BindRepeating(&EWebView::OnFocusOut, base::Unretained(this)));
1856 #if defined(TIZEN_VIDEO_HOLE)
1857 if (rwhva() && pending_video_hole_setting_) {
1858 EnableVideoHoleSupportInternal();
1859 pending_video_hole_setting_ = false;
1863 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1865 SendDelayedMessages(render_view_host);
1866 UpdateWebkitPreferencesEfl(render_view_host);
1868 if (render_view_host) {
1869 WebContents* content = WebContents::FromRenderViewHost(render_view_host);
1871 RenderProcessHost* host = render_view_host->GetProcess();
1873 host->AddFilter(new WebViewBrowserMessageFilter(content));
1878 void EWebView::SetQuotaPermissionRequestCallback(
1879 Ewk_Quota_Permission_Request_Callback callback,
1881 quota_request_callback_.Set(callback, user_data);
1884 #if !defined(EWK_BRINGUP) // FIXME: m114 bringup
1885 void EWebView::InvokeQuotaPermissionRequest(
1886 _Ewk_Quota_Permission_Request* request,
1887 content::QuotaPermissionContext::PermissionCallback cb) {
1888 quota_permission_request_map_[request] = std::move(cb);
1889 request->setView(evas_object());
1890 if (quota_request_callback_.IsCallbackSet())
1891 quota_request_callback_.Run(evas_object(), request);
1893 QuotaRequestCancel(request);
1896 void EWebView::QuotaRequestReply(const _Ewk_Quota_Permission_Request* request,
1898 DCHECK(quota_permission_request_map_.find(request) !=
1899 quota_permission_request_map_.end());
1901 QuotaPermissionContextEfl::DispatchCallback(
1902 std::move(quota_permission_request_map_[request]),
1903 (allow ? QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_ALLOW
1904 : QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_DISALLOW));
1906 quota_permission_request_map_.erase(request);
1910 void EWebView::QuotaRequestCancel(
1911 const _Ewk_Quota_Permission_Request* request) {
1912 DCHECK(quota_permission_request_map_.find(request) !=
1913 quota_permission_request_map_.end());
1915 QuotaPermissionContextEfl::DispatchCallback(
1916 std::move(quota_permission_request_map_[request]),
1917 QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_CANCELLED);
1918 quota_permission_request_map_.erase(request);
1923 bool EWebView::GetLinkMagnifierEnabled() const {
1924 #if !defined(EWK_BRINGUP) // FIXME: m71 bringup
1925 return web_contents_->GetMutableRendererPrefs()
1926 ->tap_multiple_targets_strategy ==
1927 TAP_MULTIPLE_TARGETS_STRATEGY_POPUP;
1933 void EWebView::SetLinkMagnifierEnabled(bool enabled) {
1934 #if !defined(EWK_BRINGUP) // FIXME: m71 bringup
1935 web_contents_->GetMutableRendererPrefs()->tap_multiple_targets_strategy =
1936 enabled ? TAP_MULTIPLE_TARGETS_STRATEGY_POPUP
1937 : TAP_MULTIPLE_TARGETS_STRATEGY_NONE;
1939 web_contents_->SyncRendererPrefs();
1942 bool EWebView::GetSnapshotAsync(
1943 Eina_Rectangle rect,
1944 Ewk_Web_App_Screenshot_Captured_Callback callback,
1946 float scale_factor) {
1947 if (!rwhva() || !rwhva()->offscreen_helper())
1950 rwhva()->offscreen_helper()->RequestSnapshotAsync(
1951 gfx::Rect(rect.x, rect.y, rect.w, rect.h), callback, user_data,
1956 Evas_Object* EWebView::GetSnapshot(Eina_Rectangle rect, float scale_factor) {
1957 if (!rwhva() || !rwhva()->offscreen_helper())
1960 return rwhva()->offscreen_helper()->GetSnapshot(
1961 gfx::Rect(rect.x, rect.y, rect.w, rect.h), scale_factor);
1964 void EWebView::BackForwardListClear() {
1965 content::NavigationController& controller = web_contents_->GetController();
1967 int entry_count = controller.GetEntryCount();
1968 bool entry_removed = false;
1970 for (int i = 0; i < entry_count; i++) {
1971 if (controller.RemoveEntryAtIndex(i)) {
1972 entry_removed = true;
1973 entry_count = controller.GetEntryCount();
1978 if (entry_removed) {
1979 back_forward_list_->ClearCache();
1980 InvokeBackForwardListChangedCallback();
1984 _Ewk_Back_Forward_List* EWebView::GetBackForwardList() const {
1985 return back_forward_list_.get();
1988 void EWebView::InvokeBackForwardListChangedCallback() {
1989 SmartCallback<EWebViewCallbacks::BackForwardListChange>().call();
1992 _Ewk_History* EWebView::GetBackForwardHistory() const {
1993 return new _Ewk_History(web_contents_->GetController());
1996 bool EWebView::WebAppCapableGet(Ewk_Web_App_Capable_Get_Callback callback,
1998 RenderViewHost* renderViewHost = web_contents_->GetRenderViewHost();
1999 if (!renderViewHost) {
2002 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
2003 WebApplicationCapableGetCallback* cb =
2004 new WebApplicationCapableGetCallback(callback, userData);
2005 int callbackId = web_app_capable_get_callback_map_.Add(cb);
2006 return renderViewHost->Send(new EwkViewMsg_WebAppCapableGet(
2007 renderViewHost->GetRoutingID(), callbackId));
2013 bool EWebView::WebAppIconUrlGet(Ewk_Web_App_Icon_URL_Get_Callback callback,
2015 RenderViewHost* renderViewHost = web_contents_->GetRenderViewHost();
2016 if (!renderViewHost) {
2019 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
2020 WebApplicationIconUrlGetCallback* cb =
2021 new WebApplicationIconUrlGetCallback(callback, userData);
2022 int callbackId = web_app_icon_url_get_callback_map_.Add(cb);
2023 return renderViewHost->Send(new EwkViewMsg_WebAppIconUrlGet(
2024 renderViewHost->GetRoutingID(), callbackId));
2030 bool EWebView::WebAppIconUrlsGet(Ewk_Web_App_Icon_URLs_Get_Callback callback,
2032 RenderViewHost* renderViewHost = web_contents_->GetRenderViewHost();
2033 if (!renderViewHost) {
2036 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
2037 WebApplicationIconUrlsGetCallback* cb =
2038 new WebApplicationIconUrlsGetCallback(callback, userData);
2039 int callbackId = web_app_icon_urls_get_callback_map_.Add(cb);
2040 return renderViewHost->Send(new EwkViewMsg_WebAppIconUrlsGet(
2041 renderViewHost->GetRoutingID(), callbackId));
2047 void EWebView::InvokeWebAppCapableGetCallback(bool capable, int callbackId) {
2048 WebApplicationCapableGetCallback* callback =
2049 web_app_capable_get_callback_map_.Lookup(callbackId);
2052 callback->Run(capable);
2053 web_app_capable_get_callback_map_.Remove(callbackId);
2056 void EWebView::InvokeWebAppIconUrlGetCallback(const std::string& iconUrl,
2058 WebApplicationIconUrlGetCallback* callback =
2059 web_app_icon_url_get_callback_map_.Lookup(callbackId);
2062 callback->Run(iconUrl);
2063 web_app_icon_url_get_callback_map_.Remove(callbackId);
2066 void EWebView::InvokeWebAppIconUrlsGetCallback(const StringMap& iconUrls,
2068 WebApplicationIconUrlsGetCallback* callback =
2069 web_app_icon_urls_get_callback_map_.Lookup(callbackId);
2073 callback->Run(iconUrls);
2074 web_app_icon_urls_get_callback_map_.Remove(callbackId);
2077 void EWebView::SetNotificationPermissionCallback(
2078 Ewk_View_Notification_Permission_Callback callback,
2080 notification_permission_callback_.Set(callback, user_data);
2083 bool EWebView::IsNotificationPermissionCallbackSet() const {
2084 return notification_permission_callback_.IsCallbackSet();
2087 bool EWebView::InvokeNotificationPermissionCallback(
2088 Ewk_Notification_Permission_Request* request) {
2089 Eina_Bool ret = EINA_FALSE;
2090 notification_permission_callback_.Run(evas_object_, request, &ret);
2094 int EWebView::SetEwkViewPlainTextGetCallback(
2095 Ewk_View_Plain_Text_Get_Callback callback,
2097 EwkViewPlainTextGetCallback* view_plain_text_callback_ptr =
2098 new EwkViewPlainTextGetCallback;
2099 view_plain_text_callback_ptr->Set(callback, user_data);
2100 return plain_text_get_callback_map_.Add(view_plain_text_callback_ptr);
2103 bool EWebView::PlainTextGet(Ewk_View_Plain_Text_Get_Callback callback,
2105 auto* render_frame_host = web_contents_->GetPrimaryMainFrame();
2106 if (!render_frame_host)
2109 auto callback_id = SetEwkViewPlainTextGetCallback(callback, user_data);
2110 return render_frame_host->Send(new EwkFrameMsg_GetPlainText(
2111 render_frame_host->GetRoutingID(), callback_id));
2114 void EWebView::InvokePlainTextGetCallback(const std::string& content_text,
2115 int plain_text_get_callback_id) {
2116 EwkViewPlainTextGetCallback* view_plain_text_callback_invoke_ptr =
2117 plain_text_get_callback_map_.Lookup(plain_text_get_callback_id);
2118 view_plain_text_callback_invoke_ptr->Run(evas_object(), content_text.c_str());
2119 plain_text_get_callback_map_.Remove(plain_text_get_callback_id);
2122 void EWebView::SetViewGeolocationPermissionCallback(
2123 Ewk_View_Geolocation_Permission_Callback callback,
2125 geolocation_permission_cb_.Set(callback, user_data);
2128 bool EWebView::InvokeViewGeolocationPermissionCallback(
2129 _Ewk_Geolocation_Permission_Request* permission_context,
2130 Eina_Bool* callback_result) {
2131 return geolocation_permission_cb_.Run(evas_object_, permission_context,
2135 void EWebView::SetViewUserMediaPermissionCallback(
2136 Ewk_View_User_Media_Permission_Callback callback,
2138 user_media_permission_cb_.Set(callback, user_data);
2141 bool EWebView::InvokeViewUserMediaPermissionCallback(
2142 _Ewk_User_Media_Permission_Request* permission_context,
2143 Eina_Bool* callback_result) {
2144 return user_media_permission_cb_.Run(evas_object_, permission_context,
2148 void EWebView::SetViewUserMediaPermissionQueryCallback(
2149 Ewk_View_User_Media_Permission_Query_Callback callback,
2151 user_media_permission_query_cb_.Set(callback, user_data);
2154 Ewk_User_Media_Permission_Query_Result
2155 EWebView::InvokeViewUserMediaPermissionQueryCallback(
2156 _Ewk_User_Media_Permission_Query* permission_context) {
2157 return user_media_permission_query_cb_.Run(evas_object_, permission_context);
2160 void EWebView::SetViewUnfocusAllowCallback(
2161 Ewk_View_Unfocus_Allow_Callback callback,
2163 unfocus_allow_cb_.Set(callback, user_data);
2166 bool EWebView::InvokeViewUnfocusAllowCallback(Ewk_Unfocus_Direction direction,
2167 Eina_Bool* callback_result) {
2168 return unfocus_allow_cb_.Run(evas_object_, direction, callback_result);
2171 void EWebView::StopFinding() {
2172 web_contents_->StopFinding(content::STOP_FIND_ACTION_CLEAR_SELECTION);
2175 void EWebView::SetProgressValue(double progress) {
2176 progress_ = progress;
2179 double EWebView::GetProgressValue() {
2183 const char* EWebView::GetTitle() {
2184 title_ = base::UTF16ToUTF8(web_contents_->GetTitle());
2185 return title_.c_str();
2188 bool EWebView::SaveAsPdf(int width, int height, const std::string& filename) {
2191 rwhva()->host()->PrintToPdf(width, height, base::FilePath(filename));
2195 bool EWebView::GetMHTMLData(Ewk_View_MHTML_Data_Get_Callback callback,
2197 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
2198 if (!render_view_host)
2201 MHTMLCallbackDetails* callback_details = new MHTMLCallbackDetails;
2202 callback_details->Set(callback, user_data);
2203 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
2204 int mhtml_callback_id = mhtml_callback_map_.Add(callback_details);
2205 return render_view_host->Send(new EwkViewMsg_GetMHTMLData(
2206 render_view_host->GetRoutingID(), mhtml_callback_id));
2212 void EWebView::OnMHTMLContentGet(const std::string& mhtml_content,
2214 MHTMLCallbackDetails* callback_details =
2215 mhtml_callback_map_.Lookup(callback_id);
2216 callback_details->Run(evas_object(), mhtml_content.c_str());
2217 mhtml_callback_map_.Remove(callback_id);
2220 bool EWebView::SavePageAsMHTML(const std::string& path,
2221 Ewk_View_Save_Page_Callback callback,
2226 GURL url(web_contents_->GetLastCommittedURL());
2227 std::u16string title(web_contents_->GetTitle());
2229 // Post function that has file access to blocking task runner.
2230 base::ThreadPool::PostTaskAndReplyWithResult(
2232 {base::MayBlock(), base::TaskPriority::BEST_EFFORT,
2233 base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN},
2234 base::BindOnce(&GenerateMHTMLFilePath, url, base::UTF16ToUTF8(title),
2236 base::BindOnce(&EWebView::GenerateMHTML, base::Unretained(this), callback,
2241 void EWebView::GenerateMHTML(Ewk_View_Save_Page_Callback callback,
2243 const base::FilePath& file_path) {
2244 if (file_path.empty()) {
2245 LOG(ERROR) << "Generating file path was failed";
2246 callback(evas_object_, nullptr, user_data);
2250 MHTMLGenerationParams params(file_path);
2251 web_contents_->GenerateMHTML(
2252 params, base::BindOnce(&EWebView::MHTMLGenerated, base::Unretained(this),
2253 callback, user_data, file_path));
2256 void EWebView::MHTMLGenerated(Ewk_View_Save_Page_Callback callback,
2258 const base::FilePath& file_path,
2259 int64_t file_size) {
2260 callback(evas_object_, file_size > 0 ? file_path.value().c_str() : nullptr,
2264 bool EWebView::GetBackgroundColor(
2265 Ewk_View_Background_Color_Get_Callback callback,
2269 BackgroundColorGetCallback* cb =
2270 new BackgroundColorGetCallback(callback, user_data);
2271 int callback_id = background_color_get_callback_map_.Add(cb);
2273 rwhva()->host()->RequestBackgroundColor(callback_id);
2277 void EWebView::OnGetBackgroundColor(int callback_id, SkColor bg_color) {
2278 BackgroundColorGetCallback* cb =
2279 background_color_get_callback_map_.Lookup(callback_id);
2284 cb->Run(evas_object(), SkColorGetR(bg_color), SkColorGetG(bg_color),
2285 SkColorGetB(bg_color), SkColorGetA(bg_color));
2286 background_color_get_callback_map_.Remove(callback_id);
2289 bool EWebView::IsFullscreen() {
2290 return web_contents_delegate_->IsFullscreenForTabOrPending(
2291 web_contents_.get());
2294 void EWebView::ExitFullscreen() {
2295 WebContentsImpl* wci = static_cast<WebContentsImpl*>(web_contents_.get());
2296 wci->ExitFullscreen(false);
2299 double EWebView::GetScale() {
2300 return page_scale_factor_;
2303 void EWebView::DidChangePageScaleFactor(double scale_factor) {
2304 page_scale_factor_ = scale_factor;
2305 wcva()->wcva_helper()->SetPageScaleFactor(scale_factor);
2306 SetScaledContentsSize();
2308 // Notify app about the scale change.
2309 scale_changed_cb_.Run(evas_object_, scale_factor);
2312 inline JavaScriptDialogManagerEfl* EWebView::GetJavaScriptDialogManagerEfl() {
2313 return static_cast<JavaScriptDialogManagerEfl*>(
2314 web_contents_delegate_->GetJavaScriptDialogManager(web_contents_.get()));
2317 void EWebView::SetJavaScriptAlertCallback(
2318 Ewk_View_JavaScript_Alert_Callback callback,
2320 GetJavaScriptDialogManagerEfl()->SetAlertCallback(callback, user_data);
2323 void EWebView::JavaScriptAlertReply() {
2324 GetJavaScriptDialogManagerEfl()->ExecuteDialogClosedCallBack(true,
2326 SmartCallback<EWebViewCallbacks::PopupReplyWaitFinish>().call(0);
2329 void EWebView::SetJavaScriptConfirmCallback(
2330 Ewk_View_JavaScript_Confirm_Callback callback,
2332 GetJavaScriptDialogManagerEfl()->SetConfirmCallback(callback, user_data);
2335 void EWebView::JavaScriptConfirmReply(bool result) {
2336 GetJavaScriptDialogManagerEfl()->ExecuteDialogClosedCallBack(result,
2338 SmartCallback<EWebViewCallbacks::PopupReplyWaitFinish>().call(0);
2341 void EWebView::SetJavaScriptPromptCallback(
2342 Ewk_View_JavaScript_Prompt_Callback callback,
2344 GetJavaScriptDialogManagerEfl()->SetPromptCallback(callback, user_data);
2347 void EWebView::JavaScriptPromptReply(const char* result) {
2348 GetJavaScriptDialogManagerEfl()->ExecuteDialogClosedCallBack(
2349 true, (std::string(result)));
2350 SmartCallback<EWebViewCallbacks::PopupReplyWaitFinish>().call(0);
2353 void EWebView::GetPageScaleRange(double* min_scale, double* max_scale) {
2354 auto prefs = web_contents_->GetOrCreateWebPreferences();
2356 *min_scale = prefs.default_minimum_page_scale_factor;
2358 *max_scale = prefs.default_maximum_page_scale_factor;
2361 content::WebContentsViewAura* EWebView::GetWebContentsViewAura() const {
2362 WebContentsImpl* wc = static_cast<WebContentsImpl*>(web_contents_.get());
2363 return static_cast<WebContentsViewAura*>(wc->GetView());
2366 bool EWebView::SetDrawsTransparentBackground(bool enabled) {
2367 #if BUILDFLAG(IS_TIZEN)
2368 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
2369 if (!render_view_host || !rwhva())
2372 if (!rwhva()->offscreen_helper())
2374 elm_object_style_set(rwhva()->offscreen_helper()->content_image_elm_host(),
2375 enabled ? "transparent" : "default");
2376 evas_object_image_alpha_set(rwhva()->offscreen_helper()->content_image(),
2378 GetWebContentsViewAura()->SetBackgroundColor(enabled ? SK_ColorTRANSPARENT
2380 static_cast<RenderViewHostImpl*>(render_view_host)
2382 ->GetAssociatedFrameWidget()
2383 ->SetDrawsTransparentBackground(enabled);
2384 rwhva()->SetBackgroundColor(enabled ? SK_ColorTRANSPARENT : SK_ColorWHITE);
2391 bool EWebView::GetDrawsTransparentBackground() {
2392 #if BUILDFLAG(IS_TIZEN)
2393 return GetWebContentsViewAura()->GetBackgroundColor() == SK_ColorTRANSPARENT;
2399 bool EWebView::SetBackgroundColor(int red, int green, int blue, int alpha) {
2400 #if BUILDFLAG(IS_TIZEN)
2402 return SetDrawsTransparentBackground(true);
2404 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
2405 if (!render_view_host || !rwhva())
2408 if (!rwhva()->offscreen_helper())
2410 elm_object_style_set(rwhva()->offscreen_helper()->content_image_elm_host(),
2411 alpha < 255 ? "transparent" : "default");
2412 evas_object_image_alpha_set(rwhva()->offscreen_helper()->content_image(),
2414 GetWebContentsViewAura()->SetBackgroundColor(
2415 SkColorSetARGB(alpha, red, green, blue));
2416 static_cast<RenderViewHostImpl*>(render_view_host)
2418 ->GetAssociatedFrameWidget()
2419 ->SetBackgroundColor(red, green, blue, alpha);
2420 rwhva()->SetBackgroundColor(SkColorSetARGB(alpha, red, green, blue));
2428 void EWebView::GetSessionData(const char** data, unsigned* length) const {
2429 static const int MAX_SESSION_ENTRY_SIZE = std::numeric_limits<int>::max();
2431 NavigationController& navigationController = web_contents_->GetController();
2432 base::Pickle sessionPickle;
2433 const int itemCount = navigationController.GetEntryCount();
2435 sessionPickle.WriteInt(itemCount);
2436 sessionPickle.WriteInt(navigationController.GetCurrentEntryIndex());
2438 for (int i = 0; i < itemCount; i++) {
2439 NavigationEntry* navigationEntry = navigationController.GetEntryAtIndex(i);
2440 sessions::SerializedNavigationEntry serializedEntry =
2441 sessions::ContentSerializedNavigationBuilder::FromNavigationEntry(
2442 i, navigationEntry);
2443 serializedEntry.WriteToPickle(MAX_SESSION_ENTRY_SIZE, &sessionPickle);
2446 if (sessionPickle.size() <= 0 ||
2448 static_cast<char*>(malloc(sizeof(char) * sessionPickle.size())))) {
2449 LOG(ERROR) << "Failed to get session data";
2453 memcpy(const_cast<char*>(*data), sessionPickle.data(), sessionPickle.size());
2454 *length = sessionPickle.size();
2457 bool EWebView::RestoreFromSessionData(const char* data, unsigned length) {
2458 base::Pickle sessionPickle(data, length);
2459 base::PickleIterator pickleIterator(sessionPickle);
2463 if (!pickleIterator.ReadInt(&entryCount))
2465 if (!pickleIterator.ReadInt(¤tEntry))
2468 std::vector<sessions::SerializedNavigationEntry> serializedEntries;
2469 serializedEntries.resize(entryCount);
2470 for (int i = 0; i < entryCount; ++i) {
2471 if (!serializedEntries.at(i).ReadFromPickle(&pickleIterator))
2481 std::vector<std::unique_ptr<content::NavigationEntry>> scopedEntries =
2482 sessions::ContentSerializedNavigationBuilder::ToNavigationEntries(
2483 serializedEntries, context()->browser_context());
2485 NavigationController& navigationController = web_contents_->GetController();
2487 if (currentEntry < 0)
2490 if (currentEntry >= static_cast<int>(scopedEntries.size()))
2491 currentEntry = scopedEntries.size() - 1;
2493 navigationController.Restore(currentEntry, RestoreType::kRestored,
2498 void EWebView::SetBrowserFont() {
2499 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
2500 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
2501 if (render_view_host) {
2502 IPC::Message* message =
2503 new EwkViewMsg_SetBrowserFont(render_view_host->GetRoutingID());
2505 if (render_view_host->IsRenderViewLive())
2506 render_view_host->Send(message);
2508 delayed_messages_.push_back(message);
2513 bool EWebView::IsDragging() const {
2514 return wcva()->wcva_helper()->IsDragging();
2517 void EWebView::ShowFileChooser(content::RenderFrameHost* render_frame_host,
2518 const blink::mojom::FileChooserParams& params) {
2519 if (!IsMobileProfile() && !IsWearableProfile())
2522 #if !defined(EWK_BRINGUP) // FIXME: m71 bringup
2523 if (params.capture) {
2524 const std::string capture_types[] = {"video/*", "audio/*", "image/*"};
2525 unsigned int capture_types_num =
2526 sizeof(capture_types) / sizeof(*capture_types);
2527 for (unsigned int i = 0; i < capture_types_num; ++i) {
2528 for (unsigned int j = 0; j < params.accept_types.size(); ++j) {
2529 if (UTF16ToUTF8(params.accept_types[j]) == capture_types[i]) {
2530 filechooser_mode_ = params.mode;
2531 LaunchCamera(params.accept_types[j]);
2537 file_chooser_.reset(
2538 new content::FileChooserControllerEfl(render_frame_host, ¶ms));
2539 file_chooser_->Open();
2543 #if !defined(EWK_BRINGUP) // FIXME: m67 bringup
2544 void EWebView::SetViewMode(blink::WebViewMode view_mode) {
2545 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
2546 if (!render_view_host)
2549 IPC::Message* message =
2550 new ViewMsg_SetViewMode(render_view_host->GetRoutingID(), view_mode);
2551 if (render_view_host->IsRenderViewLive()) {
2552 render_view_host->Send(message);
2554 delayed_messages_.push_back(message);
2559 gfx::Point EWebView::GetContextMenuPosition() const {
2560 return context_menu_position_;
2563 void EWebView::ShowContentsDetectedPopup(const char* message) {
2564 popup_controller_.reset(new PopupControllerEfl(this));
2565 popup_controller_->openPopup(message);
2568 void EWebView::RequestColorPicker(int r, int g, int b, int a) {
2569 input_picker_.reset(
2570 new InputPicker(this, web_contents_.get(), evas_object()));
2571 input_picker_->ShowColorPicker(r, g, b, a);
2574 bool EWebView::SetColorPickerColor(int r, int g, int b, int a) {
2575 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
2576 web_contents_->DidChooseColorInColorChooser(SkColorSetARGB(a, r, g, b));
2581 void EWebView::InputPickerShow(ui::TextInputType input_type,
2583 content::DateTimeChooserEfl* date_time_chooser) {
2584 input_picker_.reset(new InputPicker(this, web_contents_.get(), evas_object(),
2585 date_time_chooser));
2586 input_picker_->ShowDatePicker(input_type, input_value);
2589 void EWebView::LoadNotFoundErrorPage(const std::string& invalidUrl) {
2590 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
2591 RenderFrameHost* render_frame_host = web_contents_->GetPrimaryMainFrame();
2592 if (render_frame_host)
2593 render_frame_host->Send(new EwkFrameMsg_LoadNotFoundErrorPage(
2594 render_frame_host->GetRoutingID(), invalidUrl));
2598 std::string EWebView::GetPlatformLocale() {
2599 char* local_default = setlocale(LC_CTYPE, 0);
2601 return std::string("en-US");
2602 std::string locale = std::string(local_default);
2603 size_t position = locale.find('_');
2604 if (position != std::string::npos)
2605 locale.replace(position, 1, "-");
2606 position = locale.find('.');
2607 if (position != std::string::npos)
2608 locale = locale.substr(0, position);
2612 int EWebView::StartInspectorServer(int port) {
2613 #if BUILDFLAG(IS_TIZEN_TV)
2615 use_early_rwi_ = false;
2616 rwi_info_showed_ = false;
2618 if (!context_->GetImpl()->GetInspectorServerState()) {
2620 if (!devtools_http_handler::DevToolsPortManager::GetInstance()
2621 ->GetValidPort(validPort))
2627 return context_->InspectorServerStart(port);
2630 bool EWebView::StopInspectorServer() {
2631 #if BUILDFLAG(IS_TIZEN_TV)
2633 use_early_rwi_ = false;
2634 rwi_info_showed_ = false;
2637 return context_->InspectorServerStop();
2640 void EWebView::InvokeWebProcessCrashedCallback() {
2641 DCHECK_CURRENTLY_ON(BrowserThread::UI);
2642 const GURL last_url = GetURL();
2643 bool callback_handled = false;
2644 SmartCallback<EWebViewCallbacks::WebProcessCrashed>().call(&callback_handled);
2645 if (!callback_handled)
2646 LoadHTMLString(kRendererCrashedHTMLMessage, NULL,
2647 last_url.possibly_invalid_spec().c_str());
2650 void EWebView::SyncAcceptLanguages(const std::string& accept_languages) {
2651 web_contents_->GetMutableRendererPrefs()->accept_languages = accept_languages;
2652 web_contents_->SyncRendererPrefs();
2653 BrowserContext* browser_context = web_contents_->GetBrowserContext();
2654 if (!browser_context)
2657 auto* storage_partition = browser_context->GetDefaultStoragePartition();
2658 if (!storage_partition)
2661 if (auto* network_context = storage_partition->GetNetworkContext())
2662 network_context->SetAcceptLanguage(accept_languages);
2665 #if BUILDFLAG(IS_TIZEN_TV)
2666 bool EWebView::EdgeScrollBy(int delta_x, int delta_y) {
2667 if ((delta_x == 0 && delta_y == 0) || is_processing_edge_scroll_)
2670 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
2671 if (!render_view_host)
2677 gfx::Point offset = gfx::Point(delta_x, delta_y);
2678 gfx::Point mouse_position;
2679 GetMousePosition(mouse_position);
2680 is_processing_edge_scroll_ = true;
2682 static_cast<RenderViewHostImpl*>(render_view_host)
2684 ->GetAssociatedFrameWidget()
2685 ->EdgeScrollBy(offset, mouse_position);
2689 void EWebView::GetMousePosition(gfx::Point& mouse_position) {
2690 int mouse_x, mouse_y;
2691 evas_pointer_output_xy_get(GetEvas(), &mouse_x, &mouse_y);
2692 Evas_Coord x, y, width, height;
2693 evas_object_geometry_get(evas_object(), &x, &y, &width, &height);
2697 else if (mouse_y > y + height)
2698 mouse_y = y + height - 1;
2701 else if (mouse_x > x + width)
2702 mouse_x = x + width - 1;
2708 display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
2710 display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
2712 mouse_position.set_x(mouse_x);
2713 mouse_position.set_y(mouse_y);
2716 void EWebView::InvokeEdgeScrollByCallback(const gfx::Point& offset,
2718 is_processing_edge_scroll_ = false;
2721 SmartCallback<EWebViewCallbacks::EdgeScrollLeft>().call(&handled);
2722 else if (offset.x() > 0)
2723 SmartCallback<EWebViewCallbacks::EdgeScrollRight>().call(&handled);
2726 SmartCallback<EWebViewCallbacks::EdgeScrollTop>().call(&handled);
2727 else if (offset.y() > 0)
2728 SmartCallback<EWebViewCallbacks::EdgeScrollBottom>().call(&handled);
2732 void EWebView::HandleRendererProcessCrash() {
2733 content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
2734 base::BindOnce(&EWebView::InvokeWebProcessCrashedCallback,
2735 base::Unretained(this)));
2738 void EWebView::InitializeContent() {
2739 LOG(INFO) << "eweb_view.cc InitializeContent" ;
2740 #if BUILDFLAG(IS_TIZEN_TV)
2741 // When initialize content init inspector server
2742 InitInspectorServer();
2744 WebContents* new_contents = create_new_window_web_contents_cb_.Run(this);
2745 if (!new_contents) {
2746 WebContents::CreateParams params(context_->browser_context());
2747 web_contents_.reset(
2748 new WebContentsImplEfl(context_->browser_context(), this));
2749 static_cast<WebContentsImpl*>(web_contents_.get())
2750 ->Init(params, blink::FramePolicy());
2752 web_contents_.reset(new_contents);
2754 // When a new webview is created in response to a request from the
2755 // engine, the BrowserContext instance of the originator WebContents
2756 // is used by the newly created WebContents object.
2757 // See more in WebContentsImplEfl::HandleNewWebContentsCreate.
2759 // Hence, if as part of the WebView creation, the embedding APP
2760 // passes in a Ewk_Context instance that wraps a different instance of
2761 // BrowserContext than the one the originator WebContents holds,
2762 // undefined behavior can be seen.
2764 // This is a snippet code that illustrate the scenario:
2767 // evas_object_smart_callback_add(web_view_, "create,window",
2768 // &OnNewWindowRequest, this);
2771 // void OnNewWindowRequest(void *data, Evas_Object*, void* out_view) {
2773 // EvasObject* new_web_view = ewk_view_add_with_context(GetEvas(),
2774 // ewk_context_new());
2775 // *static_cast<Evas_Object**>(out_view) = new_web_view;
2779 // The new Ewk_Context object created and passed in as parameter to
2780 // ewk_view_add_with_context wraps a different instance of BrowserContext
2781 // than the one the new WebContents object will hold.
2783 // CHECK below aims at catching misuse of this API.
2784 bool should_crash = context_->GetImpl()->browser_context() !=
2785 web_contents_->GetBrowserContext();
2788 << "BrowserContext of new WebContents does not match EWebView's. "
2789 << "Please see 'ewk_view_add*' documentation. "
2790 << "Aborting execution ...";
2794 web_contents_delegate_.reset(new WebContentsDelegateEfl(this));
2795 web_contents_->SetDelegate(web_contents_delegate_.get());
2797 // EWebView's delegate. Calls to WebContentsImplEfl and
2798 // WebContentsViewAuraHelperEfl are delegated to this class.
2799 // For more details, refer commit message of patch 301647.
2800 webview_delegate_.reset(new WebViewDelegateEfl(this));
2801 WebContentsImplEfl* wc_efl =
2802 static_cast<WebContentsImplEfl*>(web_contents_.get());
2803 wc_efl->SetWebviewDelegate(webview_delegate_.get());
2804 wcva()->wcva_helper()->SetWebviewDelegate(webview_delegate_.get());
2806 back_forward_list_.reset(new _Ewk_Back_Forward_List(web_contents_.get()));
2808 permission_popup_manager_.reset(new PermissionPopupManager(evas_object_));
2809 gin_native_bridge_dispatcher_host_.reset(
2810 new content::GinNativeBridgeDispatcherHost(web_contents_.get()));
2813 static_cast<WebContentsImplEfl*>(web_contents_.get())->GetEflNativeView();
2814 evas_object_smart_member_add(native_view_, evas_object_);
2815 static_cast<WebContentsImpl*>(web_contents_.get())
2816 ->set_ewk_view(evas_object_);
2817 InitializeWindowTreeHost();
2820 #if BUILDFLAG(IS_TIZEN_TV)
2821 void EWebView::OnDialogClosed() {
2822 if (!use_early_rwi_)
2825 use_early_rwi_ = false;
2826 LOG(INFO) << "[FAST RWI] SetURL Restore [" << rwi_gurl_.spec()
2827 << "] from [about:blank]";
2830 rwi_info_showed_ = true;
2833 void EWebView::InitInspectorServer() {
2834 if (devtools_http_handler::DevToolsPortManager::GetInstance()
2835 ->ProcessCompare()) {
2836 int res = StartInspectorServer(0);
2838 LOG(INFO) << "InitInspectorServer SetPort";
2839 devtools_http_handler::DevToolsPortManager::GetInstance()->SetPort(res);
2845 #if defined(TIZEN_TBM_SUPPORT)
2846 void EWebView::SetOffscreenRendering(bool enable) {
2848 host_->compositor()->SetUseTbmSuraceForOffscreenRendering(enable);
2852 void EWebView::InitializeWindowTreeHost() {
2853 CHECK(aura::Env::GetInstance());
2855 int x, y, width, height;
2857 ecore_evas_ecore_evas_get(evas_object_evas_get(native_view_));
2858 ecore_evas_geometry_get(ee, &x, &y, &width, &height);
2860 gfx::Rect bounds(x, y, width, height);
2861 ui::PlatformWindowInitProperties properties;
2862 properties.bounds = bounds;
2864 host_ = aura::WindowTreeHost::Create(std::move(properties));
2866 host_->window()->Show();
2869 std::make_unique<aura::test::TestFocusClient>(host_->window());
2870 window_parenting_client_ =
2871 std::make_unique<aura::test::TestWindowParentingClient>(host_->window());
2872 compositor_observer_ = std::make_unique<ui::CompositorObserverEfl>(
2873 host_->compositor(), web_contents_.get());
2875 aura::Window* content = web_contents_->GetNativeView();
2876 aura::Window* parent = host_->window();
2877 if (!parent->Contains(content)) {
2878 parent->AddChild(content);
2881 content->SetBounds(bounds);
2882 RenderWidgetHostView* host_view = web_contents_->GetRenderWidgetHostView();
2884 host_view->SetSize(bounds.size());
2887 #if BUILDFLAG(IS_TIZEN) && !defined(EWK_BRINGUP)
2888 void EWebView::cameraResultCb(service_h request,
2890 service_result_e result,
2892 if (!IsMobileProfile() && !IsWearableProfile())
2895 EWebView* webview = static_cast<EWebView*>(data);
2896 RenderViewHost* render_view_host =
2897 webview->web_contents_->GetRenderViewHost();
2898 if (result == SERVICE_RESULT_SUCCEEDED) {
2902 ret = service_get_extra_data_array(reply, SERVICE_DATA_SELECTED,
2903 &filesarray, &number);
2905 for (int i = 0; i < number; i++) {
2906 std::vector<ui::SelectedFileInfo> files;
2907 if (!render_view_host) {
2910 if (filesarray[i]) {
2911 GURL url(filesarray[i]);
2912 if (!url.is_valid()) {
2913 base::FilePath path(url.SchemeIsFile() ? url.path()
2915 files.push_back(ui::SelectedFileInfo(path, base::FilePath()));
2918 render_view_host->FilesSelectedInChooser(files,
2919 webview->filechooser_mode_);
2923 std::vector<ui::SelectedFileInfo> files;
2924 if (render_view_host) {
2925 render_view_host->FilesSelectedInChooser(files,
2926 webview->filechooser_mode_);
2931 bool EWebView::LaunchCamera(std::u16string mimetype) {
2932 service_h svcHandle = 0;
2933 if (service_create(&svcHandle) < 0 || !svcHandle) {
2934 LOG(ERROR) << __FUNCTION__ << " Service Creation Failed ";
2937 service_set_operation(svcHandle, SERVICE_OPERATION_CREATE_CONTENT);
2938 service_set_mime(svcHandle, UTF16ToUTF8(mimetype).c_str());
2939 service_add_extra_data(svcHandle, "CALLER", "Browser");
2941 int ret = service_send_launch_request(svcHandle, cameraResultCb, this);
2942 if (ret != SERVICE_ERROR_NONE) {
2943 LOG(ERROR) << __FUNCTION__ << " Service Launch Failed ";
2944 service_destroy(svcHandle);
2947 service_destroy(svcHandle);
2952 void EWebView::UrlRequestSet(
2954 content::NavigationController::LoadURLType loadtype,
2958 content::NavigationController::LoadURLParams params(gurl);
2959 params.load_type = loadtype;
2960 params.override_user_agent = NavigationController::UA_OVERRIDE_TRUE;
2963 std::string s(body);
2965 network::ResourceRequestBody::CreateFromBytes(s.data(), s.size());
2968 net::HttpRequestHeaders header;
2970 Eina_Iterator* it = eina_hash_iterator_tuple_new(headers);
2972 while (eina_iterator_next(it, reinterpret_cast<void**>(&t))) {
2974 const char* value_str =
2975 t->data ? static_cast<const char*>(t->data) : "";
2976 base::StringPiece name = static_cast<const char*>(t->key);
2977 base::StringPiece value = value_str;
2978 header.SetHeader(name, value);
2979 // net::HttpRequestHeaders.ToString() returns string with newline
2980 params.extra_headers += header.ToString();
2983 eina_iterator_free(it);
2986 web_contents_->GetController().LoadURLWithParams(params);
2989 #if defined(TIZEN_VIDEO_HOLE)
2990 void EWebView::EnableVideoHoleSupport() {
2991 if (!web_contents_->GetPrimaryMainFrame() ||
2992 !web_contents_->GetPrimaryMainFrame()->IsRenderFrameLive() || !rwhva()) {
2993 pending_video_hole_setting_ = true;
2997 EnableVideoHoleSupportInternal();
3000 void EWebView::EnableVideoHoleSupportInternal() {
3001 if (settings_->getPreferences().video_hole_enabled)
3003 settings_->getPreferences().video_hole_enabled = true;
3004 UpdateWebKitPreferences();
3008 bool EWebView::HandleShow() {
3016 bool EWebView::HandleHide() {
3024 bool EWebView::HandleMove(int x, int y) {
3027 evas_object_move(native_view_, x, y);
3029 #if defined(TIZEN_VIDEO_HOLE) && !defined(EWK_BRINGUP)
3031 rwhva()->offscreen_helper()->DidMoveWebView();
3035 context_menu_->Move(x, y);
3040 bool EWebView::HandleResize(int width, int height) {
3043 evas_object_resize(native_view_, width, height);
3045 if (select_picker_) {
3046 AdjustViewPortHeightToPopupMenu(true /* is_popup_menu_visible */);
3047 ScrollFocusedNodeIntoView();
3050 #if defined(USE_AURA) && BUILDFLAG(IS_TIZEN_TV)
3053 evas_object_geometry_get(native_view_, &x, &y, nullptr, nullptr);
3054 gfx::Rect bounds(x, y, width, height);
3055 host_->SetBoundsInPixels(bounds);
3062 bool EWebView::HandleTextSelectionDown(int x, int y) {
3063 if (!GetSelectionController())
3065 return GetSelectionController()->TextSelectionDown(x, y);
3068 bool EWebView::HandleTextSelectionUp(int x, int y) {
3069 if (!GetSelectionController())
3071 return GetSelectionController()->TextSelectionUp(x, y);
3074 void EWebView::HandleTapGestureForSelection(bool is_content_editable) {
3075 if (!GetSelectionController())
3078 GetSelectionController()->PostHandleTapGesture(is_content_editable);
3081 void EWebView::HandleZoomGesture(blink::WebGestureEvent& event) {
3082 blink::WebInputEvent::Type event_type = event.GetType();
3083 if (event_type == blink::WebInputEvent::Type::kGestureDoubleTap ||
3084 event_type == blink::WebInputEvent::Type::kGesturePinchBegin) {
3085 SmartCallback<EWebViewCallbacks::ZoomStarted>().call();
3087 if (event_type == blink::WebInputEvent::Type::kGestureDoubleTap ||
3088 event_type == blink::WebInputEvent::Type::kGesturePinchEnd) {
3089 SmartCallback<EWebViewCallbacks::ZoomFinished>().call();
3093 bool EWebView::GetHorizontalPanningHold() const {
3096 return rwhva()->offscreen_helper()->GetHorizontalPanningHold();
3099 void EWebView::SetHorizontalPanningHold(bool hold) {
3101 rwhva()->offscreen_helper()->SetHorizontalPanningHold(hold);
3104 bool EWebView::GetVerticalPanningHold() const {
3107 return rwhva()->offscreen_helper()->GetVerticalPanningHold();
3110 void EWebView::SetVerticalPanningHold(bool hold) {
3112 rwhva()->offscreen_helper()->SetVerticalPanningHold(hold);
3115 void EWebView::SendDelayedMessages(RenderViewHost* render_view_host) {
3116 DCHECK(render_view_host);
3118 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
3119 content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
3120 base::BindOnce(&EWebView::SendDelayedMessages, base::Unretained(this),
3125 for (auto iter = delayed_messages_.begin(); iter != delayed_messages_.end();
3127 IPC::Message* message = *iter;
3128 message->set_routing_id(render_view_host->GetRoutingID());
3129 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
3130 render_view_host->Send(message);
3134 delayed_messages_.clear();
3137 void EWebView::ClosePage() {
3138 web_contents_->ClosePage();
3141 bool EWebView::SetMainFrameScrollbarVisible(bool visible) {
3142 if (web_contents_->GetPrimaryMainFrame()->IsRenderFrameLive() && rwhva())
3143 rwhva()->host()->SetMainFrameScrollbarVisible(visible);
3147 bool EWebView::GetMainFrameScrollbarVisible(
3148 Ewk_View_Main_Frame_Scrollbar_Visible_Get_Callback callback,
3153 MainFrameScrollbarVisibleGetCallback* callback_ptr =
3154 new MainFrameScrollbarVisibleGetCallback;
3155 callback_ptr->Set(callback, user_data);
3157 main_frame_scrollbar_visible_callback_map_.Add(callback_ptr);
3158 rwhva()->host()->RequestMainFrameScrollbarVisible(callback_id);
3162 void EWebView::InvokeMainFrameScrollbarVisibleCallback(int callback_id,
3164 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
3165 content::GetUIThreadTaskRunner({})->PostTask(
3167 base::BindOnce(&EWebView::InvokeMainFrameScrollbarVisibleCallback,
3168 base::Unretained(this), visible, callback_id));
3172 MainFrameScrollbarVisibleGetCallback* callback =
3173 main_frame_scrollbar_visible_callback_map_.Lookup(callback_id);
3177 main_frame_scrollbar_visible_callback_map_.Remove(callback_id);
3178 callback->Run(evas_object(), visible);
3179 main_frame_scrollbar_visible_callback_map_.Remove(callback_id);
3182 void EWebView::OnOverscrolled(const gfx::Vector2dF& accumulated_overscroll,
3183 const gfx::Vector2dF& latest_overscroll_delta) {
3184 const gfx::Vector2dF old_overscroll =
3185 accumulated_overscroll - latest_overscroll_delta;
3187 if (latest_overscroll_delta.x() && !old_overscroll.x()) {
3188 latest_overscroll_delta.x() < 0
3189 ? SmartCallback<EWebViewCallbacks::OverscrolledLeft>().call()
3190 : SmartCallback<EWebViewCallbacks::OverscrolledRight>().call();
3192 if (latest_overscroll_delta.y() && !old_overscroll.y()) {
3193 latest_overscroll_delta.y() < 0
3194 ? SmartCallback<EWebViewCallbacks::OverscrolledTop>().call()
3195 : SmartCallback<EWebViewCallbacks::OverscrolledBottom>().call();
3199 void EWebView::SetDidChangeThemeColorCallback(
3200 Ewk_View_Did_Change_Theme_Color_Callback callback,
3202 did_change_theme_color_callback_.Set(callback, user_data);
3205 void EWebView::DidChangeThemeColor(const SkColor& color) {
3206 did_change_theme_color_callback_.Run(evas_object_, color);
3209 #if BUILDFLAG(IS_TIZEN_TV)
3210 void EWebView::DrawLabel(Evas_Object* image, Eina_Rectangle rect) {
3212 rwhva()->offscreen_helper()->DrawLabel(image, rect);
3215 void EWebView::DeactivateAtk(bool deactivated) {
3216 #if defined(TIZEN_ATK_SUPPORT)
3217 EWebAccessibilityUtil::GetInstance()->Deactivate(deactivated);
3221 void EWebView::ClearLabels() {
3223 rwhva()->offscreen_helper()->ClearLabels();
3227 void EWebView::RequestManifest(Ewk_View_Request_Manifest_Callback callback,
3229 web_contents_delegate_->RequestManifestInfo(callback, user_data);
3232 void EWebView::DidRespondRequestManifest(
3233 _Ewk_View_Request_Manifest* manifest,
3234 Ewk_View_Request_Manifest_Callback callback,
3236 callback(evas_object_, manifest, user_data);
3239 void EWebView::SetSessionTimeout(uint64_t timeout) {
3240 if (web_contents_->GetPrimaryMainFrame()->IsRenderFrameLive() && rwhva())
3241 rwhva()->host()->SetLongPollingGlobalTimeout(timeout);
3244 void EWebView::SetBeforeUnloadConfirmPanelCallback(
3245 Ewk_View_Before_Unload_Confirm_Panel_Callback callback,
3247 GetJavaScriptDialogManagerEfl()->SetBeforeUnloadConfirmPanelCallback(
3248 callback, user_data);
3251 void EWebView::ReplyBeforeUnloadConfirmPanel(Eina_Bool result) {
3252 GetJavaScriptDialogManagerEfl()->ReplyBeforeUnloadConfirmPanel(result);
3255 #if defined(TIZEN_PEPPER_EXTENSIONS)
3256 void EWebView::InitializePepperExtensionSystem() {
3257 RegisterPepperExtensionDelegate();
3261 EwkExtensionSystemDelegate* EWebView::GetExtensionDelegate() {
3262 RenderFrameHost* render_frame_host = web_contents_->GetPrimaryMainFrame();
3263 if (!render_frame_host)
3266 return static_cast<EwkExtensionSystemDelegate*>(
3267 ExtensionSystemDelegateManager::GetInstance()->GetDelegateForFrame(render_frame_id_));
3270 void EWebView::SetWindowId() {
3271 EwkExtensionSystemDelegate* delegate = GetExtensionDelegate();
3273 LOG(WARNING) << "No delegate is available to set window id";
3276 Evas_Object* main_wind =
3277 efl::WindowFactory::GetHostWindow(web_contents_.get());
3279 LOG(ERROR) << "Can`t get main window";
3282 delegate->SetWindowId(main_wind);
3285 void EWebView::SetPepperExtensionWidgetInfo(Ewk_Value widget_pepper_ext_info) {
3286 EwkExtensionSystemDelegate* delegate = GetExtensionDelegate();
3288 LOG(WARNING) << "No delegate is available to set extension info";
3291 delegate->SetExtensionInfo(widget_pepper_ext_info);
3294 void EWebView::SetPepperExtensionCallback(Generic_Sync_Call_Callback cb,
3296 EwkExtensionSystemDelegate* delegate = GetExtensionDelegate();
3298 LOG(WARNING) << "No delegate is available to set generic callback";
3301 delegate->SetGenericSyncCallback(cb, data);
3304 void EWebView::RegisterPepperExtensionDelegate() {
3305 RenderFrameHost* render_frame_host = web_contents_->GetPrimaryMainFrame();
3306 if (!render_frame_host) {
3307 LOG(WARNING) << "render_frame_host is nullptr, can't register delegate";
3311 render_frame_id_.render_process_id = render_frame_host->GetProcess()->GetID();
3312 render_frame_id_.render_frame_id = render_frame_host->GetRoutingID();
3314 EwkExtensionSystemDelegate* delegate = new EwkExtensionSystemDelegate;
3315 ExtensionSystemDelegateManager::GetInstance()->RegisterDelegate(
3316 render_frame_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 if (!ExtensionSystemDelegateManager::GetInstance()->UnregisterDelegate(render_frame_id_))
3325 LOG(WARNING) << "Unregistering pepper extension delegate failed";
3327 #endif // defined(TIZEN_PEPPER_EXTENSIONS)
3329 void EWebView::SetExceededIndexedDatabaseQuotaCallback(
3330 Ewk_View_Exceeded_Indexed_Database_Quota_Callback callback,
3332 exceeded_indexed_db_quota_callback_.Set(callback, user_data);
3333 content::BrowserContextEfl* browser_context =
3334 static_cast<content::BrowserContextEfl*>(
3335 web_contents_->GetBrowserContext());
3336 if (browser_context) {
3337 browser_context->GetSpecialStoragePolicyEfl()->SetQuotaExceededCallback(
3338 base::BindOnce(&EWebView::InvokeExceededIndexedDatabaseQuotaCallback,
3339 base::Unretained(this)));
3343 void EWebView::InvokeExceededIndexedDatabaseQuotaCallback(
3345 int64_t current_quota) {
3346 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
3347 content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
3348 base::BindOnce(&EWebView::InvokeExceededIndexedDatabaseQuotaCallback,
3349 base::Unretained(this), origin, current_quota));
3352 LOG(INFO) << __func__ << "()" << origin << ", " << current_quota;
3353 CHECK(!exceeded_indexed_db_quota_origin_.get());
3354 exceeded_indexed_db_quota_origin_.reset(new Ewk_Security_Origin(origin));
3355 exceeded_indexed_db_quota_callback_.Run(
3356 evas_object_, exceeded_indexed_db_quota_origin_.get(), current_quota);
3359 void EWebView::ExceededIndexedDatabaseQuotaReply(bool allow) {
3360 if (!exceeded_indexed_db_quota_origin_.get()) {
3361 LOG(WARNING) << __func__ << "() : callback is not invoked!";
3364 LOG(INFO) << __func__ << "()" << exceeded_indexed_db_quota_origin_->GetURL()
3366 content::BrowserContextEfl* browser_context =
3367 static_cast<content::BrowserContextEfl*>(
3368 web_contents_->GetBrowserContext());
3369 if (browser_context) {
3370 browser_context->GetSpecialStoragePolicyEfl()->SetUnlimitedStoragePolicy(
3371 exceeded_indexed_db_quota_origin_->GetURL(), allow);
3373 exceeded_indexed_db_quota_origin_.reset();
3376 bool EWebView::ShouldIgnoreNavigation(
3377 content::NavigationHandle* navigation_handle) {
3378 if (!navigation_handle->GetURL().is_valid() ||
3379 !navigation_handle->GetURL().SchemeIs("appcontrol") ||
3380 (!navigation_handle->HasUserGesture() &&
3381 !navigation_handle->WasServerRedirect())) {
3385 _Ewk_App_Control app_control(
3386 this, navigation_handle->GetURL().possibly_invalid_spec());
3387 return app_control.Proceed();
3390 #if BUILDFLAG(IS_TIZEN_TV)
3391 void EWebView::AddDynamicCertificatePath(const std::string& host,
3392 const std::string& cert_path) {
3393 web_contents_->AddDynamicCertificatePath(host, cert_path);
3397 bool EWebView::SetVisibility(bool enable) {
3402 web_contents_->WasShown();
3404 web_contents_->WasHidden();
3409 void EWebView::SetDoNotTrack(Eina_Bool enable) {
3410 // enable: 0 User tend to allow tracking on the target site.
3411 // enable: 1 User tend to not be tracked on the target site.
3412 if (web_contents_->GetMutableRendererPrefs()->enable_do_not_track == enable)
3415 // Set navigator.doNotTrack attribute
3416 web_contents_->GetMutableRendererPrefs()->enable_do_not_track = enable;
3417 web_contents_->SyncRendererPrefs();
3419 // Set or remove DNT HTTP header, the effects will depend on design of target
3425 context()->HTTPCustomHeaderAdd("DNT", "1");
3427 context()->HTTPCustomHeaderRemove("DNT");
3430 #if defined(TIZEN_ATK_SUPPORT)
3431 void EWebView::UpdateSpatialNavigationStatus(Eina_Bool enable) {
3432 if (settings_->getPreferences().spatial_navigation_enabled == enable)
3435 settings_->getPreferences().spatial_navigation_enabled = enable;
3436 WebContentsImpl* wc = static_cast<WebContentsImpl*>(web_contents_.get());
3438 wc->SetSpatialNavigationEnabled(enable);
3441 void EWebView::UpdateAccessibilityStatus(Eina_Bool enable) {
3442 if (settings_->getPreferences().atk_enabled == enable)
3445 settings_->getPreferences().atk_enabled = enable;
3446 WebContentsImpl* wc = static_cast<WebContentsImpl*>(web_contents_.get());
3448 wc->SetAtkEnabled(enable);
3451 void EWebView::InitAtk() {
3452 #if defined(TIZEN_ATK_SUPPORT)
3453 EWebAccessibilityUtil::GetInstance()->ToggleAtk(lazy_initialize_atk_);
3457 /* LCOV_EXCL_START */
3458 bool EWebView::GetAtkStatus() {
3459 auto state = content::BrowserAccessibilityStateImpl::GetInstance();
3462 return state->IsAccessibleBrowser();
3464 /* LCOV_EXCL_STOP */
3467 #if BUILDFLAG(IS_TIZEN_TV)
3468 bool EWebView::SetMixedContents(bool allow) {
3469 MixedContentObserver* mixed_content_observer =
3470 MixedContentObserver::FromWebContents(web_contents_.get());
3471 return mixed_content_observer->MixedContentReply(allow);