#include <Eina.h>
#include <Elementary.h>
-#include "base/bind.h"
#include "base/command_line.h"
-#include "base/files/file_path.h"
#include "base/files/file_util.h"
+#include "base/functional/bind.h"
#include "base/json/json_string_value_serializer.h"
#include "base/logging.h"
#include "base/pickle.h"
#include "base/strings/escape.h"
#include "base/strings/utf_string_conversions.h"
-#include "base/task/task_runner_util.h"
+#include "base/task/thread_pool.h"
#include "browser/javascript_dialog_manager_efl.h"
#include "browser/javascript_interface/gin_native_bridge_dispatcher_host.h"
#include "browser/navigation_policy_handler_efl.h"
-#include "browser/quota_permission_context_efl.h"
-#include "browser/selectpicker/popup_menu_item.h"
-#include "browser/selectpicker/popup_menu_item_private.h"
+#include "browser/scoped_allow_wait_for_legacy_web_view_api.h"
+#include "browser/select_picker/select_picker_mobile.h"
+#include "browser/select_picker/select_picker_tv.h"
#include "browser/web_view_browser_message_filter.h"
-#include "browser/web_view_evas_handler.h"
#include "browser_context_efl.h"
#include "common/content_client_efl.h"
#include "common/render_messages_ewk.h"
#include "ui/aura/window.h"
#include "ui/base/clipboard/clipboard_helper_efl.h"
#include "ui/base/l10n/l10n_util.h"
+#include "ui/compositor/compositor_observer_efl.h"
#include "ui/display/screen.h"
#include "ui/events/event_switches.h"
#include "ui/gfx/geometry/dip_util.h"
#include "ui/ozone/platform/efl/efl_event_handler.h"
#include "ui/platform_window/platform_window_init_properties.h"
#include "web_contents_delegate_efl.h"
-#include "web_contents_efl_delegate_ewk.h"
+#include "webview_delegate_efl.h"
#include <iostream>
#include "eweb_accessibility_util.h"
#endif
+#if defined(TIZEN_AUTOFILL_FW)
+#include "browser/autofill/autofill_request_manager.h"
+#include "components/autofill/core/common/autofill_switches.h"
+#endif
+
+#if BUILDFLAG(IS_TIZEN_TV)
+#include "browser/mixed_content_observer.h"
+#include "common/application_type.h"
+#include "devtools_port_manager.h"
+#include "private/ewk_file_chooser_request_private.h"
+#include "public/ewk_media_downloadable_font_info.h"
+#include "public/ewk_media_parental_rating_info.h"
+#include "public/ewk_media_playback_info_product.h"
+#include "public/ewk_media_subtitle_info_product.h"
+#include "public/ewk_user_media_internal.h"
+#include "third_party/blink/public/platform/web_media_player.h"
+#endif
+
+#if defined(TIZEN_PEPPER_EXTENSIONS)
+#include "efl/window_factory.h"
+#include "ewk/efl_integration/ewk_privilege_checker.h"
+#endif // defined(TIZEN_PEPPER_EXTENSIONS)
+
+#if defined(USE_WAYLAND) && defined(TIZEN_PEPPER_EXTENSIONS)
+#include <Ecore_Wayland.h>
+#endif // defined(USE_WAYLAND)
+
+#if defined(TIZEN_TBM_SUPPORT)
+#include "ui/compositor/compositor.h"
+#endif
+
using namespace content;
using web_contents_utils::WebViewFromWebContents;
static const char* kRendererCrashedHTMLMessage =
"<html><body><h1>Renderer process has crashed!</h1></body></html>";
+// "visible,content,changed" is an email-app specific signal which informs
+// that the web view is only partially visible.
+static const char* kVisibleContentChangedSignalName = "visible,content,changed";
+
+// email-app specific signal which informs that custom scrolling is started.
+const char* kCustomScrollBeginSignalName = "custom,scroll,begin";
+
+// email-app specific signal which informs that custom scrolling is finished.
+const char* kCustomScrollEndSignalName = "custom,scroll,end";
+
+const float kDelayShowContextMenuTime = 0.2f;
+
inline void SetDefaultStringIfNull(const char*& variable,
const char* default_string) {
if (!variable) {
eina_rect->h = gfx_rect.height();
}
+#if BUILDFLAG(IS_TIZEN)
+static Eina_Bool RotateWindowCb(void* data, int type, void* event) {
+ auto wv = static_cast<EWebView*>(data);
+#if defined(TIZEN_TBM_SUPPORT)
+ if (wv->rwhva() && wv->rwhva()->GetCompositor() &&
+ wv->rwhva()->GetCompositor()->use_tbm_surface_for_offscreen_rendering()) {
+ Ecore_Wl2_Event_Window_Rotation* rotateEvent =
+ static_cast<Ecore_Wl2_Event_Window_Rotation*>(event);
+ if (rotateEvent != nullptr) {
+ LOG(INFO) << "For NUI app, new ori " << rotateEvent->angle;
+ wv->SetOrientation(rotateEvent->angle);
+ }
+ return ECORE_CALLBACK_PASS_ON;
+ }
+#endif
+ LOG(INFO) << "New ori "
+ << ecore_evas_rotation_get(
+ ecore_evas_ecore_evas_get(wv->GetEvas()));
+ wv->SetOrientation(
+ ecore_evas_rotation_get(ecore_evas_ecore_evas_get(wv->GetEvas())));
+ return ECORE_CALLBACK_PASS_ON;
+}
+#endif
+
static content::WebContents* NullCreateWebContents(void*) {
return NULL;
}
return base::FilePath();
}
+SelectPickerBase* CreateSelectPicker(
+ EWebView* web_view,
+ int selected_index,
+ std::vector<blink::mojom::MenuItemPtr> items,
+ bool is_multiple_selection,
+ const gfx::Rect& bounds) {
+ SelectPickerBase* picker;
+ if (IsTvProfile()) {
+ picker =
+ new SelectPickerTv(web_view, selected_index, is_multiple_selection);
+ } else {
+ picker =
+ new SelectPickerMobile(web_view, selected_index, is_multiple_selection);
+ }
+ // Create two separate Elm_Genlist_Item_Class classes, because EFL cannot swap
+ // item_style at runtime.
+ picker->InitializeItemClass();
+ picker->InitializeGroupClass();
+ picker->Init(std::move(items), bounds);
+ return picker;
+}
+
} // namespace
class WebViewAsyncRequestHitTestDataCallback {
void Run(_Ewk_Hit_Test* hit_test, EWebView* web_view) override {
DCHECK(callback_);
- callback_(web_view->evas_object(), GetX(), GetY(), GetMode(), hit_test,
+ callback_(web_view->ewk_view(), GetX(), GetY(), GetMode(), hit_test,
user_data_);
}
#endif
int EWebView::find_request_id_counter_ = 0;
-content::WebContentsEflDelegate::WebContentsCreateCallback
+content::WebViewDelegate::WebContentsCreateCallback
EWebView::create_new_window_web_contents_cb_ =
base::BindRepeating(&NullCreateWebContents);
-EWebView* EWebView::FromEvasObject(Evas_Object* eo) {
- return WebViewDelegateEwk::GetInstance().GetWebViewFromEvasObject(eo);
+EWebView* EWebView::FromEwkView(Evas_Object* ewk_view) {
+ return WebViewDelegateEwk::GetInstance().GetEWebViewFromEwkView(ewk_view);
}
-void EWebView::OnViewFocusIn(void* data, Evas*, Evas_Object*, void*) {
- auto view = static_cast<EWebView*>(data);
- view->SetFocus(EINA_TRUE);
+void EWebView::VisibleContentChangedCallback(void* user_data,
+ Evas_Object* /*object*/,
+ void* event_info) {
+ auto view = static_cast<EWebView*>(user_data);
+ if (!view->GetSelectionController()) {
+ return;
+ }
+ auto rect = static_cast<Eina_Rectangle*>(event_info);
+ view->GetSelectionController()->SetCustomVisibleViewRect(
+ gfx::Rect(rect->x, rect->y, rect->w, rect->h));
+}
+
+void EWebView::OnCustomScrollBeginCallback(void* user_data,
+ Evas_Object* /*object*/,
+ void* /*event_info*/) {
+ auto* view = static_cast<EWebView*>(user_data);
+ if (auto* selection_controller = view->GetSelectionController())
+ selection_controller->SetControlsTemporarilyHidden(true,true);
}
-void EWebView::OnViewFocusOut(void* data, Evas*, Evas_Object*, void*) {
- auto view = static_cast<EWebView*>(data);
- view->SetFocus(EINA_FALSE);
+void EWebView::OnCustomScrollEndCallback(void* user_data,
+ Evas_Object* /*object*/,
+ void* /*event_info*/) {
+ auto* view = static_cast<EWebView*>(user_data);
+ if (auto* selection_controller = view->GetSelectionController())
+ selection_controller->SetControlsTemporarilyHidden(false,true);
}
-EWebView::EWebView(Ewk_Context* context, Evas_Object* object)
+EWebView::EWebView(Ewk_Context* context, Evas_Object* ewk_view)
: context_(context),
- evas_object_(object),
- native_view_(object),
+ ewk_view_(ewk_view),
+ efl_main_layout_(ewk_view),
mouse_events_enabled_(false),
text_zoom_factor_(1.0),
- formIsNavigating_(false),
current_find_request_id_(find_request_id_counter_++),
progress_(0.0),
hit_test_completion_(base::WaitableEvent::ResetPolicy::AUTOMATIC,
page_scale_factor_(1.0),
x_delta_(0.0),
y_delta_(0.0),
+#if BUILDFLAG(IS_TIZEN_TV)
+ is_processing_edge_scroll_(false),
+ use_early_rwi_(false),
+ rwi_info_showed_(false),
+#endif
+#if defined(TIZEN_PEPPER_EXTENSIONS)
+ render_frame_id_{0, 0},
+#endif
is_initialized_(false) {
- if (evas_object_) {
- evas_object_event_callback_add(evas_object_, EVAS_CALLBACK_FOCUS_IN,
- OnViewFocusIn, this);
- evas_object_event_callback_add(evas_object_, EVAS_CALLBACK_FOCUS_OUT,
- OnViewFocusOut, this);
+ LOG(INFO) << "EWebView: " << this;
+ if (ewk_view_) {
+ evas_object_smart_callback_add(ewk_view_, kVisibleContentChangedSignalName,
+ VisibleContentChangedCallback, this);
+
+ evas_object_smart_callback_add(ewk_view_, kCustomScrollBeginSignalName,
+ OnCustomScrollBeginCallback, this);
+ evas_object_smart_callback_add(ewk_view_, kCustomScrollEndSignalName,
+ OnCustomScrollEndCallback, this);
+#if BUILDFLAG(IS_TIZEN)
+ window_rotate_handler_ = ecore_event_handler_add(
+ ECORE_WL2_EVENT_WINDOW_ROTATE, RotateWindowCb, this);
+#endif
}
}
InitializeContent();
- evas_event_handler_ = new WebViewEvasEventHandler(this);
-
scroll_detector_.reset(new ScrollDetector(this));
+#if defined(TIZEN_PEPPER_EXTENSIONS)
+ InitializePepperExtensionSystem();
+#endif
DCHECK(web_contents_->GetRenderViewHost());
// Settings (content::WebPreferences) will be initalized by
// RenderViewHostImpl::ComputeWebkitPrefs() based on command line switches.
- settings_.reset(new Ewk_Settings(evas_object_,
- web_contents_->GetOrCreateWebPreferences()));
+ settings_.reset(
+ new Ewk_Settings(ewk_view_, web_contents_->GetOrCreateWebPreferences()));
#if defined(TIZEN_ATK_SUPPORT)
std::unique_ptr<EWebAccessibilityObserver> observer(
new EWebAccessibilityObserver(this));
eweb_accessibility_.reset(new EWebAccessibility(
- evas_object_, web_contents_.get(), std::move(observer)));
+ ewk_view_, web_contents_.get(), std::move(observer)));
lazy_initialize_atk_ = true;
#endif
blink::UserAgentOverride::UserAgentOnly(user_agent),
false /* override_in_new_tabs */);
- popupMenuItems_ = 0;
- popupPicker_ = 0;
-
- formNavigation_.count = 1;
- formNavigation_.position = 0;
- formNavigation_.prevState = false;
- formNavigation_.nextState = false;
-
- // allow this object and its children to get a focus
- elm_object_tree_focus_allow_set(native_view_, EINA_TRUE);
+ elm_object_tree_focus_allow_set(efl_main_layout_, EINA_TRUE);
is_initialized_ = true;
+ evas_object_event_callback_add(efl_main_layout_, EVAS_CALLBACK_RESIZE,
+ EWebView::NativeViewResize, this);
auto cbce = static_cast<ContentBrowserClientEfl*>(
content::GetContentClientExport()->browser());
// Initialize accept languages
SyncAcceptLanguages(cbce->GetAcceptLangs(nullptr));
- accept_langs_changed_callback_ =
- base::BindOnce(&EWebView::SyncAcceptLanguages, base::Unretained(this));
- cbce->AddAcceptLangsChangedCallback(
- std::move(accept_langs_changed_callback_));
+ accept_langs_changed_callback_ = base::BindRepeating(
+ &EWebView::SyncAcceptLanguages, base::Unretained(this));
+ cbce->AddAcceptLangsChangedCallback(accept_langs_changed_callback_);
// If EWebView is created by window.open, RenderView is already created
// before initializing WebContents. So we should manually invoke
}
EWebView::~EWebView() {
+ LOG(INFO) << "EWebView: " << this;
+ weak_factory_.InvalidateWeakPtrs();
auto cbce = static_cast<ContentBrowserClientEfl*>(
content::GetContentClientExport()->browser());
-#if !defined(EWK_BRINGUP) // FIXME: m94 bringup
- cbce->RemoveAcceptLangsChangedCallback(
- std::move(accept_langs_changed_callback_));
+ cbce->RemoveAcceptLangsChangedCallback(accept_langs_changed_callback_);
+#if defined(TIZEN_PEPPER_EXTENSIONS)
+ UnregisterPepperExtensionDelegate();
#endif
-#if defined(USE_WAYLAND) && !BUILDFLAG(IS_TIZEN_TV)
- ClipboardHelperEfl::GetInstance()->MaybeInvalidateActiveWebview(this);
+ evas_object_event_callback_del(efl_main_layout_, EVAS_CALLBACK_RESIZE,
+ EWebView::NativeViewResize);
+#if defined(USE_WAYLAND)
+ if (GetSettings()->getClipboardEnabled())
+ ClipboardHelperEfl::GetInstance()->MaybeInvalidateActiveWebview(this);
#endif
std::map<int64_t, WebViewAsyncRequestHitTestDataCallback*>::iterator
eweb_accessibility_.reset();
#endif
+#if defined(TIZEN_AUTOFILL_FW)
+ if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
+ autofill::switches::kDisableAutofill)) {
+ autofill::AutofillRequestManager::GetInstance()->RemoveRequest(ewk_view());
+ }
+#endif
+
+ select_picker_.reset();
context_menu_.reset();
mhtml_callback_map_.Clear();
+#if BUILDFLAG(IS_TIZEN_TV)
+ is_video_playing_callback_map_.Clear();
+#endif
- ReleasePopupMenuList();
-
- if (popupPicker_)
- popup_picker_del(popupPicker_);
-
- formNavigation_.count = 1;
- formNavigation_.position = 0;
- formNavigation_.prevState = false;
- formNavigation_.nextState = false;
-
- // evas_object_del(evas_object());
+ compositor_observer_.reset();
// Release manually those scoped pointers to
// make sure they are released in correct order
gin_native_bridge_dispatcher_host_.reset();
- if (evas_object_) {
- evas_object_event_callback_del(evas_object_, EVAS_CALLBACK_FOCUS_IN,
- OnViewFocusIn);
- evas_object_event_callback_del(evas_object_, EVAS_CALLBACK_FOCUS_OUT,
- OnViewFocusOut);
- }
-}
-
-void EWebView::ReleasePopupMenuList() {
- if (!popupMenuItems_)
- return;
-
- void* dummyItem;
- EINA_LIST_FREE(popupMenuItems_, dummyItem) {
- delete static_cast<Popup_Menu_Item*>(dummyItem);
+ if (ewk_view_) {
+ evas_object_smart_callback_del(ewk_view_, kVisibleContentChangedSignalName,
+ VisibleContentChangedCallback);
+ evas_object_smart_callback_del(ewk_view_, kCustomScrollBeginSignalName,
+ OnCustomScrollBeginCallback);
+ evas_object_smart_callback_del(ewk_view_, kCustomScrollEndSignalName,
+ OnCustomScrollEndCallback);
+#if BUILDFLAG(IS_TIZEN)
+ if (window_rotate_handler_)
+ ecore_event_handler_del(window_rotate_handler_);
+#endif
}
-
- popupMenuItems_ = 0;
}
content::RenderWidgetHostViewAura* EWebView::rwhva() const {
return static_cast<WebContentsViewAura*>(wc->GetView());
}
+void EWebView::NativeViewResize(void* data,
+ Evas* e,
+ Evas_Object* obj,
+ void* event_info) {
+ auto thiz = static_cast<EWebView*>(data);
+ if (!thiz->context_menu_)
+ return;
+ int x, y, width, height;
+ evas_object_geometry_get(obj, &x, &y, &width, &height);
+ thiz->context_menu_->Resize(gfx::Rect(x, y, width, height));
+}
+
void EWebView::ResetContextMenuController() {
return context_menu_.reset();
}
+#if BUILDFLAG(IS_TIZEN_TV)
+void EWebView::RunPendingSetFocus(Eina_Bool focus) {
+ SetFocusInternal(focus);
+}
+
+void EWebView::SetFocusInternal(Eina_Bool focus) {
+ if (!rwhva() || !rwhva()->offscreen_helper() || (HasFocus() == focus))
+ return;
+ rwhva()->offscreen_helper()->Focus(focus);
+}
+#endif
+
void EWebView::SetFocus(Eina_Bool focus) {
- if (!web_contents_ || !rwhva() || (HasFocus() == focus))
+ if (!web_contents_)
return;
+#if BUILDFLAG(IS_TIZEN_TV)
+ if (web_contents_->GetPrimaryMainFrame()->IsRenderFrameLive()) {
+ SetFocusInternal(focus);
+
+ if (pending_setfocus_closure_)
+ pending_setfocus_closure_.Reset();
+ } else {
+ LOG(ERROR) << "SEND DELAY SET FOCUS BIND";
+ pending_setfocus_closure_ = base::BindOnce(&EWebView::RunPendingSetFocus,
+ base::Unretained(this), focus);
+ }
+#else
rwhva()->offscreen_helper()->Focus(focus);
+#endif
}
Eina_Bool EWebView::HasFocus() const {
- if (!rwhva())
+ if (!rwhva() || !rwhva()->offscreen_helper())
return EINA_FALSE;
return rwhva()->offscreen_helper()->HasFocus() ? EINA_TRUE : EINA_FALSE;
}
bool EWebView::CreateNewWindow(
- content::WebContentsEflDelegate::WebContentsCreateCallback cb) {
+ content::WebViewDelegate::WebContentsCreateCallback cb) {
+#if BUILDFLAG(IS_TIZEN_TV)
+ LOG(INFO) << __FUNCTION__;
+#endif
create_new_window_web_contents_cb_ = cb;
Evas_Object* new_object = NULL;
SmartCallback<EWebViewCallbacks::CreateNewWindow>().call(&new_object);
// static
Evas_Object* EWebView::GetHostWindowDelegate(const content::WebContents* wc) {
EWebView* thiz = WebViewFromWebContents(wc);
- DCHECK(thiz->evas_object_);
- Evas_Object* parent = evas_object_above_get(thiz->evas_object_);
+ DCHECK(thiz->ewk_view_);
+ Evas_Object* parent = evas_object_above_get(thiz->ewk_view_);
if (!parent) {
LOG(WARNING) << "Could not find and visual parents for EWK smart object!.";
- return thiz->evas_object_;
+ return thiz->ewk_view_;
}
if (elm_object_widget_check(parent)) {
}
LOG(WARNING) << "Could not find elementary parent for WebView object!";
- return thiz->evas_object_;
+ return thiz->ewk_view_;
}
Evas_Object* EWebView::GetElmWindow() const {
- Evas_Object* parent = elm_object_parent_widget_get(evas_object_);
+ Evas_Object* parent = elm_object_parent_widget_get(ewk_view_);
return parent ? elm_object_top_widget_get(parent) : nullptr;
}
ui::PAGE_TRANSITION_LINK | ui::PAGE_TRANSITION_FROM_API);
}
+#if BUILDFLAG(IS_TIZEN_TV)
+ if (use_early_rwi_) {
+ LOG(INFO) << "[FAST RWI] SetURL Replace [" << url.spec()
+ << "] to [about:blank]";
+ rwi_gurl_ = url;
+ params.url = GURL("about:blank");
+ }
+#endif
+
params.override_user_agent = NavigationController::UA_OVERRIDE_TRUE;
web_contents_->GetController().LoadURLWithParams(params);
}
if (!web_contents_->GetController().CanGoBack())
return EINA_FALSE;
+#if defined(TIZEN_AUTOFILL_FW)
+ if (web_contents_delegate_)
+ web_contents_delegate_->ResetLastInteractedElements();
+#endif
+
web_contents_->GetController().GoBack();
return EINA_TRUE;
}
}
void EWebView::Suspend() {
+#if BUILDFLAG(IS_TIZEN)
CHECK(web_contents_);
+ if (IsMobileProfile() && web_contents_->IsFullscreen())
+ web_contents_->ExitFullscreen(true);
RenderViewHost* rvh = web_contents_->GetRenderViewHost();
RenderFrameHost* rfh = web_contents_->GetPrimaryMainFrame();
CHECK(rvh);
CHECK(rfh);
-#if !defined(EWK_BRINGUP) // FIXME: m69 bringup
- rfh->BlockRequestsForFrame();
-#endif
-#if 0
- content::GetIOThreadTaskRunner({})->PostTask(FROM_HERE, base::BindOnce(
- &content::ResourceDispatcherHost::BlockRequestsForFrameFromUI, rfh));
-
- if (rvh)
- rvh->Send(new EwkViewMsg_SuspendScheduledTask(rvh->GetRoutingID()));
+ if (rvh->IsRenderViewLive()) {
+ RenderWidgetHostImpl* rwhi = static_cast<RenderWidgetHostImpl*>(rvh->GetWidget());
+ rwhi->PauseScheduledTasks();
+ }
#endif
}
void EWebView::Resume() {
+#if BUILDFLAG(IS_TIZEN)
CHECK(web_contents_);
RenderViewHost* rvh = web_contents_->GetRenderViewHost();
RenderFrameHost* rfh = web_contents_->GetPrimaryMainFrame();
CHECK(rvh);
CHECK(rfh);
-#if !defined(EWK_BRINGUP) // FIXME: m69 bringup
- rfh->ResumeBlockedRequestsForFrame();
+ if (rvh->IsRenderViewLive() && rwhva())
+ rwhva()->host()->UnPauseScheduledTasks();
#endif
-#if 0
- content::GetIOThreadTaskRunner({})->PostTask(FROM_HERE, base::BindOnce(
- &content::ResourceDispatcherHost::ResumeBlockedRequestsForFrameFromUI,
- rfh));
+}
- if (rvh)
- rvh->Send(new EwkViewMsg_ResumeScheduledTasks(rvh->GetRoutingID()));
-#endif
+#if BUILDFLAG(IS_TIZEN_TV)
+void EWebView::SetFloatVideoWindowState(bool enabled) {
+ RenderWidgetHostImpl* rwhi = static_cast<RenderWidgetHostImpl*>(
+ web_contents_->GetRenderViewHost()->GetWidget());
+
+ rwhi->SetFloatVideoWindowState(enabled);
+}
+
+void EWebView::SuspendNetworkLoading() {
+ RenderWidgetHostImpl* rwhi = static_cast<RenderWidgetHostImpl*>(
+ web_contents_->GetRenderViewHost()->GetWidget());
+
+ rwhi->SuspendNetworkLoading();
}
+void EWebView::ResumeNetworkLoading() {
+ RenderWidgetHostImpl* rwhi = static_cast<RenderWidgetHostImpl*>(
+ web_contents_->GetRenderViewHost()->GetWidget());
+
+ rwhi->ResumeNetworkLoading();
+}
+#endif // IS_TIZEN_TV
+
double EWebView::GetTextZoomFactor() const {
if (text_zoom_factor_ < 0.0)
return -1.0;
void EWebView::ExecuteEditCommand(const char* command, const char* value) {
EINA_SAFETY_ON_NULL_RETURN(command);
- value = (value == nullptr) ? "" : value;
-
- absl::optional<std::u16string> optional_value =
- absl::make_optional(base::ASCIIToUTF16(value));
+ absl::optional<std::u16string> optional_value;
+ if (value)
+ optional_value = absl::make_optional(base::ASCIIToUTF16(value));
WebContentsImpl* wc = static_cast<WebContentsImpl*>(web_contents_.get());
- if (wc) {
- wc->GetFocusedFrameWidgetInputHandler()->ExecuteEditCommand(
- std::string(command), optional_value);
+ if (!wc || !wc->GetFocusedFrameWidgetInputHandler())
+ return;
+
+ wc->GetFocusedFrameWidgetInputHandler()->ExecuteEditCommand(
+ std::string(command), optional_value);
+}
+
+#if BUILDFLAG(IS_TIZEN)
+void EWebView::EnterDragState() {
+ if (IsMobileProfile()) {
+ if (RenderViewHost* render_view_host = web_contents_->GetRenderViewHost())
+ web_contents_->EnterDragState(render_view_host);
}
}
+#endif
void EWebView::SetOrientation(int orientation) {
+ LOG(INFO) << "New ori " << orientation << " GetOrientation "
+ << GetOrientation();
if (GetOrientation() == orientation)
return;
+ SetRotationChanged(true);
if (orientation == 0 || orientation == 90 || orientation == 180 ||
orientation == 270) {
#if !defined(USE_AURA)
GetWebContentsViewEfl()->SetOrientation(orientation);
+#else
+#if BUILDFLAG(IS_TIZEN)
+ TRACE_EVENT2("viz", "EWebView::SetOrientation", "orientation", orientation,
+ "this", (void*)this);
+ wcva()->SetOrientation(orientation);
+#endif
#endif
int width = 0;
int height = 0;
const Ecore_Evas* ee =
- ecore_evas_ecore_evas_get(evas_object_evas_get(evas_object_));
+ ecore_evas_ecore_evas_get(evas_object_evas_get(ewk_view_));
ecore_evas_screen_geometry_get(ee, nullptr, nullptr, &width, &height);
if (orientation == 90 || orientation == 270)
std::swap(width, height);
- if (context_menu_)
- context_menu_->SetPopupSize(width, height);
if (popup_controller_)
popup_controller_->SetPopupSize(width, height);
if (JavaScriptDialogManagerEfl* dialogMG = GetJavaScriptDialogManagerEfl())
dialogMG->SetPopupSize(width, height);
- if (popupPicker_)
- popup_picker_resize(popupPicker_, width, height);
}
}
#if !defined(USE_AURA)
return GetWebContentsViewEfl()->GetOrientation();
#else
+#if BUILDFLAG(IS_TIZEN)
+ return wcva()->GetOrientation();
+#else
return 0;
#endif
+#endif
}
void EWebView::Show() {
- evas_object_show(native_view_);
+ evas_object_show(efl_main_layout_);
web_contents_->WasShown();
}
void EWebView::Hide() {
- evas_object_hide(native_view_);
+ LOG(INFO) << "EWebView: " << this;
+ evas_object_hide(efl_main_layout_);
+ if (!web_contents_)
+ return;
web_contents_->WasHidden();
}
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
auth_challenge_.reset(new _Ewk_Auth_Challenge(login_delegate, url, realm));
- authentication_cb_.Run(evas_object_, auth_challenge_.get());
+ authentication_cb_.Run(ewk_view_, auth_challenge_.get());
if (!auth_challenge_->is_decided && !auth_challenge_->is_suspended) {
auth_challenge_->is_decided = true;
const Evas_Modifier* modifiers) {
const Eina_List* l;
void* data;
+
+ if (GetSettings()->touchFocusEnabled() &&
+ (type == EWK_TOUCH_START && eina_list_count(points) == 1)) {
+ SetFocus(EINA_TRUE);
+ }
+
EINA_LIST_FOREACH(points, l, data) {
const Ewk_Touch_Point* point = static_cast<Ewk_Touch_Point*>(data);
if (point->state == EVAS_TOUCH_POINT_STILL) {
pt.y = point->y;
int delta_y = 0;
- evas_object_geometry_get(evas_object(), nullptr, &delta_y, nullptr,
- nullptr);
+ evas_object_geometry_get(ewk_view(), nullptr, &delta_y, nullptr, nullptr);
ui::TouchEvent touch_event =
ui::MakeTouchEvent(pt, point->state, point->id, 0, delta_y);
rwhva()->OnTouchEvent(&touch_event);
rwhva()->offscreen_helper()->SetTouchEventsEnabled(!enabled);
}
+bool EWebView::SetKeyEventsEnabled(bool enabled) {
+ if (!rwhva() || !rwhva()->aura_efl_helper()) {
+ LOG(WARNING) << "RWHV is not created yet!";
+ return false;
+ }
+
+ if (key_events_enabled_ == enabled)
+ return true;
+
+ key_events_enabled_ = enabled;
+ rwhva()->aura_efl_helper()->SetKeyEventsEnabled(enabled);
+ return true;
+}
+
+void EWebView::SendKeyEvent(Evas_Object* ewk_view,
+ void* key_event,
+ bool is_press) {
+ if (!rwhva() || !rwhva()->aura_efl_helper()) {
+ LOG(WARNING) << "RWHV is not created yet!";
+ return;
+ }
+
+ rwhva()->aura_efl_helper()->SendKeyEvent(ewk_view, key_event, is_press);
+}
+
namespace {
class JavaScriptCallbackDetails {
base::UTF8ToUTF16(script, strlen(script), &js_script);
if (callback) {
JavaScriptCallbackDetails* script_callback_data =
- new JavaScriptCallbackDetails(callback, userdata, evas_object_);
+ new JavaScriptCallbackDetails(callback, userdata, ewk_view_);
RenderFrameHost::JavaScriptResultCallback js_callback =
base::BindOnce(&JavaScriptComplete, base::Owned(script_callback_data));
// In M47, it isn't possible anymore to execute javascript in the generic
LoadData(plain_text, std::string::npos, "text/plain", NULL, NULL, NULL);
}
+void EWebView::LoadHTMLStringOverridingCurrentEntry(
+ const char* html,
+ const char* base_uri,
+ const char* unreachable_url) {
+ LoadData(html, std::string::npos, NULL, NULL, base_uri, unreachable_url,
+ true);
+}
+
void EWebView::LoadData(const char* data,
size_t size,
const char* mime_type,
const char* encoding,
const char* base_uri,
- const char* unreachable_uri) {
+ const char* unreachable_uri,
+ bool should_replace_current_entry) {
SetDefaultStringIfNull(mime_type, "text/html");
SetDefaultStringIfNull(encoding, "utf-8");
SetDefaultStringIfNull(base_uri, "about:blank"); // Webkit2 compatible
data_params.virtual_url_for_data_url = GURL(unreachable_uri);
data_params.load_type = NavigationController::LOAD_TYPE_DATA;
- data_params.should_replace_current_entry = false;
+ data_params.should_replace_current_entry = should_replace_current_entry;
data_params.override_user_agent = NavigationController::UA_OVERRIDE_TRUE;
web_contents_->GetController().LoadURLWithParams(data_params);
}
SmartCallback<EWebViewCallbacks::LoadError>().call(&err);
}
-void EWebView::HandlePopupMenu(std::vector<blink::mojom::MenuItemPtr> items,
- int selectedIndex,
- bool multiple) {
- // Request form navigation information as early as possible,
- // given that is renderer will ping-back with actual requested data.
- RenderFrameHostImpl* render_frame_host =
- static_cast<RenderFrameHostImpl*>(web_contents_->GetPrimaryMainFrame());
- if (render_frame_host)
- render_frame_host->Send(new EwkFrameMsg_RequestSelectCollectionInformation(
- render_frame_host->GetRoutingID()));
-
- Eina_List* popupItems = 0;
- const size_t size = items.size();
- for (size_t i = 0; i < size; ++i) {
- popupItems =
- eina_list_append(popupItems, new Popup_Menu_Item(std::move(items[i])));
- }
-
- ReleasePopupMenuList();
- popupMenuItems_ = popupItems;
-
- if (popupPicker_ && FormIsNavigating()) {
- popupPicker_->multiSelect = multiple;
- PopupMenuUpdate(popupMenuItems_, selectedIndex);
- SetFormIsNavigating(false);
- return;
- }
-
- if (popupPicker_)
- popup_picker_del(popupPicker_);
- popupPicker_ = 0;
-
- if (multiple)
- popupPicker_ =
- popup_picker_new(this, evas_object(), popupMenuItems_, 0, multiple);
- else
- popupPicker_ = popup_picker_new(this, evas_object(), popupMenuItems_,
- selectedIndex, multiple);
-
- popup_picker_buttons_update(popupPicker_, formNavigation_.position,
- formNavigation_.count, false);
-
- // Picker has been shown on top of webview and the page content gets
- // partially overlapped. Decrease viewport while showing picker.
- AdjustViewPortHeightToPopupMenu(true /* is_popup_menu_visible */);
- ScrollFocusedNodeIntoView();
+void EWebView::SetViewLoadErrorPageCallback(
+ Ewk_View_Error_Page_Load_Callback callback,
+ void* user_data) {
+ load_error_page_cb_.Set(callback, user_data);
}
-void EWebView::HidePopupMenu() {
- if (!popupPicker_)
- return;
-
- if (FormIsNavigating())
- return;
+// Remove below code while ewk_error_cancellation_get has been implemented.
+const char* EWebView::InvokeViewLoadErrorPageCallback(const GURL& url,
+ int error_code,
+ bool is_cancellation) {
+ std::unique_ptr<_Ewk_Error> err(new _Ewk_Error(
+ error_code, is_cancellation, url.possibly_invalid_spec().c_str()));
+ _Ewk_Error_Page error_page;
- AdjustViewPortHeightToPopupMenu(false /* is_popup_menu_visible */);
- popup_picker_del(popupPicker_);
- popupPicker_ = 0;
-}
+ LOG(INFO) << "EWebView::InvokeLoadErrorPageCallback url: "
+ << url.spec().c_str() << ", error_code: " << error_code;
-void EWebView::UpdateFormNavigation(int formElementCount,
- int currentNodeIndex,
- bool prevState,
- bool nextState) {
- formNavigation_.count = formElementCount;
- formNavigation_.position = currentNodeIndex;
- formNavigation_.prevState = prevState;
- formNavigation_.nextState = nextState;
+ load_error_page_cb_.Run(ewk_view_, err.get(), &error_page);
+ return error_page.content;
}
-void EWebView::SetFormIsNavigating(bool formIsNavigating) {
- formIsNavigating_ = formIsNavigating;
+bool EWebView::IsLoadErrorPageCallbackSet() const {
+ return load_error_page_cb_.IsCallbackSet();
}
+void EWebView::HandlePopupMenu(std::vector<blink::mojom::MenuItemPtr> items,
+ int selectedIndex,
+ bool multiple,
+ const gfx::Rect& bounds) {
+ if (!select_picker_) {
+ select_picker_.reset(CreateSelectPicker(
+ this, selectedIndex, std::move(items), multiple, bounds));
+
+ // Picker has been shown on top of webview and the page content gets
+ // partially overlapped. Decrease viewport while showing picker.
+ AdjustViewPortHeightToPopupMenu(true /* is_popup_menu_visible */);
+#if BUILDFLAG(IS_TIZEN_TV)
+ SmartCallback<EWebViewCallbacks::PopupMenuShow>().call();
+#endif
+ } else {
+ select_picker_->UpdatePickerData(selectedIndex, std::move(items), multiple);
+ }
-Eina_Bool EWebView::PopupMenuUpdate(Eina_List* items, int selectedIndex) {
- if (!popupPicker_)
- return false;
-
- popup_picker_update(evas_object(), popupPicker_, items, selectedIndex);
- popup_picker_buttons_update(popupPicker_, formNavigation_.position,
- formNavigation_.count, false);
- return true;
+ select_picker_->Show();
}
-void EWebView::FormNavigate(bool direction) {
- RenderFrameHostImpl* render_frame_host =
- static_cast<RenderFrameHostImpl*>(web_contents_->GetPrimaryMainFrame());
- if (!render_frame_host)
+void EWebView::HidePopupMenu() {
+ if (!select_picker_)
return;
- popup_picker_buttons_update(popupPicker_, formNavigation_.position,
- formNavigation_.count, true);
-
- if ((direction && formNavigation_.nextState) ||
- (!direction && formNavigation_.prevState))
- SetFormIsNavigating(true);
-
- listClosed(popupPicker_, 0, 0, 0);
- render_frame_host->Send(new EwkFrameMsg_MoveToNextOrPreviousSelectElement(
- render_frame_host->GetRoutingID(), direction));
-}
-
-Eina_Bool EWebView::DidSelectPopupMenuItem(int selectedIndex) {
- RenderFrameHostImpl* render_frame_host =
- static_cast<RenderFrameHostImpl*>(web_contents_->GetPrimaryMainFrame());
- if (!render_frame_host)
- return false;
-
- if (!popupMenuItems_)
- return false;
-
- // When user select empty space then no index is selected, so selectedIndex
- // value is -1
- // In that case we should call valueChanged() with -1 index.That in turn call
- // popupDidHide()
- // in didChangeSelectedIndex() for reseting the value of m_popupIsVisible in
- // RenderMenuList.
- if (selectedIndex != -1 &&
- selectedIndex >= (int)eina_list_count(popupMenuItems_))
- return false;
-
- // In order to reuse RenderFrameHostImpl::DidSelectPopupMenuItems() method in
- // Android,
- // put selectedIndex into std::vector<int>.
- std::vector<int> selectedIndices;
- selectedIndices.push_back(selectedIndex);
-#if !defined(EWK_BRINGUP) // FIXME: m67 bringup
- render_frame_host->DidSelectPopupMenuItems(selectedIndices);
+ AdjustViewPortHeightToPopupMenu(false /* is_popup_menu_visible */);
+#if BUILDFLAG(IS_TIZEN_TV)
+ SmartCallback<EWebViewCallbacks::PopupMenuHide>().call();
#endif
- return true;
+ select_picker_.reset();
}
-Eina_Bool EWebView::DidMultipleSelectPopupMenuItem(
- std::vector<int>& selectedIndices) {
- RenderFrameHostImpl* render_frame_host =
- static_cast<RenderFrameHostImpl*>(web_contents_->GetPrimaryMainFrame());
- if (!render_frame_host)
- return false;
-
- if (!popupMenuItems_)
- return false;
-#if !defined(EWK_BRINGUP) // FIXME: m67 bringup
- render_frame_host->DidSelectPopupMenuItems(selectedIndices);
-#endif
- return true;
+void EWebView::DidSelectPopupMenuItems(std::vector<int>& indices) {
+ wcva()->wcva_helper()->DidSelectPopupMenuItems(indices);
}
-void EWebView::PopupMenuClose() {
- HidePopupMenu();
- ReleasePopupMenuList();
+void EWebView::DidCancelPopupMenu() {
wcva()->wcva_helper()->DidCancelPopupMenu();
}
// This menu is created in renderer process and it does not now anything about
// view scaling factor and it has another calling sequence, so coordinates is
// not updated.
+ if (settings_ && !settings_->getPreferences().long_press_enabled)
+ return;
+
content::ContextMenuParams convertedParams = params;
gfx::Point convertedPoint =
rwhva()->offscreen_helper()->ConvertPointInViewPix(
convertedParams.y = convertedPoint.y();
Evas_Coord x, y;
- evas_object_geometry_get(evas_object(), &x, &y, 0, 0);
+ evas_object_geometry_get(ewk_view(), &x, &y, 0, 0);
convertedParams.x += x;
convertedParams.y += y;
+ bool show_context_menu_now = true;
if (GetSelectionController() && GetSelectionController()->GetLongPressed()) {
- bool show_context_menu_now =
- !GetSelectionController()->HandleLongPressEvent(convertedPoint,
- convertedParams);
- if (show_context_menu_now)
- ShowContextMenuInternal(convertedParams);
+ show_context_menu_now = !GetSelectionController()->HandleLongPressEvent(
+ convertedPoint, convertedParams);
+ }
+ if (show_context_menu_now) {
+ ShowContextMenuInternal(convertedParams);
}
}
void EWebView::ShowContextMenu(const content::ContextMenuParams& params) {
-#if !defined(USE_AURA)
+ if (!rwhva())
+ return;
+
// This menu is created in renderer process and it does not now anything about
// view scaling factor and it has another calling sequence, so coordinates is
// not updated.
content::ContextMenuParams convertedParams = params;
gfx::Point convertedPoint =
- rwhv()->ConvertPointInViewPix(gfx::Point(params.x, params.y));
+ rwhva()->offscreen_helper()->ConvertPointInViewPix(
+ gfx::Point(params.x, params.y));
convertedParams.x = convertedPoint.x();
convertedParams.y = convertedPoint.y();
Evas_Coord x, y;
- evas_object_geometry_get(evas_object(), &x, &y, 0, 0);
+ evas_object_geometry_get(ewk_view(), &x, &y, 0, 0);
convertedParams.x += x;
convertedParams.y += y;
context_menu_position_ = gfx::Point(convertedParams.x, convertedParams.y);
ShowContextMenuInternal(convertedParams);
-#endif
}
void EWebView::ShowContextMenuInternal(
const content::ContextMenuParams& params) {
+ // We don't want to show 'cut' or 'copy' for inputs of type 'password' in
+ // selection context menu, but params.input_field_type might not be set
+ // correctly, because in some cases params is received from SelectionBoxEfl,
+ // not from FrameHostMsg_ContextMenu message. In SelectionBoxEfl
+ // ContextMenuParams is constructed on our side with limited information and
+ // input_field_type is not set.
+ //
+ // To work around this, we query for input type and set it separately. In
+ // response to EwkViewMsg_QueryInputType we run ::UpdateContextMenu with
+ // information about input's type.
+ //
+ // FIXME: the way we get ContextMenuParams for context menu is flawed in some
+ // cases. This should be fixed by restructuring context menu code.
+ // Context menu creation should be unified to always have
+ // ContextMenuParams received from FrameHostMsg_ContextMenu.
+ // Tracked at: http://suprem.sec.samsung.net/jira/browse/TWF-1640
+ if (params.is_editable) {
+ saved_context_menu_params_ = params;
+ if (rwhva())
+ rwhva()->host()->QueryInputType();
+ } else {
+ UpdateContextMenuWithParams(params);
+ }
+}
+
+void EWebView::UpdateContextMenu(bool is_password_input) {
+ if (is_password_input) {
+ saved_context_menu_params_.form_control_type =
+ blink::mojom::FormControlType::kInputPassword;
+ }
+ UpdateContextMenuWithParams(saved_context_menu_params_);
+}
+
+void EWebView::UpdateContextMenuWithParams(
+ const content::ContextMenuParams& params) {
context_menu_.reset(
new content::ContextMenuControllerEfl(this, *web_contents_.get()));
- if (!context_menu_->PopulateAndShowContextMenu(params)) {
- context_menu_.reset();
- if (GetSelectionController())
- GetSelectionController()->HideHandles();
+
+ if (IsMobileProfile()) {
+ if (delayed_show_context_menu_timer_) {
+ ecore_timer_del(delayed_show_context_menu_timer_);
+ delayed_show_context_menu_timer_ = nullptr;
+ }
+ saved_context_menu_params_ = params;
+ delayed_show_context_menu_timer_ = ecore_timer_add(
+ kDelayShowContextMenuTime, DelayedPopulateAndShowContextMenu, this);
+ } else {
+ if (!context_menu_->PopulateAndShowContextMenu(params)) {
+ context_menu_.reset();
+ if (GetSelectionController())
+ GetSelectionController()->HideHandles();
+ }
+ }
+}
+
+Eina_Bool EWebView::DelayedPopulateAndShowContextMenu(void* data) {
+ if (IsMobileProfile()) {
+ EWebView* view = static_cast<EWebView*>(data);
+ if (view) {
+ if (view->context_menu_ &&
+ !(view->context_menu_->PopulateAndShowContextMenu(
+ view->saved_context_menu_params_))) {
+ view->context_menu_.reset();
+ }
+ view->delayed_show_context_menu_timer_ = nullptr;
+ }
}
+ return ECORE_CALLBACK_CANCEL;
}
void EWebView::CancelContextMenu(int request_id) {
}
void EWebView::AdjustViewPortHeightToPopupMenu(bool is_popup_menu_visible) {
- DCHECK(popupPicker_);
+ if (!rwhva() || !IsMobileProfile() ||
+ settings_->getPreferences().TizenCompatibilityModeEnabled()) {
+ return;
+ }
- int picker_height = 0;
- popup_picker_geometry_get(popupPicker_, 0, 0, 0, &picker_height);
+ int picker_height = select_picker_->GetGeometryDIP().height();
+ gfx::Rect screen_rect =
+ display::Screen::GetScreen()->GetPrimaryDisplay().bounds();
+ gfx::Rect view_rect = rwhva()->offscreen_helper()->GetViewBounds();
+ int bottom_height =
+ screen_rect.height() - (view_rect.y() + view_rect.height());
- gfx::Rect rect = rwhva()->offscreen_helper()->GetViewBounds();
- // FIXME(g.czajkowski): detect the need of resizing viewport.
- // Checking the position of focused <select> element and do resize only when
- // the picker overlaps the element will prevent Blink from doing re-layout.
- // Bug: http://107.108.218.239/bugzilla/show_bug.cgi?id=15488.
- rwhva()->offscreen_helper()->SetCustomViewportSize(gfx::Size(
- rect.width(), is_popup_menu_visible ? rect.height() - picker_height
- : rect.height() + picker_height));
+ rwhva()->offscreen_helper()->SetCustomViewportSize(
+ is_popup_menu_visible
+ ? gfx::Size(view_rect.width(),
+ view_rect.height() - picker_height + bottom_height)
+ : gfx::Size());
}
void EWebView::SetScaleChangedCallback(Ewk_View_Scale_Changed_Callback callback,
}
void EWebView::SetScroll(int x, int y) {
- RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
- if (!render_view_host)
- return;
-
- ChangeScroll(x, y);
-#if !defined(EWK_BRINGUP) // FIXME: m94 bringup
- render_view_host->Send(
- new EwkViewMsg_SetScroll(render_view_host->GetRoutingID(), x, y));
-#endif
+ if (auto* render_view_host = web_contents_->GetRenderViewHost()) {
+ if (auto& broadcast = static_cast<RenderViewHostImpl*>(render_view_host)
+ ->GetAssociatedPageBroadcast()) {
+ ChangeScroll(x, y);
+ broadcast->SetScrollOffset(x, y);
+ }
+ }
}
void EWebView::UseSettingsFont() {
}
void EWebView::MoveCaret(const gfx::Point& point) {
-#if !defined(USE_AURA)
- if (rwhv())
- rwhv()->MoveCaret(point);
-#endif
+ if (rwhva())
+ rwhva()->offscreen_helper()->MoveCaret(point);
}
SelectionControllerEfl* EWebView::GetSelectionController() const {
return view ? view->offscreen_helper()->GetSelectionController() : 0;
}
-void EWebView::SelectLinkText(const gfx::Point& touch_point) {
-#if !defined(EWK_BRINGUP) // FIXME: m67 bringup
- float device_scale_factor =
- display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
- RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
- render_view_host->Send(new ViewMsg_SelectLinkText(
- render_view_host->GetRoutingID(),
- gfx::Point(touch_point.x() / device_scale_factor,
- touch_point.y() / device_scale_factor)));
-#endif
+void EWebView::SelectFocusedLink() {
+ if (!rwhva()) {
+ return;
+ }
+
+ rwhva()->host()->SelectFocusedLink();
}
bool EWebView::GetSelectionRange(Eina_Rectangle* left_rect,
return false;
}
+void EWebView::OnSelectionRectReceived(const gfx::Rect& selection_rect) const {
+ if (context_menu_)
+ context_menu_->OnSelectionRectReceived(selection_rect);
+}
+
Eina_Bool EWebView::ClearSelection() {
if (!rwhva())
return EINA_FALSE;
ResetContextMenuController();
- rwhva()->offscreen_helper()->SelectionChanged(std::u16string(), 0,
- gfx::Range());
+ rwhva()->SelectionChanged(std::u16string(), 0, gfx::Range());
if (GetSelectionController())
return GetSelectionController()->ClearSelectionViaEWebView();
void EWebView::EvasToBlinkCords(int x, int y, int* view_x, int* view_y) {
DCHECK(display::Screen::GetScreen());
- Evas_Coord tmpX, tmpY;
- evas_object_geometry_get(evas_object_, &tmpX, &tmpY, NULL, NULL);
+ if (!rwhva())
+ return;
+
+ gfx::Rect view_bounds = rwhva()->offscreen_helper()->GetViewBoundsInPix();
if (view_x) {
- *view_x = x - tmpX;
+ *view_x = x - view_bounds.x();
*view_x /=
display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
}
if (view_y) {
- *view_y = y - tmpY;
+ *view_y = y - view_bounds.y();
*view_y /=
display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
}
void EWebView::OnFocusIn() {
SmartCallback<EWebViewCallbacks::FocusIn>().call();
-#if defined(USE_WAYLAND) && !BUILDFLAG(IS_TIZEN_TV)
+#if defined(USE_WAYLAND)
if (!rwhva() || !rwhva()->offscreen_helper())
return;
- ClipboardHelperEfl::GetInstance()->OnWebviewFocusIn(
- this, rwhva()->offscreen_helper()->content_image_elm_host(),
- rwhva()->offscreen_helper()->IsFocusedNodeContentEditable(),
- base::BindRepeating(&EWebView::ExecuteEditCommand,
- base::Unretained(this)));
+ if (GetSettings()->getClipboardEnabled()) {
+ ClipboardHelperEfl::GetInstance()->OnWebviewFocusIn(
+ this, rwhva()->offscreen_helper()->content_image_elm_host(),
+ rwhva()->offscreen_helper()->IsFocusedNodeContentEditable(),
+ base::BindRepeating(&EWebView::ExecuteEditCommand,
+ base::Unretained(this)));
+ }
#endif
}
void EWebView::OnFocusOut() {
+#if defined(TIZEN_ATK_SUPPORT)
+ if (IsMobileProfile())
+ eweb_accessibility_->OnFocusOut();
+#endif
SmartCallback<EWebViewCallbacks::FocusOut>().call();
-#if defined(USE_WAYLAND) && !BUILDFLAG(IS_TIZEN_TV)
- ClipboardHelperEfl::GetInstance()->MaybeInvalidateActiveWebview(this);
+#if defined(USE_WAYLAND)
+ if (GetSettings()->getClipboardEnabled())
+ ClipboardHelperEfl::GetInstance()->MaybeInvalidateActiveWebview(this);
#endif
}
#if defined(TIZEN_VIDEO_HOLE)
if (rwhva() && pending_video_hole_setting_) {
- rwhva()->host()->SetVideoHoleForRender(pending_video_hole_setting_);
+ EnableVideoHoleSupportInternal();
pending_video_hole_setting_ = false;
}
#endif
quota_request_callback_.Set(callback, user_data);
}
+#if !defined(EWK_BRINGUP) // FIXME: m114 bringup
void EWebView::InvokeQuotaPermissionRequest(
_Ewk_Quota_Permission_Request* request,
content::QuotaPermissionContext::PermissionCallback cb) {
quota_permission_request_map_[request] = std::move(cb);
- request->setView(evas_object());
+ request->setView(ewk_view());
if (quota_request_callback_.IsCallbackSet())
- quota_request_callback_.Run(evas_object(), request);
+ quota_request_callback_.Run(ewk_view(), request);
else
QuotaRequestCancel(request);
}
quota_permission_request_map_.erase(request);
delete request;
}
+#endif
bool EWebView::GetLinkMagnifierEnabled() const {
#if !defined(EWK_BRINGUP) // FIXME: m71 bringup
bool EWebView::InvokeNotificationPermissionCallback(
Ewk_Notification_Permission_Request* request) {
Eina_Bool ret = EINA_FALSE;
- notification_permission_callback_.Run(evas_object_, request, &ret);
+ notification_permission_callback_.Run(ewk_view_, request, &ret);
return ret;
}
bool EWebView::PlainTextGet(Ewk_View_Plain_Text_Get_Callback callback,
void* user_data) {
- RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
- if (!render_view_host)
+ auto* render_frame_host = web_contents_->GetPrimaryMainFrame();
+ if (!render_frame_host)
return false;
-#if !defined(EWK_BRINGUP) // FIXME: m94 bringup
- int plain_text_get_callback_id =
- SetEwkViewPlainTextGetCallback(callback, user_data);
- return render_view_host->Send(new EwkViewMsg_PlainTextGet(
- render_view_host->GetRoutingID(), plain_text_get_callback_id));
-#else
- return false;
-#endif
+
+ auto callback_id = SetEwkViewPlainTextGetCallback(callback, user_data);
+ return render_frame_host->Send(new EwkFrameMsg_GetPlainText(
+ render_frame_host->GetRoutingID(), callback_id));
}
void EWebView::InvokePlainTextGetCallback(const std::string& content_text,
int plain_text_get_callback_id) {
EwkViewPlainTextGetCallback* view_plain_text_callback_invoke_ptr =
plain_text_get_callback_map_.Lookup(plain_text_get_callback_id);
- view_plain_text_callback_invoke_ptr->Run(evas_object(), content_text.c_str());
+ view_plain_text_callback_invoke_ptr->Run(ewk_view(), content_text.c_str());
plain_text_get_callback_map_.Remove(plain_text_get_callback_id);
}
bool EWebView::InvokeViewGeolocationPermissionCallback(
_Ewk_Geolocation_Permission_Request* permission_context,
Eina_Bool* callback_result) {
- return geolocation_permission_cb_.Run(evas_object_, permission_context,
+ return geolocation_permission_cb_.Run(ewk_view_, permission_context,
callback_result);
}
bool EWebView::InvokeViewUserMediaPermissionCallback(
_Ewk_User_Media_Permission_Request* permission_context,
Eina_Bool* callback_result) {
- return user_media_permission_cb_.Run(evas_object_, permission_context,
+ return user_media_permission_cb_.Run(ewk_view_, permission_context,
callback_result);
}
Ewk_User_Media_Permission_Query_Result
EWebView::InvokeViewUserMediaPermissionQueryCallback(
_Ewk_User_Media_Permission_Query* permission_context) {
- return user_media_permission_query_cb_.Run(evas_object_, permission_context);
+ return user_media_permission_query_cb_.Run(ewk_view_, permission_context);
}
void EWebView::SetViewUnfocusAllowCallback(
bool EWebView::InvokeViewUnfocusAllowCallback(Ewk_Unfocus_Direction direction,
Eina_Bool* callback_result) {
- return unfocus_allow_cb_.Run(evas_object_, direction, callback_result);
+ return unfocus_allow_cb_.Run(ewk_view_, direction, callback_result);
}
void EWebView::StopFinding() {
if (!render_view_host)
return false;
+#if !defined(EWK_BRINGUP) // FIXME: m94 bringup
MHTMLCallbackDetails* callback_details = new MHTMLCallbackDetails;
callback_details->Set(callback, user_data);
-#if !defined(EWK_BRINGUP) // FIXME: m94 bringup
int mhtml_callback_id = mhtml_callback_map_.Add(callback_details);
return render_view_host->Send(new EwkViewMsg_GetMHTMLData(
render_view_host->GetRoutingID(), mhtml_callback_id));
int callback_id) {
MHTMLCallbackDetails* callback_details =
mhtml_callback_map_.Lookup(callback_id);
- callback_details->Run(evas_object(), mhtml_content.c_str());
+ callback_details->Run(ewk_view(), mhtml_content.c_str());
mhtml_callback_map_.Remove(callback_id);
}
std::u16string title(web_contents_->GetTitle());
// Post function that has file access to blocking task runner.
- return base::PostTaskAndReplyWithResult(
- base::ThreadPool::CreateSequencedTaskRunner(
- {base::MayBlock(), base::TaskPriority::BEST_EFFORT,
- base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})
- .get(),
+ base::ThreadPool::PostTaskAndReplyWithResult(
FROM_HERE,
+ {base::MayBlock(), base::TaskPriority::BEST_EFFORT,
+ base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN},
base::BindOnce(&GenerateMHTMLFilePath, url, base::UTF16ToUTF8(title),
path),
base::BindOnce(&EWebView::GenerateMHTML, base::Unretained(this), callback,
user_data));
+ return true;
}
void EWebView::GenerateMHTML(Ewk_View_Save_Page_Callback callback,
const base::FilePath& file_path) {
if (file_path.empty()) {
LOG(ERROR) << "Generating file path was failed";
- callback(evas_object_, nullptr, user_data);
+ callback(ewk_view_, nullptr, user_data);
return;
}
void* user_data,
const base::FilePath& file_path,
int64_t file_size) {
- callback(evas_object_, file_size > 0 ? file_path.value().c_str() : nullptr,
+ callback(ewk_view_, file_size > 0 ? file_path.value().c_str() : nullptr,
user_data);
}
if (!cb)
return;
- cb->Run(evas_object(), SkColorGetR(bg_color), SkColorGetG(bg_color),
+ cb->Run(ewk_view(), SkColorGetR(bg_color), SkColorGetG(bg_color),
SkColorGetB(bg_color), SkColorGetA(bg_color));
background_color_get_callback_map_.Remove(callback_id);
}
SetScaledContentsSize();
// Notify app about the scale change.
- scale_changed_cb_.Run(evas_object_, scale_factor);
+ scale_changed_cb_.Run(ewk_view_, scale_factor);
}
inline JavaScriptDialogManagerEfl* EWebView::GetJavaScriptDialogManagerEfl() {
}
void EWebView::GetPageScaleRange(double* min_scale, double* max_scale) {
- auto prefs = web_contents_->GetOrCreateWebPreferences();
+ auto& prefs = web_contents_->GetOrCreateWebPreferences();
if (min_scale)
*min_scale = prefs.default_minimum_page_scale_factor;
if (max_scale)
*max_scale = prefs.default_maximum_page_scale_factor;
}
-void EWebView::SetDrawsTransparentBackground(bool enabled) {
+content::WebContentsViewAura* EWebView::GetWebContentsViewAura() const {
+ WebContentsImpl* wc = static_cast<WebContentsImpl*>(web_contents_.get());
+ return static_cast<WebContentsViewAura*>(wc->GetView());
+}
+
+bool EWebView::SetDrawsTransparentBackground(bool enabled) {
+#if BUILDFLAG(IS_TIZEN)
RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
- if (!render_view_host)
- return;
-#if !defined(EWK_BRINGUP) // FIXME: m94 bringup
- render_view_host->Send(new EwkViewMsg_SetDrawsTransparentBackground(
- render_view_host->GetRoutingID(), enabled));
+ if (!render_view_host || !rwhva())
+ return false;
+
+ if (!rwhva()->offscreen_helper())
+ return false;
+ elm_object_style_set(rwhva()->offscreen_helper()->content_image_elm_host(),
+ enabled ? "transparent" : "default");
+ evas_object_image_alpha_set(rwhva()->offscreen_helper()->content_image(),
+ enabled);
+ GetWebContentsViewAura()->SetBackgroundColor(enabled ? SK_ColorTRANSPARENT
+ : SK_ColorWHITE);
+ static_cast<RenderViewHostImpl*>(render_view_host)
+ ->GetWidget()
+ ->GetAssociatedFrameWidget()
+ ->SetDrawsTransparentBackground(enabled);
+ rwhva()->SetBackgroundColor(enabled ? SK_ColorTRANSPARENT : SK_ColorWHITE);
+ return true;
+#else
+ return false;
+#endif
+}
+
+bool EWebView::GetDrawsTransparentBackground() {
+#if BUILDFLAG(IS_TIZEN)
+ return GetWebContentsViewAura()->GetBackgroundColor() == SK_ColorTRANSPARENT;
+#else
+ return false;
+#endif
+}
+
+bool EWebView::SetBackgroundColor(int red, int green, int blue, int alpha) {
+#if BUILDFLAG(IS_TIZEN)
+ if (!alpha)
+ return SetDrawsTransparentBackground(true);
+
+ RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
+ if (!render_view_host || !rwhva())
+ return false;
+
+ if (!rwhva()->offscreen_helper())
+ return false;
+ elm_object_style_set(rwhva()->offscreen_helper()->content_image_elm_host(),
+ alpha < 255 ? "transparent" : "default");
+ evas_object_image_alpha_set(rwhva()->offscreen_helper()->content_image(),
+ alpha < 255);
+ GetWebContentsViewAura()->SetBackgroundColor(
+ SkColorSetARGB(alpha, red, green, blue));
+ static_cast<RenderViewHostImpl*>(render_view_host)
+ ->GetWidget()
+ ->GetAssociatedFrameWidget()
+ ->SetBackgroundColor(red, green, blue, alpha);
+ rwhva()->SetBackgroundColor(SkColorSetARGB(alpha, red, green, blue));
+
+ return true;
+#else
+ return false;
#endif
}
return wcva()->wcva_helper()->IsDragging();
}
-void EWebView::ShowFileChooser(content::RenderFrameHost* render_frame_host,
- const blink::mojom::FileChooserParams& params) {
+void EWebView::ShowFileChooser(
+ scoped_refptr<content::FileSelectListener> listener,
+ const blink::mojom::FileChooserParams& params) {
+#if BUILDFLAG(IS_TIZEN_TV)
+ LOG(INFO) << "File chooser request callback.";
+ file_chooser_request_.reset(new _Ewk_File_Chooser_Request(
+ std::move(listener), params.accept_types, params.mode));
+ SmartCallback<EWebViewCallbacks::FileChooserRequest>().call(
+ file_chooser_request_.get());
+#else
if (!IsMobileProfile() && !IsWearableProfile())
return;
-
-#if !defined(EWK_BRINGUP) // FIXME: m71 bringup
- if (params.capture) {
- const std::string capture_types[] = {"video/*", "audio/*", "image/*"};
- unsigned int capture_types_num =
- sizeof(capture_types) / sizeof(*capture_types);
- for (unsigned int i = 0; i < capture_types_num; ++i) {
- for (unsigned int j = 0; j < params.accept_types.size(); ++j) {
- if (UTF16ToUTF8(params.accept_types[j]) == capture_types[i]) {
- filechooser_mode_ = params.mode;
- LaunchCamera(params.accept_types[j]);
- return;
- }
- }
- }
- }
file_chooser_.reset(
- new content::FileChooserControllerEfl(render_frame_host, ¶ms));
+ new content::FileChooserControllerEfl(std::move(listener), params));
file_chooser_->Open();
#endif
}
}
void EWebView::RequestColorPicker(int r, int g, int b, int a) {
- input_picker_.reset(new InputPicker(this));
+ input_picker_.reset(new InputPicker(this, web_contents_.get(), ewk_view()));
input_picker_->ShowColorPicker(r, g, b, a);
}
void EWebView::InputPickerShow(ui::TextInputType input_type,
double input_value,
content::DateTimeChooserEfl* date_time_chooser) {
- input_picker_.reset(new InputPicker(this));
- date_time_chooser_ = date_time_chooser;
+ input_picker_.reset(new InputPicker(this, web_contents_.get(), ewk_view(),
+ date_time_chooser));
input_picker_->ShowDatePicker(input_type, input_value);
}
}
int EWebView::StartInspectorServer(int port) {
+#if BUILDFLAG(IS_TIZEN_TV)
+ if (IsTIZENWRT()) {
+ use_early_rwi_ = false;
+ rwi_info_showed_ = false;
+ }
+ if (!context_->GetImpl()->GetInspectorServerState()) {
+ int validPort = 0;
+ if (!devtools_http_handler::DevToolsPortManager::GetInstance()
+ ->GetValidPort(validPort))
+ return 0;
+
+ port = validPort;
+ }
+#endif
return context_->InspectorServerStart(port);
}
bool EWebView::StopInspectorServer() {
+#if BUILDFLAG(IS_TIZEN_TV)
+ if (IsTIZENWRT()) {
+ use_early_rwi_ = false;
+ rwi_info_showed_ = false;
+ }
+#endif
return context_->InspectorServerStop();
}
network_context->SetAcceptLanguage(accept_languages);
}
+#if BUILDFLAG(IS_TIZEN_TV)
+bool EWebView::EdgeScrollBy(int delta_x, int delta_y) {
+ if ((delta_x == 0 && delta_y == 0) || is_processing_edge_scroll_)
+ return false;
+
+ RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
+ if (!render_view_host)
+ return false;
+
+ if (!rwhva())
+ return false;
+
+ gfx::Point offset = gfx::Point(delta_x, delta_y);
+ gfx::Point mouse_position;
+ GetMousePosition(mouse_position);
+ is_processing_edge_scroll_ = true;
+
+ static_cast<RenderViewHostImpl*>(render_view_host)
+ ->GetWidget()
+ ->GetAssociatedFrameWidget()
+ ->EdgeScrollBy(offset, mouse_position);
+ return true;
+}
+
+void EWebView::GetMousePosition(gfx::Point& mouse_position) {
+ int mouse_x, mouse_y;
+ evas_pointer_output_xy_get(GetEvas(), &mouse_x, &mouse_y);
+ Evas_Coord x, y, width, height;
+ evas_object_geometry_get(ewk_view(), &x, &y, &width, &height);
+
+ if (mouse_y < y)
+ mouse_y = y + 1;
+ else if (mouse_y > y + height)
+ mouse_y = y + height - 1;
+ if (mouse_x < x)
+ mouse_x = x + 1;
+ else if (mouse_x > x + width)
+ mouse_x = x + width - 1;
+
+ mouse_x -= x;
+ mouse_y -= y;
+
+ mouse_x /=
+ display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
+ mouse_y /=
+ display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
+
+ mouse_position.set_x(mouse_x);
+ mouse_position.set_y(mouse_y);
+}
+
+void EWebView::InvokeEdgeScrollByCallback(const gfx::Point& offset,
+ bool handled) {
+ is_processing_edge_scroll_ = false;
+
+ if (offset.x() < 0)
+ SmartCallback<EWebViewCallbacks::EdgeScrollLeft>().call(&handled);
+ else if (offset.x() > 0)
+ SmartCallback<EWebViewCallbacks::EdgeScrollRight>().call(&handled);
+
+ if (offset.y() < 0)
+ SmartCallback<EWebViewCallbacks::EdgeScrollTop>().call(&handled);
+ else if (offset.y() > 0)
+ SmartCallback<EWebViewCallbacks::EdgeScrollBottom>().call(&handled);
+}
+#endif
+
+#if BUILDFLAG(IS_TIZEN_TV)
+void EWebView::InvokeScrollbarThumbFocusChangedCallback(
+ Ewk_Scrollbar_Orientation orientation,
+ bool focused) {
+ Ewk_Scrollbar_Data data;
+ data.orientation = orientation;
+ data.focused = focused;
+ SmartCallback<EWebViewCallbacks::DidChagneScrollbarsThumbFocus>().call(&data);
+}
+#endif
+
void EWebView::HandleRendererProcessCrash() {
content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
base::BindOnce(&EWebView::InvokeWebProcessCrashedCallback,
}
void EWebView::InitializeContent() {
+ LOG(INFO) << "eweb_view.cc InitializeContent" ;
+#if BUILDFLAG(IS_TIZEN_TV)
+ // When initialize content init inspector server
+ InitInspectorServer();
+#endif
WebContents* new_contents = create_new_window_web_contents_cb_.Run(this);
if (!new_contents) {
WebContents::CreateParams params(context_->browser_context());
<< "Aborting execution ...";
}
}
+
web_contents_delegate_.reset(new WebContentsDelegateEfl(this));
web_contents_->SetDelegate(web_contents_delegate_.get());
+
+ // EWebView's delegate. Calls to WebContentsImplEfl and
+ // WebContentsViewAuraHelperEfl are delegated to this class.
+ // For more details, refer commit message of patch 301647.
+ webview_delegate_.reset(new WebViewDelegateEfl(this));
WebContentsImplEfl* wc_efl =
static_cast<WebContentsImplEfl*>(web_contents_.get());
- wc_efl->SetEflDelegate(new WebContentsEflDelegateEwk(this));
- wcva()->wcva_helper()->SetEflDelegate(wc_efl->GetEflDelegate());
+ wc_efl->SetWebviewDelegate(webview_delegate_.get());
+ wcva()->wcva_helper()->SetWebviewDelegate(webview_delegate_.get());
back_forward_list_.reset(new _Ewk_Back_Forward_List(web_contents_.get()));
- permission_popup_manager_.reset(new PermissionPopupManager(evas_object_));
+ permission_popup_manager_.reset(new PermissionPopupManager(ewk_view_));
gin_native_bridge_dispatcher_host_.reset(
new content::GinNativeBridgeDispatcherHost(web_contents_.get()));
- native_view_ =
- static_cast<WebContentsImplEfl*>(web_contents_.get())->GetEflNativeView();
- evas_object_smart_member_add(native_view_, evas_object_);
- static_cast<WebContentsImpl*>(web_contents_.get())
- ->set_ewk_view(evas_object_);
+ efl_main_layout_ =
+ static_cast<WebContentsImplEfl*>(web_contents_.get())->GetEflMainLayout();
+ evas_object_smart_member_add(efl_main_layout_, ewk_view_);
+ static_cast<WebContentsImpl*>(web_contents_.get())->set_ewk_view(ewk_view_);
InitializeWindowTreeHost();
}
+#if BUILDFLAG(IS_TIZEN_TV)
+void EWebView::OnDialogClosed() {
+ if (!use_early_rwi_)
+ return;
+
+ use_early_rwi_ = false;
+ LOG(INFO) << "[FAST RWI] SetURL Restore [" << rwi_gurl_.spec()
+ << "] from [about:blank]";
+ SetURL(rwi_gurl_);
+ rwi_gurl_ = GURL();
+ rwi_info_showed_ = true;
+}
+
+void EWebView::InitInspectorServer() {
+ if (devtools_http_handler::DevToolsPortManager::GetInstance()
+ ->ProcessCompare()) {
+ int res = StartInspectorServer(0);
+ if (res) {
+ LOG(INFO) << "InitInspectorServer SetPort";
+ devtools_http_handler::DevToolsPortManager::GetInstance()->SetPort(res);
+ }
+ }
+}
+#endif
+
+#if defined(TIZEN_TBM_SUPPORT)
+void EWebView::SetOffscreenRendering(bool enable) {
+ if (host_)
+ host_->compositor()->SetUseTbmSuraceForOffscreenRendering(enable);
+}
+#endif
+
void EWebView::InitializeWindowTreeHost() {
CHECK(aura::Env::GetInstance());
int x, y, width, height;
Ecore_Evas* ee =
- ecore_evas_ecore_evas_get(evas_object_evas_get(native_view_));
+ ecore_evas_ecore_evas_get(evas_object_evas_get(efl_main_layout_));
ecore_evas_geometry_get(ee, &x, &y, &width, &height);
gfx::Rect bounds(x, y, width, height);
std::make_unique<aura::test::TestFocusClient>(host_->window());
window_parenting_client_ =
std::make_unique<aura::test::TestWindowParentingClient>(host_->window());
+ compositor_observer_ = std::make_unique<ui::CompositorObserverEfl>(
+ host_->compositor(), web_contents_.get());
aura::Window* content = web_contents_->GetNativeView();
aura::Window* parent = host_->window();
host_view->SetSize(bounds.size());
}
-#if BUILDFLAG(IS_TIZEN) && !defined(EWK_BRINGUP)
-void EWebView::cameraResultCb(service_h request,
- service_h reply,
- service_result_e result,
- void* data) {
- if (!IsMobileProfile() && !IsWearableProfile())
- return;
-
- EWebView* webview = static_cast<EWebView*>(data);
- RenderViewHost* render_view_host =
- webview->web_contents_->GetRenderViewHost();
- if (result == SERVICE_RESULT_SUCCEEDED) {
- int ret = -1;
- char** filesarray;
- int number;
- ret = service_get_extra_data_array(reply, SERVICE_DATA_SELECTED,
- &filesarray, &number);
- if (filesarray) {
- for (int i = 0; i < number; i++) {
- std::vector<ui::SelectedFileInfo> files;
- if (!render_view_host) {
- return;
- }
- if (filesarray[i]) {
- GURL url(filesarray[i]);
- if (!url.is_valid()) {
- base::FilePath path(url.SchemeIsFile() ? url.path()
- : filesarray[i]);
- files.push_back(ui::SelectedFileInfo(path, base::FilePath()));
- }
- }
- render_view_host->FilesSelectedInChooser(files,
- webview->filechooser_mode_);
- }
- }
- } else {
- std::vector<ui::SelectedFileInfo> files;
- if (render_view_host) {
- render_view_host->FilesSelectedInChooser(files,
- webview->filechooser_mode_);
- }
- }
-}
-
-bool EWebView::LaunchCamera(std::u16string mimetype) {
- service_h svcHandle = 0;
- if (service_create(&svcHandle) < 0 || !svcHandle) {
- LOG(ERROR) << __FUNCTION__ << " Service Creation Failed ";
- return false;
- }
- service_set_operation(svcHandle, SERVICE_OPERATION_CREATE_CONTENT);
- service_set_mime(svcHandle, UTF16ToUTF8(mimetype).c_str());
- service_add_extra_data(svcHandle, "CALLER", "Browser");
-
- int ret = service_send_launch_request(svcHandle, cameraResultCb, this);
- if (ret != SERVICE_ERROR_NONE) {
- LOG(ERROR) << __FUNCTION__ << " Service Launch Failed ";
- service_destroy(svcHandle);
- return false;
- }
- service_destroy(svcHandle);
- return true;
-}
-#endif
-
void EWebView::UrlRequestSet(
const char* url,
content::NavigationController::LoadURLType loadtype,
}
#if defined(TIZEN_VIDEO_HOLE)
-void EWebView::SetVideoHoleSupport(bool enable) {
+void EWebView::EnableVideoHoleSupport() {
if (!web_contents_->GetPrimaryMainFrame() ||
!web_contents_->GetPrimaryMainFrame()->IsRenderFrameLive() || !rwhva()) {
- pending_video_hole_setting_ = enable;
+ pending_video_hole_setting_ = true;
return;
}
- rwhva()->host()->SetVideoHoleForRender(enable);
+ EnableVideoHoleSupportInternal();
+}
+
+void EWebView::EnableVideoHoleSupportInternal() {
+ if (settings_->getPreferences().video_hole_enabled)
+ return;
+
+ settings_->getPreferences().video_hole_enabled = true;
+ WebContentsImpl* wc = static_cast<WebContentsImpl*>(web_contents_.get());
+ if (wc)
+ wc->EnableVideoHole();
}
#endif
bool EWebView::HandleShow() {
- if (!native_view_)
+ if (!efl_main_layout_)
return false;
Show();
}
bool EWebView::HandleHide() {
- if (!native_view_)
+ if (!efl_main_layout_)
return false;
Hide();
}
bool EWebView::HandleMove(int x, int y) {
- if (!native_view_)
+ if (!efl_main_layout_)
return false;
- evas_object_move(native_view_, x, y);
-
-#if defined(TIZEN_VIDEO_HOLE) && !defined(EWK_BRINGUP)
+ evas_object_move(efl_main_layout_, x, y);
+ LOG(INFO) << "Move x " << x << " y " << y;
+#if defined(TIZEN_VIDEO_HOLE)
if (rwhva())
- rwhva()->offscreen_helper()->DidMoveWebView();
+ rwhva()->DidMoveWebView();
#endif
+ if (context_menu_)
+ context_menu_->Move(x, y);
+
return true;
}
bool EWebView::HandleResize(int width, int height) {
- if (!native_view_)
+ if (!efl_main_layout_)
return false;
- evas_object_resize(native_view_, width, height);
+ evas_object_resize(efl_main_layout_, width, height);
+
+#if defined(TIZEN_VIDEO_HOLE)
+ LOG(INFO) << __func__ << " new size " << width << "*" << height;
+ if (rwhva())
+ rwhva()->DidMoveWebView();
+#endif
+
+ if (select_picker_) {
+ AdjustViewPortHeightToPopupMenu(true /* is_popup_menu_visible */);
+ ScrollFocusedNodeIntoView();
+ }
+
+#if defined(USE_AURA) && BUILDFLAG(IS_TIZEN_TV)
+ if (host_) {
+ int x, y;
+ evas_object_geometry_get(efl_main_layout_, &x, &y, nullptr, nullptr);
+ gfx::Rect bounds(x, y, width, height);
+ host_->SetBoundsInPixels(bounds);
+ }
+#endif
+
return true;
}
return;
}
+#if BUILDFLAG(IS_TIZEN_TV)
+ if (pending_setfocus_closure_)
+ std::move(pending_setfocus_closure_).Run();
+#endif
+
for (auto iter = delayed_messages_.begin(); iter != delayed_messages_.end();
++iter) {
IPC::Message* message = *iter;
web_contents_->ClosePage();
}
+bool EWebView::SetMainFrameScrollbarVisible(bool visible) {
+ if (web_contents_->GetPrimaryMainFrame()->IsRenderFrameLive() && rwhva())
+ rwhva()->host()->SetMainFrameScrollbarVisible(visible);
+ return true;
+}
+
+bool EWebView::GetMainFrameScrollbarVisible(
+ Ewk_View_Main_Frame_Scrollbar_Visible_Get_Callback callback,
+ void* user_data) {
+ if (!rwhva())
+ return false;
+
+ MainFrameScrollbarVisibleGetCallback* callback_ptr =
+ new MainFrameScrollbarVisibleGetCallback;
+ callback_ptr->Set(callback, user_data);
+ int callback_id =
+ main_frame_scrollbar_visible_callback_map_.Add(callback_ptr);
+ rwhva()->host()->RequestMainFrameScrollbarVisible(callback_id);
+ return true;
+}
+
+void EWebView::InvokeMainFrameScrollbarVisibleCallback(int callback_id,
+ bool visible) {
+ if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
+ content::GetUIThreadTaskRunner({})->PostTask(
+ FROM_HERE,
+ base::BindOnce(&EWebView::InvokeMainFrameScrollbarVisibleCallback,
+ base::Unretained(this), visible, callback_id));
+ return;
+ }
+
+ MainFrameScrollbarVisibleGetCallback* callback =
+ main_frame_scrollbar_visible_callback_map_.Lookup(callback_id);
+ if (!callback)
+ return;
+
+ main_frame_scrollbar_visible_callback_map_.Remove(callback_id);
+ callback->Run(ewk_view(), visible);
+ main_frame_scrollbar_visible_callback_map_.Remove(callback_id);
+}
+
void EWebView::OnOverscrolled(const gfx::Vector2dF& accumulated_overscroll,
const gfx::Vector2dF& latest_overscroll_delta) {
const gfx::Vector2dF old_overscroll =
}
void EWebView::DidChangeThemeColor(const SkColor& color) {
- did_change_theme_color_callback_.Run(evas_object_, color);
+ did_change_theme_color_callback_.Run(ewk_view_, color);
}
#if BUILDFLAG(IS_TIZEN_TV)
rwhva()->offscreen_helper()->DrawLabel(image, rect);
}
+void EWebView::DeactivateAtk(bool deactivated) {
+#if defined(TIZEN_ATK_SUPPORT)
+ EWebAccessibilityUtil::GetInstance()->Deactivate(deactivated);
+#endif
+}
+
void EWebView::ClearLabels() {
if (rwhva())
rwhva()->offscreen_helper()->ClearLabels();
}
+
+void EWebView::SetTranslatedURL(const char* url) {
+ if (!rwhva() || !rwhva()->aura_efl_helper())
+ return;
+ rwhva()->aura_efl_helper()->SetTranslatedURL(std::string(url));
+ LOG(INFO) << "translate_url:" << url;
+}
+
+bool EWebView::IsVideoPlaying(Ewk_Is_Video_Playing_Callback callback,
+ void* user_data) {
+ IsVideoPlayingCallback* cb = new IsVideoPlayingCallback(callback, user_data);
+ int callback_id = is_video_playing_callback_map_.Add(cb);
+
+ if (!rwhva() || !rwhva()->aura_efl_helper()) {
+ LOG(ERROR) << "rwhva() or rwhva()->aura_efl_helper() is false";
+ return false;
+ }
+ rwhva()->aura_efl_helper()->RequestVideoPlaying(callback_id);
+ return true;
+}
+
+void EWebView::InvokeIsVideoPlayingCallback(bool is_playing, int callback_id) {
+ IsVideoPlayingCallback* callback =
+ is_video_playing_callback_map_.Lookup(callback_id);
+ if (!callback) {
+ LOG(INFO) << "callback is null";
+ return;
+ }
+
+ LOG(INFO) << __func__ << " ; is_playing : " << is_playing;
+ callback->Run(ewk_view(), is_playing);
+ is_video_playing_callback_map_.Remove(callback_id);
+}
#endif
void EWebView::RequestManifest(Ewk_View_Request_Manifest_Callback callback,
_Ewk_View_Request_Manifest* manifest,
Ewk_View_Request_Manifest_Callback callback,
void* user_data) {
- callback(evas_object_, manifest, user_data);
+ callback(ewk_view_, manifest, user_data);
}
void EWebView::SetSessionTimeout(uint64_t timeout) {
rwhva()->host()->SetLongPollingGlobalTimeout(timeout);
}
+void EWebView::SetBeforeUnloadConfirmPanelCallback(
+ Ewk_View_Before_Unload_Confirm_Panel_Callback callback,
+ void* user_data) {
+ GetJavaScriptDialogManagerEfl()->SetBeforeUnloadConfirmPanelCallback(
+ callback, user_data);
+}
+
+void EWebView::ReplyBeforeUnloadConfirmPanel(Eina_Bool result) {
+ GetJavaScriptDialogManagerEfl()->ReplyBeforeUnloadConfirmPanel(result);
+}
+
+#if defined(TIZEN_PEPPER_EXTENSIONS)
+void EWebView::InitializePepperExtensionSystem() {
+ RegisterPepperExtensionDelegate();
+ SetWindowId();
+}
+
+EwkExtensionSystemDelegate* EWebView::GetExtensionDelegate() {
+ RenderFrameHost* render_frame_host = web_contents_->GetPrimaryMainFrame();
+ if (!render_frame_host)
+ return nullptr;
+
+ return static_cast<EwkExtensionSystemDelegate*>(
+ ExtensionSystemDelegateManager::GetInstance()->GetDelegateForFrame(render_frame_id_));
+}
+
+void EWebView::SetWindowId() {
+ EwkExtensionSystemDelegate* delegate = GetExtensionDelegate();
+ if (!delegate) {
+ LOG(WARNING) << "No delegate is available to set window id";
+ return;
+ }
+ Evas_Object* main_wind =
+ efl::WindowFactory::GetHostWindow(web_contents_.get());
+ if (!main_wind) {
+ LOG(ERROR) << "Can`t get main window";
+ return;
+ }
+ delegate->SetWindowId(main_wind);
+}
+
+void EWebView::SetPepperExtensionWidgetInfo(Ewk_Value widget_pepper_ext_info) {
+ EwkExtensionSystemDelegate* delegate = GetExtensionDelegate();
+ if (!delegate) {
+ LOG(WARNING) << "No delegate is available to set extension info";
+ return;
+ }
+ delegate->SetExtensionInfo(widget_pepper_ext_info);
+}
+
+void EWebView::SetPepperExtensionCallback(Generic_Sync_Call_Callback cb,
+ void* data) {
+ EwkExtensionSystemDelegate* delegate = GetExtensionDelegate();
+ if (!delegate) {
+ LOG(WARNING) << "No delegate is available to set generic callback";
+ return;
+ }
+ delegate->SetGenericSyncCallback(cb, data);
+}
+
+void EWebView::RegisterPepperExtensionDelegate() {
+ RenderFrameHost* render_frame_host = web_contents_->GetPrimaryMainFrame();
+ if (!render_frame_host) {
+ LOG(WARNING) << "render_frame_host is nullptr, can't register delegate";
+ return;
+ }
+
+ render_frame_id_.render_process_id = render_frame_host->GetProcess()->GetID();
+ render_frame_id_.render_frame_id = render_frame_host->GetRoutingID();
+
+ EwkExtensionSystemDelegate* delegate = new EwkExtensionSystemDelegate;
+ ExtensionSystemDelegateManager::GetInstance()->RegisterDelegate(
+ render_frame_id_, std::unique_ptr<EwkExtensionSystemDelegate>{delegate});
+}
+
+void EWebView::UnregisterPepperExtensionDelegate() {
+ if (!web_contents_) {
+ LOG(WARNING) << "web_contents_ is nullptr, can't unregister delegate";
+ return;
+ }
+ if (!ExtensionSystemDelegateManager::GetInstance()->UnregisterDelegate(render_frame_id_))
+ LOG(WARNING) << "Unregistering pepper extension delegate failed";
+}
+#endif // defined(TIZEN_PEPPER_EXTENSIONS)
+
void EWebView::SetExceededIndexedDatabaseQuotaCallback(
Ewk_View_Exceeded_Indexed_Database_Quota_Callback callback,
void* user_data) {
CHECK(!exceeded_indexed_db_quota_origin_.get());
exceeded_indexed_db_quota_origin_.reset(new Ewk_Security_Origin(origin));
exceeded_indexed_db_quota_callback_.Run(
- evas_object_, exceeded_indexed_db_quota_origin_.get(), current_quota);
+ ewk_view_, exceeded_indexed_db_quota_origin_.get(), current_quota);
}
void EWebView::ExceededIndexedDatabaseQuotaReply(bool allow) {
return app_control.Proceed();
}
+#if BUILDFLAG(IS_TIZEN_TV)
+void EWebView::AddDynamicCertificatePath(const std::string& host,
+ const std::string& cert_path) {
+ web_contents_->AddDynamicCertificatePath(host, cert_path);
+}
+
+void EWebView::NotifySubtitleState(int state, double time_stamp) {
+ LOG(INFO) << "subtitle state: " << state
+ << ",(0-Play : 1-Pause : 2-SeekStart : 3-SeekComplete : 4-Stop "
+ ":5-Resume)";
+ switch (state) {
+ case blink::WebMediaPlayer::kSubtitlePause:
+ SmartCallback<EWebViewCallbacks::SubtitlePause>().call();
+ break;
+ case blink::WebMediaPlayer::kSubtitleStop:
+ SmartCallback<EWebViewCallbacks::SubtitleStop>().call();
+ break;
+ case blink::WebMediaPlayer::kSubtitleResume:
+ SmartCallback<EWebViewCallbacks::SubtitleResume>().call();
+ break;
+ case blink::WebMediaPlayer::kSubtitleSeekStart: {
+ double ts = time_stamp;
+ SmartCallback<EWebViewCallbacks::SubtitleSeekStart>().call(&ts);
+ } break;
+ case blink::WebMediaPlayer::kSubtitleSeekComplete:
+ SmartCallback<EWebViewCallbacks::SubtitleSeekComplete>().call();
+ break;
+ default:
+ NOTREACHED();
+ break;
+ }
+}
+
+void EWebView::NotifySubtitlePlay(int active_track_id,
+ const char* url,
+ const char* lang) {
+ LOG(INFO) << "id:" << active_track_id << ",url:" << url << ",lang:" << lang;
+ Ewk_Media_Subtitle_Info* subtitle_info =
+ ewkMediaSubtitleInfoCreate(active_track_id, url, lang, 0);
+ SmartCallback<EWebViewCallbacks::SubtitlePlay>().call(
+ static_cast<void*>(subtitle_info));
+ ewkMediaSubtitleInfoDelete(subtitle_info);
+}
+
+void EWebView::NotifySubtitleData(int track_id,
+ double time_stamp,
+ const std::string& data,
+ unsigned int size) {
+ const void* buffer = static_cast<const void*>(data.c_str());
+ Ewk_Media_Subtitle_Data* subtitle_data =
+ ewkMediaSubtitleDataCreate(track_id, time_stamp, buffer, size);
+ SmartCallback<EWebViewCallbacks::SubtitleNotifyData>().call(
+ static_cast<void*>(subtitle_data));
+ ewkMediaSubtitleDataDelete(subtitle_data);
+}
+
+void EWebView::UpdateCurrentTime(double current_time) {
+ current_time_ = current_time;
+}
+
+void EWebView::UpdateEventData(void* data) {
+ LOG(INFO) << "EWebView::UpdateEventData data:" << (char*)data;
+ SmartCallback<EWebViewCallbacks::EVENTData>().call(data);
+}
+
+void EWebView::NotifyParentalRatingInfo(const char* info, const char* url) {
+ LOG(INFO) << "info:" << info << ",url:" << url;
+ Ewk_Media_Parental_Rating_Info* data =
+ ewkMediaParentalRatingInfoCreate(info, url);
+ SmartCallback<EWebViewCallbacks::ParentalRatingInfo>().call(
+ static_cast<void*>(data));
+ ewkMediaParentalRatingInfoDelete(data);
+}
+
+void EWebView::SetParentalRatingResult(const char* url, bool is_pass) {
+ LOG(INFO) << "SetParentalRatingResult,url:" << url
+ << ",pass:" << std::boolalpha << is_pass;
+
+ if (!rwhva() || !rwhva()->aura_efl_helper()){
+ LOG(ERROR) << "rwhva() or rwhva()->aura_efl_helper() is false";
+ return;
+ }
+ rwhva()->aura_efl_helper()->SetParentalRatingResult(
+ static_cast<std::string>(url), is_pass);
+}
+void EWebView::NotifyFirstTimeStamp(unsigned long long timestamp,
+ int time_base_num,
+ int time_base_den) {
+ Ewk_First_Timestamp_Info* info =
+ ewkFirstTimeStampInfoCreate(timestamp, time_base_num, time_base_den);
+ SmartCallback<EWebViewCallbacks::FirstTimestamp>().call(
+ static_cast<void*>(info));
+ ewkFirstTimeStampInfoDelete(info);
+}
+
+void EWebView::NotifyPESData(const std::string& buf,
+ unsigned int len,
+ int media_position) {
+ const void* data = static_cast<const void*>(buf.c_str());
+ Ewk_PES_Info* info = ewkPESInfoCreate(data, len, media_position);
+ SmartCallback<EWebViewCallbacks::PESData>().call(static_cast<void*>(info));
+ ewkPESInfoDelete(info);
+}
+
+void EWebView::SetPreferSubtitleLang(const char* lang_list) {
+ LOG(INFO) << "SetPreferSubtitleLang: " << lang_list;
+ const std::string lang(lang_list ? lang_list : "");
+
+ if (!rwhva()) {
+ LOG(ERROR) << "rwhva() is null";
+ return;
+ }
+
+ rwhva()->aura_efl_helper()->SetPreferSubtitleLang(lang);
+}
+#endif
+
bool EWebView::SetVisibility(bool enable) {
if (!web_contents_)
return false;
return true;
}
+void EWebView::SetDoNotTrack(Eina_Bool enable) {
+ // enable: 0 User tend to allow tracking on the target site.
+ // enable: 1 User tend to not be tracked on the target site.
+ if (web_contents_->GetMutableRendererPrefs()->enable_do_not_track == enable)
+ return;
+
+ // Set navigator.doNotTrack attribute
+ web_contents_->GetMutableRendererPrefs()->enable_do_not_track = enable;
+ web_contents_->SyncRendererPrefs();
+
+ // Set or remove DNT HTTP header, the effects will depend on design of target
+ // site.
+ if (!context())
+ return;
+
+ if (enable)
+ context()->HTTPCustomHeaderAdd("DNT", "1");
+ else
+ context()->HTTPCustomHeaderRemove("DNT");
+}
+
#if defined(TIZEN_ATK_SUPPORT)
void EWebView::UpdateSpatialNavigationStatus(Eina_Bool enable) {
if (settings_->getPreferences().spatial_navigation_enabled == enable)
}
void EWebView::InitAtk() {
+#if defined(TIZEN_ATK_SUPPORT)
EWebAccessibilityUtil::GetInstance()->ToggleAtk(lazy_initialize_atk_);
+#endif
}
/* LCOV_EXCL_START */
}
/* LCOV_EXCL_STOP */
#endif
+
+#if BUILDFLAG(IS_TIZEN_TV)
+bool EWebView::SetMixedContents(bool allow) {
+ MixedContentObserver* mixed_content_observer =
+ MixedContentObserver::FromWebContents(web_contents_.get());
+ return mixed_content_observer->MixedContentReply(allow);
+}
+
+void EWebView::NotifyDownloadableFontInfo(const char* scheme_id_uri,
+ const char* value,
+ const char* data,
+ int type) {
+ LOG(INFO) << "scheme_id_uri:" << scheme_id_uri << ",value:" << value
+ << ",data:" << data << ",type:" << type;
+ Ewk_Media_Downloadable_Font_Info* info =
+ ewkMediaDownloadableFontInfoCreate(scheme_id_uri, value, data, type);
+ SmartCallback<EWebViewCallbacks::DownloadableFontInfo>().call(
+ static_cast<void*>(info));
+ ewkMediaDownloadableFontInfoDelete(info);
+}
+
+std::vector<std::string> EWebView::NotifyPlaybackState(int state,
+ int player_id,
+ const char* url,
+ const char* mime_type) {
+ std::vector<std::string> data;
+ Ewk_Media_Playback_Info* playback_info =
+ ewkMediaPlaybackInfoCreate(player_id, url, mime_type);
+
+ LOG(INFO)
+ << "player_id:" << player_id << ",state: " << state
+ << "(0-load : 1-videoready : 2-ready : 3-start : 4-finish : 5-stop)";
+ switch (state) {
+ case kPlaybackLoad:
+ SmartCallback<EWebViewCallbacks::PlaybackLoad>().call(
+ static_cast<void*>(playback_info));
+ break;
+ case kPlaybackReady:
+ SmartCallback<EWebViewCallbacks::PlaybackReady>().call(
+ static_cast<void*>(playback_info));
+ break;
+ case kPlaybackStart:
+ SmartCallback<EWebViewCallbacks::PlaybackStart>().call(
+ static_cast<void*>(playback_info));
+ break;
+ case kPlaybackFinish:
+ SmartCallback<EWebViewCallbacks::PlaybackFinish>().call(
+ static_cast<void*>(playback_info));
+ break;
+ case kPlaybackStop:
+ SmartCallback<EWebViewCallbacks::PlaybackStop>().call(
+ static_cast<void*>(playback_info));
+ break;
+ default:
+ NOTREACHED();
+ data.push_back("");
+ ewkMediaPlaybackInfoDelete(playback_info);
+ return data;
+ }
+
+ bool media_resource_acquired =
+ ewk_media_playback_info_media_resource_acquired_get(playback_info)
+ ? true
+ : false;
+ data.push_back(media_resource_acquired ? "mediaResourceAcquired" : "");
+ const char* translated_url =
+ ewk_media_playback_info_translated_url_get(playback_info);
+ data.push_back(translated_url ? std::string(translated_url) : "");
+ const char* drm_info = ewk_media_playback_info_drm_info_get(playback_info);
+ data.push_back(drm_info ? std::string(drm_info) : "");
+
+ LOG(INFO) << "evasObject: " << ewk_view_
+ << ", media_resource_acquired :" << media_resource_acquired
+ << ", translated_url:" << translated_url
+ << ", drm_info:" << drm_info;
+ ewkMediaPlaybackInfoDelete(playback_info);
+ return data;
+}
+
+void EWebView::NotifyMediaStateChanged(uint32_t device_type,
+ uint32_t previous,
+ uint32_t current) {
+ LOG(INFO) << "NotifyMediaStateChanged type : " << device_type
+ << " ;previous: " << previous << " ; current: " << current;
+ Ewk_User_Media_State_Info* user_media_state_info =
+ new _Ewk_User_Media_State_Info;
+ user_media_state_info->device_type =
+ static_cast<Ewk_User_Media_Device_Type>(device_type);
+ user_media_state_info->previous_state = previous;
+ user_media_state_info->current_state = current;
+ SmartCallback<EWebViewCallbacks::UserMediaState>().call(
+ static_cast<void*>(user_media_state_info));
+
+ delete user_media_state_info;
+}
+
+void EWebView::SetHighBitRate(Eina_Bool high_bitrate) {
+ LOG(INFO) << "high_bitrate: " << std::boolalpha << high_bitrate;
+ is_high_bitrate_ = high_bitrate;
+}
+
+void EWebView::OnDeviceListed(const MediaDeviceEnumeration& devices) {
+ int device_count = 0;
+ EwkMediaDeviceInfo* device_list = nullptr;
+ for (const auto& device : devices)
+ device_count += device.size();
+
+ device_list =
+ (EwkMediaDeviceInfo*)malloc(sizeof(EwkMediaDeviceInfo) * device_count);
+ if (!device_list) {
+ LOG(ERROR) << "malloc EwkMediaDeviceInfo failed";
+ device_cb_.Run(device_list, 0);
+ return;
+ }
+
+ int idx = 0;
+ for (int i = 0; i < NUM_MEDIA_DEVICE_TYPES; i++) {
+ blink::WebMediaDeviceInfoArray array = devices[i];
+ for (const auto& device : array) {
+ LOG(INFO) << "OnDeviceListed type:" << i
+ << ",device_id:" << device.device_id
+ << ",lable:" << device.label;
+
+ // convert device info to ewk structure
+ EwkMediaDeviceInfo* data = &device_list[idx++];
+ data->device_id = eina_stringshare_add(device.device_id.c_str());
+ data->label = eina_stringshare_add(device.label.c_str());
+ data->type = static_cast<EwkMediaDeviceType>(i);
+ data->connected = true;
+ }
+ }
+
+ device_cb_.Run(device_list, device_count);
+
+ // free data
+ for (int i = 0; i < device_count; i++) {
+ EwkMediaDeviceInfo* device = &device_list[i];
+ if (device->device_id)
+ eina_stringshare_del(device->device_id);
+ if (device->label)
+ eina_stringshare_del(device->label);
+ }
+ if (device_list) {
+ free(device_list);
+ device_list = NULL;
+ }
+}
+
+void EWebView::GetMediaDeviceList(Ewk_Media_Device_List_Get_Callback callback,
+ void* userData) {
+ if (!web_contents_delegate_) {
+ LOG(ERROR) << "no web_contents_delegate_";
+ return;
+ }
+
+ device_cb_.Set(callback, userData);
+
+ web_contents_delegate_->GetMediaDeviceList(
+ base::BindOnce(&EWebView::OnDeviceListed, weak_factory_.GetWeakPtr()));
+}
+#endif