2 * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #include "runtime/browser/web_view_impl.h"
23 #include "common/file_utils.h"
24 #include "common/logger.h"
25 #include "common/profiler.h"
26 #include "runtime/browser/native_window.h"
32 const char* kKeyNameBack = "back";
33 const char* kKeyNameMenu = "menu";
34 const char* kDefaultEncoding = "UTF-8";
35 const char* kSmartClassUserDataKey = "__SC_USERDATA__";
37 static int ToWebRotation(int r) {
47 static NativeWindow::ScreenOrientation ToNativeRotation(int r) {
49 (EWK_SCREEN_ORIENTATION_PORTRAIT_PRIMARY
50 | EWK_SCREEN_ORIENTATION_PORTRAIT_SECONDARY
51 | EWK_SCREEN_ORIENTATION_LANDSCAPE_PRIMARY
52 | EWK_SCREEN_ORIENTATION_LANDSCAPE_SECONDARY)) {
53 return NativeWindow::ScreenOrientation::ANY;
55 (EWK_SCREEN_ORIENTATION_PORTRAIT_PRIMARY
56 | EWK_SCREEN_ORIENTATION_LANDSCAPE_PRIMARY)) {
57 return NativeWindow::ScreenOrientation::NATURAL;
58 } else if (r & EWK_SCREEN_ORIENTATION_PORTRAIT_PRIMARY) {
59 return NativeWindow::ScreenOrientation::PORTRAIT_PRIMARY;
60 } else if (r & EWK_SCREEN_ORIENTATION_PORTRAIT_SECONDARY) {
61 return NativeWindow::ScreenOrientation::PORTRAIT_SECONDARY;
62 } else if (r & EWK_SCREEN_ORIENTATION_LANDSCAPE_PRIMARY) {
63 return NativeWindow::ScreenOrientation::LANDSCAPE_PRIMARY;
65 return NativeWindow::ScreenOrientation::LANDSCAPE_SECONDARY;
71 WebViewImpl::WebViewImpl(WebView* view,
78 rotation_handler_id_(0),
81 evas_smart_class_(NULL),
82 internal_popup_opened_(false),
88 WebViewImpl::~WebViewImpl() {
89 if (internal_popup_opened_) {
90 internal_popup_opened_ = false;
91 ewk_view_javascript_alert_reply(ewk_view_);
94 evas_object_del(ewk_view_);
95 if (evas_smart_class_ != NULL)
96 evas_smart_free(evas_smart_class_);
99 void WebViewImpl::ReplyToJavascriptDialog() {
100 if (internal_popup_opened_) {
101 internal_popup_opened_ = false;
102 ewk_view_javascript_alert_reply(ewk_view_);
106 void WebViewImpl::LoadUrl(const std::string& url, const std::string& mime) {
109 mime_set_cb_ = [url, mime]
110 (const char* request_url, const char* request_mime,
111 char** new_mime, void* data) {
112 WebViewImpl* view = static_cast<WebViewImpl*>(data);
113 if (view != nullptr &&
114 common::utils::BaseName(url) ==
115 common::utils::BaseName(request_url)) {
116 *new_mime = strdup(mime.c_str());
117 LOGGER(DEBUG) << "ewk's new_mime: " << *new_mime;
122 auto mime_override_cb = [](const char* url, const char* mime,
123 char** new_mime, void* data) -> Eina_Bool {
124 WebViewImpl* view = static_cast<WebViewImpl*>(data);
125 return view->mime_set_cb_(url, mime, new_mime, data);
127 ewk_context_mime_override_callback_set(context_, mime_override_cb, this);
129 // In order to prevent crash issue, the callback should be released
130 // when the mime is empty.
131 ewk_context_mime_override_callback_set(context_, nullptr, nullptr);
133 ewk_view_url_set(ewk_view_, url.c_str());
136 void WebViewImpl::Suspend() {
138 ewk_view_suspend(ewk_view_);
141 void WebViewImpl::Resume() {
143 ewk_view_resume(ewk_view_);
146 void WebViewImpl::Reload() {
147 ewk_view_reload(ewk_view_);
150 bool WebViewImpl::Backward() {
151 if (ewk_view_back_possible(ewk_view_)) {
152 ewk_view_back(ewk_view_);
158 void WebViewImpl::SetVisibility(bool show) {
159 ewk_view_page_visibility_state_set(ewk_view_,
160 show ? EWK_PAGE_VISIBILITY_STATE_VISIBLE :
161 EWK_PAGE_VISIBILITY_STATE_HIDDEN,
166 bool WebViewImpl::EvalJavascript(const std::string& script) {
167 return ewk_view_script_execute(ewk_view_, script.c_str(), NULL, NULL);
170 void WebViewImpl::Initialize() {
171 ewk_smart_class_ = EWK_VIEW_SMART_CLASS_INIT_NAME_VERSION("WebView");
172 ewk_view_smart_class_set(&ewk_smart_class_);
173 ewk_smart_class_.orientation_lock = [](Ewk_View_Smart_Data *sd,
175 WebViewImpl* self = static_cast<WebViewImpl*>(
176 evas_object_data_get(sd->self, kSmartClassUserDataKey));
177 if (self == NULL || self->listener_ == NULL)
179 self->listener_->OnOrientationLock(self->view_,
181 ToNativeRotation(orientation));
185 ewk_smart_class_.orientation_unlock = [](Ewk_View_Smart_Data *sd) {
186 WebViewImpl* self = static_cast<WebViewImpl*>(
187 evas_object_data_get(sd->self, kSmartClassUserDataKey));
188 if (self == NULL || self->listener_ == NULL)
190 self->listener_->OnOrientationLock(
193 NativeWindow::ScreenOrientation::PORTRAIT_PRIMARY);
196 if (evas_smart_class_ != NULL)
197 evas_smart_free(evas_smart_class_);
198 evas_smart_class_ = evas_smart_class_new(&ewk_smart_class_.sc);
199 if (evas_smart_class_ == NULL) {
200 LOGGER(ERROR) << "Can't create evas smart class";
204 Ewk_Page_Group* page_group = ewk_page_group_create("");
205 ewk_view_ = ewk_view_smart_add(evas_object_evas_get(window_->evas_object()),
209 evas_object_data_set(ewk_view_, kSmartClassUserDataKey, this);
212 InitLoaderCallback();
213 InitPolicyDecideCallback();
214 InitQuotaExceededCallback();
215 InitIPCMessageCallback();
216 InitConsoleMessageCallback();
217 InitCustomContextMenuCallback();
218 InitRotationCallback();
219 InitWindowCreateCallback();
220 InitFullscreenCallback();
221 InitNotificationPermissionCallback();
222 InitGeolocationPermissionCallback();
223 InitAuthenticationCallback();
224 InitCertificateAllowCallback();
225 InitPopupWaitCallback();
226 InitUsermediaCallback();
227 InitEditorClientImeCallback();
228 #ifdef ROTARY_EVENT_FEATURE_SUPPORT
229 InitRotaryEventCallback();
230 #endif // ROTARY_EVENT_FEATURE_SUPPORT
232 Ewk_Settings* settings = ewk_view_settings_get(ewk_view_);
233 ewk_settings_scripts_can_open_windows_set(settings, EINA_TRUE);
234 #ifndef PROFILE_WEARABLE
235 ewk_settings_form_candidate_data_enabled_set(settings, EINA_TRUE);
237 ewk_settings_default_text_encoding_name_set(settings, kDefaultEncoding);
239 // TODO(sngn.lee): "protocolhandler,registration,requested"
240 // custom protocol handler
243 evas_object_show(ewk_view_);
246 void WebViewImpl::Deinitialize() {
247 auto it = smart_callbacks_.begin();
248 for ( ; it != smart_callbacks_.end(); ++it) {
249 evas_object_smart_callback_del(
254 eext_object_event_callback_del(ewk_view_,
256 smart_callbacks_["key_callback"]);
257 ewk_view_exceeded_database_quota_callback_set(
261 ewk_view_exceeded_indexed_database_quota_callback_set(
265 ewk_view_exceeded_local_file_system_quota_callback_set(
269 ewk_view_notification_permission_callback_set(
273 ewk_view_geolocation_permission_callback_set(
277 ewk_view_user_media_permission_callback_set(
281 window_->RemoveRotationHandler(rotation_handler_id_);
284 void WebViewImpl::InitKeyCallback() {
285 auto key_callback = [](void* user_data,
286 Evas_Object* /*obj*/,
287 void* event_info) -> void {
288 WebViewImpl* self = static_cast<WebViewImpl*>(user_data);
289 Eext_Callback_Type key = static_cast<Eext_Callback_Type>(
290 reinterpret_cast<long long>(event_info)); // NOLINT
291 self->OnKeyEvent(key);
293 eext_object_event_callback_add(ewk_view_,
297 eext_object_event_callback_add(ewk_view_,
301 smart_callbacks_["key_callback"] = key_callback;
304 void WebViewImpl::InitLoaderCallback() {
305 // load statred callback
306 auto loadstart_callback = [](void* user_data,
307 Evas_Object* /*obj*/,
309 WebViewImpl* self = static_cast<WebViewImpl*>(user_data);
311 self->listener_->OnLoadStart(self->view_);
313 evas_object_smart_callback_add(ewk_view_,
317 // load finished callback
318 auto loadfinished_callback = [](void* user_data,
321 WebViewImpl* self = static_cast<WebViewImpl*>(user_data);
323 self->listener_->OnLoadFinished(self->view_);
325 evas_object_smart_callback_add(ewk_view_,
327 loadfinished_callback,
330 // load progress callback
331 auto loadprogress_callback = [](void* user_data,
334 WebViewImpl* self = static_cast<WebViewImpl*>(user_data);
335 double* progress = static_cast<double*>(event_info);
337 self->listener_->OnLoadProgress(self->view_, *progress);
339 evas_object_smart_callback_add(ewk_view_,
341 loadprogress_callback,
344 auto rendered_callback = [](void* user_data,
347 WebViewImpl* self = static_cast<WebViewImpl*>(user_data);
349 self->listener_->OnRendered(self->view_);
351 evas_object_smart_callback_add(ewk_view_,
355 smart_callbacks_["load,started"] = loadstart_callback;
356 smart_callbacks_["load,finished"] = loadfinished_callback;
357 smart_callbacks_["load,progress"] = loadprogress_callback;
358 smart_callbacks_["frame,rendered"] = rendered_callback;
360 #ifdef MANUAL_ROTATE_FEATURE_SUPPORT
361 // rotate prepared callback
362 auto rotateprepared_callback = [](void* user_data,
365 WebViewImpl* self = static_cast<WebViewImpl*>(user_data);
367 self->listener_->OnRotatePrepared(self->view_);
369 evas_object_smart_callback_add(ewk_view_,
371 rotateprepared_callback,
373 smart_callbacks_["rotate,prepared"] = rotateprepared_callback;
374 #endif // MANUAL_ROTATE_FEATURE_SUPPORT
377 void WebViewImpl::InitPolicyDecideCallback() {
378 // "policy,navigation,decide"
379 auto navigation_decide_callback = [](void* user_data,
382 WebViewImpl* self = static_cast<WebViewImpl*>(user_data);
383 Ewk_Policy_Decision* policy =
384 static_cast<Ewk_Policy_Decision*>(event_info);
385 const char* url = ewk_policy_decision_url_get(policy);
387 if (self->listener_) {
388 if (self->listener_->OnDidNavigation(self->view_, url))
389 ewk_policy_decision_use(policy);
391 ewk_policy_decision_ignore(policy);
393 ewk_policy_decision_use(policy);
396 evas_object_smart_callback_add(ewk_view_,
397 "policy,navigation,decide",
398 navigation_decide_callback,
401 // policy,newwindow,decide
402 auto newwindow_decide_callback = [](void* user_data,
405 WebViewImpl* self = static_cast<WebViewImpl*>(user_data);
406 Ewk_Policy_Decision* policy =
407 static_cast<Ewk_Policy_Decision*>(event_info);
409 const char* url = ewk_policy_decision_url_get(policy);
411 if (self->listener_) {
412 if (self->listener_->OnDidNavigation(self->view_, url) &&
413 self->listener_->OnDidOpenWindow(self->view_, url)) {
414 ewk_policy_decision_use(policy);
416 ewk_policy_decision_ignore(policy);
419 ewk_policy_decision_use(policy);
422 evas_object_smart_callback_add(ewk_view_,
423 "policy,newwindow,decide",
424 newwindow_decide_callback,
426 smart_callbacks_["policy,navigation,decide"] = navigation_decide_callback;
427 smart_callbacks_["policy,newwindow,decide"] = newwindow_decide_callback;
430 void WebViewImpl::InitQuotaExceededCallback() {
431 // TODO(sngn.lee): Need callback interface - OnQutaExceed
432 // check http://tizen.org/privilege/unlimitedstorage
434 // callback for database quota exceeded
435 auto database_exceeded_callback = [](Evas_Object* view,
436 Ewk_Security_Origin* origin,
438 unsigned long long, // NOLINT
439 void* user_data) -> Eina_Bool {
440 WebViewImpl* self = static_cast<WebViewImpl*>(user_data);
441 if (self == NULL || self->listener_ == NULL)
444 auto result_handler = [view](bool result) {
445 LOGGER(DEBUG) << "database quota Permission Result : " << result;
446 ewk_view_exceeded_database_quota_reply(view, result);
448 std::stringstream url;
449 url << ewk_security_origin_protocol_get(origin)
451 << ewk_security_origin_host_get(origin)
453 << ewk_security_origin_port_get(origin);
454 self->listener_->OnQuotaExceed(
460 ewk_view_exceeded_database_quota_callback_set(
462 database_exceeded_callback,
465 // callback for indexed database quota exceeded
466 auto indexed_db_exceeded_callback = [](Evas_Object* view,
467 Ewk_Security_Origin* origin,
469 void* user_data) -> Eina_Bool {
470 WebViewImpl* self = static_cast<WebViewImpl*>(user_data);
471 if (self == NULL || self->listener_ == NULL)
474 auto result_handler = [view](bool result) {
475 LOGGER(DEBUG) << "indexed db quota Permission Result : " << result;
476 ewk_view_exceeded_indexed_database_quota_reply(view, result);
478 std::stringstream url;
479 url << ewk_security_origin_protocol_get(origin)
481 << ewk_security_origin_host_get(origin)
483 << ewk_security_origin_port_get(origin);
484 self->listener_->OnQuotaExceed(
490 ewk_view_exceeded_indexed_database_quota_callback_set(
492 indexed_db_exceeded_callback,
495 // callback for localfile quota exceeded
496 auto localfile_exceeded_callback = [](Evas_Object* view,
497 Ewk_Security_Origin* origin,
499 void* user_data) -> Eina_Bool {
500 WebViewImpl* self = static_cast<WebViewImpl*>(user_data);
501 if (self == NULL || self->listener_ == NULL)
504 auto result_handler = [view](bool result) {
505 LOGGER(DEBUG) << "local file quota Permission Result : " << result;
506 ewk_view_exceeded_local_file_system_quota_reply(view, result);
508 std::stringstream url;
509 url << ewk_security_origin_protocol_get(origin)
511 << ewk_security_origin_host_get(origin)
513 << ewk_security_origin_port_get(origin);
514 self->listener_->OnQuotaExceed(
520 ewk_view_exceeded_local_file_system_quota_callback_set(
522 localfile_exceeded_callback,
526 void WebViewImpl::InitIPCMessageCallback() {
528 auto wrt_message_callback = [](void* user_data,
531 WebViewImpl* self = static_cast<WebViewImpl*>(user_data);
532 Ewk_IPC_Wrt_Message_Data* msg =
533 static_cast<Ewk_IPC_Wrt_Message_Data*>(event_info);
535 self->listener_->OnReceivedWrtMessage(self->view_, msg);
537 evas_object_smart_callback_add(ewk_view_,
539 wrt_message_callback,
541 smart_callbacks_["wrt,message"] = wrt_message_callback;
544 void WebViewImpl::InitConsoleMessageCallback() {
546 auto console_message_callback = [](void* user_data,
549 WebViewImpl* self = static_cast<WebViewImpl*>(user_data);
550 if (!self->listener_) {
553 Ewk_Console_Message* msg = static_cast<Ewk_Console_Message*>(event_info);
554 unsigned int line_number = ewk_console_message_line_get(msg);
556 std::stringstream buf;
558 buf << ewk_console_message_source_get(msg)
559 << ":" << line_number << ": ";
561 buf << ewk_console_message_text_get(msg);
562 int level = ewk_console_message_level_get(msg);
563 self->listener_->OnConsoleMessage(buf.str(), level);
565 evas_object_smart_callback_add(ewk_view_,
567 console_message_callback,
569 smart_callbacks_["console,message"] = console_message_callback;
572 void WebViewImpl::InitCustomContextMenuCallback() {
573 auto custom_context_menu_callback = [](void* user_data,
576 Ewk_Context_Menu* contextmenu = static_cast<Ewk_Context_Menu*>(event_info);
577 WebViewImpl* self = static_cast<WebViewImpl*>(user_data);
578 bool disabled = false;
579 if (self->listener_ &&
580 self->listener_->OnContextMenuDisabled(self->view_)) {
583 int cnt = ewk_context_menu_item_count(contextmenu);
584 for (int idx = cnt-1; idx >= 0; --idx) {
585 auto* item = ewk_context_menu_nth_item_get(contextmenu, idx);
586 Ewk_Context_Menu_Item_Tag tag = ewk_context_menu_item_tag_get(item);
588 case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_IMAGE_IN_CURRENT_WINDOW:
589 case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_LINK:
590 case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_IMAGE_IN_NEW_WINDOW:
591 case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_LINK_IN_NEW_WINDOW:
592 case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_FRAME_IN_NEW_WINDOW:
593 case EWK_CONTEXT_MENU_ITEM_TAG_SEARCH_WEB:
594 case EWK_CONTEXT_MENU_ITEM_TAG_DOWNLOAD_IMAGE_TO_DISK:
595 case EWK_CONTEXT_MENU_ITEM_TAG_DOWNLOAD_LINK_TO_DISK:
596 ewk_context_menu_item_remove(contextmenu, item);
600 ewk_context_menu_item_remove(contextmenu, item);
604 evas_object_smart_callback_add(ewk_view_,
605 "contextmenu,customize",
606 custom_context_menu_callback,
608 smart_callbacks_["contextmenu,customize"] = custom_context_menu_callback;
611 void WebViewImpl::InitRotationCallback() {
613 ewk_view_orientation_send(ewk_view_, ToWebRotation(window_->rotation()));
614 rotation_handler_id_ = window_->AddRotationHandler(
615 std::bind(&WebViewImpl::OnRotation,
617 std::placeholders::_1));
620 void WebViewImpl::InitWindowCreateCallback() {
621 auto create_callback = [](void* user_data,
624 WebViewImpl* self = static_cast<WebViewImpl*>(user_data);
625 if (!self->listener_) {
628 WebView* new_view = new WebView(self->window_, self->context_);
629 self->listener_->OnCreatedNewWebView(self->view_, new_view);
630 *(static_cast<Evas_Object **>(event_info)) = new_view->evas_object();
633 auto close_callback = [](void* user_data,
636 LOGGER(DEBUG) << "close_callback is called";
637 WebViewImpl* self = static_cast<WebViewImpl*>(user_data);
638 if (!self->listener_) {
641 self->listener_->OnClosedWebView(self->view_);
643 evas_object_smart_callback_add(ewk_view_,
647 evas_object_smart_callback_add(ewk_view_,
652 smart_callbacks_["create,window"] = create_callback;
653 smart_callbacks_["close,window"] = close_callback;
656 void WebViewImpl::InitFullscreenCallback() {
657 auto enter_callback = [](void* user_data,
659 void* /*event_info*/) {
660 WebViewImpl* self = static_cast<WebViewImpl*>(user_data);
661 self->fullscreen_ = true;
662 self->window_->FullScreen(true);
664 auto exit_callback = [](void* user_data,
666 void* /*event_info*/) {
667 WebViewImpl* self = static_cast<WebViewImpl*>(user_data);
668 self->fullscreen_ = false;
669 self->window_->FullScreen(false);
671 evas_object_smart_callback_add(ewk_view_,
672 "fullscreen,enterfullscreen",
675 evas_object_smart_callback_add(ewk_view_,
676 "fullscreen,exitfullscreen",
679 smart_callbacks_["fullscreen,enterfullscreen"] = enter_callback;
680 smart_callbacks_["fullscreen,exitfullscreen"] = exit_callback;
683 void WebViewImpl::InitNotificationPermissionCallback() {
684 auto request_callback = [](Evas_Object*,
685 Ewk_Notification_Permission_Request* request,
687 LOGGER(DEBUG) << "Notification Permission Request";
688 WebViewImpl* self = static_cast<WebViewImpl*>(user_data);
689 if (!self->listener_) {
690 ewk_notification_permission_reply(request, EINA_FALSE);
694 ewk_notification_permission_request_suspend(request);
695 auto result_handler = [request](bool result) {
696 LOGGER(DEBUG) << "Notification Permission Result : %d" << result;
697 ewk_notification_permission_reply(request, result);
699 const Ewk_Security_Origin* ewk_origin =
700 ewk_notification_permission_request_origin_get(request);
702 std::stringstream url;
703 url << ewk_security_origin_protocol_get(ewk_origin)
705 << ewk_security_origin_host_get(ewk_origin)
707 << ewk_security_origin_port_get(ewk_origin);
708 self->listener_->OnNotificationPermissionRequest(
714 ewk_view_notification_permission_callback_set(ewk_view_,
719 void WebViewImpl::InitGeolocationPermissionCallback() {
720 auto permission_callback = [](
722 Ewk_Geolocation_Permission_Request* request,
724 LOGGER(DEBUG) << "Geolocation Permission Request";
725 WebViewImpl* self = static_cast<WebViewImpl*>(user_data);
726 if (self == NULL || self->listener_ == NULL) {
727 ewk_geolocation_permission_reply(request, EINA_FALSE);
730 ewk_geolocation_permission_request_suspend(request);
732 const Ewk_Security_Origin* ewk_origin =
733 ewk_geolocation_permission_request_origin_get(request);
734 auto result_handler = [request](bool result) {
735 LOGGER(DEBUG) << "Geolocation Permission Result : " << result;
736 ewk_geolocation_permission_reply(request, result);
739 std::stringstream url;
740 url << ewk_security_origin_protocol_get(ewk_origin)
742 << ewk_security_origin_host_get(ewk_origin)
744 << ewk_security_origin_port_get(ewk_origin);
746 self->listener_->OnGeolocationPermissionRequest(
752 ewk_view_geolocation_permission_callback_set(ewk_view_,
757 void WebViewImpl::InitAuthenticationCallback() {
758 auto auth_callback = [](void* user_data,
761 LOGGER(DEBUG) << "Authentication Request";
762 WebViewImpl* self = static_cast<WebViewImpl*>(user_data);
763 Ewk_Auth_Challenge* auth_challenge =
764 static_cast<Ewk_Auth_Challenge*>(event_info);
766 if (self == NULL || self->listener_ == NULL) {
767 ewk_auth_challenge_credential_cancel(auth_challenge);
770 auto result_handler = [auth_challenge](bool submit,
771 const std::string& id,
772 const std::string& password) {
773 LOGGER(DEBUG) << "Authentication Result : submit = " << submit;
775 ewk_auth_challenge_credential_cancel(auth_challenge);
778 ewk_auth_challenge_credential_use(auth_challenge,
782 ewk_auth_challenge_suspend(auth_challenge);
783 const char* message =
784 ewk_auth_challenge_realm_get(auth_challenge);
785 std::string url = self->GetUrl();
786 self->listener_->OnAuthenticationRequest(self->view_,
791 // "authentication,challenge"
792 evas_object_smart_callback_add(ewk_view_,
793 "authentication,challenge",
796 smart_callbacks_["authentication,challenge"] = auth_callback;
799 void WebViewImpl::InitCertificateAllowCallback() {
800 auto certi_callback = [](void* user_data,
803 WebViewImpl* self = static_cast<WebViewImpl*>(user_data);
804 Ewk_Certificate_Policy_Decision* policy =
805 static_cast<Ewk_Certificate_Policy_Decision*>(event_info);
807 if (self == NULL || self->listener_ == NULL) {
808 ewk_certificate_policy_decision_allowed_set(policy, EINA_FALSE);
812 ewk_certificate_policy_decision_suspend(policy);
813 auto result_handler = [policy](bool allow) {
814 ewk_certificate_policy_decision_allowed_set(policy, allow);
817 auto ptr = ewk_certificate_policy_decision_url_get(policy);
818 std::string url(ptr ? ptr : "");
819 ptr = ewk_certificate_policy_decision_certificate_pem_get(policy);
820 std::string pem(ptr ? ptr : "");
821 self->listener_->OnCertificateAllowRequest(self->view_,
826 evas_object_smart_callback_add(ewk_view_,
827 "request,certificate,confirm",
830 smart_callbacks_["request,certificate,confirm"] = certi_callback;
833 void WebViewImpl::InitPopupWaitCallback() {
834 evas_object_smart_callback_add(ewk_view_,
835 "popup,reply,wait,start",
836 [](void* user_data, Evas_Object* /*obj*/, void*) {
837 WebViewImpl* self = static_cast<WebViewImpl*>(user_data);
838 self->internal_popup_opened_ = true;
839 #ifdef MANUAL_ROTATE_FEATURE_SUPPORT
840 self->window_->EnableManualRotation(false);
841 #endif // MANUAL_ROTATE_FEATURE_SUPPORT
843 evas_object_smart_callback_add(ewk_view_,
844 "popup,reply,wait,finish",
845 [](void* user_data, Evas_Object* /*obj*/, void*) {
846 WebViewImpl* self = static_cast<WebViewImpl*>(user_data);
847 self->internal_popup_opened_ = false;
848 #ifdef MANUAL_ROTATE_FEATURE_SUPPORT
849 self->window_->EnableManualRotation(true);
850 #endif // MANUAL_ROTATE_FEATURE_SUPPORT
854 void WebViewImpl::InitUsermediaCallback() {
855 auto callback = [](Evas_Object*,
856 Ewk_User_Media_Permission_Request* request,
858 WebViewImpl* self = static_cast<WebViewImpl*>(user_data);
859 if (self == NULL || self->listener_ == NULL) {
860 ewk_user_media_permission_reply(request, EINA_FALSE);
864 ewk_user_media_permission_request_suspend(request);
865 const Ewk_Security_Origin* origin =
866 ewk_user_media_permission_request_origin_get(request);
867 std::stringstream url;
868 url << ewk_security_origin_protocol_get(origin)
870 << ewk_security_origin_host_get(origin)
872 << ewk_security_origin_port_get(origin);
874 auto result_handler = [request](bool result) {
875 LOGGER(DEBUG) << "Getusermedia Permission Result : " << result;
876 ewk_user_media_permission_reply(request, result);
878 self->listener_->OnUsermediaPermissionRequest(self->view_,
883 ewk_view_user_media_permission_callback_set(ewk_view_, callback, this);
886 void WebViewImpl::InitEditorClientImeCallback() {
887 auto ime_changed_callback = [](void* user_data,
890 WebViewImpl* self = static_cast<WebViewImpl*>(user_data);
892 Eina_Rectangle *rect = static_cast<Eina_Rectangle *>(event_info);
893 self->ime_width_ = rect->w;
894 self->ime_height_ = rect->h;
897 auto ime_opened_callback = [](void* user_data,
900 WebViewImpl* self = static_cast<WebViewImpl*>(user_data);
901 if (!self->listener_)
904 SoftKeyboardChangeEventValue softkeyboard_value;
905 softkeyboard_value.state = "on";
906 softkeyboard_value.width = self->ime_width_;
907 softkeyboard_value.height = self->ime_height_;
909 self->listener_->OnSoftKeyboardChangeEvent(self->view_, softkeyboard_value);
912 auto ime_closed_callback = [](void* user_data,
915 WebViewImpl* self = static_cast<WebViewImpl*>(user_data);
916 if (!self->listener_)
919 SoftKeyboardChangeEventValue softkeyboard_value;
920 softkeyboard_value.state = "off";
922 self->listener_->OnSoftKeyboardChangeEvent(self->view_, softkeyboard_value);
924 evas_object_smart_callback_add(ewk_view_,
925 "inputmethod,changed",
926 ime_changed_callback,
928 evas_object_smart_callback_add(ewk_view_,
929 "editorclient,ime,opened",
932 evas_object_smart_callback_add(ewk_view_,
933 "editorclient,ime,closed",
936 smart_callbacks_["inputmethod,changed"] = ime_changed_callback;
937 smart_callbacks_["editorclient,ime,opened"] = ime_opened_callback;
938 smart_callbacks_["editorclient,ime,closed"] = ime_closed_callback;
941 #ifdef ROTARY_EVENT_FEATURE_SUPPORT
942 void WebViewImpl::InitRotaryEventCallback() {
943 auto rotary_callback = [](void* user_data,
945 Eext_Rotary_Event_Info* event_info) -> Eina_Bool {
946 WebViewImpl* self = static_cast<WebViewImpl*>(user_data);
947 if (!self->listener_)
950 Eext_Rotary_Event_Info* rotary = event_info;
952 RotaryEventType type;
953 if (rotary->direction == EEXT_ROTARY_DIRECTION_CLOCKWISE)
954 type = RotaryEventType::CLOCKWISE;
956 type = RotaryEventType::COUNTER_CLOCKWISE;
958 self->listener_->OnRotaryEvent(self->view_, type);
962 // add callback to handle rotary event
963 eext_rotary_object_event_callback_add(ewk_view_, rotary_callback, this);
964 eext_rotary_object_event_activated_set(ewk_view_, EINA_TRUE);
966 #endif // ROTARY_EVENT_FEATURE_SUPPORT
968 std::string WebViewImpl::GetUrl() {
969 return std::string(ewk_view_url_get(ewk_view_));
972 Evas_Object* WebViewImpl::evas_object() const {
976 void WebViewImpl::OnRotation(int degree) {
977 ewk_view_orientation_send(ewk_view_, ToWebRotation(degree));
980 void WebViewImpl::OnKeyEvent(Eext_Callback_Type key_type) {
982 if (key_type == EEXT_CALLBACK_BACK) {
984 ewk_view_fullscreen_exit(ewk_view_);
987 if (EINA_TRUE == ewk_view_text_selection_clear(ewk_view_)) {
990 keyname = kKeyNameBack;
991 } else if (key_type == EEXT_CALLBACK_MORE) {
992 keyname = kKeyNameMenu;
997 if (listener_ && !internal_popup_opened_) {
998 listener_->OnHardwareKey(view_, keyname);
1002 void WebViewImpl::SetEventListener(WebView::EventListener* listener) {
1003 listener_ = listener;
1006 void WebViewImpl::SetAppInfo(const std::string& app_name,
1007 const std::string& version) {
1008 std::string ua = app_name + "/" + version;
1009 ewk_view_application_name_for_user_agent_set(ewk_view_, ua.c_str());
1011 bool WebViewImpl::SetUserAgent(const std::string& user_agent) {
1012 return ewk_view_user_agent_set(ewk_view_, user_agent.c_str());
1015 void WebViewImpl::SetCSPRule(const std::string& rule, bool report_only) {
1016 ewk_view_content_security_policy_set(
1019 report_only ? EWK_REPORT_ONLY : EWK_ENFORCE_POLICY);
1022 void WebViewImpl::SetDefaultEncoding(const std::string& encoding) {
1023 if (ewk_settings_is_encoding_valid(encoding.c_str())) {
1024 Ewk_Settings* settings = ewk_view_settings_get(ewk_view_);
1025 ewk_settings_default_text_encoding_name_set(settings, encoding.c_str());
1029 void WebViewImpl::SetLongPolling(unsigned long longpolling) {
1030 ewk_view_session_timeout_set(ewk_view_, longpolling);
1033 #ifdef PROFILE_WEARABLE
1034 void WebViewImpl::SetBGColor(int r, int g, int b, int a) {
1035 ewk_view_bg_color_set(ewk_view_, r, g, b, a);
1039 } // namespace runtime