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_util.h"
13 #include "base/functional/bind.h"
14 #include "base/json/json_string_value_serializer.h"
15 #include "base/logging.h"
16 #include "base/pickle.h"
17 #include "base/strings/escape.h"
18 #include "base/strings/utf_string_conversions.h"
19 #include "base/task/thread_pool.h"
20 #include "browser/javascript_dialog_manager_efl.h"
21 #include "browser/javascript_interface/gin_native_bridge_dispatcher_host.h"
22 #include "browser/navigation_policy_handler_efl.h"
23 #include "browser/scoped_allow_wait_for_legacy_web_view_api.h"
24 #include "browser/select_picker/select_picker_mobile.h"
25 #include "browser/select_picker/select_picker_tv.h"
26 #include "browser/web_view_browser_message_filter.h"
27 #include "browser_context_efl.h"
28 #include "common/content_client_efl.h"
29 #include "common/render_messages_ewk.h"
30 #include "common/version_info.h"
31 #include "common/web_contents_utils.h"
32 #include "components/sessions/content/content_serialized_navigation_builder.h"
33 #include "components/sessions/core/serialized_navigation_entry.h"
34 #include "content/browser/renderer_host/render_view_host_impl.h"
35 #include "content/browser/renderer_host/render_widget_host_view_aura.h"
36 #include "content/browser/renderer_host/ui_events_helper.h"
37 #include "content/browser/web_contents/web_contents_impl_efl.h"
38 #include "content/browser/web_contents/web_contents_view.h"
39 #include "content/browser/web_contents/web_contents_view_aura.h"
40 #include "content/browser/web_contents/web_contents_view_aura_helper_efl.h"
41 #include "content/common/content_client_export.h"
42 #include "content/public/browser/browser_message_filter.h"
43 #include "content/public/browser/browser_task_traits.h"
44 #include "content/public/browser/browser_thread.h"
45 #include "content/public/browser/host_zoom_map.h"
46 #include "content/public/browser/navigation_controller.h"
47 #include "content/public/browser/navigation_entry.h"
48 #include "content/public/browser/navigation_handle.h"
49 #include "content/public/common/content_client.h"
50 #include "content/public/common/content_switches.h"
51 #include "content/public/common/mhtml_generation_params.h"
52 #include "content/public/common/user_agent.h"
53 #include "net/base/filename_util.h"
54 #include "permission_popup_manager.cc"
55 #include "private/ewk_app_control_private.h"
56 #include "private/ewk_back_forward_list_private.h"
57 #include "private/ewk_context_private.h"
58 #include "private/ewk_frame_private.h"
59 #include "private/ewk_policy_decision_private.h"
60 #include "private/ewk_quota_permission_request_private.h"
61 #include "private/ewk_settings_private.h"
62 #include "private/webview_delegate_ewk.h"
63 #include "public/ewk_hit_test_internal.h"
64 #include "services/network/public/cpp/features.h"
65 #include "services/network/public/cpp/resource_request_body.h"
66 #include "services/network/public/mojom/network_context.mojom.h"
67 #include "skia/ext/platform_canvas.h"
68 #include "third_party/blink/public/common/page/page_zoom.h"
69 #include "third_party/blink/public/platform/web_string.h"
70 #include "tizen/system_info.h"
71 #include "ui/aura/env.h"
72 #include "ui/aura/test/test_focus_client.h"
73 #include "ui/aura/test/test_window_parenting_client.h"
74 #include "ui/aura/window.h"
75 #include "ui/base/clipboard/clipboard_helper_efl.h"
76 #include "ui/base/l10n/l10n_util.h"
77 #include "ui/compositor/compositor_observer_efl.h"
78 #include "ui/display/screen.h"
79 #include "ui/events/event_switches.h"
80 #include "ui/gfx/geometry/dip_util.h"
81 #include "ui/gfx/geometry/vector2d_f.h"
82 #include "ui/ozone/platform/efl/efl_event_handler.h"
83 #include "ui/platform_window/platform_window_init_properties.h"
84 #include "web_contents_delegate_efl.h"
85 #include "webview_delegate_efl.h"
89 #if defined(TIZEN_ATK_SUPPORT)
90 #include "content/browser/accessibility/browser_accessibility_state_impl.h"
91 #include "eweb_accessibility.h"
92 #include "eweb_accessibility_util.h"
95 #if defined(TIZEN_AUTOFILL_FW)
96 #include "browser/autofill/autofill_request_manager.h"
97 #include "components/autofill/core/common/autofill_switches.h"
100 #if BUILDFLAG(IS_TIZEN_TV)
101 #include "browser/mixed_content_observer.h"
102 #include "common/application_type.h"
103 #include "devtools_port_manager.h"
104 #include "private/ewk_file_chooser_request_private.h"
105 #include "public/ewk_media_downloadable_font_info.h"
106 #include "public/ewk_user_media_internal.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->ewk_view(), 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::FromEwkView(Evas_Object* ewk_view) {
304 return WebViewDelegateEwk::GetInstance().GetEWebViewFromEwkView(ewk_view);
307 void EWebView::VisibleContentChangedCallback(void* user_data,
308 Evas_Object* /*object*/,
310 auto view = static_cast<EWebView*>(user_data);
311 auto rect = static_cast<Eina_Rectangle*>(event_info);
312 view->GetSelectionController()->SetCustomVisibleViewRect(
313 gfx::Rect(rect->x, rect->y, rect->w, rect->h));
316 void EWebView::OnCustomScrollBeginCallback(void* user_data,
317 Evas_Object* /*object*/,
318 void* /*event_info*/) {
319 auto* view = static_cast<EWebView*>(user_data);
320 if (auto* selection_controller = view->GetSelectionController())
321 selection_controller->SetControlsTemporarilyHidden(true,true);
324 void EWebView::OnCustomScrollEndCallback(void* user_data,
325 Evas_Object* /*object*/,
326 void* /*event_info*/) {
327 auto* view = static_cast<EWebView*>(user_data);
328 if (auto* selection_controller = view->GetSelectionController())
329 selection_controller->SetControlsTemporarilyHidden(false,true);
332 EWebView::EWebView(Ewk_Context* context, Evas_Object* ewk_view)
335 efl_main_layout_(ewk_view),
336 mouse_events_enabled_(false),
337 text_zoom_factor_(1.0),
338 current_find_request_id_(find_request_id_counter_++),
340 hit_test_completion_(base::WaitableEvent::ResetPolicy::AUTOMATIC,
341 base::WaitableEvent::InitialState::NOT_SIGNALED),
342 page_scale_factor_(1.0),
345 #if BUILDFLAG(IS_TIZEN_TV)
346 is_processing_edge_scroll_(false),
347 use_early_rwi_(false),
348 rwi_info_showed_(false),
350 #if defined(TIZEN_PEPPER_EXTENSIONS)
351 render_frame_id_{0, 0},
353 is_initialized_(false) {
354 LOG(INFO) << "EWebView: " << this;
356 evas_object_smart_callback_add(ewk_view_, kVisibleContentChangedSignalName,
357 VisibleContentChangedCallback, this);
359 evas_object_smart_callback_add(ewk_view_, kCustomScrollBeginSignalName,
360 OnCustomScrollBeginCallback, this);
361 evas_object_smart_callback_add(ewk_view_, kCustomScrollEndSignalName,
362 OnCustomScrollEndCallback, this);
363 #if BUILDFLAG(IS_TIZEN)
364 window_rotate_handler_ = ecore_event_handler_add(
365 ECORE_WL2_EVENT_WINDOW_ROTATE, RotateWindowCb, this);
370 void EWebView::Initialize() {
371 if (is_initialized_) {
377 scroll_detector_.reset(new ScrollDetector(this));
379 #if defined(TIZEN_PEPPER_EXTENSIONS)
380 InitializePepperExtensionSystem();
382 DCHECK(web_contents_->GetRenderViewHost());
383 // Settings (content::WebPreferences) will be initalized by
384 // RenderViewHostImpl::ComputeWebkitPrefs() based on command line switches.
386 new Ewk_Settings(ewk_view_, web_contents_->GetOrCreateWebPreferences()));
387 #if defined(TIZEN_ATK_SUPPORT)
388 std::unique_ptr<EWebAccessibilityObserver> observer(
389 new EWebAccessibilityObserver(this));
390 eweb_accessibility_.reset(new EWebAccessibility(
391 ewk_view_, web_contents_.get(), std::move(observer)));
392 lazy_initialize_atk_ = true;
395 base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess();
396 if (cmdline->HasSwitch(switches::kTouchEventFeatureDetection)) {
397 SetTouchEventsEnabled(
398 cmdline->GetSwitchValueASCII(switches::kTouchEventFeatureDetection) ==
399 switches::kTouchEventFeatureDetectionEnabled);
401 SetMouseEventsEnabled(true);
404 std::string user_agent =
405 EflWebView::VersionInfo::GetInstance()->DefaultUserAgent();
406 web_contents_->SetUserAgentOverride(
407 blink::UserAgentOverride::UserAgentOnly(user_agent),
408 false /* override_in_new_tabs */);
410 elm_object_tree_focus_allow_set(efl_main_layout_, EINA_TRUE);
411 is_initialized_ = true;
412 evas_object_event_callback_add(efl_main_layout_, EVAS_CALLBACK_RESIZE,
413 EWebView::NativeViewResize, this);
415 auto cbce = static_cast<ContentBrowserClientEfl*>(
416 content::GetContentClientExport()->browser());
417 // Initialize accept languages
418 SyncAcceptLanguages(cbce->GetAcceptLangs(nullptr));
419 accept_langs_changed_callback_ = base::BindRepeating(
420 &EWebView::SyncAcceptLanguages, base::Unretained(this));
421 cbce->AddAcceptLangsChangedCallback(accept_langs_changed_callback_);
423 // If EWebView is created by window.open, RenderView is already created
424 // before initializing WebContents. So we should manually invoke
425 // EWebView::RenderViewReady here.
426 if (web_contents_->GetPrimaryMainFrame() &&
427 web_contents_->GetPrimaryMainFrame()->IsRenderFrameLive()) {
432 EWebView::~EWebView() {
433 LOG(INFO) << "EWebView: " << this;
434 weak_factory_.InvalidateWeakPtrs();
435 auto cbce = static_cast<ContentBrowserClientEfl*>(
436 content::GetContentClientExport()->browser());
437 cbce->RemoveAcceptLangsChangedCallback(accept_langs_changed_callback_);
438 #if defined(TIZEN_PEPPER_EXTENSIONS)
439 UnregisterPepperExtensionDelegate();
442 evas_object_event_callback_del(efl_main_layout_, EVAS_CALLBACK_RESIZE,
443 EWebView::NativeViewResize);
444 #if defined(USE_WAYLAND)
445 if (GetSettings()->getClipboardEnabled())
446 ClipboardHelperEfl::GetInstance()->MaybeInvalidateActiveWebview(this);
449 std::map<int64_t, WebViewAsyncRequestHitTestDataCallback*>::iterator
450 hit_test_callback_iterator;
451 for (hit_test_callback_iterator = hit_test_callback_.begin();
452 hit_test_callback_iterator != hit_test_callback_.end();
453 hit_test_callback_iterator++)
454 delete hit_test_callback_iterator->second;
455 hit_test_callback_.clear();
457 for (auto iter = delayed_messages_.begin(); iter != delayed_messages_.end();
461 delayed_messages_.clear();
463 if (!is_initialized_) {
467 #if defined(TIZEN_ATK_SUPPORT)
468 eweb_accessibility_.reset();
471 #if defined(TIZEN_AUTOFILL_FW)
472 if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
473 autofill::switches::kDisableAutofill)) {
474 autofill::AutofillRequestManager::GetInstance()->RemoveRequest(ewk_view());
478 select_picker_.reset();
479 context_menu_.reset();
480 mhtml_callback_map_.Clear();
482 compositor_observer_.reset();
484 // Release manually those scoped pointers to
485 // make sure they are released in correct order
486 web_contents_.reset();
487 web_contents_delegate_.reset();
489 // This code must be executed after WebContents deletion
490 // because WebContents depends on BrowserContext which
491 // is deleted along with EwkContext.
492 CHECK(!web_contents_);
494 permission_popup_manager_.reset();
496 gin_native_bridge_dispatcher_host_.reset();
499 evas_object_smart_callback_del(ewk_view_, kVisibleContentChangedSignalName,
500 VisibleContentChangedCallback);
501 evas_object_smart_callback_del(ewk_view_, kCustomScrollBeginSignalName,
502 OnCustomScrollBeginCallback);
503 evas_object_smart_callback_del(ewk_view_, kCustomScrollEndSignalName,
504 OnCustomScrollEndCallback);
505 #if BUILDFLAG(IS_TIZEN)
506 if (window_rotate_handler_)
507 ecore_event_handler_del(window_rotate_handler_);
512 content::RenderWidgetHostViewAura* EWebView::rwhva() const {
513 return static_cast<content::RenderWidgetHostViewAura*>(
514 web_contents_->GetRenderWidgetHostView());
517 content::WebContentsViewAura* EWebView::wcva() const {
518 WebContentsImpl* wc = static_cast<WebContentsImpl*>(web_contents_.get());
519 return static_cast<WebContentsViewAura*>(wc->GetView());
522 void EWebView::NativeViewResize(void* data,
526 auto thiz = static_cast<EWebView*>(data);
527 if (!thiz->context_menu_)
529 int x, y, width, height;
530 evas_object_geometry_get(obj, &x, &y, &width, &height);
531 thiz->context_menu_->Resize(gfx::Rect(x, y, width, height));
534 void EWebView::ResetContextMenuController() {
535 return context_menu_.reset();
538 #if BUILDFLAG(IS_TIZEN_TV)
539 void EWebView::RunPendingSetFocus(Eina_Bool focus) {
540 if (!web_contents_ || !rwhva() || (HasFocus() == focus))
542 rwhva()->offscreen_helper()->Focus(focus);
546 void EWebView::SetFocus(Eina_Bool focus) {
547 if (!web_contents_ || !rwhva() || (HasFocus() == focus))
550 #if BUILDFLAG(IS_TIZEN_TV)
551 if (web_contents_->GetPrimaryMainFrame()->IsRenderFrameLive()) {
552 rwhva()->offscreen_helper()->Focus(focus);
554 if (pending_setfocus_closure_)
555 pending_setfocus_closure_.Reset();
557 LOG(ERROR) << "SEND DELAY SET FOCUS BIND";
558 pending_setfocus_closure_ = base::BindOnce(&EWebView::RunPendingSetFocus,
559 base::Unretained(this), focus);
562 rwhva()->offscreen_helper()->Focus(focus);
566 Eina_Bool EWebView::HasFocus() const {
570 return rwhva()->offscreen_helper()->HasFocus() ? EINA_TRUE : EINA_FALSE;
573 Eina_Bool EWebView::AddJavaScriptMessageHandler(
575 Ewk_View_Script_Message_Cb callback,
577 if (!gin_native_bridge_dispatcher_host_)
580 return gin_native_bridge_dispatcher_host_->AddNamedObject(view, callback,
584 bool EWebView::SetPageVisibility(
585 Ewk_Page_Visibility_State page_visibility_state) {
589 // TODO: We should able to set 'prerender' or 'unloaded' as visibility state.
590 // http://www.w3.org/TR/page-visibility/#dom-document-visibilitystate
591 switch (page_visibility_state) {
592 case EWK_PAGE_VISIBILITY_STATE_VISIBLE:
593 rwhva()->offscreen_helper()->SetPageVisibility(true);
595 case EWK_PAGE_VISIBILITY_STATE_HIDDEN:
596 rwhva()->offscreen_helper()->SetPageVisibility(false);
598 case EWK_PAGE_VISIBILITY_STATE_PRERENDER:
608 bool EWebView::CreateNewWindow(
609 content::WebViewDelegate::WebContentsCreateCallback cb) {
610 create_new_window_web_contents_cb_ = cb;
611 Evas_Object* new_object = NULL;
612 SmartCallback<EWebViewCallbacks::CreateNewWindow>().call(&new_object);
613 create_new_window_web_contents_cb_ =
614 base::BindRepeating(&NullCreateWebContents);
619 Evas_Object* EWebView::GetHostWindowDelegate(const content::WebContents* wc) {
620 EWebView* thiz = WebViewFromWebContents(wc);
621 DCHECK(thiz->ewk_view_);
622 Evas_Object* parent = evas_object_above_get(thiz->ewk_view_);
624 LOG(WARNING) << "Could not find and visual parents for EWK smart object!.";
625 return thiz->ewk_view_;
628 if (elm_object_widget_check(parent)) {
629 Evas_Object* elm_parent = elm_object_top_widget_get(parent);
635 LOG(WARNING) << "Could not find elementary parent for WebView object!";
636 return thiz->ewk_view_;
639 Evas_Object* EWebView::GetElmWindow() const {
640 Evas_Object* parent = elm_object_parent_widget_get(ewk_view_);
641 return parent ? elm_object_top_widget_get(parent) : nullptr;
644 void EWebView::SetURL(const GURL& url, bool from_api) {
645 NavigationController::LoadURLParams params(url);
648 params.transition_type = ui::PageTransitionFromInt(
649 ui::PAGE_TRANSITION_LINK | ui::PAGE_TRANSITION_FROM_API);
652 #if BUILDFLAG(IS_TIZEN_TV)
653 if (use_early_rwi_) {
654 LOG(INFO) << "[FAST RWI] SetURL Replace [" << url.spec()
655 << "] to [about:blank]";
657 params.url = GURL("about:blank");
661 params.override_user_agent = NavigationController::UA_OVERRIDE_TRUE;
662 web_contents_->GetController().LoadURLWithParams(params);
665 const GURL& EWebView::GetURL() const {
666 return web_contents_->GetVisibleURL();
669 const GURL& EWebView::GetOriginalURL() const {
670 const auto entry = web_contents_->GetController().GetVisibleEntry();
672 return entry->GetOriginalRequestURL();
674 return web_contents_->GetVisibleURL();
677 void EWebView::Reload() {
678 web_contents_->GetController().Reload(content::ReloadType::NORMAL, true);
681 void EWebView::ReloadBypassingCache() {
682 web_contents_->GetController().Reload(content::ReloadType::BYPASSING_CACHE,
686 Eina_Bool EWebView::CanGoBack() {
687 return web_contents_->GetController().CanGoBack();
690 Eina_Bool EWebView::CanGoForward() {
691 return web_contents_->GetController().CanGoForward();
694 Eina_Bool EWebView::GoBack() {
695 if (!web_contents_->GetController().CanGoBack())
698 #if defined(TIZEN_AUTOFILL_FW)
699 if (web_contents_delegate_)
700 web_contents_delegate_->ResetLastInteractedElements();
703 web_contents_->GetController().GoBack();
707 Eina_Bool EWebView::GoForward() {
708 if (!web_contents_->GetController().CanGoForward())
711 web_contents_->GetController().GoForward();
715 void EWebView::Stop() {
716 if (web_contents_->IsLoading())
717 web_contents_->Stop();
720 void EWebView::Suspend() {
721 #if BUILDFLAG(IS_TIZEN)
722 CHECK(web_contents_);
723 if (IsMobileProfile() && web_contents_->IsFullscreen())
724 web_contents_->ExitFullscreen(true);
725 RenderViewHost* rvh = web_contents_->GetRenderViewHost();
726 RenderFrameHost* rfh = web_contents_->GetPrimaryMainFrame();
729 if (rvh->IsRenderViewLive()) {
730 RenderWidgetHostImpl* rwhi = static_cast<RenderWidgetHostImpl*>(rvh->GetWidget());
731 rwhi->PauseScheduledTasks();
736 void EWebView::Resume() {
737 #if BUILDFLAG(IS_TIZEN)
738 CHECK(web_contents_);
739 RenderViewHost* rvh = web_contents_->GetRenderViewHost();
740 RenderFrameHost* rfh = web_contents_->GetPrimaryMainFrame();
743 if (rvh->IsRenderViewLive() && rwhva())
744 rwhva()->host()->UnPauseScheduledTasks();
748 #if BUILDFLAG(IS_TIZEN_TV)
749 void EWebView::SetFloatVideoWindowState(bool enabled) {
750 RenderWidgetHostImpl* rwhi = static_cast<RenderWidgetHostImpl*>(
751 web_contents_->GetRenderViewHost()->GetWidget());
753 rwhi->SetFloatVideoWindowState(enabled);
755 #endif // IS_TIZEN_TV
757 double EWebView::GetTextZoomFactor() const {
758 if (text_zoom_factor_ < 0.0)
761 return text_zoom_factor_;
764 void EWebView::SetTextZoomFactor(double text_zoom_factor) {
765 if (text_zoom_factor_ == text_zoom_factor || text_zoom_factor < 0.0)
768 text_zoom_factor_ = text_zoom_factor;
769 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
770 if (!render_view_host)
772 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
773 render_view_host->Send(new ViewMsg_SetTextZoomFactor(
774 render_view_host->GetRoutingID(), text_zoom_factor));
778 double EWebView::GetPageZoomFactor() const {
779 return blink::PageZoomLevelToZoomFactor(
780 content::HostZoomMap::GetZoomLevel(web_contents_.get()));
783 void EWebView::SetPageZoomFactor(double page_zoom_factor) {
784 content::HostZoomMap::SetZoomLevel(
785 web_contents_.get(), blink::PageZoomFactorToZoomLevel(page_zoom_factor));
788 void EWebView::ExecuteEditCommand(const char* command, const char* value) {
789 EINA_SAFETY_ON_NULL_RETURN(command);
791 absl::optional<std::u16string> optional_value;
793 optional_value = absl::make_optional(base::ASCIIToUTF16(value));
795 WebContentsImpl* wc = static_cast<WebContentsImpl*>(web_contents_.get());
796 if (!wc || !wc->GetFocusedFrameWidgetInputHandler())
799 wc->GetFocusedFrameWidgetInputHandler()->ExecuteEditCommand(
800 std::string(command), optional_value);
803 #if BUILDFLAG(IS_TIZEN)
804 void EWebView::EnterDragState() {
805 if (IsMobileProfile()) {
806 if (RenderViewHost* render_view_host = web_contents_->GetRenderViewHost())
807 web_contents_->EnterDragState(render_view_host);
812 void EWebView::SetOrientation(int orientation) {
813 if (GetOrientation() == orientation)
816 if (orientation == 0 || orientation == 90 || orientation == 180 ||
817 orientation == 270) {
818 #if !defined(USE_AURA)
819 GetWebContentsViewEfl()->SetOrientation(orientation);
823 const Ecore_Evas* ee =
824 ecore_evas_ecore_evas_get(evas_object_evas_get(ewk_view_));
825 ecore_evas_screen_geometry_get(ee, nullptr, nullptr, &width, &height);
826 if (orientation == 90 || orientation == 270)
827 std::swap(width, height);
829 if (popup_controller_)
830 popup_controller_->SetPopupSize(width, height);
831 if (JavaScriptDialogManagerEfl* dialogMG = GetJavaScriptDialogManagerEfl())
832 dialogMG->SetPopupSize(width, height);
836 int EWebView::GetOrientation() {
837 #if !defined(USE_AURA)
838 return GetWebContentsViewEfl()->GetOrientation();
844 void EWebView::Show() {
845 evas_object_show(efl_main_layout_);
846 web_contents_->WasShown();
849 void EWebView::Hide() {
850 LOG(INFO) << "EWebView: " << this;
851 evas_object_hide(efl_main_layout_);
854 web_contents_->WasHidden();
857 void EWebView::SetViewAuthCallback(Ewk_View_Authentication_Callback callback,
859 authentication_cb_.Set(callback, user_data);
862 void EWebView::InvokeAuthCallback(LoginDelegateEfl* login_delegate,
864 const std::string& realm) {
865 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
867 auth_challenge_.reset(new _Ewk_Auth_Challenge(login_delegate, url, realm));
868 authentication_cb_.Run(ewk_view_, auth_challenge_.get());
870 if (!auth_challenge_->is_decided && !auth_challenge_->is_suspended) {
871 auth_challenge_->is_decided = true;
872 auth_challenge_->login_delegate->Cancel();
876 void EWebView::InvokePolicyResponseCallback(
877 _Ewk_Policy_Decision* policy_decision,
879 SmartCallback<EWebViewCallbacks::PolicyResponseDecide>().call(
882 if (policy_decision->isSuspended()) {
887 if (!policy_decision->isDecided())
888 policy_decision->Use();
890 policy_decision->SelfDeleteIfNecessary();
893 void EWebView::InvokePolicyNavigationCallback(
894 const NavigationPolicyParams& params,
896 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
898 SmartCallback<EWebViewCallbacks::SaveSessionData>().call();
900 std::unique_ptr<_Ewk_Policy_Decision> policy_decision(
901 new _Ewk_Policy_Decision(params));
903 SmartCallback<EWebViewCallbacks::NavigationPolicyDecision>().call(
904 policy_decision.get());
906 CHECK(!policy_decision->isSuspended());
908 // TODO: Navigation can't be suspended
909 // this aproach is synchronous and requires immediate response
910 // Maybe there is different approach (like resource throttle response
911 // mechanism) that allows us to
912 // suspend navigation
913 if (!policy_decision->isDecided())
914 policy_decision->Use();
916 *handled = policy_decision->GetNavigationPolicyHandler()->GetDecision() ==
917 NavigationPolicyHandlerEfl::Handled;
920 void EWebView::HandleTouchEvents(Ewk_Touch_Event_Type type,
921 const Eina_List* points,
922 const Evas_Modifier* modifiers) {
926 if (GetSettings()->touchFocusEnabled() &&
927 (type == EWK_TOUCH_START && eina_list_count(points) == 1)) {
931 EINA_LIST_FOREACH(points, l, data) {
932 const Ewk_Touch_Point* point = static_cast<Ewk_Touch_Point*>(data);
933 if (point->state == EVAS_TOUCH_POINT_STILL) {
934 // Chromium doesn't expect (and doesn't like) these events.
943 evas_object_geometry_get(ewk_view(), nullptr, &delta_y, nullptr, nullptr);
944 ui::TouchEvent touch_event =
945 ui::MakeTouchEvent(pt, point->state, point->id, 0, delta_y);
946 rwhva()->OnTouchEvent(&touch_event);
951 bool EWebView::TouchEventsEnabled() const {
952 return rwhva()->offscreen_helper()->TouchEventsEnabled();
955 // TODO: Touch events use the same mouse events in EFL API.
956 // Figure out how to distinguish touch and mouse events on touch&mice devices.
957 // Currently mouse and touch support is mutually exclusive.
958 void EWebView::SetTouchEventsEnabled(bool enabled) {
959 if (!rwhva() || !rwhva()->offscreen_helper()) {
960 LOG(WARNING) << "RWHV is not created yet!";
964 if (rwhva()->offscreen_helper()->TouchEventsEnabled() == enabled)
967 rwhva()->offscreen_helper()->SetTouchEventsEnabled(enabled);
969 GetSettings()->getPreferences().touch_event_feature_detection_enabled =
971 GetSettings()->getPreferences().double_tap_to_zoom_enabled = enabled;
972 GetSettings()->getPreferences().editing_behavior =
973 enabled ? blink::mojom::EditingBehavior::kEditingAndroidBehavior
974 : blink::mojom::EditingBehavior::kEditingUnixBehavior,
975 UpdateWebKitPreferences();
978 bool EWebView::MouseEventsEnabled() const {
979 return mouse_events_enabled_;
982 void EWebView::SetMouseEventsEnabled(bool enabled) {
983 if (!rwhva() || !rwhva()->offscreen_helper()) {
984 LOG(WARNING) << "RWHV is not created yet!";
988 if (mouse_events_enabled_ == enabled)
991 mouse_events_enabled_ = enabled;
992 rwhva()->offscreen_helper()->SetTouchEventsEnabled(!enabled);
995 bool EWebView::SetKeyEventsEnabled(bool enabled) {
996 if (!rwhva() || !rwhva()->aura_efl_helper()) {
997 LOG(WARNING) << "RWHV is not created yet!";
1001 if (key_events_enabled_ == enabled)
1004 key_events_enabled_ = enabled;
1005 rwhva()->aura_efl_helper()->SetKeyEventsEnabled(enabled);
1009 void EWebView::SendKeyEvent(Evas_Object* ewk_view,
1012 if (!rwhva() || !rwhva()->aura_efl_helper()) {
1013 LOG(WARNING) << "RWHV is not created yet!";
1017 rwhva()->aura_efl_helper()->SendKeyEvent(ewk_view, key_event, is_press);
1022 class JavaScriptCallbackDetails {
1024 JavaScriptCallbackDetails(Ewk_View_Script_Execute_Callback callback_func,
1027 : callback_func_(callback_func), user_data_(user_data), view_(view) {}
1029 Ewk_View_Script_Execute_Callback callback_func_;
1034 void JavaScriptComplete(JavaScriptCallbackDetails* script_callback_data,
1035 base::Value result) {
1036 if (!script_callback_data->callback_func_)
1039 std::string return_string;
1040 if (result.is_string()) {
1041 // We don't want to serialize strings with JSONStringValueSerializer
1042 // to avoid quotation marks.
1043 return_string = result.GetString();
1044 } else if (result.is_none()) {
1045 // Value::TYPE_NULL is for lack of value, undefined, null
1048 JSONStringValueSerializer serializer(&return_string);
1049 serializer.Serialize(result);
1052 script_callback_data->callback_func_(script_callback_data->view_,
1053 return_string.c_str(),
1054 script_callback_data->user_data_);
1059 bool EWebView::ExecuteJavaScript(const char* script,
1060 Ewk_View_Script_Execute_Callback callback,
1062 LOG(INFO) << __FUNCTION__;
1063 if (!web_contents_) {
1064 LOG(ERROR) << __FUNCTION__ << "web_contents_ is null";
1068 RenderFrameHost* render_frame_host = web_contents_->GetPrimaryMainFrame();
1069 if (!render_frame_host) {
1070 LOG(ERROR) << __FUNCTION__ << " render_frame_host is null";
1074 // Note: M37. Execute JavaScript, |script| with
1075 // |RenderFrameHost::ExecuteJavaScript|.
1076 // @see also https://codereview.chromium.org/188893005 for more details.
1077 std::u16string js_script;
1078 base::UTF8ToUTF16(script, strlen(script), &js_script);
1080 JavaScriptCallbackDetails* script_callback_data =
1081 new JavaScriptCallbackDetails(callback, userdata, ewk_view_);
1082 RenderFrameHost::JavaScriptResultCallback js_callback =
1083 base::BindOnce(&JavaScriptComplete, base::Owned(script_callback_data));
1084 // In M47, it isn't possible anymore to execute javascript in the generic
1085 // case. We need to call ExecuteJavaScriptForTests to keep the behaviour
1086 // unchanged @see https://codereview.chromium.org/1123783002
1087 render_frame_host->ExecuteJavaScriptWithUserGestureForTests(
1088 js_script, std::move(js_callback));
1090 // We use ExecuteJavaScriptWithUserGestureForTests instead of
1091 // ExecuteJavaScript because
1092 // ExecuteJavaScriptWithUserGestureForTests sets user_gesture to true. This
1094 // behaviour is m34, and we want to keep it that way.
1095 render_frame_host->ExecuteJavaScriptWithUserGestureForTests(
1096 js_script, base::NullCallback());
1102 bool EWebView::SetUserAgent(const char* userAgent) {
1103 content::NavigationController& controller = web_contents_->GetController();
1104 bool override = userAgent && strlen(userAgent);
1105 for (int i = 0; i < controller.GetEntryCount(); ++i)
1106 controller.GetEntryAtIndex(i)->SetIsOverridingUserAgent(override);
1107 // TODO: Check if override_in_new_tabs has to be true.
1108 web_contents_->SetUserAgentOverride(
1109 blink::UserAgentOverride::UserAgentOnly(userAgent),
1110 false /* override_in_new_tabs */);
1114 bool EWebView::SetUserAgentAppName(const char* application_name) {
1115 EflWebView::VersionInfo::GetInstance()->UpdateUserAgentWithAppName(
1116 application_name ? application_name : "");
1117 std::string user_agent =
1118 EflWebView::VersionInfo::GetInstance()->DefaultUserAgent();
1119 web_contents_->SetUserAgentOverride(
1120 blink::UserAgentOverride::UserAgentOnly(user_agent),
1121 false /* override_in_new_tabs */);
1125 #if BUILDFLAG(IS_TIZEN)
1126 bool EWebView::SetPrivateBrowsing(bool incognito) {
1127 if (context_->GetImpl()->browser_context()->IsOffTheRecord() == incognito)
1129 context_->GetImpl()->browser_context()->SetOffTheRecord(incognito);
1133 bool EWebView::GetPrivateBrowsing() const {
1134 return context_->GetImpl()->browser_context()->IsOffTheRecord();
1138 const char* EWebView::GetUserAgent() const {
1139 std::string user_agent =
1140 web_contents_->GetUserAgentOverride().ua_string_override;
1141 if (user_agent.empty())
1142 user_agent_ = content::GetContentClientExport()->browser()->GetUserAgent();
1144 user_agent_ = user_agent;
1146 return user_agent_.c_str();
1149 const char* EWebView::GetUserAgentAppName() const {
1150 user_agent_app_name_ = EflWebView::VersionInfo::GetInstance()->AppName();
1151 return user_agent_app_name_.c_str();
1154 const char* EWebView::CacheSelectedText() {
1158 selected_text_cached_ = base::UTF16ToUTF8(rwhva()->GetSelectedText());
1159 return selected_text_cached_.c_str();
1162 _Ewk_Frame* EWebView::GetMainFrame() {
1163 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1166 frame_.reset(new _Ewk_Frame(web_contents_->GetPrimaryMainFrame()));
1168 return frame_.get();
1171 void EWebView::UpdateWebKitPreferences() {
1172 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1174 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1175 if (!render_view_host)
1178 web_contents_delegate_->OnUpdateSettings(settings_.get());
1179 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
1180 render_view_host->UpdateWebkitPreferences(settings_->getPreferences());
1182 UpdateWebkitPreferencesEfl(render_view_host);
1185 void EWebView::UpdateWebkitPreferencesEfl(RenderViewHost* render_view_host) {
1186 DCHECK(render_view_host);
1187 #if !defined(EWK_BRINGUP) // FIXME: m108 bringup
1188 IPC::Message* message = new EwkSettingsMsg_UpdateWebKitPreferencesEfl(
1189 render_view_host->GetRoutingID(), settings_->getPreferencesEfl());
1191 if (render_view_host->IsRenderViewLive()) {
1192 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
1193 render_view_host->Send(message);
1196 delayed_messages_.push_back(message);
1201 void EWebView::SetContentSecurityPolicy(const char* policy,
1202 Ewk_CSP_Header_Type type) {
1203 web_contents_delegate_->SetContentSecurityPolicy(
1204 (policy ? policy : std::string()), type);
1207 void EWebView::LoadHTMLString(const char* html,
1208 const char* base_uri,
1209 const char* unreachable_uri) {
1210 LoadData(html, std::string::npos, NULL, NULL, base_uri, unreachable_uri);
1213 void EWebView::LoadPlainTextString(const char* plain_text) {
1214 LoadData(plain_text, std::string::npos, "text/plain", NULL, NULL, NULL);
1217 void EWebView::LoadHTMLStringOverridingCurrentEntry(
1219 const char* base_uri,
1220 const char* unreachable_url) {
1221 LoadData(html, std::string::npos, NULL, NULL, base_uri, unreachable_url,
1225 void EWebView::LoadData(const char* data,
1227 const char* mime_type,
1228 const char* encoding,
1229 const char* base_uri,
1230 const char* unreachable_uri,
1231 bool should_replace_current_entry) {
1232 SetDefaultStringIfNull(mime_type, "text/html");
1233 SetDefaultStringIfNull(encoding, "utf-8");
1234 SetDefaultStringIfNull(base_uri, "about:blank"); // Webkit2 compatible
1235 SetDefaultStringIfNull(unreachable_uri, "");
1237 std::string str_data = data;
1239 if (size < str_data.length())
1240 str_data = str_data.substr(0, size);
1242 std::string url_str("data:");
1243 url_str.append(mime_type);
1244 url_str.append(";charset=");
1245 url_str.append(encoding);
1246 url_str.append(",");
1248 // GURL constructor performs canonicalization of url string, but this is not
1249 // enough for correctly escaping contents of "data:" url.
1250 url_str.append(base::EscapeUrlEncodedData(str_data, false));
1252 NavigationController::LoadURLParams data_params(GURL(url_str.c_str()));
1254 data_params.base_url_for_data_url = GURL(base_uri);
1255 data_params.virtual_url_for_data_url = GURL(unreachable_uri);
1257 data_params.load_type = NavigationController::LOAD_TYPE_DATA;
1258 data_params.should_replace_current_entry = should_replace_current_entry;
1259 data_params.override_user_agent = NavigationController::UA_OVERRIDE_TRUE;
1260 web_contents_->GetController().LoadURLWithParams(data_params);
1263 void EWebView::InvokeLoadError(const GURL& url,
1265 bool is_cancellation) {
1266 _Ewk_Error err(error_code, is_cancellation,
1267 url.possibly_invalid_spec().c_str());
1269 SmartCallback<EWebViewCallbacks::LoadError>().call(&err);
1272 void EWebView::SetViewLoadErrorPageCallback(
1273 Ewk_View_Error_Page_Load_Callback callback,
1275 load_error_page_cb_.Set(callback, user_data);
1278 // Remove below code while ewk_error_cancellation_get has been implemented.
1279 const char* EWebView::InvokeViewLoadErrorPageCallback(
1282 const std::string& error_description) {
1283 std::unique_ptr<_Ewk_Error> err(
1284 new _Ewk_Error(error_code, url.possibly_invalid_spec().c_str(),
1285 error_description.c_str()));
1286 _Ewk_Error_Page error_page;
1288 LOG(INFO) << "EWebView::InvokeLoadErrorPageCallback url: "
1289 << url.spec().c_str() << ", error_code: " << error_code;
1291 load_error_page_cb_.Run(ewk_view_, err.get(), &error_page);
1292 return error_page.content;
1295 bool EWebView::IsLoadErrorPageCallbackSet() const {
1296 return load_error_page_cb_.IsCallbackSet();
1298 void EWebView::HandlePopupMenu(std::vector<blink::mojom::MenuItemPtr> items,
1301 const gfx::Rect& bounds) {
1302 if (!select_picker_) {
1303 select_picker_.reset(CreateSelectPicker(
1304 this, selectedIndex, std::move(items), multiple, bounds));
1306 // Picker has been shown on top of webview and the page content gets
1307 // partially overlapped. Decrease viewport while showing picker.
1308 AdjustViewPortHeightToPopupMenu(true /* is_popup_menu_visible */);
1309 #if BUILDFLAG(IS_TIZEN_TV)
1310 SmartCallback<EWebViewCallbacks::PopupMenuShow>().call();
1313 select_picker_->UpdatePickerData(selectedIndex, std::move(items), multiple);
1316 select_picker_->Show();
1319 void EWebView::HidePopupMenu() {
1320 if (!select_picker_)
1323 AdjustViewPortHeightToPopupMenu(false /* is_popup_menu_visible */);
1324 #if BUILDFLAG(IS_TIZEN_TV)
1325 SmartCallback<EWebViewCallbacks::PopupMenuHide>().call();
1327 select_picker_.reset();
1330 void EWebView::DidSelectPopupMenuItems(std::vector<int>& indices) {
1331 wcva()->wcva_helper()->DidSelectPopupMenuItems(indices);
1334 void EWebView::DidCancelPopupMenu() {
1335 wcva()->wcva_helper()->DidCancelPopupMenu();
1338 void EWebView::HandleLongPressGesture(
1339 const content::ContextMenuParams& params) {
1340 // This menu is created in renderer process and it does not now anything about
1341 // view scaling factor and it has another calling sequence, so coordinates is
1343 if (settings_ && !settings_->getPreferences().long_press_enabled)
1346 content::ContextMenuParams convertedParams = params;
1347 gfx::Point convertedPoint =
1348 rwhva()->offscreen_helper()->ConvertPointInViewPix(
1349 gfx::Point(params.x, params.y));
1350 convertedParams.x = convertedPoint.x();
1351 convertedParams.y = convertedPoint.y();
1354 evas_object_geometry_get(ewk_view(), &x, &y, 0, 0);
1355 convertedParams.x += x;
1356 convertedParams.y += y;
1358 if (GetSelectionController() && GetSelectionController()->GetLongPressed()) {
1359 bool show_context_menu_now =
1360 !GetSelectionController()->HandleLongPressEvent(convertedPoint,
1362 if (show_context_menu_now)
1363 ShowContextMenuInternal(convertedParams);
1367 void EWebView::ShowContextMenu(const content::ContextMenuParams& params) {
1371 // This menu is created in renderer process and it does not now anything about
1372 // view scaling factor and it has another calling sequence, so coordinates is
1374 content::ContextMenuParams convertedParams = params;
1375 gfx::Point convertedPoint =
1376 rwhva()->offscreen_helper()->ConvertPointInViewPix(
1377 gfx::Point(params.x, params.y));
1378 convertedParams.x = convertedPoint.x();
1379 convertedParams.y = convertedPoint.y();
1382 evas_object_geometry_get(ewk_view(), &x, &y, 0, 0);
1383 convertedParams.x += x;
1384 convertedParams.y += y;
1386 context_menu_position_ = gfx::Point(convertedParams.x, convertedParams.y);
1388 ShowContextMenuInternal(convertedParams);
1391 void EWebView::ShowContextMenuInternal(
1392 const content::ContextMenuParams& params) {
1393 // We don't want to show 'cut' or 'copy' for inputs of type 'password' in
1394 // selection context menu, but params.input_field_type might not be set
1395 // correctly, because in some cases params is received from SelectionBoxEfl,
1396 // not from FrameHostMsg_ContextMenu message. In SelectionBoxEfl
1397 // ContextMenuParams is constructed on our side with limited information and
1398 // input_field_type is not set.
1400 // To work around this, we query for input type and set it separately. In
1401 // response to EwkViewMsg_QueryInputType we run ::UpdateContextMenu with
1402 // information about input's type.
1404 // FIXME: the way we get ContextMenuParams for context menu is flawed in some
1405 // cases. This should be fixed by restructuring context menu code.
1406 // Context menu creation should be unified to always have
1407 // ContextMenuParams received from FrameHostMsg_ContextMenu.
1408 // Tracked at: http://suprem.sec.samsung.net/jira/browse/TWF-1640
1409 if (params.is_editable) {
1410 saved_context_menu_params_ = params;
1412 rwhva()->host()->QueryInputType();
1414 UpdateContextMenuWithParams(params);
1418 void EWebView::UpdateContextMenu(bool is_password_input) {
1419 if (is_password_input) {
1420 saved_context_menu_params_.form_control_type =
1421 blink::mojom::FormControlType::kInputPassword;
1423 UpdateContextMenuWithParams(saved_context_menu_params_);
1426 void EWebView::UpdateContextMenuWithParams(
1427 const content::ContextMenuParams& params) {
1428 context_menu_.reset(
1429 new content::ContextMenuControllerEfl(this, *web_contents_.get()));
1431 if (IsMobileProfile()) {
1432 if (delayed_show_context_menu_timer_) {
1433 ecore_timer_del(delayed_show_context_menu_timer_);
1434 delayed_show_context_menu_timer_ = nullptr;
1436 saved_context_menu_params_ = params;
1437 delayed_show_context_menu_timer_ = ecore_timer_add(
1438 kDelayShowContextMenuTime, DelayedPopulateAndShowContextMenu, this);
1440 if (!context_menu_->PopulateAndShowContextMenu(params)) {
1441 context_menu_.reset();
1442 if (GetSelectionController())
1443 GetSelectionController()->HideHandles();
1448 Eina_Bool EWebView::DelayedPopulateAndShowContextMenu(void* data) {
1449 if (IsMobileProfile()) {
1450 EWebView* view = static_cast<EWebView*>(data);
1452 if (view->context_menu_ &&
1453 !(view->context_menu_->PopulateAndShowContextMenu(
1454 view->saved_context_menu_params_))) {
1455 view->context_menu_.reset();
1457 view->delayed_show_context_menu_timer_ = nullptr;
1460 return ECORE_CALLBACK_CANCEL;
1463 void EWebView::CancelContextMenu(int request_id) {
1465 context_menu_->HideContextMenu();
1468 void EWebView::Find(const char* text, Ewk_Find_Options ewk_find_options) {
1469 std::u16string find_text = base::UTF8ToUTF16(text);
1470 bool find_next = (previous_text_ == find_text);
1473 current_find_request_id_ = find_request_id_counter_++;
1474 previous_text_ = find_text;
1477 auto find_options = blink::mojom::FindOptions::New();
1478 find_options->forward = !(ewk_find_options & EWK_FIND_OPTIONS_BACKWARDS);
1479 find_options->match_case =
1480 !(ewk_find_options & EWK_FIND_OPTIONS_CASE_INSENSITIVE);
1482 web_contents_->Find(current_find_request_id_, find_text,
1483 std::move(find_options));
1486 void EWebView::SetScale(double scale_factor) {
1487 // Do not cache |scale_factor| here as it may be discarded by Blink's
1488 // minimumPageScaleFactor and maximumPageScaleFactor.
1489 // |scale_factor| is cached as responde to DidChangePageScaleFactor.
1490 WebContentsImpl* wci = static_cast<WebContentsImpl*>(web_contents_.get());
1491 wci->GetPrimaryMainFrame()->GetAssociatedLocalMainFrame()->SetScaleFactor(
1495 void EWebView::ScrollFocusedNodeIntoView() {
1496 if (RenderViewHost* render_view_host = web_contents_->GetRenderViewHost()) {
1497 if (auto& broadcast = static_cast<RenderViewHostImpl*>(render_view_host)
1498 ->GetAssociatedPageBroadcast())
1499 broadcast->ScrollFocusedNodeIntoView();
1503 void EWebView::AdjustViewPortHeightToPopupMenu(bool is_popup_menu_visible) {
1504 if (!rwhva() || !IsMobileProfile() ||
1505 settings_->getPreferences().TizenCompatibilityModeEnabled()) {
1509 int picker_height = select_picker_->GetGeometryDIP().height();
1510 gfx::Rect screen_rect =
1511 display::Screen::GetScreen()->GetPrimaryDisplay().bounds();
1512 gfx::Rect view_rect = rwhva()->offscreen_helper()->GetViewBounds();
1514 screen_rect.height() - (view_rect.y() + view_rect.height());
1516 rwhva()->offscreen_helper()->SetCustomViewportSize(
1517 is_popup_menu_visible
1518 ? gfx::Size(view_rect.width(),
1519 view_rect.height() - picker_height + bottom_height)
1523 void EWebView::SetScaleChangedCallback(Ewk_View_Scale_Changed_Callback callback,
1525 scale_changed_cb_.Set(callback, user_data);
1528 bool EWebView::GetScrollPosition(int* x, int* y) const {
1530 LOG(ERROR) << "rwhva() returns nullptr";
1533 if (scroll_detector_->IsScrollOffsetChanged()) {
1535 *x = previous_scroll_position_.x();
1537 *y = previous_scroll_position_.y();
1539 const gfx::Vector2d scroll_position_dip =
1540 scroll_detector_->GetLastScrollPosition();
1541 const float device_scale_factor = display::Screen::GetScreen()
1542 ->GetPrimaryDisplay()
1543 .device_scale_factor();
1545 *x = base::ClampRound((scroll_position_dip.x() - x_delta_) *
1546 device_scale_factor);
1549 *y = base::ClampRound((scroll_position_dip.y() - y_delta_) *
1550 device_scale_factor);
1556 void EWebView::ChangeScroll(int& x, int& y) {
1558 LOG(ERROR) << "rwhva() returns nullptr";
1563 GetScrollSize(&max_x, &max_y);
1564 previous_scroll_position_.set_x(std::min(std::max(x, 0), max_x));
1565 previous_scroll_position_.set_y(std::min(std::max(y, 0), max_y));
1567 const float device_scale_factor = display::Screen::GetScreen()
1568 ->GetPrimaryDisplay()
1569 .device_scale_factor();
1573 x = base::ClampCeil(x / device_scale_factor);
1574 y = base::ClampCeil(y / device_scale_factor);
1576 x_delta_ = x - (x_input / device_scale_factor);
1577 y_delta_ = y - (y_input / device_scale_factor);
1579 scroll_detector_->SetScrollOffsetChanged();
1582 void EWebView::SetScroll(int x, int y) {
1583 if (auto* render_view_host = web_contents_->GetRenderViewHost()) {
1584 if (auto& broadcast = static_cast<RenderViewHostImpl*>(render_view_host)
1585 ->GetAssociatedPageBroadcast()) {
1587 broadcast->SetScrollOffset(x, y);
1592 void EWebView::UseSettingsFont() {
1593 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
1594 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1595 if (render_view_host)
1596 render_view_host->Send(
1597 new EwkViewMsg_UseSettingsFont(render_view_host->GetRoutingID()));
1601 void EWebView::DidChangeContentsSize(int width, int height) {
1602 contents_size_ = gfx::Size(width, height);
1603 SmartCallback<EWebViewCallbacks::ContentsSizeChanged>().call();
1604 SetScaledContentsSize();
1607 const Eina_Rectangle EWebView::GetContentsSize() const {
1608 Eina_Rectangle rect;
1609 EINA_RECTANGLE_SET(&rect, 0, 0, contents_size_.width(),
1610 contents_size_.height());
1614 void EWebView::SetScaledContentsSize() {
1616 return; // LCOV_EXCL_LINE
1618 const float device_scale_factor =
1619 display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
1620 gfx::SizeF scaled_contents_size = gfx::ConvertSizeToPixels(
1621 contents_size_, device_scale_factor * page_scale_factor_);
1622 rwhva()->offscreen_helper()->SetScaledContentSize(scaled_contents_size);
1625 void EWebView::GetScrollSize(int* width, int* height) {
1628 *width = (rwhva() &&
1629 (w = rwhva()->offscreen_helper()->GetScrollableSize().width()))
1634 *height = (rwhva() &&
1635 (h = rwhva()->offscreen_helper()->GetScrollableSize().height()))
1641 void EWebView::MoveCaret(const gfx::Point& point) {
1643 rwhva()->offscreen_helper()->MoveCaret(point);
1646 SelectionControllerEfl* EWebView::GetSelectionController() const {
1647 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1648 RenderWidgetHostViewAura* view = static_cast<RenderWidgetHostViewAura*>(
1649 render_view_host->GetWidget()->GetView());
1650 return view ? view->offscreen_helper()->GetSelectionController() : 0;
1653 void EWebView::SelectFocusedLink() {
1654 rwhva()->host()->SelectFocusedLink();
1657 bool EWebView::GetSelectionRange(Eina_Rectangle* left_rect,
1658 Eina_Rectangle* right_rect) {
1659 if (left_rect && right_rect) {
1660 gfx::Rect left, right;
1661 if (GetSelectionController()) {
1662 GetSelectionController()->GetSelectionBounds(&left, &right);
1663 GetEinaRectFromGfxRect(left, left_rect);
1664 GetEinaRectFromGfxRect(right, right_rect);
1671 void EWebView::OnSelectionRectReceived(const gfx::Rect& selection_rect) const {
1673 context_menu_->OnSelectionRectReceived(selection_rect);
1676 Eina_Bool EWebView::ClearSelection() {
1680 ResetContextMenuController();
1681 rwhva()->SelectionChanged(std::u16string(), 0, gfx::Range());
1683 if (GetSelectionController())
1684 return GetSelectionController()->ClearSelectionViaEWebView();
1689 _Ewk_Hit_Test* EWebView::RequestHitTestDataAt(int x,
1691 Ewk_Hit_Test_Mode mode) {
1692 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1695 EvasToBlinkCords(x, y, &view_x, &view_y);
1697 return RequestHitTestDataAtBlinkCoords(view_x, view_y, mode);
1700 Eina_Bool EWebView::AsyncRequestHitTestDataAt(
1703 Ewk_Hit_Test_Mode mode,
1704 Ewk_View_Hit_Test_Request_Callback callback,
1707 EvasToBlinkCords(x, y, &view_x, &view_y);
1708 return AsyncRequestHitTestDataAtBlinkCords(
1709 view_x, view_y, mode,
1710 new WebViewAsyncRequestHitTestDataUserCallback(x, y, mode, callback,
1714 Eina_Bool EWebView::AsyncRequestHitTestDataAtBlinkCords(
1717 Ewk_Hit_Test_Mode mode,
1718 Ewk_View_Hit_Test_Request_Callback callback,
1720 return AsyncRequestHitTestDataAtBlinkCords(
1722 new WebViewAsyncRequestHitTestDataUserCallback(x, y, mode, callback,
1726 Eina_Bool EWebView::AsyncRequestHitTestDataAtBlinkCords(
1729 Ewk_Hit_Test_Mode mode,
1730 WebViewAsyncRequestHitTestDataCallback* cb) {
1731 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1734 static int64_t request_id = 1;
1737 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1738 DCHECK(render_view_host);
1740 if (render_view_host) {
1741 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
1742 render_view_host->Send(new EwkViewMsg_DoHitTestAsync(
1743 render_view_host->GetRoutingID(), x, y, mode, request_id));
1745 hit_test_callback_[request_id] = cb;
1751 // if failed we delete callback as it is not needed anymore
1756 void EWebView::DispatchAsyncHitTestData(const Hit_Test_Params& params,
1757 int64_t request_id) {
1758 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1760 std::map<int64_t, WebViewAsyncRequestHitTestDataCallback*>::iterator it =
1761 hit_test_callback_.find(request_id);
1763 if (it == hit_test_callback_.end())
1765 std::unique_ptr<_Ewk_Hit_Test> hit_test(new _Ewk_Hit_Test(params));
1767 it->second->Run(hit_test.get(), this);
1769 hit_test_callback_.erase(it);
1772 _Ewk_Hit_Test* EWebView::RequestHitTestDataAtBlinkCoords(
1775 Ewk_Hit_Test_Mode mode) {
1776 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1778 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1780 if (render_view_host) {
1781 // We wait on UI thread till hit test data is updated.
1782 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
1783 render_view_host->Send(
1784 new EwkViewMsg_DoHitTest(render_view_host->GetRoutingID(), x, y, mode));
1786 hit_test_completion_.Wait();
1787 return new _Ewk_Hit_Test(hit_test_params_);
1793 void EWebView::EvasToBlinkCords(int x, int y, int* view_x, int* view_y) {
1794 DCHECK(display::Screen::GetScreen());
1798 gfx::Rect view_bounds = rwhva()->offscreen_helper()->GetViewBoundsInPix();
1801 *view_x = x - view_bounds.x();
1803 display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
1807 *view_y = y - view_bounds.y();
1809 display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
1813 void EWebView::UpdateHitTestData(const Hit_Test_Params& params) {
1814 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
1815 hit_test_params_ = params;
1816 hit_test_completion_.Signal();
1819 void EWebView::OnCopyFromBackingStore(bool success, const SkBitmap& bitmap) {}
1821 void EWebView::OnFocusIn() {
1822 SmartCallback<EWebViewCallbacks::FocusIn>().call();
1823 #if defined(USE_WAYLAND)
1824 if (!rwhva() || !rwhva()->offscreen_helper())
1826 if (GetSettings()->getClipboardEnabled()) {
1827 ClipboardHelperEfl::GetInstance()->OnWebviewFocusIn(
1828 this, rwhva()->offscreen_helper()->content_image_elm_host(),
1829 rwhva()->offscreen_helper()->IsFocusedNodeContentEditable(),
1830 base::BindRepeating(&EWebView::ExecuteEditCommand,
1831 base::Unretained(this)));
1836 void EWebView::OnFocusOut() {
1837 #if defined(TIZEN_ATK_SUPPORT)
1838 if (IsMobileProfile())
1839 eweb_accessibility_->OnFocusOut();
1841 SmartCallback<EWebViewCallbacks::FocusOut>().call();
1842 #if defined(USE_WAYLAND)
1843 if (GetSettings()->getClipboardEnabled())
1844 ClipboardHelperEfl::GetInstance()->MaybeInvalidateActiveWebview(this);
1848 void EWebView::RenderViewReady() {
1850 rwhva()->offscreen_helper()->SetFocusInOutCallbacks(
1851 base::BindRepeating(&EWebView::OnFocusIn, base::Unretained(this)),
1852 base::BindRepeating(&EWebView::OnFocusOut, base::Unretained(this)));
1855 #if defined(TIZEN_VIDEO_HOLE)
1856 if (rwhva() && pending_video_hole_setting_) {
1857 EnableVideoHoleSupportInternal();
1858 pending_video_hole_setting_ = false;
1862 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1864 SendDelayedMessages(render_view_host);
1865 UpdateWebkitPreferencesEfl(render_view_host);
1867 if (render_view_host) {
1868 WebContents* content = WebContents::FromRenderViewHost(render_view_host);
1870 RenderProcessHost* host = render_view_host->GetProcess();
1872 host->AddFilter(new WebViewBrowserMessageFilter(content));
1877 void EWebView::SetQuotaPermissionRequestCallback(
1878 Ewk_Quota_Permission_Request_Callback callback,
1880 quota_request_callback_.Set(callback, user_data);
1883 #if !defined(EWK_BRINGUP) // FIXME: m114 bringup
1884 void EWebView::InvokeQuotaPermissionRequest(
1885 _Ewk_Quota_Permission_Request* request,
1886 content::QuotaPermissionContext::PermissionCallback cb) {
1887 quota_permission_request_map_[request] = std::move(cb);
1888 request->setView(ewk_view());
1889 if (quota_request_callback_.IsCallbackSet())
1890 quota_request_callback_.Run(ewk_view(), request);
1892 QuotaRequestCancel(request);
1895 void EWebView::QuotaRequestReply(const _Ewk_Quota_Permission_Request* request,
1897 DCHECK(quota_permission_request_map_.find(request) !=
1898 quota_permission_request_map_.end());
1900 QuotaPermissionContextEfl::DispatchCallback(
1901 std::move(quota_permission_request_map_[request]),
1902 (allow ? QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_ALLOW
1903 : QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_DISALLOW));
1905 quota_permission_request_map_.erase(request);
1909 void EWebView::QuotaRequestCancel(
1910 const _Ewk_Quota_Permission_Request* request) {
1911 DCHECK(quota_permission_request_map_.find(request) !=
1912 quota_permission_request_map_.end());
1914 QuotaPermissionContextEfl::DispatchCallback(
1915 std::move(quota_permission_request_map_[request]),
1916 QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_CANCELLED);
1917 quota_permission_request_map_.erase(request);
1922 bool EWebView::GetLinkMagnifierEnabled() const {
1923 #if !defined(EWK_BRINGUP) // FIXME: m71 bringup
1924 return web_contents_->GetMutableRendererPrefs()
1925 ->tap_multiple_targets_strategy ==
1926 TAP_MULTIPLE_TARGETS_STRATEGY_POPUP;
1932 void EWebView::SetLinkMagnifierEnabled(bool enabled) {
1933 #if !defined(EWK_BRINGUP) // FIXME: m71 bringup
1934 web_contents_->GetMutableRendererPrefs()->tap_multiple_targets_strategy =
1935 enabled ? TAP_MULTIPLE_TARGETS_STRATEGY_POPUP
1936 : TAP_MULTIPLE_TARGETS_STRATEGY_NONE;
1938 web_contents_->SyncRendererPrefs();
1941 bool EWebView::GetSnapshotAsync(
1942 Eina_Rectangle rect,
1943 Ewk_Web_App_Screenshot_Captured_Callback callback,
1945 float scale_factor) {
1946 if (!rwhva() || !rwhva()->offscreen_helper())
1949 rwhva()->offscreen_helper()->RequestSnapshotAsync(
1950 gfx::Rect(rect.x, rect.y, rect.w, rect.h), callback, user_data,
1955 Evas_Object* EWebView::GetSnapshot(Eina_Rectangle rect, float scale_factor) {
1956 if (!rwhva() || !rwhva()->offscreen_helper())
1959 return rwhva()->offscreen_helper()->GetSnapshot(
1960 gfx::Rect(rect.x, rect.y, rect.w, rect.h), scale_factor);
1963 void EWebView::BackForwardListClear() {
1964 content::NavigationController& controller = web_contents_->GetController();
1966 int entry_count = controller.GetEntryCount();
1967 bool entry_removed = false;
1969 for (int i = 0; i < entry_count; i++) {
1970 if (controller.RemoveEntryAtIndex(i)) {
1971 entry_removed = true;
1972 entry_count = controller.GetEntryCount();
1977 if (entry_removed) {
1978 back_forward_list_->ClearCache();
1979 InvokeBackForwardListChangedCallback();
1983 _Ewk_Back_Forward_List* EWebView::GetBackForwardList() const {
1984 return back_forward_list_.get();
1987 void EWebView::InvokeBackForwardListChangedCallback() {
1988 SmartCallback<EWebViewCallbacks::BackForwardListChange>().call();
1991 _Ewk_History* EWebView::GetBackForwardHistory() const {
1992 return new _Ewk_History(web_contents_->GetController());
1995 bool EWebView::WebAppCapableGet(Ewk_Web_App_Capable_Get_Callback callback,
1997 RenderViewHost* renderViewHost = web_contents_->GetRenderViewHost();
1998 if (!renderViewHost) {
2001 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
2002 WebApplicationCapableGetCallback* cb =
2003 new WebApplicationCapableGetCallback(callback, userData);
2004 int callbackId = web_app_capable_get_callback_map_.Add(cb);
2005 return renderViewHost->Send(new EwkViewMsg_WebAppCapableGet(
2006 renderViewHost->GetRoutingID(), callbackId));
2012 bool EWebView::WebAppIconUrlGet(Ewk_Web_App_Icon_URL_Get_Callback callback,
2014 RenderViewHost* renderViewHost = web_contents_->GetRenderViewHost();
2015 if (!renderViewHost) {
2018 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
2019 WebApplicationIconUrlGetCallback* cb =
2020 new WebApplicationIconUrlGetCallback(callback, userData);
2021 int callbackId = web_app_icon_url_get_callback_map_.Add(cb);
2022 return renderViewHost->Send(new EwkViewMsg_WebAppIconUrlGet(
2023 renderViewHost->GetRoutingID(), callbackId));
2029 bool EWebView::WebAppIconUrlsGet(Ewk_Web_App_Icon_URLs_Get_Callback callback,
2031 RenderViewHost* renderViewHost = web_contents_->GetRenderViewHost();
2032 if (!renderViewHost) {
2035 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
2036 WebApplicationIconUrlsGetCallback* cb =
2037 new WebApplicationIconUrlsGetCallback(callback, userData);
2038 int callbackId = web_app_icon_urls_get_callback_map_.Add(cb);
2039 return renderViewHost->Send(new EwkViewMsg_WebAppIconUrlsGet(
2040 renderViewHost->GetRoutingID(), callbackId));
2046 void EWebView::InvokeWebAppCapableGetCallback(bool capable, int callbackId) {
2047 WebApplicationCapableGetCallback* callback =
2048 web_app_capable_get_callback_map_.Lookup(callbackId);
2051 callback->Run(capable);
2052 web_app_capable_get_callback_map_.Remove(callbackId);
2055 void EWebView::InvokeWebAppIconUrlGetCallback(const std::string& iconUrl,
2057 WebApplicationIconUrlGetCallback* callback =
2058 web_app_icon_url_get_callback_map_.Lookup(callbackId);
2061 callback->Run(iconUrl);
2062 web_app_icon_url_get_callback_map_.Remove(callbackId);
2065 void EWebView::InvokeWebAppIconUrlsGetCallback(const StringMap& iconUrls,
2067 WebApplicationIconUrlsGetCallback* callback =
2068 web_app_icon_urls_get_callback_map_.Lookup(callbackId);
2072 callback->Run(iconUrls);
2073 web_app_icon_urls_get_callback_map_.Remove(callbackId);
2076 void EWebView::SetNotificationPermissionCallback(
2077 Ewk_View_Notification_Permission_Callback callback,
2079 notification_permission_callback_.Set(callback, user_data);
2082 bool EWebView::IsNotificationPermissionCallbackSet() const {
2083 return notification_permission_callback_.IsCallbackSet();
2086 bool EWebView::InvokeNotificationPermissionCallback(
2087 Ewk_Notification_Permission_Request* request) {
2088 Eina_Bool ret = EINA_FALSE;
2089 notification_permission_callback_.Run(ewk_view_, request, &ret);
2093 int EWebView::SetEwkViewPlainTextGetCallback(
2094 Ewk_View_Plain_Text_Get_Callback callback,
2096 EwkViewPlainTextGetCallback* view_plain_text_callback_ptr =
2097 new EwkViewPlainTextGetCallback;
2098 view_plain_text_callback_ptr->Set(callback, user_data);
2099 return plain_text_get_callback_map_.Add(view_plain_text_callback_ptr);
2102 bool EWebView::PlainTextGet(Ewk_View_Plain_Text_Get_Callback callback,
2104 auto* render_frame_host = web_contents_->GetPrimaryMainFrame();
2105 if (!render_frame_host)
2108 auto callback_id = SetEwkViewPlainTextGetCallback(callback, user_data);
2109 return render_frame_host->Send(new EwkFrameMsg_GetPlainText(
2110 render_frame_host->GetRoutingID(), callback_id));
2113 void EWebView::InvokePlainTextGetCallback(const std::string& content_text,
2114 int plain_text_get_callback_id) {
2115 EwkViewPlainTextGetCallback* view_plain_text_callback_invoke_ptr =
2116 plain_text_get_callback_map_.Lookup(plain_text_get_callback_id);
2117 view_plain_text_callback_invoke_ptr->Run(ewk_view(), content_text.c_str());
2118 plain_text_get_callback_map_.Remove(plain_text_get_callback_id);
2121 void EWebView::SetViewGeolocationPermissionCallback(
2122 Ewk_View_Geolocation_Permission_Callback callback,
2124 geolocation_permission_cb_.Set(callback, user_data);
2127 bool EWebView::InvokeViewGeolocationPermissionCallback(
2128 _Ewk_Geolocation_Permission_Request* permission_context,
2129 Eina_Bool* callback_result) {
2130 return geolocation_permission_cb_.Run(ewk_view_, permission_context,
2134 void EWebView::SetViewUserMediaPermissionCallback(
2135 Ewk_View_User_Media_Permission_Callback callback,
2137 user_media_permission_cb_.Set(callback, user_data);
2140 bool EWebView::InvokeViewUserMediaPermissionCallback(
2141 _Ewk_User_Media_Permission_Request* permission_context,
2142 Eina_Bool* callback_result) {
2143 return user_media_permission_cb_.Run(ewk_view_, permission_context,
2147 void EWebView::SetViewUserMediaPermissionQueryCallback(
2148 Ewk_View_User_Media_Permission_Query_Callback callback,
2150 user_media_permission_query_cb_.Set(callback, user_data);
2153 Ewk_User_Media_Permission_Query_Result
2154 EWebView::InvokeViewUserMediaPermissionQueryCallback(
2155 _Ewk_User_Media_Permission_Query* permission_context) {
2156 return user_media_permission_query_cb_.Run(ewk_view_, permission_context);
2159 void EWebView::SetViewUnfocusAllowCallback(
2160 Ewk_View_Unfocus_Allow_Callback callback,
2162 unfocus_allow_cb_.Set(callback, user_data);
2165 bool EWebView::InvokeViewUnfocusAllowCallback(Ewk_Unfocus_Direction direction,
2166 Eina_Bool* callback_result) {
2167 return unfocus_allow_cb_.Run(ewk_view_, direction, callback_result);
2170 void EWebView::StopFinding() {
2171 web_contents_->StopFinding(content::STOP_FIND_ACTION_CLEAR_SELECTION);
2174 void EWebView::SetProgressValue(double progress) {
2175 progress_ = progress;
2178 double EWebView::GetProgressValue() {
2182 const char* EWebView::GetTitle() {
2183 title_ = base::UTF16ToUTF8(web_contents_->GetTitle());
2184 return title_.c_str();
2187 bool EWebView::SaveAsPdf(int width, int height, const std::string& filename) {
2190 rwhva()->host()->PrintToPdf(width, height, base::FilePath(filename));
2194 bool EWebView::GetMHTMLData(Ewk_View_MHTML_Data_Get_Callback callback,
2196 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
2197 if (!render_view_host)
2200 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
2201 MHTMLCallbackDetails* callback_details = new MHTMLCallbackDetails;
2202 callback_details->Set(callback, user_data);
2203 int mhtml_callback_id = mhtml_callback_map_.Add(callback_details);
2204 return render_view_host->Send(new EwkViewMsg_GetMHTMLData(
2205 render_view_host->GetRoutingID(), mhtml_callback_id));
2211 void EWebView::OnMHTMLContentGet(const std::string& mhtml_content,
2213 MHTMLCallbackDetails* callback_details =
2214 mhtml_callback_map_.Lookup(callback_id);
2215 callback_details->Run(ewk_view(), mhtml_content.c_str());
2216 mhtml_callback_map_.Remove(callback_id);
2219 bool EWebView::SavePageAsMHTML(const std::string& path,
2220 Ewk_View_Save_Page_Callback callback,
2225 GURL url(web_contents_->GetLastCommittedURL());
2226 std::u16string title(web_contents_->GetTitle());
2228 // Post function that has file access to blocking task runner.
2229 base::ThreadPool::PostTaskAndReplyWithResult(
2231 {base::MayBlock(), base::TaskPriority::BEST_EFFORT,
2232 base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN},
2233 base::BindOnce(&GenerateMHTMLFilePath, url, base::UTF16ToUTF8(title),
2235 base::BindOnce(&EWebView::GenerateMHTML, base::Unretained(this), callback,
2240 void EWebView::GenerateMHTML(Ewk_View_Save_Page_Callback callback,
2242 const base::FilePath& file_path) {
2243 if (file_path.empty()) {
2244 LOG(ERROR) << "Generating file path was failed";
2245 callback(ewk_view_, nullptr, user_data);
2249 MHTMLGenerationParams params(file_path);
2250 web_contents_->GenerateMHTML(
2251 params, base::BindOnce(&EWebView::MHTMLGenerated, base::Unretained(this),
2252 callback, user_data, file_path));
2255 void EWebView::MHTMLGenerated(Ewk_View_Save_Page_Callback callback,
2257 const base::FilePath& file_path,
2258 int64_t file_size) {
2259 callback(ewk_view_, file_size > 0 ? file_path.value().c_str() : nullptr,
2263 bool EWebView::GetBackgroundColor(
2264 Ewk_View_Background_Color_Get_Callback callback,
2268 BackgroundColorGetCallback* cb =
2269 new BackgroundColorGetCallback(callback, user_data);
2270 int callback_id = background_color_get_callback_map_.Add(cb);
2272 rwhva()->host()->RequestBackgroundColor(callback_id);
2276 void EWebView::OnGetBackgroundColor(int callback_id, SkColor bg_color) {
2277 BackgroundColorGetCallback* cb =
2278 background_color_get_callback_map_.Lookup(callback_id);
2283 cb->Run(ewk_view(), SkColorGetR(bg_color), SkColorGetG(bg_color),
2284 SkColorGetB(bg_color), SkColorGetA(bg_color));
2285 background_color_get_callback_map_.Remove(callback_id);
2288 bool EWebView::IsFullscreen() {
2289 return web_contents_delegate_->IsFullscreenForTabOrPending(
2290 web_contents_.get());
2293 void EWebView::ExitFullscreen() {
2294 WebContentsImpl* wci = static_cast<WebContentsImpl*>(web_contents_.get());
2295 wci->ExitFullscreen(false);
2298 double EWebView::GetScale() {
2299 return page_scale_factor_;
2302 void EWebView::DidChangePageScaleFactor(double scale_factor) {
2303 page_scale_factor_ = scale_factor;
2304 wcva()->wcva_helper()->SetPageScaleFactor(scale_factor);
2305 SetScaledContentsSize();
2307 // Notify app about the scale change.
2308 scale_changed_cb_.Run(ewk_view_, scale_factor);
2311 inline JavaScriptDialogManagerEfl* EWebView::GetJavaScriptDialogManagerEfl() {
2312 return static_cast<JavaScriptDialogManagerEfl*>(
2313 web_contents_delegate_->GetJavaScriptDialogManager(web_contents_.get()));
2316 void EWebView::SetJavaScriptAlertCallback(
2317 Ewk_View_JavaScript_Alert_Callback callback,
2319 GetJavaScriptDialogManagerEfl()->SetAlertCallback(callback, user_data);
2322 void EWebView::JavaScriptAlertReply() {
2323 GetJavaScriptDialogManagerEfl()->ExecuteDialogClosedCallBack(true,
2325 SmartCallback<EWebViewCallbacks::PopupReplyWaitFinish>().call(0);
2328 void EWebView::SetJavaScriptConfirmCallback(
2329 Ewk_View_JavaScript_Confirm_Callback callback,
2331 GetJavaScriptDialogManagerEfl()->SetConfirmCallback(callback, user_data);
2334 void EWebView::JavaScriptConfirmReply(bool result) {
2335 GetJavaScriptDialogManagerEfl()->ExecuteDialogClosedCallBack(result,
2337 SmartCallback<EWebViewCallbacks::PopupReplyWaitFinish>().call(0);
2340 void EWebView::SetJavaScriptPromptCallback(
2341 Ewk_View_JavaScript_Prompt_Callback callback,
2343 GetJavaScriptDialogManagerEfl()->SetPromptCallback(callback, user_data);
2346 void EWebView::JavaScriptPromptReply(const char* result) {
2347 GetJavaScriptDialogManagerEfl()->ExecuteDialogClosedCallBack(
2348 true, (std::string(result)));
2349 SmartCallback<EWebViewCallbacks::PopupReplyWaitFinish>().call(0);
2352 void EWebView::GetPageScaleRange(double* min_scale, double* max_scale) {
2353 auto& prefs = web_contents_->GetOrCreateWebPreferences();
2355 *min_scale = prefs.default_minimum_page_scale_factor;
2357 *max_scale = prefs.default_maximum_page_scale_factor;
2360 content::WebContentsViewAura* EWebView::GetWebContentsViewAura() const {
2361 WebContentsImpl* wc = static_cast<WebContentsImpl*>(web_contents_.get());
2362 return static_cast<WebContentsViewAura*>(wc->GetView());
2365 bool EWebView::SetDrawsTransparentBackground(bool enabled) {
2366 #if BUILDFLAG(IS_TIZEN)
2367 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
2368 if (!render_view_host || !rwhva())
2371 if (!rwhva()->offscreen_helper())
2373 elm_object_style_set(rwhva()->offscreen_helper()->content_image_elm_host(),
2374 enabled ? "transparent" : "default");
2375 evas_object_image_alpha_set(rwhva()->offscreen_helper()->content_image(),
2377 GetWebContentsViewAura()->SetBackgroundColor(enabled ? SK_ColorTRANSPARENT
2379 static_cast<RenderViewHostImpl*>(render_view_host)
2381 ->GetAssociatedFrameWidget()
2382 ->SetDrawsTransparentBackground(enabled);
2383 rwhva()->SetBackgroundColor(enabled ? SK_ColorTRANSPARENT : SK_ColorWHITE);
2390 bool EWebView::GetDrawsTransparentBackground() {
2391 #if BUILDFLAG(IS_TIZEN)
2392 return GetWebContentsViewAura()->GetBackgroundColor() == SK_ColorTRANSPARENT;
2398 bool EWebView::SetBackgroundColor(int red, int green, int blue, int alpha) {
2399 #if BUILDFLAG(IS_TIZEN)
2401 return SetDrawsTransparentBackground(true);
2403 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
2404 if (!render_view_host || !rwhva())
2407 if (!rwhva()->offscreen_helper())
2409 elm_object_style_set(rwhva()->offscreen_helper()->content_image_elm_host(),
2410 alpha < 255 ? "transparent" : "default");
2411 evas_object_image_alpha_set(rwhva()->offscreen_helper()->content_image(),
2413 GetWebContentsViewAura()->SetBackgroundColor(
2414 SkColorSetARGB(alpha, red, green, blue));
2415 static_cast<RenderViewHostImpl*>(render_view_host)
2417 ->GetAssociatedFrameWidget()
2418 ->SetBackgroundColor(red, green, blue, alpha);
2419 rwhva()->SetBackgroundColor(SkColorSetARGB(alpha, red, green, blue));
2427 void EWebView::GetSessionData(const char** data, unsigned* length) const {
2428 static const int MAX_SESSION_ENTRY_SIZE = std::numeric_limits<int>::max();
2430 NavigationController& navigationController = web_contents_->GetController();
2431 base::Pickle sessionPickle;
2432 const int itemCount = navigationController.GetEntryCount();
2434 sessionPickle.WriteInt(itemCount);
2435 sessionPickle.WriteInt(navigationController.GetCurrentEntryIndex());
2437 for (int i = 0; i < itemCount; i++) {
2438 NavigationEntry* navigationEntry = navigationController.GetEntryAtIndex(i);
2439 sessions::SerializedNavigationEntry serializedEntry =
2440 sessions::ContentSerializedNavigationBuilder::FromNavigationEntry(
2441 i, navigationEntry);
2442 serializedEntry.WriteToPickle(MAX_SESSION_ENTRY_SIZE, &sessionPickle);
2445 if (sessionPickle.size() <= 0 ||
2447 static_cast<char*>(malloc(sizeof(char) * sessionPickle.size())))) {
2448 LOG(ERROR) << "Failed to get session data";
2452 memcpy(const_cast<char*>(*data), sessionPickle.data(), sessionPickle.size());
2453 *length = sessionPickle.size();
2456 bool EWebView::RestoreFromSessionData(const char* data, unsigned length) {
2457 base::Pickle sessionPickle(data, length);
2458 base::PickleIterator pickleIterator(sessionPickle);
2462 if (!pickleIterator.ReadInt(&entryCount))
2464 if (!pickleIterator.ReadInt(¤tEntry))
2467 std::vector<sessions::SerializedNavigationEntry> serializedEntries;
2468 serializedEntries.resize(entryCount);
2469 for (int i = 0; i < entryCount; ++i) {
2470 if (!serializedEntries.at(i).ReadFromPickle(&pickleIterator))
2480 std::vector<std::unique_ptr<content::NavigationEntry>> scopedEntries =
2481 sessions::ContentSerializedNavigationBuilder::ToNavigationEntries(
2482 serializedEntries, context()->browser_context());
2484 NavigationController& navigationController = web_contents_->GetController();
2486 if (currentEntry < 0)
2489 if (currentEntry >= static_cast<int>(scopedEntries.size()))
2490 currentEntry = scopedEntries.size() - 1;
2492 navigationController.Restore(currentEntry, RestoreType::kRestored,
2497 void EWebView::SetBrowserFont() {
2498 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
2499 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
2500 if (render_view_host) {
2501 IPC::Message* message =
2502 new EwkViewMsg_SetBrowserFont(render_view_host->GetRoutingID());
2504 if (render_view_host->IsRenderViewLive())
2505 render_view_host->Send(message);
2507 delayed_messages_.push_back(message);
2512 bool EWebView::IsDragging() const {
2513 return wcva()->wcva_helper()->IsDragging();
2516 void EWebView::ShowFileChooser(
2517 scoped_refptr<content::FileSelectListener> listener,
2518 const blink::mojom::FileChooserParams& params) {
2519 #if BUILDFLAG(IS_TIZEN_TV)
2520 LOG(INFO) << "File chooser request callback.";
2521 file_chooser_request_.reset(new _Ewk_File_Chooser_Request(
2522 std::move(listener), params.accept_types, params.mode));
2523 SmartCallback<EWebViewCallbacks::FileChooserRequest>().call(
2524 file_chooser_request_.get());
2526 if (!IsMobileProfile() && !IsWearableProfile())
2528 file_chooser_.reset(
2529 new content::FileChooserControllerEfl(std::move(listener), params));
2530 file_chooser_->Open();
2534 #if !defined(EWK_BRINGUP) // FIXME: m67 bringup
2535 void EWebView::SetViewMode(blink::WebViewMode view_mode) {
2536 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
2537 if (!render_view_host)
2540 IPC::Message* message =
2541 new ViewMsg_SetViewMode(render_view_host->GetRoutingID(), view_mode);
2542 if (render_view_host->IsRenderViewLive()) {
2543 render_view_host->Send(message);
2545 delayed_messages_.push_back(message);
2550 gfx::Point EWebView::GetContextMenuPosition() const {
2551 return context_menu_position_;
2554 void EWebView::ShowContentsDetectedPopup(const char* message) {
2555 popup_controller_.reset(new PopupControllerEfl(this));
2556 popup_controller_->openPopup(message);
2559 void EWebView::RequestColorPicker(int r, int g, int b, int a) {
2560 input_picker_.reset(new InputPicker(this, web_contents_.get(), ewk_view()));
2561 input_picker_->ShowColorPicker(r, g, b, a);
2564 bool EWebView::SetColorPickerColor(int r, int g, int b, int a) {
2565 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
2566 web_contents_->DidChooseColorInColorChooser(SkColorSetARGB(a, r, g, b));
2571 void EWebView::InputPickerShow(ui::TextInputType input_type,
2573 content::DateTimeChooserEfl* date_time_chooser) {
2574 input_picker_.reset(new InputPicker(this, web_contents_.get(), ewk_view(),
2575 date_time_chooser));
2576 input_picker_->ShowDatePicker(input_type, input_value);
2579 void EWebView::LoadNotFoundErrorPage(const std::string& invalidUrl) {
2580 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
2581 RenderFrameHost* render_frame_host = web_contents_->GetPrimaryMainFrame();
2582 if (render_frame_host)
2583 render_frame_host->Send(new EwkFrameMsg_LoadNotFoundErrorPage(
2584 render_frame_host->GetRoutingID(), invalidUrl));
2588 std::string EWebView::GetPlatformLocale() {
2589 char* local_default = setlocale(LC_CTYPE, 0);
2591 return std::string("en-US");
2592 std::string locale = std::string(local_default);
2593 size_t position = locale.find('_');
2594 if (position != std::string::npos)
2595 locale.replace(position, 1, "-");
2596 position = locale.find('.');
2597 if (position != std::string::npos)
2598 locale = locale.substr(0, position);
2602 int EWebView::StartInspectorServer(int port) {
2603 #if BUILDFLAG(IS_TIZEN_TV)
2605 use_early_rwi_ = false;
2606 rwi_info_showed_ = false;
2608 if (!context_->GetImpl()->GetInspectorServerState()) {
2610 if (!devtools_http_handler::DevToolsPortManager::GetInstance()
2611 ->GetValidPort(validPort))
2617 return context_->InspectorServerStart(port);
2620 bool EWebView::StopInspectorServer() {
2621 #if BUILDFLAG(IS_TIZEN_TV)
2623 use_early_rwi_ = false;
2624 rwi_info_showed_ = false;
2627 return context_->InspectorServerStop();
2630 void EWebView::InvokeWebProcessCrashedCallback() {
2631 DCHECK_CURRENTLY_ON(BrowserThread::UI);
2632 const GURL last_url = GetURL();
2633 bool callback_handled = false;
2634 SmartCallback<EWebViewCallbacks::WebProcessCrashed>().call(&callback_handled);
2635 if (!callback_handled)
2636 LoadHTMLString(kRendererCrashedHTMLMessage, NULL,
2637 last_url.possibly_invalid_spec().c_str());
2640 void EWebView::SyncAcceptLanguages(const std::string& accept_languages) {
2641 web_contents_->GetMutableRendererPrefs()->accept_languages = accept_languages;
2642 web_contents_->SyncRendererPrefs();
2643 BrowserContext* browser_context = web_contents_->GetBrowserContext();
2644 if (!browser_context)
2647 auto* storage_partition = browser_context->GetDefaultStoragePartition();
2648 if (!storage_partition)
2651 if (auto* network_context = storage_partition->GetNetworkContext())
2652 network_context->SetAcceptLanguage(accept_languages);
2655 #if BUILDFLAG(IS_TIZEN_TV)
2656 bool EWebView::EdgeScrollBy(int delta_x, int delta_y) {
2657 if ((delta_x == 0 && delta_y == 0) || is_processing_edge_scroll_)
2660 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
2661 if (!render_view_host)
2667 gfx::Point offset = gfx::Point(delta_x, delta_y);
2668 gfx::Point mouse_position;
2669 GetMousePosition(mouse_position);
2670 is_processing_edge_scroll_ = true;
2672 static_cast<RenderViewHostImpl*>(render_view_host)
2674 ->GetAssociatedFrameWidget()
2675 ->EdgeScrollBy(offset, mouse_position);
2679 void EWebView::GetMousePosition(gfx::Point& mouse_position) {
2680 int mouse_x, mouse_y;
2681 evas_pointer_output_xy_get(GetEvas(), &mouse_x, &mouse_y);
2682 Evas_Coord x, y, width, height;
2683 evas_object_geometry_get(ewk_view(), &x, &y, &width, &height);
2687 else if (mouse_y > y + height)
2688 mouse_y = y + height - 1;
2691 else if (mouse_x > x + width)
2692 mouse_x = x + width - 1;
2698 display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
2700 display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
2702 mouse_position.set_x(mouse_x);
2703 mouse_position.set_y(mouse_y);
2706 void EWebView::InvokeEdgeScrollByCallback(const gfx::Point& offset,
2708 is_processing_edge_scroll_ = false;
2711 SmartCallback<EWebViewCallbacks::EdgeScrollLeft>().call(&handled);
2712 else if (offset.x() > 0)
2713 SmartCallback<EWebViewCallbacks::EdgeScrollRight>().call(&handled);
2716 SmartCallback<EWebViewCallbacks::EdgeScrollTop>().call(&handled);
2717 else if (offset.y() > 0)
2718 SmartCallback<EWebViewCallbacks::EdgeScrollBottom>().call(&handled);
2722 void EWebView::HandleRendererProcessCrash() {
2723 content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
2724 base::BindOnce(&EWebView::InvokeWebProcessCrashedCallback,
2725 base::Unretained(this)));
2728 void EWebView::InitializeContent() {
2729 LOG(INFO) << "eweb_view.cc InitializeContent" ;
2730 #if BUILDFLAG(IS_TIZEN_TV)
2731 // When initialize content init inspector server
2732 InitInspectorServer();
2734 WebContents* new_contents = create_new_window_web_contents_cb_.Run(this);
2735 if (!new_contents) {
2736 WebContents::CreateParams params(context_->browser_context());
2737 web_contents_.reset(
2738 new WebContentsImplEfl(context_->browser_context(), this));
2739 static_cast<WebContentsImpl*>(web_contents_.get())
2740 ->Init(params, blink::FramePolicy());
2742 web_contents_.reset(new_contents);
2744 // When a new webview is created in response to a request from the
2745 // engine, the BrowserContext instance of the originator WebContents
2746 // is used by the newly created WebContents object.
2747 // See more in WebContentsImplEfl::HandleNewWebContentsCreate.
2749 // Hence, if as part of the WebView creation, the embedding APP
2750 // passes in a Ewk_Context instance that wraps a different instance of
2751 // BrowserContext than the one the originator WebContents holds,
2752 // undefined behavior can be seen.
2754 // This is a snippet code that illustrate the scenario:
2757 // evas_object_smart_callback_add(web_view_, "create,window",
2758 // &OnNewWindowRequest, this);
2761 // void OnNewWindowRequest(void *data, Evas_Object*, void* out_view) {
2763 // EvasObject* new_web_view = ewk_view_add_with_context(GetEvas(),
2764 // ewk_context_new());
2765 // *static_cast<Evas_Object**>(out_view) = new_web_view;
2769 // The new Ewk_Context object created and passed in as parameter to
2770 // ewk_view_add_with_context wraps a different instance of BrowserContext
2771 // than the one the new WebContents object will hold.
2773 // CHECK below aims at catching misuse of this API.
2774 bool should_crash = context_->GetImpl()->browser_context() !=
2775 web_contents_->GetBrowserContext();
2778 << "BrowserContext of new WebContents does not match EWebView's. "
2779 << "Please see 'ewk_view_add*' documentation. "
2780 << "Aborting execution ...";
2784 web_contents_delegate_.reset(new WebContentsDelegateEfl(this));
2785 web_contents_->SetDelegate(web_contents_delegate_.get());
2787 // EWebView's delegate. Calls to WebContentsImplEfl and
2788 // WebContentsViewAuraHelperEfl are delegated to this class.
2789 // For more details, refer commit message of patch 301647.
2790 webview_delegate_.reset(new WebViewDelegateEfl(this));
2791 WebContentsImplEfl* wc_efl =
2792 static_cast<WebContentsImplEfl*>(web_contents_.get());
2793 wc_efl->SetWebviewDelegate(webview_delegate_.get());
2794 wcva()->wcva_helper()->SetWebviewDelegate(webview_delegate_.get());
2796 back_forward_list_.reset(new _Ewk_Back_Forward_List(web_contents_.get()));
2798 permission_popup_manager_.reset(new PermissionPopupManager(ewk_view_));
2799 gin_native_bridge_dispatcher_host_.reset(
2800 new content::GinNativeBridgeDispatcherHost(web_contents_.get()));
2803 static_cast<WebContentsImplEfl*>(web_contents_.get())->GetEflMainLayout();
2804 evas_object_smart_member_add(efl_main_layout_, ewk_view_);
2805 static_cast<WebContentsImpl*>(web_contents_.get())->set_ewk_view(ewk_view_);
2806 InitializeWindowTreeHost();
2809 #if BUILDFLAG(IS_TIZEN_TV)
2810 void EWebView::OnDialogClosed() {
2811 if (!use_early_rwi_)
2814 use_early_rwi_ = false;
2815 LOG(INFO) << "[FAST RWI] SetURL Restore [" << rwi_gurl_.spec()
2816 << "] from [about:blank]";
2819 rwi_info_showed_ = true;
2822 void EWebView::InitInspectorServer() {
2823 if (devtools_http_handler::DevToolsPortManager::GetInstance()
2824 ->ProcessCompare()) {
2825 int res = StartInspectorServer(0);
2827 LOG(INFO) << "InitInspectorServer SetPort";
2828 devtools_http_handler::DevToolsPortManager::GetInstance()->SetPort(res);
2834 #if defined(TIZEN_TBM_SUPPORT)
2835 void EWebView::SetOffscreenRendering(bool enable) {
2837 host_->compositor()->SetUseTbmSuraceForOffscreenRendering(enable);
2841 void EWebView::InitializeWindowTreeHost() {
2842 CHECK(aura::Env::GetInstance());
2844 int x, y, width, height;
2846 ecore_evas_ecore_evas_get(evas_object_evas_get(efl_main_layout_));
2847 ecore_evas_geometry_get(ee, &x, &y, &width, &height);
2849 gfx::Rect bounds(x, y, width, height);
2850 ui::PlatformWindowInitProperties properties;
2851 properties.bounds = bounds;
2853 host_ = aura::WindowTreeHost::Create(std::move(properties));
2855 host_->window()->Show();
2858 std::make_unique<aura::test::TestFocusClient>(host_->window());
2859 window_parenting_client_ =
2860 std::make_unique<aura::test::TestWindowParentingClient>(host_->window());
2861 compositor_observer_ = std::make_unique<ui::CompositorObserverEfl>(
2862 host_->compositor(), web_contents_.get());
2864 aura::Window* content = web_contents_->GetNativeView();
2865 aura::Window* parent = host_->window();
2866 if (!parent->Contains(content)) {
2867 parent->AddChild(content);
2870 content->SetBounds(bounds);
2871 RenderWidgetHostView* host_view = web_contents_->GetRenderWidgetHostView();
2873 host_view->SetSize(bounds.size());
2876 void EWebView::UrlRequestSet(
2878 content::NavigationController::LoadURLType loadtype,
2882 content::NavigationController::LoadURLParams params(gurl);
2883 params.load_type = loadtype;
2884 params.override_user_agent = NavigationController::UA_OVERRIDE_TRUE;
2887 std::string s(body);
2889 network::ResourceRequestBody::CreateFromBytes(s.data(), s.size());
2892 net::HttpRequestHeaders header;
2894 Eina_Iterator* it = eina_hash_iterator_tuple_new(headers);
2896 while (eina_iterator_next(it, reinterpret_cast<void**>(&t))) {
2898 const char* value_str =
2899 t->data ? static_cast<const char*>(t->data) : "";
2900 base::StringPiece name = static_cast<const char*>(t->key);
2901 base::StringPiece value = value_str;
2902 header.SetHeader(name, value);
2903 // net::HttpRequestHeaders.ToString() returns string with newline
2904 params.extra_headers += header.ToString();
2907 eina_iterator_free(it);
2910 web_contents_->GetController().LoadURLWithParams(params);
2913 #if defined(TIZEN_VIDEO_HOLE)
2914 void EWebView::EnableVideoHoleSupport() {
2915 if (!web_contents_->GetPrimaryMainFrame() ||
2916 !web_contents_->GetPrimaryMainFrame()->IsRenderFrameLive() || !rwhva()) {
2917 pending_video_hole_setting_ = true;
2921 EnableVideoHoleSupportInternal();
2924 void EWebView::EnableVideoHoleSupportInternal() {
2925 if (settings_->getPreferences().video_hole_enabled)
2928 settings_->getPreferences().video_hole_enabled = true;
2929 WebContentsImpl* wc = static_cast<WebContentsImpl*>(web_contents_.get());
2931 wc->EnableVideoHole();
2935 bool EWebView::HandleShow() {
2936 if (!efl_main_layout_)
2943 bool EWebView::HandleHide() {
2944 if (!efl_main_layout_)
2951 bool EWebView::HandleMove(int x, int y) {
2952 if (!efl_main_layout_)
2954 evas_object_move(efl_main_layout_, x, y);
2955 LOG(INFO) << "Move x " << x << " y " << y;
2956 #if defined(TIZEN_VIDEO_HOLE)
2958 rwhva()->DidMoveWebView();
2962 context_menu_->Move(x, y);
2967 bool EWebView::HandleResize(int width, int height) {
2968 if (!efl_main_layout_)
2970 evas_object_resize(efl_main_layout_, width, height);
2972 #if defined(TIZEN_VIDEO_HOLE)
2973 LOG(INFO) << __func__ << " new size " << width << "*" << height;
2975 rwhva()->DidMoveWebView();
2978 if (select_picker_) {
2979 AdjustViewPortHeightToPopupMenu(true /* is_popup_menu_visible */);
2980 ScrollFocusedNodeIntoView();
2983 #if defined(USE_AURA) && BUILDFLAG(IS_TIZEN_TV)
2986 evas_object_geometry_get(efl_main_layout_, &x, &y, nullptr, nullptr);
2987 gfx::Rect bounds(x, y, width, height);
2988 host_->SetBoundsInPixels(bounds);
2995 bool EWebView::HandleTextSelectionDown(int x, int y) {
2996 if (!GetSelectionController())
2998 return GetSelectionController()->TextSelectionDown(x, y);
3001 bool EWebView::HandleTextSelectionUp(int x, int y) {
3002 if (!GetSelectionController())
3004 return GetSelectionController()->TextSelectionUp(x, y);
3007 void EWebView::HandleTapGestureForSelection(bool is_content_editable) {
3008 if (!GetSelectionController())
3011 GetSelectionController()->PostHandleTapGesture(is_content_editable);
3014 void EWebView::HandleZoomGesture(blink::WebGestureEvent& event) {
3015 blink::WebInputEvent::Type event_type = event.GetType();
3016 if (event_type == blink::WebInputEvent::Type::kGestureDoubleTap ||
3017 event_type == blink::WebInputEvent::Type::kGesturePinchBegin) {
3018 SmartCallback<EWebViewCallbacks::ZoomStarted>().call();
3020 if (event_type == blink::WebInputEvent::Type::kGestureDoubleTap ||
3021 event_type == blink::WebInputEvent::Type::kGesturePinchEnd) {
3022 SmartCallback<EWebViewCallbacks::ZoomFinished>().call();
3026 bool EWebView::GetHorizontalPanningHold() const {
3029 return rwhva()->offscreen_helper()->GetHorizontalPanningHold();
3032 void EWebView::SetHorizontalPanningHold(bool hold) {
3034 rwhva()->offscreen_helper()->SetHorizontalPanningHold(hold);
3037 bool EWebView::GetVerticalPanningHold() const {
3040 return rwhva()->offscreen_helper()->GetVerticalPanningHold();
3043 void EWebView::SetVerticalPanningHold(bool hold) {
3045 rwhva()->offscreen_helper()->SetVerticalPanningHold(hold);
3048 void EWebView::SendDelayedMessages(RenderViewHost* render_view_host) {
3049 DCHECK(render_view_host);
3051 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
3052 content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
3053 base::BindOnce(&EWebView::SendDelayedMessages, base::Unretained(this),
3058 for (auto iter = delayed_messages_.begin(); iter != delayed_messages_.end();
3060 IPC::Message* message = *iter;
3061 message->set_routing_id(render_view_host->GetRoutingID());
3062 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
3063 render_view_host->Send(message);
3067 delayed_messages_.clear();
3070 void EWebView::ClosePage() {
3071 web_contents_->ClosePage();
3074 bool EWebView::SetMainFrameScrollbarVisible(bool visible) {
3075 if (web_contents_->GetPrimaryMainFrame()->IsRenderFrameLive() && rwhva())
3076 rwhva()->host()->SetMainFrameScrollbarVisible(visible);
3080 bool EWebView::GetMainFrameScrollbarVisible(
3081 Ewk_View_Main_Frame_Scrollbar_Visible_Get_Callback callback,
3086 MainFrameScrollbarVisibleGetCallback* callback_ptr =
3087 new MainFrameScrollbarVisibleGetCallback;
3088 callback_ptr->Set(callback, user_data);
3090 main_frame_scrollbar_visible_callback_map_.Add(callback_ptr);
3091 rwhva()->host()->RequestMainFrameScrollbarVisible(callback_id);
3095 void EWebView::InvokeMainFrameScrollbarVisibleCallback(int callback_id,
3097 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
3098 content::GetUIThreadTaskRunner({})->PostTask(
3100 base::BindOnce(&EWebView::InvokeMainFrameScrollbarVisibleCallback,
3101 base::Unretained(this), visible, callback_id));
3105 MainFrameScrollbarVisibleGetCallback* callback =
3106 main_frame_scrollbar_visible_callback_map_.Lookup(callback_id);
3110 main_frame_scrollbar_visible_callback_map_.Remove(callback_id);
3111 callback->Run(ewk_view(), visible);
3112 main_frame_scrollbar_visible_callback_map_.Remove(callback_id);
3115 void EWebView::OnOverscrolled(const gfx::Vector2dF& accumulated_overscroll,
3116 const gfx::Vector2dF& latest_overscroll_delta) {
3117 const gfx::Vector2dF old_overscroll =
3118 accumulated_overscroll - latest_overscroll_delta;
3120 if (latest_overscroll_delta.x() && !old_overscroll.x()) {
3121 latest_overscroll_delta.x() < 0
3122 ? SmartCallback<EWebViewCallbacks::OverscrolledLeft>().call()
3123 : SmartCallback<EWebViewCallbacks::OverscrolledRight>().call();
3125 if (latest_overscroll_delta.y() && !old_overscroll.y()) {
3126 latest_overscroll_delta.y() < 0
3127 ? SmartCallback<EWebViewCallbacks::OverscrolledTop>().call()
3128 : SmartCallback<EWebViewCallbacks::OverscrolledBottom>().call();
3132 void EWebView::SetDidChangeThemeColorCallback(
3133 Ewk_View_Did_Change_Theme_Color_Callback callback,
3135 did_change_theme_color_callback_.Set(callback, user_data);
3138 void EWebView::DidChangeThemeColor(const SkColor& color) {
3139 did_change_theme_color_callback_.Run(ewk_view_, color);
3142 #if BUILDFLAG(IS_TIZEN_TV)
3143 void EWebView::DrawLabel(Evas_Object* image, Eina_Rectangle rect) {
3145 rwhva()->offscreen_helper()->DrawLabel(image, rect);
3148 void EWebView::DeactivateAtk(bool deactivated) {
3149 #if defined(TIZEN_ATK_SUPPORT)
3150 EWebAccessibilityUtil::GetInstance()->Deactivate(deactivated);
3154 void EWebView::ClearLabels() {
3156 rwhva()->offscreen_helper()->ClearLabels();
3160 void EWebView::RequestManifest(Ewk_View_Request_Manifest_Callback callback,
3162 web_contents_delegate_->RequestManifestInfo(callback, user_data);
3165 void EWebView::DidRespondRequestManifest(
3166 _Ewk_View_Request_Manifest* manifest,
3167 Ewk_View_Request_Manifest_Callback callback,
3169 callback(ewk_view_, manifest, user_data);
3172 void EWebView::SetSessionTimeout(uint64_t timeout) {
3173 if (web_contents_->GetPrimaryMainFrame()->IsRenderFrameLive() && rwhva())
3174 rwhva()->host()->SetLongPollingGlobalTimeout(timeout);
3177 void EWebView::SetBeforeUnloadConfirmPanelCallback(
3178 Ewk_View_Before_Unload_Confirm_Panel_Callback callback,
3180 GetJavaScriptDialogManagerEfl()->SetBeforeUnloadConfirmPanelCallback(
3181 callback, user_data);
3184 void EWebView::ReplyBeforeUnloadConfirmPanel(Eina_Bool result) {
3185 GetJavaScriptDialogManagerEfl()->ReplyBeforeUnloadConfirmPanel(result);
3188 #if defined(TIZEN_PEPPER_EXTENSIONS)
3189 void EWebView::InitializePepperExtensionSystem() {
3190 RegisterPepperExtensionDelegate();
3194 EwkExtensionSystemDelegate* EWebView::GetExtensionDelegate() {
3195 RenderFrameHost* render_frame_host = web_contents_->GetPrimaryMainFrame();
3196 if (!render_frame_host)
3199 return static_cast<EwkExtensionSystemDelegate*>(
3200 ExtensionSystemDelegateManager::GetInstance()->GetDelegateForFrame(render_frame_id_));
3203 void EWebView::SetWindowId() {
3204 EwkExtensionSystemDelegate* delegate = GetExtensionDelegate();
3206 LOG(WARNING) << "No delegate is available to set window id";
3209 Evas_Object* main_wind =
3210 efl::WindowFactory::GetHostWindow(web_contents_.get());
3212 LOG(ERROR) << "Can`t get main window";
3215 delegate->SetWindowId(main_wind);
3218 void EWebView::SetPepperExtensionWidgetInfo(Ewk_Value widget_pepper_ext_info) {
3219 EwkExtensionSystemDelegate* delegate = GetExtensionDelegate();
3221 LOG(WARNING) << "No delegate is available to set extension info";
3224 delegate->SetExtensionInfo(widget_pepper_ext_info);
3227 void EWebView::SetPepperExtensionCallback(Generic_Sync_Call_Callback cb,
3229 EwkExtensionSystemDelegate* delegate = GetExtensionDelegate();
3231 LOG(WARNING) << "No delegate is available to set generic callback";
3234 delegate->SetGenericSyncCallback(cb, data);
3237 void EWebView::RegisterPepperExtensionDelegate() {
3238 RenderFrameHost* render_frame_host = web_contents_->GetPrimaryMainFrame();
3239 if (!render_frame_host) {
3240 LOG(WARNING) << "render_frame_host is nullptr, can't register delegate";
3244 render_frame_id_.render_process_id = render_frame_host->GetProcess()->GetID();
3245 render_frame_id_.render_frame_id = render_frame_host->GetRoutingID();
3247 EwkExtensionSystemDelegate* delegate = new EwkExtensionSystemDelegate;
3248 ExtensionSystemDelegateManager::GetInstance()->RegisterDelegate(
3249 render_frame_id_, std::unique_ptr<EwkExtensionSystemDelegate>{delegate});
3252 void EWebView::UnregisterPepperExtensionDelegate() {
3253 if (!web_contents_) {
3254 LOG(WARNING) << "web_contents_ is nullptr, can't unregister delegate";
3257 if (!ExtensionSystemDelegateManager::GetInstance()->UnregisterDelegate(render_frame_id_))
3258 LOG(WARNING) << "Unregistering pepper extension delegate failed";
3260 #endif // defined(TIZEN_PEPPER_EXTENSIONS)
3262 void EWebView::SetExceededIndexedDatabaseQuotaCallback(
3263 Ewk_View_Exceeded_Indexed_Database_Quota_Callback callback,
3265 exceeded_indexed_db_quota_callback_.Set(callback, user_data);
3266 content::BrowserContextEfl* browser_context =
3267 static_cast<content::BrowserContextEfl*>(
3268 web_contents_->GetBrowserContext());
3269 if (browser_context) {
3270 browser_context->GetSpecialStoragePolicyEfl()->SetQuotaExceededCallback(
3271 base::BindOnce(&EWebView::InvokeExceededIndexedDatabaseQuotaCallback,
3272 base::Unretained(this)));
3276 void EWebView::InvokeExceededIndexedDatabaseQuotaCallback(
3278 int64_t current_quota) {
3279 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
3280 content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
3281 base::BindOnce(&EWebView::InvokeExceededIndexedDatabaseQuotaCallback,
3282 base::Unretained(this), origin, current_quota));
3285 LOG(INFO) << __func__ << "()" << origin << ", " << current_quota;
3286 CHECK(!exceeded_indexed_db_quota_origin_.get());
3287 exceeded_indexed_db_quota_origin_.reset(new Ewk_Security_Origin(origin));
3288 exceeded_indexed_db_quota_callback_.Run(
3289 ewk_view_, exceeded_indexed_db_quota_origin_.get(), current_quota);
3292 void EWebView::ExceededIndexedDatabaseQuotaReply(bool allow) {
3293 if (!exceeded_indexed_db_quota_origin_.get()) {
3294 LOG(WARNING) << __func__ << "() : callback is not invoked!";
3297 LOG(INFO) << __func__ << "()" << exceeded_indexed_db_quota_origin_->GetURL()
3299 content::BrowserContextEfl* browser_context =
3300 static_cast<content::BrowserContextEfl*>(
3301 web_contents_->GetBrowserContext());
3302 if (browser_context) {
3303 browser_context->GetSpecialStoragePolicyEfl()->SetUnlimitedStoragePolicy(
3304 exceeded_indexed_db_quota_origin_->GetURL(), allow);
3306 exceeded_indexed_db_quota_origin_.reset();
3309 bool EWebView::ShouldIgnoreNavigation(
3310 content::NavigationHandle* navigation_handle) {
3311 if (!navigation_handle->GetURL().is_valid() ||
3312 !navigation_handle->GetURL().SchemeIs("appcontrol") ||
3313 (!navigation_handle->HasUserGesture() &&
3314 !navigation_handle->WasServerRedirect())) {
3318 _Ewk_App_Control app_control(
3319 this, navigation_handle->GetURL().possibly_invalid_spec());
3320 return app_control.Proceed();
3323 #if BUILDFLAG(IS_TIZEN_TV)
3324 void EWebView::AddDynamicCertificatePath(const std::string& host,
3325 const std::string& cert_path) {
3326 web_contents_->AddDynamicCertificatePath(host, cert_path);
3330 bool EWebView::SetVisibility(bool enable) {
3335 web_contents_->WasShown();
3337 web_contents_->WasHidden();
3342 void EWebView::SetDoNotTrack(Eina_Bool enable) {
3343 // enable: 0 User tend to allow tracking on the target site.
3344 // enable: 1 User tend to not be tracked on the target site.
3345 if (web_contents_->GetMutableRendererPrefs()->enable_do_not_track == enable)
3348 // Set navigator.doNotTrack attribute
3349 web_contents_->GetMutableRendererPrefs()->enable_do_not_track = enable;
3350 web_contents_->SyncRendererPrefs();
3352 // Set or remove DNT HTTP header, the effects will depend on design of target
3358 context()->HTTPCustomHeaderAdd("DNT", "1");
3360 context()->HTTPCustomHeaderRemove("DNT");
3363 #if defined(TIZEN_ATK_SUPPORT)
3364 void EWebView::UpdateSpatialNavigationStatus(Eina_Bool enable) {
3365 if (settings_->getPreferences().spatial_navigation_enabled == enable)
3368 settings_->getPreferences().spatial_navigation_enabled = enable;
3369 WebContentsImpl* wc = static_cast<WebContentsImpl*>(web_contents_.get());
3371 wc->SetSpatialNavigationEnabled(enable);
3374 void EWebView::UpdateAccessibilityStatus(Eina_Bool enable) {
3375 if (settings_->getPreferences().atk_enabled == enable)
3378 settings_->getPreferences().atk_enabled = enable;
3379 WebContentsImpl* wc = static_cast<WebContentsImpl*>(web_contents_.get());
3381 wc->SetAtkEnabled(enable);
3384 void EWebView::InitAtk() {
3385 #if defined(TIZEN_ATK_SUPPORT)
3386 EWebAccessibilityUtil::GetInstance()->ToggleAtk(lazy_initialize_atk_);
3390 /* LCOV_EXCL_START */
3391 bool EWebView::GetAtkStatus() {
3392 auto state = content::BrowserAccessibilityStateImpl::GetInstance();
3395 return state->IsAccessibleBrowser();
3397 /* LCOV_EXCL_STOP */
3400 #if BUILDFLAG(IS_TIZEN_TV)
3401 bool EWebView::SetMixedContents(bool allow) {
3402 MixedContentObserver* mixed_content_observer =
3403 MixedContentObserver::FromWebContents(web_contents_.get());
3404 return mixed_content_observer->MixedContentReply(allow);
3407 void EWebView::NotifyMediaStateChanged(uint32_t device_type,
3410 LOG(INFO) << "NotifyMediaStateChanged type : " << device_type
3411 << " ;previous: " << previous << " ; current: " << current;
3412 Ewk_User_Media_State_Info* user_media_state_info =
3413 new _Ewk_User_Media_State_Info;
3414 user_media_state_info->device_type =
3415 static_cast<Ewk_User_Media_Device_Type>(device_type);
3416 user_media_state_info->previous_state = previous;
3417 user_media_state_info->current_state = current;
3418 SmartCallback<EWebViewCallbacks::UserMediaState>().call(
3419 static_cast<void*>(user_media_state_info));
3421 delete user_media_state_info;
3424 void EWebView::SetHighBitRate(Eina_Bool high_bitrate) {
3425 LOG(INFO) << "high_bitrate: " << std::boolalpha << high_bitrate;
3426 is_high_bitrate_ = high_bitrate;
3429 void EWebView::OnDeviceListed(const MediaDeviceEnumeration& devices) {
3430 int device_count = 0;
3431 EwkMediaDeviceInfo* device_list = nullptr;
3432 for (const auto& device : devices)
3433 device_count += device.size();
3436 (EwkMediaDeviceInfo*)malloc(sizeof(EwkMediaDeviceInfo) * device_count);
3438 LOG(ERROR) << "malloc EwkMediaDeviceInfo failed";
3439 device_cb_.Run(device_list, 0);
3444 for (int i = 0; i < NUM_MEDIA_DEVICE_TYPES; i++) {
3445 blink::WebMediaDeviceInfoArray array = devices[i];
3446 for (const auto& device : array) {
3447 LOG(INFO) << "OnDeviceListed type:" << i
3448 << ",device_id:" << device.device_id
3449 << ",lable:" << device.label;
3451 // convert device info to ewk structure
3452 EwkMediaDeviceInfo* data = &device_list[idx++];
3453 data->device_id = eina_stringshare_add(device.device_id.c_str());
3454 data->label = eina_stringshare_add(device.label.c_str());
3455 data->type = static_cast<EwkMediaDeviceType>(i);
3456 data->connected = true;
3460 device_cb_.Run(device_list, device_count);
3463 for (int i = 0; i < device_count; i++) {
3464 EwkMediaDeviceInfo* device = &device_list[i];
3465 if (device->device_id)
3466 eina_stringshare_del(device->device_id);
3468 eina_stringshare_del(device->label);
3476 void EWebView::GetMediaDeviceList(Ewk_Media_Device_List_Get_Callback callback,
3478 if (!web_contents_delegate_) {
3479 LOG(ERROR) << "no web_contents_delegate_";
3483 device_cb_.Set(callback, userData);
3485 web_contents_delegate_->GetMediaDeviceList(
3486 base::BindOnce(&EWebView::OnDeviceListed, weak_factory_.GetWeakPtr()));