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_media_parental_rating_info.h"
107 #include "public/ewk_media_playback_info_product.h"
108 #include "public/ewk_user_media_internal.h"
111 #if defined(TIZEN_PEPPER_EXTENSIONS)
112 #include "efl/window_factory.h"
113 #include "ewk/efl_integration/ewk_privilege_checker.h"
114 #endif // defined(TIZEN_PEPPER_EXTENSIONS)
116 #if defined(USE_WAYLAND) && defined(TIZEN_PEPPER_EXTENSIONS)
117 #include <Ecore_Wayland.h>
118 #endif // defined(USE_WAYLAND)
120 #if defined(TIZEN_TBM_SUPPORT)
121 #include "ui/compositor/compositor.h"
124 using namespace content;
125 using web_contents_utils::WebViewFromWebContents;
129 const int kTitleLengthMax = 80;
130 const base::FilePath::CharType kMHTMLFileNameExtension[] =
131 FILE_PATH_LITERAL(".mhtml");
132 const base::FilePath::CharType kMHTMLExtension[] = FILE_PATH_LITERAL("mhtml");
133 const base::FilePath::CharType kDefaultFileName[] =
134 FILE_PATH_LITERAL("saved_page");
135 const char kReplaceChars[] = " ";
136 const char kReplaceWith[] = "_";
138 static const char* kRendererCrashedHTMLMessage =
139 "<html><body><h1>Renderer process has crashed!</h1></body></html>";
141 // "visible,content,changed" is an email-app specific signal which informs
142 // that the web view is only partially visible.
143 static const char* kVisibleContentChangedSignalName = "visible,content,changed";
145 // email-app specific signal which informs that custom scrolling is started.
146 const char* kCustomScrollBeginSignalName = "custom,scroll,begin";
148 // email-app specific signal which informs that custom scrolling is finished.
149 const char* kCustomScrollEndSignalName = "custom,scroll,end";
151 const float kDelayShowContextMenuTime = 0.2f;
153 inline void SetDefaultStringIfNull(const char*& variable,
154 const char* default_string) {
156 variable = default_string;
160 void GetEinaRectFromGfxRect(const gfx::Rect& gfx_rect,
161 Eina_Rectangle* eina_rect) {
162 eina_rect->x = gfx_rect.x();
163 eina_rect->y = gfx_rect.y();
164 eina_rect->w = gfx_rect.width();
165 eina_rect->h = gfx_rect.height();
168 #if BUILDFLAG(IS_TIZEN)
169 static Eina_Bool RotateWindowCb(void* data, int type, void* event) {
170 auto wv = static_cast<EWebView*>(data);
171 #if defined(TIZEN_TBM_SUPPORT)
172 if (wv->rwhva() && wv->rwhva()->GetCompositor() &&
173 wv->rwhva()->GetCompositor()->use_tbm_surface_for_offscreen_rendering()) {
174 Ecore_Wl2_Event_Window_Rotation* rotateEvent =
175 static_cast<Ecore_Wl2_Event_Window_Rotation*>(event);
176 if (rotateEvent != nullptr) {
177 LOG(INFO) << "For NUI app, new ori " << rotateEvent->angle;
178 wv->SetOrientation(rotateEvent->angle);
180 return ECORE_CALLBACK_PASS_ON;
183 LOG(INFO) << "New ori "
184 << ecore_evas_rotation_get(
185 ecore_evas_ecore_evas_get(wv->GetEvas()));
187 ecore_evas_rotation_get(ecore_evas_ecore_evas_get(wv->GetEvas())));
188 return ECORE_CALLBACK_PASS_ON;
192 static content::WebContents* NullCreateWebContents(void*) {
196 base::FilePath GenerateMHTMLFilePath(const GURL& url,
197 const std::string& title,
198 const std::string& base_path) {
199 base::FilePath file_path(base_path);
201 if (base::DirectoryExists(file_path)) {
202 std::string title_part(title.substr(0, kTitleLengthMax));
203 base::ReplaceChars(title_part, kReplaceChars, kReplaceWith, &title_part);
204 base::FilePath file_name =
205 net::GenerateFileName(url, std::string(), std::string(), title_part,
206 std::string(), kDefaultFileName);
207 DCHECK(!file_name.empty());
208 file_path = file_path.Append(file_name);
211 if (file_path.Extension().empty())
212 file_path = file_path.AddExtension(kMHTMLExtension);
213 else if (!file_path.MatchesExtension(kMHTMLFileNameExtension))
214 file_path = file_path.ReplaceExtension(kMHTMLExtension);
216 if (!base::PathExists(file_path))
219 int uniquifier = base::GetUniquePathNumber(file_path);
220 if (uniquifier > 0) {
221 return file_path.InsertBeforeExtensionASCII(
222 base::StringPrintf(" (%d)", uniquifier));
225 return base::FilePath();
228 SelectPickerBase* CreateSelectPicker(
231 std::vector<blink::mojom::MenuItemPtr> items,
232 bool is_multiple_selection,
233 const gfx::Rect& bounds) {
234 SelectPickerBase* picker;
237 new SelectPickerTv(web_view, selected_index, is_multiple_selection);
240 new SelectPickerMobile(web_view, selected_index, is_multiple_selection);
242 // Create two separate Elm_Genlist_Item_Class classes, because EFL cannot swap
243 // item_style at runtime.
244 picker->InitializeItemClass();
245 picker->InitializeGroupClass();
246 picker->Init(std::move(items), bounds);
252 class WebViewAsyncRequestHitTestDataCallback {
254 WebViewAsyncRequestHitTestDataCallback(int x, int y, Ewk_Hit_Test_Mode mode)
255 : x_(x), y_(y), mode_(mode) {}
256 virtual ~WebViewAsyncRequestHitTestDataCallback(){};
258 virtual void Run(_Ewk_Hit_Test* hit_test, EWebView* web_view) = 0;
261 int GetX() const { return x_; }
262 int GetY() const { return y_; }
263 Ewk_Hit_Test_Mode GetMode() const { return mode_; }
268 Ewk_Hit_Test_Mode mode_;
271 class WebViewAsyncRequestHitTestDataUserCallback
272 : public WebViewAsyncRequestHitTestDataCallback {
274 WebViewAsyncRequestHitTestDataUserCallback(
277 Ewk_Hit_Test_Mode mode,
278 Ewk_View_Hit_Test_Request_Callback callback,
280 : WebViewAsyncRequestHitTestDataCallback(x, y, mode),
282 user_data_(user_data) {}
284 void Run(_Ewk_Hit_Test* hit_test, EWebView* web_view) override {
286 callback_(web_view->ewk_view(), GetX(), GetY(), GetMode(), hit_test,
291 Ewk_View_Hit_Test_Request_Callback callback_;
295 #if defined(TIZEN_ATK_SUPPORT)
296 class EWebAccessibilityObserver : public EWebAccessibility::Observer {
298 explicit EWebAccessibilityObserver(EWebView* webview) : webview_(webview) {}
299 virtual ~EWebAccessibilityObserver() {}
301 // EWebAccessibility::Observer implementation
302 void OnSpatialNavigationStatusChanged(Eina_Bool enable) override {
303 webview_->UpdateSpatialNavigationStatus(enable);
306 void OnAccessibilityStatusChanged(Eina_Bool enable) override {
307 webview_->UpdateAccessibilityStatus(enable);
315 int EWebView::find_request_id_counter_ = 0;
316 content::WebViewDelegate::WebContentsCreateCallback
317 EWebView::create_new_window_web_contents_cb_ =
318 base::BindRepeating(&NullCreateWebContents);
320 EWebView* EWebView::FromEwkView(Evas_Object* ewk_view) {
321 return WebViewDelegateEwk::GetInstance().GetEWebViewFromEwkView(ewk_view);
324 void EWebView::VisibleContentChangedCallback(void* user_data,
325 Evas_Object* /*object*/,
327 auto view = static_cast<EWebView*>(user_data);
328 auto rect = static_cast<Eina_Rectangle*>(event_info);
329 view->GetSelectionController()->SetCustomVisibleViewRect(
330 gfx::Rect(rect->x, rect->y, rect->w, rect->h));
333 void EWebView::OnCustomScrollBeginCallback(void* user_data,
334 Evas_Object* /*object*/,
335 void* /*event_info*/) {
336 auto* view = static_cast<EWebView*>(user_data);
337 if (auto* selection_controller = view->GetSelectionController())
338 selection_controller->SetControlsTemporarilyHidden(true,true);
341 void EWebView::OnCustomScrollEndCallback(void* user_data,
342 Evas_Object* /*object*/,
343 void* /*event_info*/) {
344 auto* view = static_cast<EWebView*>(user_data);
345 if (auto* selection_controller = view->GetSelectionController())
346 selection_controller->SetControlsTemporarilyHidden(false,true);
349 EWebView::EWebView(Ewk_Context* context, Evas_Object* ewk_view)
352 efl_main_layout_(ewk_view),
353 mouse_events_enabled_(false),
354 text_zoom_factor_(1.0),
355 current_find_request_id_(find_request_id_counter_++),
357 hit_test_completion_(base::WaitableEvent::ResetPolicy::AUTOMATIC,
358 base::WaitableEvent::InitialState::NOT_SIGNALED),
359 page_scale_factor_(1.0),
362 #if BUILDFLAG(IS_TIZEN_TV)
363 is_processing_edge_scroll_(false),
364 use_early_rwi_(false),
365 rwi_info_showed_(false),
367 #if defined(TIZEN_PEPPER_EXTENSIONS)
368 render_frame_id_{0, 0},
370 is_initialized_(false) {
371 LOG(INFO) << "EWebView: " << this;
373 evas_object_smart_callback_add(ewk_view_, kVisibleContentChangedSignalName,
374 VisibleContentChangedCallback, this);
376 evas_object_smart_callback_add(ewk_view_, kCustomScrollBeginSignalName,
377 OnCustomScrollBeginCallback, this);
378 evas_object_smart_callback_add(ewk_view_, kCustomScrollEndSignalName,
379 OnCustomScrollEndCallback, this);
380 #if BUILDFLAG(IS_TIZEN)
381 window_rotate_handler_ = ecore_event_handler_add(
382 ECORE_WL2_EVENT_WINDOW_ROTATE, RotateWindowCb, this);
387 void EWebView::Initialize() {
388 if (is_initialized_) {
394 scroll_detector_.reset(new ScrollDetector(this));
396 #if defined(TIZEN_PEPPER_EXTENSIONS)
397 InitializePepperExtensionSystem();
399 DCHECK(web_contents_->GetRenderViewHost());
400 // Settings (content::WebPreferences) will be initalized by
401 // RenderViewHostImpl::ComputeWebkitPrefs() based on command line switches.
403 new Ewk_Settings(ewk_view_, web_contents_->GetOrCreateWebPreferences()));
404 #if defined(TIZEN_ATK_SUPPORT)
405 std::unique_ptr<EWebAccessibilityObserver> observer(
406 new EWebAccessibilityObserver(this));
407 eweb_accessibility_.reset(new EWebAccessibility(
408 ewk_view_, web_contents_.get(), std::move(observer)));
409 lazy_initialize_atk_ = true;
412 base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess();
413 if (cmdline->HasSwitch(switches::kTouchEventFeatureDetection)) {
414 SetTouchEventsEnabled(
415 cmdline->GetSwitchValueASCII(switches::kTouchEventFeatureDetection) ==
416 switches::kTouchEventFeatureDetectionEnabled);
418 SetMouseEventsEnabled(true);
421 std::string user_agent =
422 EflWebView::VersionInfo::GetInstance()->DefaultUserAgent();
423 web_contents_->SetUserAgentOverride(
424 blink::UserAgentOverride::UserAgentOnly(user_agent),
425 false /* override_in_new_tabs */);
427 elm_object_tree_focus_allow_set(efl_main_layout_, EINA_TRUE);
428 is_initialized_ = true;
429 evas_object_event_callback_add(efl_main_layout_, EVAS_CALLBACK_RESIZE,
430 EWebView::NativeViewResize, this);
432 auto cbce = static_cast<ContentBrowserClientEfl*>(
433 content::GetContentClientExport()->browser());
434 // Initialize accept languages
435 SyncAcceptLanguages(cbce->GetAcceptLangs(nullptr));
436 accept_langs_changed_callback_ = base::BindRepeating(
437 &EWebView::SyncAcceptLanguages, base::Unretained(this));
438 cbce->AddAcceptLangsChangedCallback(accept_langs_changed_callback_);
440 // If EWebView is created by window.open, RenderView is already created
441 // before initializing WebContents. So we should manually invoke
442 // EWebView::RenderViewReady here.
443 if (web_contents_->GetPrimaryMainFrame() &&
444 web_contents_->GetPrimaryMainFrame()->IsRenderFrameLive()) {
449 EWebView::~EWebView() {
450 LOG(INFO) << "EWebView: " << this;
451 weak_factory_.InvalidateWeakPtrs();
452 auto cbce = static_cast<ContentBrowserClientEfl*>(
453 content::GetContentClientExport()->browser());
454 cbce->RemoveAcceptLangsChangedCallback(accept_langs_changed_callback_);
455 #if defined(TIZEN_PEPPER_EXTENSIONS)
456 UnregisterPepperExtensionDelegate();
459 evas_object_event_callback_del(efl_main_layout_, EVAS_CALLBACK_RESIZE,
460 EWebView::NativeViewResize);
461 #if defined(USE_WAYLAND)
462 if (GetSettings()->getClipboardEnabled())
463 ClipboardHelperEfl::GetInstance()->MaybeInvalidateActiveWebview(this);
466 std::map<int64_t, WebViewAsyncRequestHitTestDataCallback*>::iterator
467 hit_test_callback_iterator;
468 for (hit_test_callback_iterator = hit_test_callback_.begin();
469 hit_test_callback_iterator != hit_test_callback_.end();
470 hit_test_callback_iterator++)
471 delete hit_test_callback_iterator->second;
472 hit_test_callback_.clear();
474 for (auto iter = delayed_messages_.begin(); iter != delayed_messages_.end();
478 delayed_messages_.clear();
480 if (!is_initialized_) {
484 #if defined(TIZEN_ATK_SUPPORT)
485 eweb_accessibility_.reset();
488 #if defined(TIZEN_AUTOFILL_FW)
489 if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
490 autofill::switches::kDisableAutofill)) {
491 autofill::AutofillRequestManager::GetInstance()->RemoveRequest(ewk_view());
495 select_picker_.reset();
496 context_menu_.reset();
497 mhtml_callback_map_.Clear();
498 #if BUILDFLAG(IS_TIZEN_TV)
499 is_video_playing_callback_map_.Clear();
502 compositor_observer_.reset();
504 // Release manually those scoped pointers to
505 // make sure they are released in correct order
506 web_contents_.reset();
507 web_contents_delegate_.reset();
509 // This code must be executed after WebContents deletion
510 // because WebContents depends on BrowserContext which
511 // is deleted along with EwkContext.
512 CHECK(!web_contents_);
514 permission_popup_manager_.reset();
516 gin_native_bridge_dispatcher_host_.reset();
519 evas_object_smart_callback_del(ewk_view_, kVisibleContentChangedSignalName,
520 VisibleContentChangedCallback);
521 evas_object_smart_callback_del(ewk_view_, kCustomScrollBeginSignalName,
522 OnCustomScrollBeginCallback);
523 evas_object_smart_callback_del(ewk_view_, kCustomScrollEndSignalName,
524 OnCustomScrollEndCallback);
525 #if BUILDFLAG(IS_TIZEN)
526 if (window_rotate_handler_)
527 ecore_event_handler_del(window_rotate_handler_);
532 content::RenderWidgetHostViewAura* EWebView::rwhva() const {
533 return static_cast<content::RenderWidgetHostViewAura*>(
534 web_contents_->GetRenderWidgetHostView());
537 content::WebContentsViewAura* EWebView::wcva() const {
538 WebContentsImpl* wc = static_cast<WebContentsImpl*>(web_contents_.get());
539 return static_cast<WebContentsViewAura*>(wc->GetView());
542 void EWebView::NativeViewResize(void* data,
546 auto thiz = static_cast<EWebView*>(data);
547 if (!thiz->context_menu_)
549 int x, y, width, height;
550 evas_object_geometry_get(obj, &x, &y, &width, &height);
551 thiz->context_menu_->Resize(gfx::Rect(x, y, width, height));
554 void EWebView::ResetContextMenuController() {
555 return context_menu_.reset();
558 #if BUILDFLAG(IS_TIZEN_TV)
559 void EWebView::RunPendingSetFocus(Eina_Bool focus) {
560 SetFocusInternal(focus);
563 void EWebView::SetFocusInternal(Eina_Bool focus) {
564 if (!rwhva() || !rwhva()->offscreen_helper() || (HasFocus() == focus))
566 rwhva()->offscreen_helper()->Focus(focus);
570 void EWebView::SetFocus(Eina_Bool focus) {
574 #if BUILDFLAG(IS_TIZEN_TV)
575 if (web_contents_->GetPrimaryMainFrame()->IsRenderFrameLive()) {
576 SetFocusInternal(focus);
578 if (pending_setfocus_closure_)
579 pending_setfocus_closure_.Reset();
581 LOG(ERROR) << "SEND DELAY SET FOCUS BIND";
582 pending_setfocus_closure_ = base::BindOnce(&EWebView::RunPendingSetFocus,
583 base::Unretained(this), focus);
586 rwhva()->offscreen_helper()->Focus(focus);
590 Eina_Bool EWebView::HasFocus() const {
591 if (!rwhva() || !rwhva()->offscreen_helper())
594 return rwhva()->offscreen_helper()->HasFocus() ? EINA_TRUE : EINA_FALSE;
597 Eina_Bool EWebView::AddJavaScriptMessageHandler(
599 Ewk_View_Script_Message_Cb callback,
601 if (!gin_native_bridge_dispatcher_host_)
604 return gin_native_bridge_dispatcher_host_->AddNamedObject(view, callback,
608 bool EWebView::SetPageVisibility(
609 Ewk_Page_Visibility_State page_visibility_state) {
613 // TODO: We should able to set 'prerender' or 'unloaded' as visibility state.
614 // http://www.w3.org/TR/page-visibility/#dom-document-visibilitystate
615 switch (page_visibility_state) {
616 case EWK_PAGE_VISIBILITY_STATE_VISIBLE:
617 rwhva()->offscreen_helper()->SetPageVisibility(true);
619 case EWK_PAGE_VISIBILITY_STATE_HIDDEN:
620 rwhva()->offscreen_helper()->SetPageVisibility(false);
622 case EWK_PAGE_VISIBILITY_STATE_PRERENDER:
632 bool EWebView::CreateNewWindow(
633 content::WebViewDelegate::WebContentsCreateCallback cb) {
634 create_new_window_web_contents_cb_ = cb;
635 Evas_Object* new_object = NULL;
636 SmartCallback<EWebViewCallbacks::CreateNewWindow>().call(&new_object);
637 create_new_window_web_contents_cb_ =
638 base::BindRepeating(&NullCreateWebContents);
643 Evas_Object* EWebView::GetHostWindowDelegate(const content::WebContents* wc) {
644 EWebView* thiz = WebViewFromWebContents(wc);
645 DCHECK(thiz->ewk_view_);
646 Evas_Object* parent = evas_object_above_get(thiz->ewk_view_);
648 LOG(WARNING) << "Could not find and visual parents for EWK smart object!.";
649 return thiz->ewk_view_;
652 if (elm_object_widget_check(parent)) {
653 Evas_Object* elm_parent = elm_object_top_widget_get(parent);
659 LOG(WARNING) << "Could not find elementary parent for WebView object!";
660 return thiz->ewk_view_;
663 Evas_Object* EWebView::GetElmWindow() const {
664 Evas_Object* parent = elm_object_parent_widget_get(ewk_view_);
665 return parent ? elm_object_top_widget_get(parent) : nullptr;
668 void EWebView::SetURL(const GURL& url, bool from_api) {
669 NavigationController::LoadURLParams params(url);
672 params.transition_type = ui::PageTransitionFromInt(
673 ui::PAGE_TRANSITION_LINK | ui::PAGE_TRANSITION_FROM_API);
676 #if BUILDFLAG(IS_TIZEN_TV)
677 if (use_early_rwi_) {
678 LOG(INFO) << "[FAST RWI] SetURL Replace [" << url.spec()
679 << "] to [about:blank]";
681 params.url = GURL("about:blank");
685 params.override_user_agent = NavigationController::UA_OVERRIDE_TRUE;
686 web_contents_->GetController().LoadURLWithParams(params);
689 const GURL& EWebView::GetURL() const {
690 return web_contents_->GetVisibleURL();
693 const GURL& EWebView::GetOriginalURL() const {
694 const auto entry = web_contents_->GetController().GetVisibleEntry();
696 return entry->GetOriginalRequestURL();
698 return web_contents_->GetVisibleURL();
701 void EWebView::Reload() {
702 web_contents_->GetController().Reload(content::ReloadType::NORMAL, true);
705 void EWebView::ReloadBypassingCache() {
706 web_contents_->GetController().Reload(content::ReloadType::BYPASSING_CACHE,
710 Eina_Bool EWebView::CanGoBack() {
711 return web_contents_->GetController().CanGoBack();
714 Eina_Bool EWebView::CanGoForward() {
715 return web_contents_->GetController().CanGoForward();
718 Eina_Bool EWebView::GoBack() {
719 if (!web_contents_->GetController().CanGoBack())
722 #if defined(TIZEN_AUTOFILL_FW)
723 if (web_contents_delegate_)
724 web_contents_delegate_->ResetLastInteractedElements();
727 web_contents_->GetController().GoBack();
731 Eina_Bool EWebView::GoForward() {
732 if (!web_contents_->GetController().CanGoForward())
735 web_contents_->GetController().GoForward();
739 void EWebView::Stop() {
740 if (web_contents_->IsLoading())
741 web_contents_->Stop();
744 void EWebView::Suspend() {
745 #if BUILDFLAG(IS_TIZEN)
746 CHECK(web_contents_);
747 if (IsMobileProfile() && web_contents_->IsFullscreen())
748 web_contents_->ExitFullscreen(true);
749 RenderViewHost* rvh = web_contents_->GetRenderViewHost();
750 RenderFrameHost* rfh = web_contents_->GetPrimaryMainFrame();
753 if (rvh->IsRenderViewLive()) {
754 RenderWidgetHostImpl* rwhi = static_cast<RenderWidgetHostImpl*>(rvh->GetWidget());
755 rwhi->PauseScheduledTasks();
760 void EWebView::Resume() {
761 #if BUILDFLAG(IS_TIZEN)
762 CHECK(web_contents_);
763 RenderViewHost* rvh = web_contents_->GetRenderViewHost();
764 RenderFrameHost* rfh = web_contents_->GetPrimaryMainFrame();
767 if (rvh->IsRenderViewLive() && rwhva())
768 rwhva()->host()->UnPauseScheduledTasks();
772 #if BUILDFLAG(IS_TIZEN_TV)
773 void EWebView::SetFloatVideoWindowState(bool enabled) {
774 RenderWidgetHostImpl* rwhi = static_cast<RenderWidgetHostImpl*>(
775 web_contents_->GetRenderViewHost()->GetWidget());
777 rwhi->SetFloatVideoWindowState(enabled);
779 #endif // IS_TIZEN_TV
781 double EWebView::GetTextZoomFactor() const {
782 if (text_zoom_factor_ < 0.0)
785 return text_zoom_factor_;
788 void EWebView::SetTextZoomFactor(double text_zoom_factor) {
789 if (text_zoom_factor_ == text_zoom_factor || text_zoom_factor < 0.0)
792 text_zoom_factor_ = text_zoom_factor;
793 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
794 if (!render_view_host)
796 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
797 render_view_host->Send(new ViewMsg_SetTextZoomFactor(
798 render_view_host->GetRoutingID(), text_zoom_factor));
802 double EWebView::GetPageZoomFactor() const {
803 return blink::PageZoomLevelToZoomFactor(
804 content::HostZoomMap::GetZoomLevel(web_contents_.get()));
807 void EWebView::SetPageZoomFactor(double page_zoom_factor) {
808 content::HostZoomMap::SetZoomLevel(
809 web_contents_.get(), blink::PageZoomFactorToZoomLevel(page_zoom_factor));
812 void EWebView::ExecuteEditCommand(const char* command, const char* value) {
813 EINA_SAFETY_ON_NULL_RETURN(command);
815 absl::optional<std::u16string> optional_value;
817 optional_value = absl::make_optional(base::ASCIIToUTF16(value));
819 WebContentsImpl* wc = static_cast<WebContentsImpl*>(web_contents_.get());
820 if (!wc || !wc->GetFocusedFrameWidgetInputHandler())
823 wc->GetFocusedFrameWidgetInputHandler()->ExecuteEditCommand(
824 std::string(command), optional_value);
827 #if BUILDFLAG(IS_TIZEN)
828 void EWebView::EnterDragState() {
829 if (IsMobileProfile()) {
830 if (RenderViewHost* render_view_host = web_contents_->GetRenderViewHost())
831 web_contents_->EnterDragState(render_view_host);
836 void EWebView::SetOrientation(int orientation) {
837 if (GetOrientation() == orientation)
840 if (orientation == 0 || orientation == 90 || orientation == 180 ||
841 orientation == 270) {
842 #if !defined(USE_AURA)
843 GetWebContentsViewEfl()->SetOrientation(orientation);
847 const Ecore_Evas* ee =
848 ecore_evas_ecore_evas_get(evas_object_evas_get(ewk_view_));
849 ecore_evas_screen_geometry_get(ee, nullptr, nullptr, &width, &height);
850 if (orientation == 90 || orientation == 270)
851 std::swap(width, height);
853 if (popup_controller_)
854 popup_controller_->SetPopupSize(width, height);
855 if (JavaScriptDialogManagerEfl* dialogMG = GetJavaScriptDialogManagerEfl())
856 dialogMG->SetPopupSize(width, height);
860 int EWebView::GetOrientation() {
861 #if !defined(USE_AURA)
862 return GetWebContentsViewEfl()->GetOrientation();
868 void EWebView::Show() {
869 evas_object_show(efl_main_layout_);
870 web_contents_->WasShown();
873 void EWebView::Hide() {
874 LOG(INFO) << "EWebView: " << this;
875 evas_object_hide(efl_main_layout_);
878 web_contents_->WasHidden();
881 void EWebView::SetViewAuthCallback(Ewk_View_Authentication_Callback callback,
883 authentication_cb_.Set(callback, user_data);
886 void EWebView::InvokeAuthCallback(LoginDelegateEfl* login_delegate,
888 const std::string& realm) {
889 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
891 auth_challenge_.reset(new _Ewk_Auth_Challenge(login_delegate, url, realm));
892 authentication_cb_.Run(ewk_view_, auth_challenge_.get());
894 if (!auth_challenge_->is_decided && !auth_challenge_->is_suspended) {
895 auth_challenge_->is_decided = true;
896 auth_challenge_->login_delegate->Cancel();
900 void EWebView::InvokePolicyResponseCallback(
901 _Ewk_Policy_Decision* policy_decision,
903 SmartCallback<EWebViewCallbacks::PolicyResponseDecide>().call(
906 if (policy_decision->isSuspended()) {
911 if (!policy_decision->isDecided())
912 policy_decision->Use();
914 policy_decision->SelfDeleteIfNecessary();
917 void EWebView::InvokePolicyNavigationCallback(
918 const NavigationPolicyParams& params,
920 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
922 SmartCallback<EWebViewCallbacks::SaveSessionData>().call();
924 std::unique_ptr<_Ewk_Policy_Decision> policy_decision(
925 new _Ewk_Policy_Decision(params));
927 SmartCallback<EWebViewCallbacks::NavigationPolicyDecision>().call(
928 policy_decision.get());
930 CHECK(!policy_decision->isSuspended());
932 // TODO: Navigation can't be suspended
933 // this aproach is synchronous and requires immediate response
934 // Maybe there is different approach (like resource throttle response
935 // mechanism) that allows us to
936 // suspend navigation
937 if (!policy_decision->isDecided())
938 policy_decision->Use();
940 *handled = policy_decision->GetNavigationPolicyHandler()->GetDecision() ==
941 NavigationPolicyHandlerEfl::Handled;
944 void EWebView::HandleTouchEvents(Ewk_Touch_Event_Type type,
945 const Eina_List* points,
946 const Evas_Modifier* modifiers) {
950 if (GetSettings()->touchFocusEnabled() &&
951 (type == EWK_TOUCH_START && eina_list_count(points) == 1)) {
955 EINA_LIST_FOREACH(points, l, data) {
956 const Ewk_Touch_Point* point = static_cast<Ewk_Touch_Point*>(data);
957 if (point->state == EVAS_TOUCH_POINT_STILL) {
958 // Chromium doesn't expect (and doesn't like) these events.
967 evas_object_geometry_get(ewk_view(), nullptr, &delta_y, nullptr, nullptr);
968 ui::TouchEvent touch_event =
969 ui::MakeTouchEvent(pt, point->state, point->id, 0, delta_y);
970 rwhva()->OnTouchEvent(&touch_event);
975 bool EWebView::TouchEventsEnabled() const {
976 return rwhva()->offscreen_helper()->TouchEventsEnabled();
979 // TODO: Touch events use the same mouse events in EFL API.
980 // Figure out how to distinguish touch and mouse events on touch&mice devices.
981 // Currently mouse and touch support is mutually exclusive.
982 void EWebView::SetTouchEventsEnabled(bool enabled) {
983 if (!rwhva() || !rwhva()->offscreen_helper()) {
984 LOG(WARNING) << "RWHV is not created yet!";
988 if (rwhva()->offscreen_helper()->TouchEventsEnabled() == enabled)
991 rwhva()->offscreen_helper()->SetTouchEventsEnabled(enabled);
993 GetSettings()->getPreferences().touch_event_feature_detection_enabled =
995 GetSettings()->getPreferences().double_tap_to_zoom_enabled = enabled;
996 GetSettings()->getPreferences().editing_behavior =
997 enabled ? blink::mojom::EditingBehavior::kEditingAndroidBehavior
998 : blink::mojom::EditingBehavior::kEditingUnixBehavior,
999 UpdateWebKitPreferences();
1002 bool EWebView::MouseEventsEnabled() const {
1003 return mouse_events_enabled_;
1006 void EWebView::SetMouseEventsEnabled(bool enabled) {
1007 if (!rwhva() || !rwhva()->offscreen_helper()) {
1008 LOG(WARNING) << "RWHV is not created yet!";
1012 if (mouse_events_enabled_ == enabled)
1015 mouse_events_enabled_ = enabled;
1016 rwhva()->offscreen_helper()->SetTouchEventsEnabled(!enabled);
1019 bool EWebView::SetKeyEventsEnabled(bool enabled) {
1020 if (!rwhva() || !rwhva()->aura_efl_helper()) {
1021 LOG(WARNING) << "RWHV is not created yet!";
1025 if (key_events_enabled_ == enabled)
1028 key_events_enabled_ = enabled;
1029 rwhva()->aura_efl_helper()->SetKeyEventsEnabled(enabled);
1033 void EWebView::SendKeyEvent(Evas_Object* ewk_view,
1036 if (!rwhva() || !rwhva()->aura_efl_helper()) {
1037 LOG(WARNING) << "RWHV is not created yet!";
1041 rwhva()->aura_efl_helper()->SendKeyEvent(ewk_view, key_event, is_press);
1046 class JavaScriptCallbackDetails {
1048 JavaScriptCallbackDetails(Ewk_View_Script_Execute_Callback callback_func,
1051 : callback_func_(callback_func), user_data_(user_data), view_(view) {}
1053 Ewk_View_Script_Execute_Callback callback_func_;
1058 void JavaScriptComplete(JavaScriptCallbackDetails* script_callback_data,
1059 base::Value result) {
1060 if (!script_callback_data->callback_func_)
1063 std::string return_string;
1064 if (result.is_string()) {
1065 // We don't want to serialize strings with JSONStringValueSerializer
1066 // to avoid quotation marks.
1067 return_string = result.GetString();
1068 } else if (result.is_none()) {
1069 // Value::TYPE_NULL is for lack of value, undefined, null
1072 JSONStringValueSerializer serializer(&return_string);
1073 serializer.Serialize(result);
1076 script_callback_data->callback_func_(script_callback_data->view_,
1077 return_string.c_str(),
1078 script_callback_data->user_data_);
1083 bool EWebView::ExecuteJavaScript(const char* script,
1084 Ewk_View_Script_Execute_Callback callback,
1086 LOG(INFO) << __FUNCTION__;
1087 if (!web_contents_) {
1088 LOG(ERROR) << __FUNCTION__ << "web_contents_ is null";
1092 RenderFrameHost* render_frame_host = web_contents_->GetPrimaryMainFrame();
1093 if (!render_frame_host) {
1094 LOG(ERROR) << __FUNCTION__ << " render_frame_host is null";
1098 // Note: M37. Execute JavaScript, |script| with
1099 // |RenderFrameHost::ExecuteJavaScript|.
1100 // @see also https://codereview.chromium.org/188893005 for more details.
1101 std::u16string js_script;
1102 base::UTF8ToUTF16(script, strlen(script), &js_script);
1104 JavaScriptCallbackDetails* script_callback_data =
1105 new JavaScriptCallbackDetails(callback, userdata, ewk_view_);
1106 RenderFrameHost::JavaScriptResultCallback js_callback =
1107 base::BindOnce(&JavaScriptComplete, base::Owned(script_callback_data));
1108 // In M47, it isn't possible anymore to execute javascript in the generic
1109 // case. We need to call ExecuteJavaScriptForTests to keep the behaviour
1110 // unchanged @see https://codereview.chromium.org/1123783002
1111 render_frame_host->ExecuteJavaScriptWithUserGestureForTests(
1112 js_script, std::move(js_callback));
1114 // We use ExecuteJavaScriptWithUserGestureForTests instead of
1115 // ExecuteJavaScript because
1116 // ExecuteJavaScriptWithUserGestureForTests sets user_gesture to true. This
1118 // behaviour is m34, and we want to keep it that way.
1119 render_frame_host->ExecuteJavaScriptWithUserGestureForTests(
1120 js_script, base::NullCallback());
1126 bool EWebView::SetUserAgent(const char* userAgent) {
1127 content::NavigationController& controller = web_contents_->GetController();
1128 bool override = userAgent && strlen(userAgent);
1129 for (int i = 0; i < controller.GetEntryCount(); ++i)
1130 controller.GetEntryAtIndex(i)->SetIsOverridingUserAgent(override);
1131 // TODO: Check if override_in_new_tabs has to be true.
1132 web_contents_->SetUserAgentOverride(
1133 blink::UserAgentOverride::UserAgentOnly(userAgent),
1134 false /* override_in_new_tabs */);
1138 bool EWebView::SetUserAgentAppName(const char* application_name) {
1139 EflWebView::VersionInfo::GetInstance()->UpdateUserAgentWithAppName(
1140 application_name ? application_name : "");
1141 std::string user_agent =
1142 EflWebView::VersionInfo::GetInstance()->DefaultUserAgent();
1143 web_contents_->SetUserAgentOverride(
1144 blink::UserAgentOverride::UserAgentOnly(user_agent),
1145 false /* override_in_new_tabs */);
1149 #if BUILDFLAG(IS_TIZEN)
1150 bool EWebView::SetPrivateBrowsing(bool incognito) {
1151 if (context_->GetImpl()->browser_context()->IsOffTheRecord() == incognito)
1153 context_->GetImpl()->browser_context()->SetOffTheRecord(incognito);
1157 bool EWebView::GetPrivateBrowsing() const {
1158 return context_->GetImpl()->browser_context()->IsOffTheRecord();
1162 const char* EWebView::GetUserAgent() const {
1163 std::string user_agent =
1164 web_contents_->GetUserAgentOverride().ua_string_override;
1165 if (user_agent.empty())
1166 user_agent_ = content::GetContentClientExport()->browser()->GetUserAgent();
1168 user_agent_ = user_agent;
1170 return user_agent_.c_str();
1173 const char* EWebView::GetUserAgentAppName() const {
1174 user_agent_app_name_ = EflWebView::VersionInfo::GetInstance()->AppName();
1175 return user_agent_app_name_.c_str();
1178 const char* EWebView::CacheSelectedText() {
1182 selected_text_cached_ = base::UTF16ToUTF8(rwhva()->GetSelectedText());
1183 return selected_text_cached_.c_str();
1186 _Ewk_Frame* EWebView::GetMainFrame() {
1187 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1190 frame_.reset(new _Ewk_Frame(web_contents_->GetPrimaryMainFrame()));
1192 return frame_.get();
1195 void EWebView::UpdateWebKitPreferences() {
1196 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1198 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1199 if (!render_view_host)
1202 web_contents_delegate_->OnUpdateSettings(settings_.get());
1203 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
1204 render_view_host->UpdateWebkitPreferences(settings_->getPreferences());
1206 UpdateWebkitPreferencesEfl(render_view_host);
1209 void EWebView::UpdateWebkitPreferencesEfl(RenderViewHost* render_view_host) {
1210 DCHECK(render_view_host);
1211 #if !defined(EWK_BRINGUP) // FIXME: m108 bringup
1212 IPC::Message* message = new EwkSettingsMsg_UpdateWebKitPreferencesEfl(
1213 render_view_host->GetRoutingID(), settings_->getPreferencesEfl());
1215 if (render_view_host->IsRenderViewLive()) {
1216 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
1217 render_view_host->Send(message);
1220 delayed_messages_.push_back(message);
1225 void EWebView::SetContentSecurityPolicy(const char* policy,
1226 Ewk_CSP_Header_Type type) {
1227 web_contents_delegate_->SetContentSecurityPolicy(
1228 (policy ? policy : std::string()), type);
1231 void EWebView::LoadHTMLString(const char* html,
1232 const char* base_uri,
1233 const char* unreachable_uri) {
1234 LoadData(html, std::string::npos, NULL, NULL, base_uri, unreachable_uri);
1237 void EWebView::LoadPlainTextString(const char* plain_text) {
1238 LoadData(plain_text, std::string::npos, "text/plain", NULL, NULL, NULL);
1241 void EWebView::LoadHTMLStringOverridingCurrentEntry(
1243 const char* base_uri,
1244 const char* unreachable_url) {
1245 LoadData(html, std::string::npos, NULL, NULL, base_uri, unreachable_url,
1249 void EWebView::LoadData(const char* data,
1251 const char* mime_type,
1252 const char* encoding,
1253 const char* base_uri,
1254 const char* unreachable_uri,
1255 bool should_replace_current_entry) {
1256 SetDefaultStringIfNull(mime_type, "text/html");
1257 SetDefaultStringIfNull(encoding, "utf-8");
1258 SetDefaultStringIfNull(base_uri, "about:blank"); // Webkit2 compatible
1259 SetDefaultStringIfNull(unreachable_uri, "");
1261 std::string str_data = data;
1263 if (size < str_data.length())
1264 str_data = str_data.substr(0, size);
1266 std::string url_str("data:");
1267 url_str.append(mime_type);
1268 url_str.append(";charset=");
1269 url_str.append(encoding);
1270 url_str.append(",");
1272 // GURL constructor performs canonicalization of url string, but this is not
1273 // enough for correctly escaping contents of "data:" url.
1274 url_str.append(base::EscapeUrlEncodedData(str_data, false));
1276 NavigationController::LoadURLParams data_params(GURL(url_str.c_str()));
1278 data_params.base_url_for_data_url = GURL(base_uri);
1279 data_params.virtual_url_for_data_url = GURL(unreachable_uri);
1281 data_params.load_type = NavigationController::LOAD_TYPE_DATA;
1282 data_params.should_replace_current_entry = should_replace_current_entry;
1283 data_params.override_user_agent = NavigationController::UA_OVERRIDE_TRUE;
1284 web_contents_->GetController().LoadURLWithParams(data_params);
1287 void EWebView::InvokeLoadError(const GURL& url,
1289 bool is_cancellation) {
1290 _Ewk_Error err(error_code, is_cancellation,
1291 url.possibly_invalid_spec().c_str());
1293 SmartCallback<EWebViewCallbacks::LoadError>().call(&err);
1296 void EWebView::SetViewLoadErrorPageCallback(
1297 Ewk_View_Error_Page_Load_Callback callback,
1299 load_error_page_cb_.Set(callback, user_data);
1302 // Remove below code while ewk_error_cancellation_get has been implemented.
1303 const char* EWebView::InvokeViewLoadErrorPageCallback(
1306 const std::string& error_description) {
1307 std::unique_ptr<_Ewk_Error> err(
1308 new _Ewk_Error(error_code, url.possibly_invalid_spec().c_str(),
1309 error_description.c_str()));
1310 _Ewk_Error_Page error_page;
1312 LOG(INFO) << "EWebView::InvokeLoadErrorPageCallback url: "
1313 << url.spec().c_str() << ", error_code: " << error_code;
1315 load_error_page_cb_.Run(ewk_view_, err.get(), &error_page);
1316 return error_page.content;
1319 bool EWebView::IsLoadErrorPageCallbackSet() const {
1320 return load_error_page_cb_.IsCallbackSet();
1322 void EWebView::HandlePopupMenu(std::vector<blink::mojom::MenuItemPtr> items,
1325 const gfx::Rect& bounds) {
1326 if (!select_picker_) {
1327 select_picker_.reset(CreateSelectPicker(
1328 this, selectedIndex, std::move(items), multiple, bounds));
1330 // Picker has been shown on top of webview and the page content gets
1331 // partially overlapped. Decrease viewport while showing picker.
1332 AdjustViewPortHeightToPopupMenu(true /* is_popup_menu_visible */);
1333 #if BUILDFLAG(IS_TIZEN_TV)
1334 SmartCallback<EWebViewCallbacks::PopupMenuShow>().call();
1337 select_picker_->UpdatePickerData(selectedIndex, std::move(items), multiple);
1340 select_picker_->Show();
1343 void EWebView::HidePopupMenu() {
1344 if (!select_picker_)
1347 AdjustViewPortHeightToPopupMenu(false /* is_popup_menu_visible */);
1348 #if BUILDFLAG(IS_TIZEN_TV)
1349 SmartCallback<EWebViewCallbacks::PopupMenuHide>().call();
1351 select_picker_.reset();
1354 void EWebView::DidSelectPopupMenuItems(std::vector<int>& indices) {
1355 wcva()->wcva_helper()->DidSelectPopupMenuItems(indices);
1358 void EWebView::DidCancelPopupMenu() {
1359 wcva()->wcva_helper()->DidCancelPopupMenu();
1362 void EWebView::HandleLongPressGesture(
1363 const content::ContextMenuParams& params) {
1364 // This menu is created in renderer process and it does not now anything about
1365 // view scaling factor and it has another calling sequence, so coordinates is
1367 if (settings_ && !settings_->getPreferences().long_press_enabled)
1370 content::ContextMenuParams convertedParams = params;
1371 gfx::Point convertedPoint =
1372 rwhva()->offscreen_helper()->ConvertPointInViewPix(
1373 gfx::Point(params.x, params.y));
1374 convertedParams.x = convertedPoint.x();
1375 convertedParams.y = convertedPoint.y();
1378 evas_object_geometry_get(ewk_view(), &x, &y, 0, 0);
1379 convertedParams.x += x;
1380 convertedParams.y += y;
1382 bool show_context_menu_now = true;
1383 if (GetSelectionController() && GetSelectionController()->GetLongPressed()) {
1384 show_context_menu_now = !GetSelectionController()->HandleLongPressEvent(
1385 convertedPoint, convertedParams);
1387 if (show_context_menu_now) {
1388 ShowContextMenuInternal(convertedParams);
1392 void EWebView::ShowContextMenu(const content::ContextMenuParams& params) {
1396 // This menu is created in renderer process and it does not now anything about
1397 // view scaling factor and it has another calling sequence, so coordinates is
1399 content::ContextMenuParams convertedParams = params;
1400 gfx::Point convertedPoint =
1401 rwhva()->offscreen_helper()->ConvertPointInViewPix(
1402 gfx::Point(params.x, params.y));
1403 convertedParams.x = convertedPoint.x();
1404 convertedParams.y = convertedPoint.y();
1407 evas_object_geometry_get(ewk_view(), &x, &y, 0, 0);
1408 convertedParams.x += x;
1409 convertedParams.y += y;
1411 context_menu_position_ = gfx::Point(convertedParams.x, convertedParams.y);
1413 ShowContextMenuInternal(convertedParams);
1416 void EWebView::ShowContextMenuInternal(
1417 const content::ContextMenuParams& params) {
1418 // We don't want to show 'cut' or 'copy' for inputs of type 'password' in
1419 // selection context menu, but params.input_field_type might not be set
1420 // correctly, because in some cases params is received from SelectionBoxEfl,
1421 // not from FrameHostMsg_ContextMenu message. In SelectionBoxEfl
1422 // ContextMenuParams is constructed on our side with limited information and
1423 // input_field_type is not set.
1425 // To work around this, we query for input type and set it separately. In
1426 // response to EwkViewMsg_QueryInputType we run ::UpdateContextMenu with
1427 // information about input's type.
1429 // FIXME: the way we get ContextMenuParams for context menu is flawed in some
1430 // cases. This should be fixed by restructuring context menu code.
1431 // Context menu creation should be unified to always have
1432 // ContextMenuParams received from FrameHostMsg_ContextMenu.
1433 // Tracked at: http://suprem.sec.samsung.net/jira/browse/TWF-1640
1434 if (params.is_editable) {
1435 saved_context_menu_params_ = params;
1437 rwhva()->host()->QueryInputType();
1439 UpdateContextMenuWithParams(params);
1443 void EWebView::UpdateContextMenu(bool is_password_input) {
1444 if (is_password_input) {
1445 saved_context_menu_params_.form_control_type =
1446 blink::mojom::FormControlType::kInputPassword;
1448 UpdateContextMenuWithParams(saved_context_menu_params_);
1451 void EWebView::UpdateContextMenuWithParams(
1452 const content::ContextMenuParams& params) {
1453 context_menu_.reset(
1454 new content::ContextMenuControllerEfl(this, *web_contents_.get()));
1456 if (IsMobileProfile()) {
1457 if (delayed_show_context_menu_timer_) {
1458 ecore_timer_del(delayed_show_context_menu_timer_);
1459 delayed_show_context_menu_timer_ = nullptr;
1461 saved_context_menu_params_ = params;
1462 delayed_show_context_menu_timer_ = ecore_timer_add(
1463 kDelayShowContextMenuTime, DelayedPopulateAndShowContextMenu, this);
1465 if (!context_menu_->PopulateAndShowContextMenu(params)) {
1466 context_menu_.reset();
1467 if (GetSelectionController())
1468 GetSelectionController()->HideHandles();
1473 Eina_Bool EWebView::DelayedPopulateAndShowContextMenu(void* data) {
1474 if (IsMobileProfile()) {
1475 EWebView* view = static_cast<EWebView*>(data);
1477 if (view->context_menu_ &&
1478 !(view->context_menu_->PopulateAndShowContextMenu(
1479 view->saved_context_menu_params_))) {
1480 view->context_menu_.reset();
1482 view->delayed_show_context_menu_timer_ = nullptr;
1485 return ECORE_CALLBACK_CANCEL;
1488 void EWebView::CancelContextMenu(int request_id) {
1490 context_menu_->HideContextMenu();
1493 void EWebView::Find(const char* text, Ewk_Find_Options ewk_find_options) {
1494 std::u16string find_text = base::UTF8ToUTF16(text);
1495 bool find_next = (previous_text_ == find_text);
1498 current_find_request_id_ = find_request_id_counter_++;
1499 previous_text_ = find_text;
1502 auto find_options = blink::mojom::FindOptions::New();
1503 find_options->forward = !(ewk_find_options & EWK_FIND_OPTIONS_BACKWARDS);
1504 find_options->match_case =
1505 !(ewk_find_options & EWK_FIND_OPTIONS_CASE_INSENSITIVE);
1507 web_contents_->Find(current_find_request_id_, find_text,
1508 std::move(find_options));
1511 void EWebView::SetScale(double scale_factor) {
1512 // Do not cache |scale_factor| here as it may be discarded by Blink's
1513 // minimumPageScaleFactor and maximumPageScaleFactor.
1514 // |scale_factor| is cached as responde to DidChangePageScaleFactor.
1515 WebContentsImpl* wci = static_cast<WebContentsImpl*>(web_contents_.get());
1516 wci->GetPrimaryMainFrame()->GetAssociatedLocalMainFrame()->SetScaleFactor(
1520 void EWebView::ScrollFocusedNodeIntoView() {
1521 if (RenderViewHost* render_view_host = web_contents_->GetRenderViewHost()) {
1522 if (auto& broadcast = static_cast<RenderViewHostImpl*>(render_view_host)
1523 ->GetAssociatedPageBroadcast())
1524 broadcast->ScrollFocusedNodeIntoView();
1528 void EWebView::AdjustViewPortHeightToPopupMenu(bool is_popup_menu_visible) {
1529 if (!rwhva() || !IsMobileProfile() ||
1530 settings_->getPreferences().TizenCompatibilityModeEnabled()) {
1534 int picker_height = select_picker_->GetGeometryDIP().height();
1535 gfx::Rect screen_rect =
1536 display::Screen::GetScreen()->GetPrimaryDisplay().bounds();
1537 gfx::Rect view_rect = rwhva()->offscreen_helper()->GetViewBounds();
1539 screen_rect.height() - (view_rect.y() + view_rect.height());
1541 rwhva()->offscreen_helper()->SetCustomViewportSize(
1542 is_popup_menu_visible
1543 ? gfx::Size(view_rect.width(),
1544 view_rect.height() - picker_height + bottom_height)
1548 void EWebView::SetScaleChangedCallback(Ewk_View_Scale_Changed_Callback callback,
1550 scale_changed_cb_.Set(callback, user_data);
1553 bool EWebView::GetScrollPosition(int* x, int* y) const {
1555 LOG(ERROR) << "rwhva() returns nullptr";
1558 if (scroll_detector_->IsScrollOffsetChanged()) {
1560 *x = previous_scroll_position_.x();
1562 *y = previous_scroll_position_.y();
1564 const gfx::Vector2d scroll_position_dip =
1565 scroll_detector_->GetLastScrollPosition();
1566 const float device_scale_factor = display::Screen::GetScreen()
1567 ->GetPrimaryDisplay()
1568 .device_scale_factor();
1570 *x = base::ClampRound((scroll_position_dip.x() - x_delta_) *
1571 device_scale_factor);
1574 *y = base::ClampRound((scroll_position_dip.y() - y_delta_) *
1575 device_scale_factor);
1581 void EWebView::ChangeScroll(int& x, int& y) {
1583 LOG(ERROR) << "rwhva() returns nullptr";
1588 GetScrollSize(&max_x, &max_y);
1589 previous_scroll_position_.set_x(std::min(std::max(x, 0), max_x));
1590 previous_scroll_position_.set_y(std::min(std::max(y, 0), max_y));
1592 const float device_scale_factor = display::Screen::GetScreen()
1593 ->GetPrimaryDisplay()
1594 .device_scale_factor();
1598 x = base::ClampCeil(x / device_scale_factor);
1599 y = base::ClampCeil(y / device_scale_factor);
1601 x_delta_ = x - (x_input / device_scale_factor);
1602 y_delta_ = y - (y_input / device_scale_factor);
1604 scroll_detector_->SetScrollOffsetChanged();
1607 void EWebView::SetScroll(int x, int y) {
1608 if (auto* render_view_host = web_contents_->GetRenderViewHost()) {
1609 if (auto& broadcast = static_cast<RenderViewHostImpl*>(render_view_host)
1610 ->GetAssociatedPageBroadcast()) {
1612 broadcast->SetScrollOffset(x, y);
1617 void EWebView::UseSettingsFont() {
1618 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
1619 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1620 if (render_view_host)
1621 render_view_host->Send(
1622 new EwkViewMsg_UseSettingsFont(render_view_host->GetRoutingID()));
1626 void EWebView::DidChangeContentsSize(int width, int height) {
1627 contents_size_ = gfx::Size(width, height);
1628 SmartCallback<EWebViewCallbacks::ContentsSizeChanged>().call();
1629 SetScaledContentsSize();
1632 const Eina_Rectangle EWebView::GetContentsSize() const {
1633 Eina_Rectangle rect;
1634 EINA_RECTANGLE_SET(&rect, 0, 0, contents_size_.width(),
1635 contents_size_.height());
1639 void EWebView::SetScaledContentsSize() {
1641 return; // LCOV_EXCL_LINE
1643 const float device_scale_factor =
1644 display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
1645 gfx::SizeF scaled_contents_size = gfx::ConvertSizeToPixels(
1646 contents_size_, device_scale_factor * page_scale_factor_);
1647 rwhva()->offscreen_helper()->SetScaledContentSize(scaled_contents_size);
1650 void EWebView::GetScrollSize(int* width, int* height) {
1653 *width = (rwhva() &&
1654 (w = rwhva()->offscreen_helper()->GetScrollableSize().width()))
1659 *height = (rwhva() &&
1660 (h = rwhva()->offscreen_helper()->GetScrollableSize().height()))
1666 void EWebView::MoveCaret(const gfx::Point& point) {
1668 rwhva()->offscreen_helper()->MoveCaret(point);
1671 SelectionControllerEfl* EWebView::GetSelectionController() const {
1672 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1673 RenderWidgetHostViewAura* view = static_cast<RenderWidgetHostViewAura*>(
1674 render_view_host->GetWidget()->GetView());
1675 return view ? view->offscreen_helper()->GetSelectionController() : 0;
1678 void EWebView::SelectFocusedLink() {
1679 rwhva()->host()->SelectFocusedLink();
1682 bool EWebView::GetSelectionRange(Eina_Rectangle* left_rect,
1683 Eina_Rectangle* right_rect) {
1684 if (left_rect && right_rect) {
1685 gfx::Rect left, right;
1686 if (GetSelectionController()) {
1687 GetSelectionController()->GetSelectionBounds(&left, &right);
1688 GetEinaRectFromGfxRect(left, left_rect);
1689 GetEinaRectFromGfxRect(right, right_rect);
1696 void EWebView::OnSelectionRectReceived(const gfx::Rect& selection_rect) const {
1698 context_menu_->OnSelectionRectReceived(selection_rect);
1701 Eina_Bool EWebView::ClearSelection() {
1705 ResetContextMenuController();
1706 rwhva()->SelectionChanged(std::u16string(), 0, gfx::Range());
1708 if (GetSelectionController())
1709 return GetSelectionController()->ClearSelectionViaEWebView();
1714 _Ewk_Hit_Test* EWebView::RequestHitTestDataAt(int x,
1716 Ewk_Hit_Test_Mode mode) {
1717 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1720 EvasToBlinkCords(x, y, &view_x, &view_y);
1722 return RequestHitTestDataAtBlinkCoords(view_x, view_y, mode);
1725 Eina_Bool EWebView::AsyncRequestHitTestDataAt(
1728 Ewk_Hit_Test_Mode mode,
1729 Ewk_View_Hit_Test_Request_Callback callback,
1732 EvasToBlinkCords(x, y, &view_x, &view_y);
1733 return AsyncRequestHitTestDataAtBlinkCords(
1734 view_x, view_y, mode,
1735 new WebViewAsyncRequestHitTestDataUserCallback(x, y, mode, callback,
1739 Eina_Bool EWebView::AsyncRequestHitTestDataAtBlinkCords(
1742 Ewk_Hit_Test_Mode mode,
1743 Ewk_View_Hit_Test_Request_Callback callback,
1745 return AsyncRequestHitTestDataAtBlinkCords(
1747 new WebViewAsyncRequestHitTestDataUserCallback(x, y, mode, callback,
1751 Eina_Bool EWebView::AsyncRequestHitTestDataAtBlinkCords(
1754 Ewk_Hit_Test_Mode mode,
1755 WebViewAsyncRequestHitTestDataCallback* cb) {
1756 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1759 static int64_t request_id = 1;
1762 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1763 DCHECK(render_view_host);
1765 if (render_view_host) {
1766 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
1767 render_view_host->Send(new EwkViewMsg_DoHitTestAsync(
1768 render_view_host->GetRoutingID(), x, y, mode, request_id));
1770 hit_test_callback_[request_id] = cb;
1776 // if failed we delete callback as it is not needed anymore
1781 void EWebView::DispatchAsyncHitTestData(const Hit_Test_Params& params,
1782 int64_t request_id) {
1783 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1785 std::map<int64_t, WebViewAsyncRequestHitTestDataCallback*>::iterator it =
1786 hit_test_callback_.find(request_id);
1788 if (it == hit_test_callback_.end())
1790 std::unique_ptr<_Ewk_Hit_Test> hit_test(new _Ewk_Hit_Test(params));
1792 it->second->Run(hit_test.get(), this);
1794 hit_test_callback_.erase(it);
1797 _Ewk_Hit_Test* EWebView::RequestHitTestDataAtBlinkCoords(
1800 Ewk_Hit_Test_Mode mode) {
1801 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1803 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1805 if (render_view_host) {
1806 // We wait on UI thread till hit test data is updated.
1807 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
1808 render_view_host->Send(
1809 new EwkViewMsg_DoHitTest(render_view_host->GetRoutingID(), x, y, mode));
1811 hit_test_completion_.Wait();
1812 return new _Ewk_Hit_Test(hit_test_params_);
1818 void EWebView::EvasToBlinkCords(int x, int y, int* view_x, int* view_y) {
1819 DCHECK(display::Screen::GetScreen());
1823 gfx::Rect view_bounds = rwhva()->offscreen_helper()->GetViewBoundsInPix();
1826 *view_x = x - view_bounds.x();
1828 display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
1832 *view_y = y - view_bounds.y();
1834 display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
1838 void EWebView::UpdateHitTestData(const Hit_Test_Params& params) {
1839 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
1840 hit_test_params_ = params;
1841 hit_test_completion_.Signal();
1844 void EWebView::OnCopyFromBackingStore(bool success, const SkBitmap& bitmap) {}
1846 void EWebView::OnFocusIn() {
1847 SmartCallback<EWebViewCallbacks::FocusIn>().call();
1848 #if defined(USE_WAYLAND)
1849 if (!rwhva() || !rwhva()->offscreen_helper())
1851 if (GetSettings()->getClipboardEnabled()) {
1852 ClipboardHelperEfl::GetInstance()->OnWebviewFocusIn(
1853 this, rwhva()->offscreen_helper()->content_image_elm_host(),
1854 rwhva()->offscreen_helper()->IsFocusedNodeContentEditable(),
1855 base::BindRepeating(&EWebView::ExecuteEditCommand,
1856 base::Unretained(this)));
1861 void EWebView::OnFocusOut() {
1862 #if defined(TIZEN_ATK_SUPPORT)
1863 if (IsMobileProfile())
1864 eweb_accessibility_->OnFocusOut();
1866 SmartCallback<EWebViewCallbacks::FocusOut>().call();
1867 #if defined(USE_WAYLAND)
1868 if (GetSettings()->getClipboardEnabled())
1869 ClipboardHelperEfl::GetInstance()->MaybeInvalidateActiveWebview(this);
1873 void EWebView::RenderViewReady() {
1875 rwhva()->offscreen_helper()->SetFocusInOutCallbacks(
1876 base::BindRepeating(&EWebView::OnFocusIn, base::Unretained(this)),
1877 base::BindRepeating(&EWebView::OnFocusOut, base::Unretained(this)));
1880 #if defined(TIZEN_VIDEO_HOLE)
1881 if (rwhva() && pending_video_hole_setting_) {
1882 EnableVideoHoleSupportInternal();
1883 pending_video_hole_setting_ = false;
1887 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1889 SendDelayedMessages(render_view_host);
1890 UpdateWebkitPreferencesEfl(render_view_host);
1892 if (render_view_host) {
1893 WebContents* content = WebContents::FromRenderViewHost(render_view_host);
1895 RenderProcessHost* host = render_view_host->GetProcess();
1897 host->AddFilter(new WebViewBrowserMessageFilter(content));
1902 void EWebView::SetQuotaPermissionRequestCallback(
1903 Ewk_Quota_Permission_Request_Callback callback,
1905 quota_request_callback_.Set(callback, user_data);
1908 #if !defined(EWK_BRINGUP) // FIXME: m114 bringup
1909 void EWebView::InvokeQuotaPermissionRequest(
1910 _Ewk_Quota_Permission_Request* request,
1911 content::QuotaPermissionContext::PermissionCallback cb) {
1912 quota_permission_request_map_[request] = std::move(cb);
1913 request->setView(ewk_view());
1914 if (quota_request_callback_.IsCallbackSet())
1915 quota_request_callback_.Run(ewk_view(), request);
1917 QuotaRequestCancel(request);
1920 void EWebView::QuotaRequestReply(const _Ewk_Quota_Permission_Request* request,
1922 DCHECK(quota_permission_request_map_.find(request) !=
1923 quota_permission_request_map_.end());
1925 QuotaPermissionContextEfl::DispatchCallback(
1926 std::move(quota_permission_request_map_[request]),
1927 (allow ? QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_ALLOW
1928 : QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_DISALLOW));
1930 quota_permission_request_map_.erase(request);
1934 void EWebView::QuotaRequestCancel(
1935 const _Ewk_Quota_Permission_Request* request) {
1936 DCHECK(quota_permission_request_map_.find(request) !=
1937 quota_permission_request_map_.end());
1939 QuotaPermissionContextEfl::DispatchCallback(
1940 std::move(quota_permission_request_map_[request]),
1941 QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_CANCELLED);
1942 quota_permission_request_map_.erase(request);
1947 bool EWebView::GetLinkMagnifierEnabled() const {
1948 #if !defined(EWK_BRINGUP) // FIXME: m71 bringup
1949 return web_contents_->GetMutableRendererPrefs()
1950 ->tap_multiple_targets_strategy ==
1951 TAP_MULTIPLE_TARGETS_STRATEGY_POPUP;
1957 void EWebView::SetLinkMagnifierEnabled(bool enabled) {
1958 #if !defined(EWK_BRINGUP) // FIXME: m71 bringup
1959 web_contents_->GetMutableRendererPrefs()->tap_multiple_targets_strategy =
1960 enabled ? TAP_MULTIPLE_TARGETS_STRATEGY_POPUP
1961 : TAP_MULTIPLE_TARGETS_STRATEGY_NONE;
1963 web_contents_->SyncRendererPrefs();
1966 bool EWebView::GetSnapshotAsync(
1967 Eina_Rectangle rect,
1968 Ewk_Web_App_Screenshot_Captured_Callback callback,
1970 float scale_factor) {
1971 if (!rwhva() || !rwhva()->offscreen_helper())
1974 rwhva()->offscreen_helper()->RequestSnapshotAsync(
1975 gfx::Rect(rect.x, rect.y, rect.w, rect.h), callback, user_data,
1980 Evas_Object* EWebView::GetSnapshot(Eina_Rectangle rect, float scale_factor) {
1981 if (!rwhva() || !rwhva()->offscreen_helper())
1984 return rwhva()->offscreen_helper()->GetSnapshot(
1985 gfx::Rect(rect.x, rect.y, rect.w, rect.h), scale_factor);
1988 void EWebView::BackForwardListClear() {
1989 content::NavigationController& controller = web_contents_->GetController();
1991 int entry_count = controller.GetEntryCount();
1992 bool entry_removed = false;
1994 for (int i = 0; i < entry_count; i++) {
1995 if (controller.RemoveEntryAtIndex(i)) {
1996 entry_removed = true;
1997 entry_count = controller.GetEntryCount();
2002 if (entry_removed) {
2003 back_forward_list_->ClearCache();
2004 InvokeBackForwardListChangedCallback();
2008 _Ewk_Back_Forward_List* EWebView::GetBackForwardList() const {
2009 return back_forward_list_.get();
2012 void EWebView::InvokeBackForwardListChangedCallback() {
2013 SmartCallback<EWebViewCallbacks::BackForwardListChange>().call();
2016 _Ewk_History* EWebView::GetBackForwardHistory() const {
2017 return new _Ewk_History(web_contents_->GetController());
2020 bool EWebView::WebAppCapableGet(Ewk_Web_App_Capable_Get_Callback callback,
2022 RenderViewHost* renderViewHost = web_contents_->GetRenderViewHost();
2023 if (!renderViewHost) {
2026 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
2027 WebApplicationCapableGetCallback* cb =
2028 new WebApplicationCapableGetCallback(callback, userData);
2029 int callbackId = web_app_capable_get_callback_map_.Add(cb);
2030 return renderViewHost->Send(new EwkViewMsg_WebAppCapableGet(
2031 renderViewHost->GetRoutingID(), callbackId));
2037 bool EWebView::WebAppIconUrlGet(Ewk_Web_App_Icon_URL_Get_Callback callback,
2039 RenderViewHost* renderViewHost = web_contents_->GetRenderViewHost();
2040 if (!renderViewHost) {
2043 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
2044 WebApplicationIconUrlGetCallback* cb =
2045 new WebApplicationIconUrlGetCallback(callback, userData);
2046 int callbackId = web_app_icon_url_get_callback_map_.Add(cb);
2047 return renderViewHost->Send(new EwkViewMsg_WebAppIconUrlGet(
2048 renderViewHost->GetRoutingID(), callbackId));
2054 bool EWebView::WebAppIconUrlsGet(Ewk_Web_App_Icon_URLs_Get_Callback callback,
2056 RenderViewHost* renderViewHost = web_contents_->GetRenderViewHost();
2057 if (!renderViewHost) {
2060 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
2061 WebApplicationIconUrlsGetCallback* cb =
2062 new WebApplicationIconUrlsGetCallback(callback, userData);
2063 int callbackId = web_app_icon_urls_get_callback_map_.Add(cb);
2064 return renderViewHost->Send(new EwkViewMsg_WebAppIconUrlsGet(
2065 renderViewHost->GetRoutingID(), callbackId));
2071 void EWebView::InvokeWebAppCapableGetCallback(bool capable, int callbackId) {
2072 WebApplicationCapableGetCallback* callback =
2073 web_app_capable_get_callback_map_.Lookup(callbackId);
2076 callback->Run(capable);
2077 web_app_capable_get_callback_map_.Remove(callbackId);
2080 void EWebView::InvokeWebAppIconUrlGetCallback(const std::string& iconUrl,
2082 WebApplicationIconUrlGetCallback* callback =
2083 web_app_icon_url_get_callback_map_.Lookup(callbackId);
2086 callback->Run(iconUrl);
2087 web_app_icon_url_get_callback_map_.Remove(callbackId);
2090 void EWebView::InvokeWebAppIconUrlsGetCallback(const StringMap& iconUrls,
2092 WebApplicationIconUrlsGetCallback* callback =
2093 web_app_icon_urls_get_callback_map_.Lookup(callbackId);
2097 callback->Run(iconUrls);
2098 web_app_icon_urls_get_callback_map_.Remove(callbackId);
2101 void EWebView::SetNotificationPermissionCallback(
2102 Ewk_View_Notification_Permission_Callback callback,
2104 notification_permission_callback_.Set(callback, user_data);
2107 bool EWebView::IsNotificationPermissionCallbackSet() const {
2108 return notification_permission_callback_.IsCallbackSet();
2111 bool EWebView::InvokeNotificationPermissionCallback(
2112 Ewk_Notification_Permission_Request* request) {
2113 Eina_Bool ret = EINA_FALSE;
2114 notification_permission_callback_.Run(ewk_view_, request, &ret);
2118 int EWebView::SetEwkViewPlainTextGetCallback(
2119 Ewk_View_Plain_Text_Get_Callback callback,
2121 EwkViewPlainTextGetCallback* view_plain_text_callback_ptr =
2122 new EwkViewPlainTextGetCallback;
2123 view_plain_text_callback_ptr->Set(callback, user_data);
2124 return plain_text_get_callback_map_.Add(view_plain_text_callback_ptr);
2127 bool EWebView::PlainTextGet(Ewk_View_Plain_Text_Get_Callback callback,
2129 auto* render_frame_host = web_contents_->GetPrimaryMainFrame();
2130 if (!render_frame_host)
2133 auto callback_id = SetEwkViewPlainTextGetCallback(callback, user_data);
2134 return render_frame_host->Send(new EwkFrameMsg_GetPlainText(
2135 render_frame_host->GetRoutingID(), callback_id));
2138 void EWebView::InvokePlainTextGetCallback(const std::string& content_text,
2139 int plain_text_get_callback_id) {
2140 EwkViewPlainTextGetCallback* view_plain_text_callback_invoke_ptr =
2141 plain_text_get_callback_map_.Lookup(plain_text_get_callback_id);
2142 view_plain_text_callback_invoke_ptr->Run(ewk_view(), content_text.c_str());
2143 plain_text_get_callback_map_.Remove(plain_text_get_callback_id);
2146 void EWebView::SetViewGeolocationPermissionCallback(
2147 Ewk_View_Geolocation_Permission_Callback callback,
2149 geolocation_permission_cb_.Set(callback, user_data);
2152 bool EWebView::InvokeViewGeolocationPermissionCallback(
2153 _Ewk_Geolocation_Permission_Request* permission_context,
2154 Eina_Bool* callback_result) {
2155 return geolocation_permission_cb_.Run(ewk_view_, permission_context,
2159 void EWebView::SetViewUserMediaPermissionCallback(
2160 Ewk_View_User_Media_Permission_Callback callback,
2162 user_media_permission_cb_.Set(callback, user_data);
2165 bool EWebView::InvokeViewUserMediaPermissionCallback(
2166 _Ewk_User_Media_Permission_Request* permission_context,
2167 Eina_Bool* callback_result) {
2168 return user_media_permission_cb_.Run(ewk_view_, permission_context,
2172 void EWebView::SetViewUserMediaPermissionQueryCallback(
2173 Ewk_View_User_Media_Permission_Query_Callback callback,
2175 user_media_permission_query_cb_.Set(callback, user_data);
2178 Ewk_User_Media_Permission_Query_Result
2179 EWebView::InvokeViewUserMediaPermissionQueryCallback(
2180 _Ewk_User_Media_Permission_Query* permission_context) {
2181 return user_media_permission_query_cb_.Run(ewk_view_, permission_context);
2184 void EWebView::SetViewUnfocusAllowCallback(
2185 Ewk_View_Unfocus_Allow_Callback callback,
2187 unfocus_allow_cb_.Set(callback, user_data);
2190 bool EWebView::InvokeViewUnfocusAllowCallback(Ewk_Unfocus_Direction direction,
2191 Eina_Bool* callback_result) {
2192 return unfocus_allow_cb_.Run(ewk_view_, direction, callback_result);
2195 void EWebView::StopFinding() {
2196 web_contents_->StopFinding(content::STOP_FIND_ACTION_CLEAR_SELECTION);
2199 void EWebView::SetProgressValue(double progress) {
2200 progress_ = progress;
2203 double EWebView::GetProgressValue() {
2207 const char* EWebView::GetTitle() {
2208 title_ = base::UTF16ToUTF8(web_contents_->GetTitle());
2209 return title_.c_str();
2212 bool EWebView::SaveAsPdf(int width, int height, const std::string& filename) {
2215 rwhva()->host()->PrintToPdf(width, height, base::FilePath(filename));
2219 bool EWebView::GetMHTMLData(Ewk_View_MHTML_Data_Get_Callback callback,
2221 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
2222 if (!render_view_host)
2225 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
2226 MHTMLCallbackDetails* callback_details = new MHTMLCallbackDetails;
2227 callback_details->Set(callback, user_data);
2228 int mhtml_callback_id = mhtml_callback_map_.Add(callback_details);
2229 return render_view_host->Send(new EwkViewMsg_GetMHTMLData(
2230 render_view_host->GetRoutingID(), mhtml_callback_id));
2236 void EWebView::OnMHTMLContentGet(const std::string& mhtml_content,
2238 MHTMLCallbackDetails* callback_details =
2239 mhtml_callback_map_.Lookup(callback_id);
2240 callback_details->Run(ewk_view(), mhtml_content.c_str());
2241 mhtml_callback_map_.Remove(callback_id);
2244 bool EWebView::SavePageAsMHTML(const std::string& path,
2245 Ewk_View_Save_Page_Callback callback,
2250 GURL url(web_contents_->GetLastCommittedURL());
2251 std::u16string title(web_contents_->GetTitle());
2253 // Post function that has file access to blocking task runner.
2254 base::ThreadPool::PostTaskAndReplyWithResult(
2256 {base::MayBlock(), base::TaskPriority::BEST_EFFORT,
2257 base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN},
2258 base::BindOnce(&GenerateMHTMLFilePath, url, base::UTF16ToUTF8(title),
2260 base::BindOnce(&EWebView::GenerateMHTML, base::Unretained(this), callback,
2265 void EWebView::GenerateMHTML(Ewk_View_Save_Page_Callback callback,
2267 const base::FilePath& file_path) {
2268 if (file_path.empty()) {
2269 LOG(ERROR) << "Generating file path was failed";
2270 callback(ewk_view_, nullptr, user_data);
2274 MHTMLGenerationParams params(file_path);
2275 web_contents_->GenerateMHTML(
2276 params, base::BindOnce(&EWebView::MHTMLGenerated, base::Unretained(this),
2277 callback, user_data, file_path));
2280 void EWebView::MHTMLGenerated(Ewk_View_Save_Page_Callback callback,
2282 const base::FilePath& file_path,
2283 int64_t file_size) {
2284 callback(ewk_view_, file_size > 0 ? file_path.value().c_str() : nullptr,
2288 bool EWebView::GetBackgroundColor(
2289 Ewk_View_Background_Color_Get_Callback callback,
2293 BackgroundColorGetCallback* cb =
2294 new BackgroundColorGetCallback(callback, user_data);
2295 int callback_id = background_color_get_callback_map_.Add(cb);
2297 rwhva()->host()->RequestBackgroundColor(callback_id);
2301 void EWebView::OnGetBackgroundColor(int callback_id, SkColor bg_color) {
2302 BackgroundColorGetCallback* cb =
2303 background_color_get_callback_map_.Lookup(callback_id);
2308 cb->Run(ewk_view(), SkColorGetR(bg_color), SkColorGetG(bg_color),
2309 SkColorGetB(bg_color), SkColorGetA(bg_color));
2310 background_color_get_callback_map_.Remove(callback_id);
2313 bool EWebView::IsFullscreen() {
2314 return web_contents_delegate_->IsFullscreenForTabOrPending(
2315 web_contents_.get());
2318 void EWebView::ExitFullscreen() {
2319 WebContentsImpl* wci = static_cast<WebContentsImpl*>(web_contents_.get());
2320 wci->ExitFullscreen(false);
2323 double EWebView::GetScale() {
2324 return page_scale_factor_;
2327 void EWebView::DidChangePageScaleFactor(double scale_factor) {
2328 page_scale_factor_ = scale_factor;
2329 wcva()->wcva_helper()->SetPageScaleFactor(scale_factor);
2330 SetScaledContentsSize();
2332 // Notify app about the scale change.
2333 scale_changed_cb_.Run(ewk_view_, scale_factor);
2336 inline JavaScriptDialogManagerEfl* EWebView::GetJavaScriptDialogManagerEfl() {
2337 return static_cast<JavaScriptDialogManagerEfl*>(
2338 web_contents_delegate_->GetJavaScriptDialogManager(web_contents_.get()));
2341 void EWebView::SetJavaScriptAlertCallback(
2342 Ewk_View_JavaScript_Alert_Callback callback,
2344 GetJavaScriptDialogManagerEfl()->SetAlertCallback(callback, user_data);
2347 void EWebView::JavaScriptAlertReply() {
2348 GetJavaScriptDialogManagerEfl()->ExecuteDialogClosedCallBack(true,
2350 SmartCallback<EWebViewCallbacks::PopupReplyWaitFinish>().call(0);
2353 void EWebView::SetJavaScriptConfirmCallback(
2354 Ewk_View_JavaScript_Confirm_Callback callback,
2356 GetJavaScriptDialogManagerEfl()->SetConfirmCallback(callback, user_data);
2359 void EWebView::JavaScriptConfirmReply(bool result) {
2360 GetJavaScriptDialogManagerEfl()->ExecuteDialogClosedCallBack(result,
2362 SmartCallback<EWebViewCallbacks::PopupReplyWaitFinish>().call(0);
2365 void EWebView::SetJavaScriptPromptCallback(
2366 Ewk_View_JavaScript_Prompt_Callback callback,
2368 GetJavaScriptDialogManagerEfl()->SetPromptCallback(callback, user_data);
2371 void EWebView::JavaScriptPromptReply(const char* result) {
2372 GetJavaScriptDialogManagerEfl()->ExecuteDialogClosedCallBack(
2373 true, (std::string(result)));
2374 SmartCallback<EWebViewCallbacks::PopupReplyWaitFinish>().call(0);
2377 void EWebView::GetPageScaleRange(double* min_scale, double* max_scale) {
2378 auto& prefs = web_contents_->GetOrCreateWebPreferences();
2380 *min_scale = prefs.default_minimum_page_scale_factor;
2382 *max_scale = prefs.default_maximum_page_scale_factor;
2385 content::WebContentsViewAura* EWebView::GetWebContentsViewAura() const {
2386 WebContentsImpl* wc = static_cast<WebContentsImpl*>(web_contents_.get());
2387 return static_cast<WebContentsViewAura*>(wc->GetView());
2390 bool EWebView::SetDrawsTransparentBackground(bool enabled) {
2391 #if BUILDFLAG(IS_TIZEN)
2392 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
2393 if (!render_view_host || !rwhva())
2396 if (!rwhva()->offscreen_helper())
2398 elm_object_style_set(rwhva()->offscreen_helper()->content_image_elm_host(),
2399 enabled ? "transparent" : "default");
2400 evas_object_image_alpha_set(rwhva()->offscreen_helper()->content_image(),
2402 GetWebContentsViewAura()->SetBackgroundColor(enabled ? SK_ColorTRANSPARENT
2404 static_cast<RenderViewHostImpl*>(render_view_host)
2406 ->GetAssociatedFrameWidget()
2407 ->SetDrawsTransparentBackground(enabled);
2408 rwhva()->SetBackgroundColor(enabled ? SK_ColorTRANSPARENT : SK_ColorWHITE);
2415 bool EWebView::GetDrawsTransparentBackground() {
2416 #if BUILDFLAG(IS_TIZEN)
2417 return GetWebContentsViewAura()->GetBackgroundColor() == SK_ColorTRANSPARENT;
2423 bool EWebView::SetBackgroundColor(int red, int green, int blue, int alpha) {
2424 #if BUILDFLAG(IS_TIZEN)
2426 return SetDrawsTransparentBackground(true);
2428 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
2429 if (!render_view_host || !rwhva())
2432 if (!rwhva()->offscreen_helper())
2434 elm_object_style_set(rwhva()->offscreen_helper()->content_image_elm_host(),
2435 alpha < 255 ? "transparent" : "default");
2436 evas_object_image_alpha_set(rwhva()->offscreen_helper()->content_image(),
2438 GetWebContentsViewAura()->SetBackgroundColor(
2439 SkColorSetARGB(alpha, red, green, blue));
2440 static_cast<RenderViewHostImpl*>(render_view_host)
2442 ->GetAssociatedFrameWidget()
2443 ->SetBackgroundColor(red, green, blue, alpha);
2444 rwhva()->SetBackgroundColor(SkColorSetARGB(alpha, red, green, blue));
2452 void EWebView::GetSessionData(const char** data, unsigned* length) const {
2453 static const int MAX_SESSION_ENTRY_SIZE = std::numeric_limits<int>::max();
2455 NavigationController& navigationController = web_contents_->GetController();
2456 base::Pickle sessionPickle;
2457 const int itemCount = navigationController.GetEntryCount();
2459 sessionPickle.WriteInt(itemCount);
2460 sessionPickle.WriteInt(navigationController.GetCurrentEntryIndex());
2462 for (int i = 0; i < itemCount; i++) {
2463 NavigationEntry* navigationEntry = navigationController.GetEntryAtIndex(i);
2464 sessions::SerializedNavigationEntry serializedEntry =
2465 sessions::ContentSerializedNavigationBuilder::FromNavigationEntry(
2466 i, navigationEntry);
2467 serializedEntry.WriteToPickle(MAX_SESSION_ENTRY_SIZE, &sessionPickle);
2470 if (sessionPickle.size() <= 0 ||
2472 static_cast<char*>(malloc(sizeof(char) * sessionPickle.size())))) {
2473 LOG(ERROR) << "Failed to get session data";
2477 memcpy(const_cast<char*>(*data), sessionPickle.data(), sessionPickle.size());
2478 *length = sessionPickle.size();
2481 bool EWebView::RestoreFromSessionData(const char* data, unsigned length) {
2482 base::Pickle sessionPickle(data, length);
2483 base::PickleIterator pickleIterator(sessionPickle);
2487 if (!pickleIterator.ReadInt(&entryCount))
2489 if (!pickleIterator.ReadInt(¤tEntry))
2492 std::vector<sessions::SerializedNavigationEntry> serializedEntries;
2493 serializedEntries.resize(entryCount);
2494 for (int i = 0; i < entryCount; ++i) {
2495 if (!serializedEntries.at(i).ReadFromPickle(&pickleIterator))
2505 std::vector<std::unique_ptr<content::NavigationEntry>> scopedEntries =
2506 sessions::ContentSerializedNavigationBuilder::ToNavigationEntries(
2507 serializedEntries, context()->browser_context());
2509 NavigationController& navigationController = web_contents_->GetController();
2511 if (currentEntry < 0)
2514 if (currentEntry >= static_cast<int>(scopedEntries.size()))
2515 currentEntry = scopedEntries.size() - 1;
2517 navigationController.Restore(currentEntry, RestoreType::kRestored,
2522 void EWebView::SetBrowserFont() {
2523 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
2524 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
2525 if (render_view_host) {
2526 IPC::Message* message =
2527 new EwkViewMsg_SetBrowserFont(render_view_host->GetRoutingID());
2529 if (render_view_host->IsRenderViewLive())
2530 render_view_host->Send(message);
2532 delayed_messages_.push_back(message);
2537 bool EWebView::IsDragging() const {
2538 return wcva()->wcva_helper()->IsDragging();
2541 void EWebView::ShowFileChooser(
2542 scoped_refptr<content::FileSelectListener> listener,
2543 const blink::mojom::FileChooserParams& params) {
2544 #if BUILDFLAG(IS_TIZEN_TV)
2545 LOG(INFO) << "File chooser request callback.";
2546 file_chooser_request_.reset(new _Ewk_File_Chooser_Request(
2547 std::move(listener), params.accept_types, params.mode));
2548 SmartCallback<EWebViewCallbacks::FileChooserRequest>().call(
2549 file_chooser_request_.get());
2551 if (!IsMobileProfile() && !IsWearableProfile())
2553 file_chooser_.reset(
2554 new content::FileChooserControllerEfl(std::move(listener), params));
2555 file_chooser_->Open();
2559 #if !defined(EWK_BRINGUP) // FIXME: m67 bringup
2560 void EWebView::SetViewMode(blink::WebViewMode view_mode) {
2561 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
2562 if (!render_view_host)
2565 IPC::Message* message =
2566 new ViewMsg_SetViewMode(render_view_host->GetRoutingID(), view_mode);
2567 if (render_view_host->IsRenderViewLive()) {
2568 render_view_host->Send(message);
2570 delayed_messages_.push_back(message);
2575 gfx::Point EWebView::GetContextMenuPosition() const {
2576 return context_menu_position_;
2579 void EWebView::ShowContentsDetectedPopup(const char* message) {
2580 popup_controller_.reset(new PopupControllerEfl(this));
2581 popup_controller_->openPopup(message);
2584 void EWebView::RequestColorPicker(int r, int g, int b, int a) {
2585 input_picker_.reset(new InputPicker(this, web_contents_.get(), ewk_view()));
2586 input_picker_->ShowColorPicker(r, g, b, a);
2589 bool EWebView::SetColorPickerColor(int r, int g, int b, int a) {
2590 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
2591 web_contents_->DidChooseColorInColorChooser(SkColorSetARGB(a, r, g, b));
2596 void EWebView::InputPickerShow(ui::TextInputType input_type,
2598 content::DateTimeChooserEfl* date_time_chooser) {
2599 input_picker_.reset(new InputPicker(this, web_contents_.get(), ewk_view(),
2600 date_time_chooser));
2601 input_picker_->ShowDatePicker(input_type, input_value);
2604 void EWebView::LoadNotFoundErrorPage(const std::string& invalidUrl) {
2605 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
2606 RenderFrameHost* render_frame_host = web_contents_->GetPrimaryMainFrame();
2607 if (render_frame_host)
2608 render_frame_host->Send(new EwkFrameMsg_LoadNotFoundErrorPage(
2609 render_frame_host->GetRoutingID(), invalidUrl));
2613 std::string EWebView::GetPlatformLocale() {
2614 char* local_default = setlocale(LC_CTYPE, 0);
2616 return std::string("en-US");
2617 std::string locale = std::string(local_default);
2618 size_t position = locale.find('_');
2619 if (position != std::string::npos)
2620 locale.replace(position, 1, "-");
2621 position = locale.find('.');
2622 if (position != std::string::npos)
2623 locale = locale.substr(0, position);
2627 int EWebView::StartInspectorServer(int port) {
2628 #if BUILDFLAG(IS_TIZEN_TV)
2630 use_early_rwi_ = false;
2631 rwi_info_showed_ = false;
2633 if (!context_->GetImpl()->GetInspectorServerState()) {
2635 if (!devtools_http_handler::DevToolsPortManager::GetInstance()
2636 ->GetValidPort(validPort))
2642 return context_->InspectorServerStart(port);
2645 bool EWebView::StopInspectorServer() {
2646 #if BUILDFLAG(IS_TIZEN_TV)
2648 use_early_rwi_ = false;
2649 rwi_info_showed_ = false;
2652 return context_->InspectorServerStop();
2655 void EWebView::InvokeWebProcessCrashedCallback() {
2656 DCHECK_CURRENTLY_ON(BrowserThread::UI);
2657 const GURL last_url = GetURL();
2658 bool callback_handled = false;
2659 SmartCallback<EWebViewCallbacks::WebProcessCrashed>().call(&callback_handled);
2660 if (!callback_handled)
2661 LoadHTMLString(kRendererCrashedHTMLMessage, NULL,
2662 last_url.possibly_invalid_spec().c_str());
2665 void EWebView::SyncAcceptLanguages(const std::string& accept_languages) {
2666 web_contents_->GetMutableRendererPrefs()->accept_languages = accept_languages;
2667 web_contents_->SyncRendererPrefs();
2668 BrowserContext* browser_context = web_contents_->GetBrowserContext();
2669 if (!browser_context)
2672 auto* storage_partition = browser_context->GetDefaultStoragePartition();
2673 if (!storage_partition)
2676 if (auto* network_context = storage_partition->GetNetworkContext())
2677 network_context->SetAcceptLanguage(accept_languages);
2680 #if BUILDFLAG(IS_TIZEN_TV)
2681 bool EWebView::EdgeScrollBy(int delta_x, int delta_y) {
2682 if ((delta_x == 0 && delta_y == 0) || is_processing_edge_scroll_)
2685 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
2686 if (!render_view_host)
2692 gfx::Point offset = gfx::Point(delta_x, delta_y);
2693 gfx::Point mouse_position;
2694 GetMousePosition(mouse_position);
2695 is_processing_edge_scroll_ = true;
2697 static_cast<RenderViewHostImpl*>(render_view_host)
2699 ->GetAssociatedFrameWidget()
2700 ->EdgeScrollBy(offset, mouse_position);
2704 void EWebView::GetMousePosition(gfx::Point& mouse_position) {
2705 int mouse_x, mouse_y;
2706 evas_pointer_output_xy_get(GetEvas(), &mouse_x, &mouse_y);
2707 Evas_Coord x, y, width, height;
2708 evas_object_geometry_get(ewk_view(), &x, &y, &width, &height);
2712 else if (mouse_y > y + height)
2713 mouse_y = y + height - 1;
2716 else if (mouse_x > x + width)
2717 mouse_x = x + width - 1;
2723 display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
2725 display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
2727 mouse_position.set_x(mouse_x);
2728 mouse_position.set_y(mouse_y);
2731 void EWebView::InvokeEdgeScrollByCallback(const gfx::Point& offset,
2733 is_processing_edge_scroll_ = false;
2736 SmartCallback<EWebViewCallbacks::EdgeScrollLeft>().call(&handled);
2737 else if (offset.x() > 0)
2738 SmartCallback<EWebViewCallbacks::EdgeScrollRight>().call(&handled);
2741 SmartCallback<EWebViewCallbacks::EdgeScrollTop>().call(&handled);
2742 else if (offset.y() > 0)
2743 SmartCallback<EWebViewCallbacks::EdgeScrollBottom>().call(&handled);
2747 void EWebView::HandleRendererProcessCrash() {
2748 content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
2749 base::BindOnce(&EWebView::InvokeWebProcessCrashedCallback,
2750 base::Unretained(this)));
2753 void EWebView::InitializeContent() {
2754 LOG(INFO) << "eweb_view.cc InitializeContent" ;
2755 #if BUILDFLAG(IS_TIZEN_TV)
2756 // When initialize content init inspector server
2757 InitInspectorServer();
2759 WebContents* new_contents = create_new_window_web_contents_cb_.Run(this);
2760 if (!new_contents) {
2761 WebContents::CreateParams params(context_->browser_context());
2762 web_contents_.reset(
2763 new WebContentsImplEfl(context_->browser_context(), this));
2764 static_cast<WebContentsImpl*>(web_contents_.get())
2765 ->Init(params, blink::FramePolicy());
2767 web_contents_.reset(new_contents);
2769 // When a new webview is created in response to a request from the
2770 // engine, the BrowserContext instance of the originator WebContents
2771 // is used by the newly created WebContents object.
2772 // See more in WebContentsImplEfl::HandleNewWebContentsCreate.
2774 // Hence, if as part of the WebView creation, the embedding APP
2775 // passes in a Ewk_Context instance that wraps a different instance of
2776 // BrowserContext than the one the originator WebContents holds,
2777 // undefined behavior can be seen.
2779 // This is a snippet code that illustrate the scenario:
2782 // evas_object_smart_callback_add(web_view_, "create,window",
2783 // &OnNewWindowRequest, this);
2786 // void OnNewWindowRequest(void *data, Evas_Object*, void* out_view) {
2788 // EvasObject* new_web_view = ewk_view_add_with_context(GetEvas(),
2789 // ewk_context_new());
2790 // *static_cast<Evas_Object**>(out_view) = new_web_view;
2794 // The new Ewk_Context object created and passed in as parameter to
2795 // ewk_view_add_with_context wraps a different instance of BrowserContext
2796 // than the one the new WebContents object will hold.
2798 // CHECK below aims at catching misuse of this API.
2799 bool should_crash = context_->GetImpl()->browser_context() !=
2800 web_contents_->GetBrowserContext();
2803 << "BrowserContext of new WebContents does not match EWebView's. "
2804 << "Please see 'ewk_view_add*' documentation. "
2805 << "Aborting execution ...";
2809 web_contents_delegate_.reset(new WebContentsDelegateEfl(this));
2810 web_contents_->SetDelegate(web_contents_delegate_.get());
2812 // EWebView's delegate. Calls to WebContentsImplEfl and
2813 // WebContentsViewAuraHelperEfl are delegated to this class.
2814 // For more details, refer commit message of patch 301647.
2815 webview_delegate_.reset(new WebViewDelegateEfl(this));
2816 WebContentsImplEfl* wc_efl =
2817 static_cast<WebContentsImplEfl*>(web_contents_.get());
2818 wc_efl->SetWebviewDelegate(webview_delegate_.get());
2819 wcva()->wcva_helper()->SetWebviewDelegate(webview_delegate_.get());
2821 back_forward_list_.reset(new _Ewk_Back_Forward_List(web_contents_.get()));
2823 permission_popup_manager_.reset(new PermissionPopupManager(ewk_view_));
2824 gin_native_bridge_dispatcher_host_.reset(
2825 new content::GinNativeBridgeDispatcherHost(web_contents_.get()));
2828 static_cast<WebContentsImplEfl*>(web_contents_.get())->GetEflMainLayout();
2829 evas_object_smart_member_add(efl_main_layout_, ewk_view_);
2830 static_cast<WebContentsImpl*>(web_contents_.get())->set_ewk_view(ewk_view_);
2831 InitializeWindowTreeHost();
2834 #if BUILDFLAG(IS_TIZEN_TV)
2835 void EWebView::OnDialogClosed() {
2836 if (!use_early_rwi_)
2839 use_early_rwi_ = false;
2840 LOG(INFO) << "[FAST RWI] SetURL Restore [" << rwi_gurl_.spec()
2841 << "] from [about:blank]";
2844 rwi_info_showed_ = true;
2847 void EWebView::InitInspectorServer() {
2848 if (devtools_http_handler::DevToolsPortManager::GetInstance()
2849 ->ProcessCompare()) {
2850 int res = StartInspectorServer(0);
2852 LOG(INFO) << "InitInspectorServer SetPort";
2853 devtools_http_handler::DevToolsPortManager::GetInstance()->SetPort(res);
2859 #if defined(TIZEN_TBM_SUPPORT)
2860 void EWebView::SetOffscreenRendering(bool enable) {
2862 host_->compositor()->SetUseTbmSuraceForOffscreenRendering(enable);
2866 void EWebView::InitializeWindowTreeHost() {
2867 CHECK(aura::Env::GetInstance());
2869 int x, y, width, height;
2871 ecore_evas_ecore_evas_get(evas_object_evas_get(efl_main_layout_));
2872 ecore_evas_geometry_get(ee, &x, &y, &width, &height);
2874 gfx::Rect bounds(x, y, width, height);
2875 ui::PlatformWindowInitProperties properties;
2876 properties.bounds = bounds;
2878 host_ = aura::WindowTreeHost::Create(std::move(properties));
2880 host_->window()->Show();
2883 std::make_unique<aura::test::TestFocusClient>(host_->window());
2884 window_parenting_client_ =
2885 std::make_unique<aura::test::TestWindowParentingClient>(host_->window());
2886 compositor_observer_ = std::make_unique<ui::CompositorObserverEfl>(
2887 host_->compositor(), web_contents_.get());
2889 aura::Window* content = web_contents_->GetNativeView();
2890 aura::Window* parent = host_->window();
2891 if (!parent->Contains(content)) {
2892 parent->AddChild(content);
2895 content->SetBounds(bounds);
2896 RenderWidgetHostView* host_view = web_contents_->GetRenderWidgetHostView();
2898 host_view->SetSize(bounds.size());
2901 void EWebView::UrlRequestSet(
2903 content::NavigationController::LoadURLType loadtype,
2907 content::NavigationController::LoadURLParams params(gurl);
2908 params.load_type = loadtype;
2909 params.override_user_agent = NavigationController::UA_OVERRIDE_TRUE;
2912 std::string s(body);
2914 network::ResourceRequestBody::CreateFromBytes(s.data(), s.size());
2917 net::HttpRequestHeaders header;
2919 Eina_Iterator* it = eina_hash_iterator_tuple_new(headers);
2921 while (eina_iterator_next(it, reinterpret_cast<void**>(&t))) {
2923 const char* value_str =
2924 t->data ? static_cast<const char*>(t->data) : "";
2925 base::StringPiece name = static_cast<const char*>(t->key);
2926 base::StringPiece value = value_str;
2927 header.SetHeader(name, value);
2928 // net::HttpRequestHeaders.ToString() returns string with newline
2929 params.extra_headers += header.ToString();
2932 eina_iterator_free(it);
2935 web_contents_->GetController().LoadURLWithParams(params);
2938 #if defined(TIZEN_VIDEO_HOLE)
2939 void EWebView::EnableVideoHoleSupport() {
2940 if (!web_contents_->GetPrimaryMainFrame() ||
2941 !web_contents_->GetPrimaryMainFrame()->IsRenderFrameLive() || !rwhva()) {
2942 pending_video_hole_setting_ = true;
2946 EnableVideoHoleSupportInternal();
2949 void EWebView::EnableVideoHoleSupportInternal() {
2950 if (settings_->getPreferences().video_hole_enabled)
2953 settings_->getPreferences().video_hole_enabled = true;
2954 WebContentsImpl* wc = static_cast<WebContentsImpl*>(web_contents_.get());
2956 wc->EnableVideoHole();
2960 bool EWebView::HandleShow() {
2961 if (!efl_main_layout_)
2968 bool EWebView::HandleHide() {
2969 if (!efl_main_layout_)
2976 bool EWebView::HandleMove(int x, int y) {
2977 if (!efl_main_layout_)
2979 evas_object_move(efl_main_layout_, x, y);
2980 LOG(INFO) << "Move x " << x << " y " << y;
2981 #if defined(TIZEN_VIDEO_HOLE)
2983 rwhva()->DidMoveWebView();
2987 context_menu_->Move(x, y);
2992 bool EWebView::HandleResize(int width, int height) {
2993 if (!efl_main_layout_)
2995 evas_object_resize(efl_main_layout_, width, height);
2997 #if defined(TIZEN_VIDEO_HOLE)
2998 LOG(INFO) << __func__ << " new size " << width << "*" << height;
3000 rwhva()->DidMoveWebView();
3003 if (select_picker_) {
3004 AdjustViewPortHeightToPopupMenu(true /* is_popup_menu_visible */);
3005 ScrollFocusedNodeIntoView();
3008 #if defined(USE_AURA) && BUILDFLAG(IS_TIZEN_TV)
3011 evas_object_geometry_get(efl_main_layout_, &x, &y, nullptr, nullptr);
3012 gfx::Rect bounds(x, y, width, height);
3013 host_->SetBoundsInPixels(bounds);
3020 bool EWebView::HandleTextSelectionDown(int x, int y) {
3021 if (!GetSelectionController())
3023 return GetSelectionController()->TextSelectionDown(x, y);
3026 bool EWebView::HandleTextSelectionUp(int x, int y) {
3027 if (!GetSelectionController())
3029 return GetSelectionController()->TextSelectionUp(x, y);
3032 void EWebView::HandleTapGestureForSelection(bool is_content_editable) {
3033 if (!GetSelectionController())
3036 GetSelectionController()->PostHandleTapGesture(is_content_editable);
3039 void EWebView::HandleZoomGesture(blink::WebGestureEvent& event) {
3040 blink::WebInputEvent::Type event_type = event.GetType();
3041 if (event_type == blink::WebInputEvent::Type::kGestureDoubleTap ||
3042 event_type == blink::WebInputEvent::Type::kGesturePinchBegin) {
3043 SmartCallback<EWebViewCallbacks::ZoomStarted>().call();
3045 if (event_type == blink::WebInputEvent::Type::kGestureDoubleTap ||
3046 event_type == blink::WebInputEvent::Type::kGesturePinchEnd) {
3047 SmartCallback<EWebViewCallbacks::ZoomFinished>().call();
3051 bool EWebView::GetHorizontalPanningHold() const {
3054 return rwhva()->offscreen_helper()->GetHorizontalPanningHold();
3057 void EWebView::SetHorizontalPanningHold(bool hold) {
3059 rwhva()->offscreen_helper()->SetHorizontalPanningHold(hold);
3062 bool EWebView::GetVerticalPanningHold() const {
3065 return rwhva()->offscreen_helper()->GetVerticalPanningHold();
3068 void EWebView::SetVerticalPanningHold(bool hold) {
3070 rwhva()->offscreen_helper()->SetVerticalPanningHold(hold);
3073 void EWebView::SendDelayedMessages(RenderViewHost* render_view_host) {
3074 DCHECK(render_view_host);
3076 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
3077 content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
3078 base::BindOnce(&EWebView::SendDelayedMessages, base::Unretained(this),
3083 for (auto iter = delayed_messages_.begin(); iter != delayed_messages_.end();
3085 IPC::Message* message = *iter;
3086 message->set_routing_id(render_view_host->GetRoutingID());
3087 #if !defined(EWK_BRINGUP) // FIXME: m94 bringup
3088 render_view_host->Send(message);
3092 delayed_messages_.clear();
3095 void EWebView::ClosePage() {
3096 web_contents_->ClosePage();
3099 bool EWebView::SetMainFrameScrollbarVisible(bool visible) {
3100 if (web_contents_->GetPrimaryMainFrame()->IsRenderFrameLive() && rwhva())
3101 rwhva()->host()->SetMainFrameScrollbarVisible(visible);
3105 bool EWebView::GetMainFrameScrollbarVisible(
3106 Ewk_View_Main_Frame_Scrollbar_Visible_Get_Callback callback,
3111 MainFrameScrollbarVisibleGetCallback* callback_ptr =
3112 new MainFrameScrollbarVisibleGetCallback;
3113 callback_ptr->Set(callback, user_data);
3115 main_frame_scrollbar_visible_callback_map_.Add(callback_ptr);
3116 rwhva()->host()->RequestMainFrameScrollbarVisible(callback_id);
3120 void EWebView::InvokeMainFrameScrollbarVisibleCallback(int callback_id,
3122 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
3123 content::GetUIThreadTaskRunner({})->PostTask(
3125 base::BindOnce(&EWebView::InvokeMainFrameScrollbarVisibleCallback,
3126 base::Unretained(this), visible, callback_id));
3130 MainFrameScrollbarVisibleGetCallback* callback =
3131 main_frame_scrollbar_visible_callback_map_.Lookup(callback_id);
3135 main_frame_scrollbar_visible_callback_map_.Remove(callback_id);
3136 callback->Run(ewk_view(), visible);
3137 main_frame_scrollbar_visible_callback_map_.Remove(callback_id);
3140 void EWebView::OnOverscrolled(const gfx::Vector2dF& accumulated_overscroll,
3141 const gfx::Vector2dF& latest_overscroll_delta) {
3142 const gfx::Vector2dF old_overscroll =
3143 accumulated_overscroll - latest_overscroll_delta;
3145 if (latest_overscroll_delta.x() && !old_overscroll.x()) {
3146 latest_overscroll_delta.x() < 0
3147 ? SmartCallback<EWebViewCallbacks::OverscrolledLeft>().call()
3148 : SmartCallback<EWebViewCallbacks::OverscrolledRight>().call();
3150 if (latest_overscroll_delta.y() && !old_overscroll.y()) {
3151 latest_overscroll_delta.y() < 0
3152 ? SmartCallback<EWebViewCallbacks::OverscrolledTop>().call()
3153 : SmartCallback<EWebViewCallbacks::OverscrolledBottom>().call();
3157 void EWebView::SetDidChangeThemeColorCallback(
3158 Ewk_View_Did_Change_Theme_Color_Callback callback,
3160 did_change_theme_color_callback_.Set(callback, user_data);
3163 void EWebView::DidChangeThemeColor(const SkColor& color) {
3164 did_change_theme_color_callback_.Run(ewk_view_, color);
3167 #if BUILDFLAG(IS_TIZEN_TV)
3168 void EWebView::DrawLabel(Evas_Object* image, Eina_Rectangle rect) {
3170 rwhva()->offscreen_helper()->DrawLabel(image, rect);
3173 void EWebView::DeactivateAtk(bool deactivated) {
3174 #if defined(TIZEN_ATK_SUPPORT)
3175 EWebAccessibilityUtil::GetInstance()->Deactivate(deactivated);
3179 void EWebView::ClearLabels() {
3181 rwhva()->offscreen_helper()->ClearLabels();
3184 void EWebView::SetTranslatedURL(const char* url) {
3185 if (!rwhva() || !rwhva()->aura_efl_helper())
3187 rwhva()->aura_efl_helper()->SetTranslatedURL(std::string(url));
3188 LOG(INFO) << "translate_url:" << url;
3191 bool EWebView::IsVideoPlaying(Ewk_Is_Video_Playing_Callback callback,
3193 IsVideoPlayingCallback* cb = new IsVideoPlayingCallback(callback, user_data);
3194 int callback_id = is_video_playing_callback_map_.Add(cb);
3196 if (!rwhva() || !rwhva()->aura_efl_helper()) {
3197 LOG(ERROR) << "rwhva() or rwhva()->aura_efl_helper() is false";
3200 rwhva()->aura_efl_helper()->RequestVideoPlaying(callback_id);
3204 void EWebView::InvokeIsVideoPlayingCallback(bool is_playing, int callback_id) {
3205 IsVideoPlayingCallback* callback =
3206 is_video_playing_callback_map_.Lookup(callback_id);
3208 LOG(INFO) << "callback is null";
3212 LOG(INFO) << __func__ << " ; is_playing : " << is_playing;
3213 callback->Run(ewk_view(), is_playing);
3214 is_video_playing_callback_map_.Remove(callback_id);
3218 void EWebView::RequestManifest(Ewk_View_Request_Manifest_Callback callback,
3220 web_contents_delegate_->RequestManifestInfo(callback, user_data);
3223 void EWebView::DidRespondRequestManifest(
3224 _Ewk_View_Request_Manifest* manifest,
3225 Ewk_View_Request_Manifest_Callback callback,
3227 callback(ewk_view_, manifest, user_data);
3230 void EWebView::SetSessionTimeout(uint64_t timeout) {
3231 if (web_contents_->GetPrimaryMainFrame()->IsRenderFrameLive() && rwhva())
3232 rwhva()->host()->SetLongPollingGlobalTimeout(timeout);
3235 void EWebView::SetBeforeUnloadConfirmPanelCallback(
3236 Ewk_View_Before_Unload_Confirm_Panel_Callback callback,
3238 GetJavaScriptDialogManagerEfl()->SetBeforeUnloadConfirmPanelCallback(
3239 callback, user_data);
3242 void EWebView::ReplyBeforeUnloadConfirmPanel(Eina_Bool result) {
3243 GetJavaScriptDialogManagerEfl()->ReplyBeforeUnloadConfirmPanel(result);
3246 #if defined(TIZEN_PEPPER_EXTENSIONS)
3247 void EWebView::InitializePepperExtensionSystem() {
3248 RegisterPepperExtensionDelegate();
3252 EwkExtensionSystemDelegate* EWebView::GetExtensionDelegate() {
3253 RenderFrameHost* render_frame_host = web_contents_->GetPrimaryMainFrame();
3254 if (!render_frame_host)
3257 return static_cast<EwkExtensionSystemDelegate*>(
3258 ExtensionSystemDelegateManager::GetInstance()->GetDelegateForFrame(render_frame_id_));
3261 void EWebView::SetWindowId() {
3262 EwkExtensionSystemDelegate* delegate = GetExtensionDelegate();
3264 LOG(WARNING) << "No delegate is available to set window id";
3267 Evas_Object* main_wind =
3268 efl::WindowFactory::GetHostWindow(web_contents_.get());
3270 LOG(ERROR) << "Can`t get main window";
3273 delegate->SetWindowId(main_wind);
3276 void EWebView::SetPepperExtensionWidgetInfo(Ewk_Value widget_pepper_ext_info) {
3277 EwkExtensionSystemDelegate* delegate = GetExtensionDelegate();
3279 LOG(WARNING) << "No delegate is available to set extension info";
3282 delegate->SetExtensionInfo(widget_pepper_ext_info);
3285 void EWebView::SetPepperExtensionCallback(Generic_Sync_Call_Callback cb,
3287 EwkExtensionSystemDelegate* delegate = GetExtensionDelegate();
3289 LOG(WARNING) << "No delegate is available to set generic callback";
3292 delegate->SetGenericSyncCallback(cb, data);
3295 void EWebView::RegisterPepperExtensionDelegate() {
3296 RenderFrameHost* render_frame_host = web_contents_->GetPrimaryMainFrame();
3297 if (!render_frame_host) {
3298 LOG(WARNING) << "render_frame_host is nullptr, can't register delegate";
3302 render_frame_id_.render_process_id = render_frame_host->GetProcess()->GetID();
3303 render_frame_id_.render_frame_id = render_frame_host->GetRoutingID();
3305 EwkExtensionSystemDelegate* delegate = new EwkExtensionSystemDelegate;
3306 ExtensionSystemDelegateManager::GetInstance()->RegisterDelegate(
3307 render_frame_id_, std::unique_ptr<EwkExtensionSystemDelegate>{delegate});
3310 void EWebView::UnregisterPepperExtensionDelegate() {
3311 if (!web_contents_) {
3312 LOG(WARNING) << "web_contents_ is nullptr, can't unregister delegate";
3315 if (!ExtensionSystemDelegateManager::GetInstance()->UnregisterDelegate(render_frame_id_))
3316 LOG(WARNING) << "Unregistering pepper extension delegate failed";
3318 #endif // defined(TIZEN_PEPPER_EXTENSIONS)
3320 void EWebView::SetExceededIndexedDatabaseQuotaCallback(
3321 Ewk_View_Exceeded_Indexed_Database_Quota_Callback callback,
3323 exceeded_indexed_db_quota_callback_.Set(callback, user_data);
3324 content::BrowserContextEfl* browser_context =
3325 static_cast<content::BrowserContextEfl*>(
3326 web_contents_->GetBrowserContext());
3327 if (browser_context) {
3328 browser_context->GetSpecialStoragePolicyEfl()->SetQuotaExceededCallback(
3329 base::BindOnce(&EWebView::InvokeExceededIndexedDatabaseQuotaCallback,
3330 base::Unretained(this)));
3334 void EWebView::InvokeExceededIndexedDatabaseQuotaCallback(
3336 int64_t current_quota) {
3337 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
3338 content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
3339 base::BindOnce(&EWebView::InvokeExceededIndexedDatabaseQuotaCallback,
3340 base::Unretained(this), origin, current_quota));
3343 LOG(INFO) << __func__ << "()" << origin << ", " << current_quota;
3344 CHECK(!exceeded_indexed_db_quota_origin_.get());
3345 exceeded_indexed_db_quota_origin_.reset(new Ewk_Security_Origin(origin));
3346 exceeded_indexed_db_quota_callback_.Run(
3347 ewk_view_, exceeded_indexed_db_quota_origin_.get(), current_quota);
3350 void EWebView::ExceededIndexedDatabaseQuotaReply(bool allow) {
3351 if (!exceeded_indexed_db_quota_origin_.get()) {
3352 LOG(WARNING) << __func__ << "() : callback is not invoked!";
3355 LOG(INFO) << __func__ << "()" << exceeded_indexed_db_quota_origin_->GetURL()
3357 content::BrowserContextEfl* browser_context =
3358 static_cast<content::BrowserContextEfl*>(
3359 web_contents_->GetBrowserContext());
3360 if (browser_context) {
3361 browser_context->GetSpecialStoragePolicyEfl()->SetUnlimitedStoragePolicy(
3362 exceeded_indexed_db_quota_origin_->GetURL(), allow);
3364 exceeded_indexed_db_quota_origin_.reset();
3367 bool EWebView::ShouldIgnoreNavigation(
3368 content::NavigationHandle* navigation_handle) {
3369 if (!navigation_handle->GetURL().is_valid() ||
3370 !navigation_handle->GetURL().SchemeIs("appcontrol") ||
3371 (!navigation_handle->HasUserGesture() &&
3372 !navigation_handle->WasServerRedirect())) {
3376 _Ewk_App_Control app_control(
3377 this, navigation_handle->GetURL().possibly_invalid_spec());
3378 return app_control.Proceed();
3381 #if BUILDFLAG(IS_TIZEN_TV)
3382 void EWebView::AddDynamicCertificatePath(const std::string& host,
3383 const std::string& cert_path) {
3384 web_contents_->AddDynamicCertificatePath(host, cert_path);
3387 void EWebView::NotifyParentalRatingInfo(const char* info, const char* url) {
3388 LOG(INFO) << "info:" << info << ",url:" << url;
3389 Ewk_Media_Parental_Rating_Info* data =
3390 ewkMediaParentalRatingInfoCreate(info, url);
3391 SmartCallback<EWebViewCallbacks::ParentalRatingInfo>().call(
3392 static_cast<void*>(data));
3393 ewkMediaParentalRatingInfoDelete(data);
3396 void EWebView::SetParentalRatingResult(const char* url, bool is_pass) {
3397 LOG(INFO) << "SetParentalRatingResult,url:" << url
3398 << ",pass:" << std::boolalpha << is_pass;
3400 if (!rwhva() || !rwhva()->aura_efl_helper()){
3401 LOG(ERROR) << "rwhva() or rwhva()->aura_efl_helper() is false";
3404 rwhva()->aura_efl_helper()->SetParentalRatingResult(
3405 static_cast<std::string>(url), is_pass);
3409 bool EWebView::SetVisibility(bool enable) {
3414 web_contents_->WasShown();
3416 web_contents_->WasHidden();
3421 void EWebView::SetDoNotTrack(Eina_Bool enable) {
3422 // enable: 0 User tend to allow tracking on the target site.
3423 // enable: 1 User tend to not be tracked on the target site.
3424 if (web_contents_->GetMutableRendererPrefs()->enable_do_not_track == enable)
3427 // Set navigator.doNotTrack attribute
3428 web_contents_->GetMutableRendererPrefs()->enable_do_not_track = enable;
3429 web_contents_->SyncRendererPrefs();
3431 // Set or remove DNT HTTP header, the effects will depend on design of target
3437 context()->HTTPCustomHeaderAdd("DNT", "1");
3439 context()->HTTPCustomHeaderRemove("DNT");
3442 #if defined(TIZEN_ATK_SUPPORT)
3443 void EWebView::UpdateSpatialNavigationStatus(Eina_Bool enable) {
3444 if (settings_->getPreferences().spatial_navigation_enabled == enable)
3447 settings_->getPreferences().spatial_navigation_enabled = enable;
3448 WebContentsImpl* wc = static_cast<WebContentsImpl*>(web_contents_.get());
3450 wc->SetSpatialNavigationEnabled(enable);
3453 void EWebView::UpdateAccessibilityStatus(Eina_Bool enable) {
3454 if (settings_->getPreferences().atk_enabled == enable)
3457 settings_->getPreferences().atk_enabled = enable;
3458 WebContentsImpl* wc = static_cast<WebContentsImpl*>(web_contents_.get());
3460 wc->SetAtkEnabled(enable);
3463 void EWebView::InitAtk() {
3464 #if defined(TIZEN_ATK_SUPPORT)
3465 EWebAccessibilityUtil::GetInstance()->ToggleAtk(lazy_initialize_atk_);
3469 /* LCOV_EXCL_START */
3470 bool EWebView::GetAtkStatus() {
3471 auto state = content::BrowserAccessibilityStateImpl::GetInstance();
3474 return state->IsAccessibleBrowser();
3476 /* LCOV_EXCL_STOP */
3479 #if BUILDFLAG(IS_TIZEN_TV)
3480 bool EWebView::SetMixedContents(bool allow) {
3481 MixedContentObserver* mixed_content_observer =
3482 MixedContentObserver::FromWebContents(web_contents_.get());
3483 return mixed_content_observer->MixedContentReply(allow);
3486 void EWebView::NotifyDownloadableFontInfo(const char* scheme_id_uri,
3490 LOG(INFO) << "scheme_id_uri:" << scheme_id_uri << ",value:" << value
3491 << ",data:" << data << ",type:" << type;
3492 Ewk_Media_Downloadable_Font_Info* info =
3493 ewkMediaDownloadableFontInfoCreate(scheme_id_uri, value, data, type);
3494 SmartCallback<EWebViewCallbacks::DownloadableFontInfo>().call(
3495 static_cast<void*>(info));
3496 ewkMediaDownloadableFontInfoDelete(info);
3499 std::vector<std::string> EWebView::NotifyPlaybackState(int state,
3502 const char* mime_type) {
3503 std::vector<std::string> data;
3504 Ewk_Media_Playback_Info* playback_info =
3505 ewkMediaPlaybackInfoCreate(player_id, url, mime_type);
3508 << "player_id:" << player_id << ",state: " << state
3509 << "(0-load : 1-videoready : 2-ready : 3-start : 4-finish : 5-stop)";
3512 SmartCallback<EWebViewCallbacks::PlaybackLoad>().call(
3513 static_cast<void*>(playback_info));
3515 case kPlaybackReady:
3516 SmartCallback<EWebViewCallbacks::PlaybackReady>().call(
3517 static_cast<void*>(playback_info));
3519 case kPlaybackStart:
3520 SmartCallback<EWebViewCallbacks::PlaybackStart>().call(
3521 static_cast<void*>(playback_info));
3523 case kPlaybackFinish:
3524 SmartCallback<EWebViewCallbacks::PlaybackFinish>().call(
3525 static_cast<void*>(playback_info));
3528 SmartCallback<EWebViewCallbacks::PlaybackStop>().call(
3529 static_cast<void*>(playback_info));
3534 ewkMediaPlaybackInfoDelete(playback_info);
3538 bool media_resource_acquired =
3539 ewk_media_playback_info_media_resource_acquired_get(playback_info)
3542 data.push_back(media_resource_acquired ? "mediaResourceAcquired" : "");
3543 const char* translated_url =
3544 ewk_media_playback_info_translated_url_get(playback_info);
3545 data.push_back(translated_url ? std::string(translated_url) : "");
3546 const char* drm_info = ewk_media_playback_info_drm_info_get(playback_info);
3547 data.push_back(drm_info ? std::string(drm_info) : "");
3549 LOG(INFO) << "evasObject: " << ewk_view_
3550 << ", media_resource_acquired :" << media_resource_acquired
3551 << ", translated_url:" << translated_url
3552 << ", drm_info:" << drm_info;
3553 ewkMediaPlaybackInfoDelete(playback_info);
3557 void EWebView::NotifyMediaStateChanged(uint32_t device_type,
3560 LOG(INFO) << "NotifyMediaStateChanged type : " << device_type
3561 << " ;previous: " << previous << " ; current: " << current;
3562 Ewk_User_Media_State_Info* user_media_state_info =
3563 new _Ewk_User_Media_State_Info;
3564 user_media_state_info->device_type =
3565 static_cast<Ewk_User_Media_Device_Type>(device_type);
3566 user_media_state_info->previous_state = previous;
3567 user_media_state_info->current_state = current;
3568 SmartCallback<EWebViewCallbacks::UserMediaState>().call(
3569 static_cast<void*>(user_media_state_info));
3571 delete user_media_state_info;
3574 void EWebView::SetHighBitRate(Eina_Bool high_bitrate) {
3575 LOG(INFO) << "high_bitrate: " << std::boolalpha << high_bitrate;
3576 is_high_bitrate_ = high_bitrate;
3579 void EWebView::OnDeviceListed(const MediaDeviceEnumeration& devices) {
3580 int device_count = 0;
3581 EwkMediaDeviceInfo* device_list = nullptr;
3582 for (const auto& device : devices)
3583 device_count += device.size();
3586 (EwkMediaDeviceInfo*)malloc(sizeof(EwkMediaDeviceInfo) * device_count);
3588 LOG(ERROR) << "malloc EwkMediaDeviceInfo failed";
3589 device_cb_.Run(device_list, 0);
3594 for (int i = 0; i < NUM_MEDIA_DEVICE_TYPES; i++) {
3595 blink::WebMediaDeviceInfoArray array = devices[i];
3596 for (const auto& device : array) {
3597 LOG(INFO) << "OnDeviceListed type:" << i
3598 << ",device_id:" << device.device_id
3599 << ",lable:" << device.label;
3601 // convert device info to ewk structure
3602 EwkMediaDeviceInfo* data = &device_list[idx++];
3603 data->device_id = eina_stringshare_add(device.device_id.c_str());
3604 data->label = eina_stringshare_add(device.label.c_str());
3605 data->type = static_cast<EwkMediaDeviceType>(i);
3606 data->connected = true;
3610 device_cb_.Run(device_list, device_count);
3613 for (int i = 0; i < device_count; i++) {
3614 EwkMediaDeviceInfo* device = &device_list[i];
3615 if (device->device_id)
3616 eina_stringshare_del(device->device_id);
3618 eina_stringshare_del(device->label);
3626 void EWebView::GetMediaDeviceList(Ewk_Media_Device_List_Get_Callback callback,
3628 if (!web_contents_delegate_) {
3629 LOG(ERROR) << "no web_contents_delegate_";
3633 device_cb_.Set(callback, userData);
3635 web_contents_delegate_->GetMediaDeviceList(
3636 base::BindOnce(&EWebView::OnDeviceListed, weak_factory_.GetWeakPtr()));