2 * Copyright (c) 2011 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.
17 * @file view_logic.cpp
18 * @author Pawel Sikorski (p.sikorsk@samsung.com)
19 * @author Lukasz Wrzosek (l.wrzosek@samsung.com)
20 * @author Yunchan Cho (yunchan.cho@samsung.com)
21 * @brief View logic for Webkit2
23 #include "view_logic.h"
27 #include <dpl/assert.h>
28 #include <dpl/log/log.h>
29 #include <dpl/optional.h>
30 #include <dpl/string.h>
31 #include <dpl/foreach.h>
33 #include <Elementary.h>
34 #include <efl_assist.h>
37 #include <widget_model.h>
38 #include <dpl/log/secure_log.h>
39 #include <system_settings.h>
40 #include <dpl/wrt-dao-ro/widget_dao_read_only.h>
41 #include <dpl/utils/wrt_global_settings.h>
43 #include <application_data.h>
44 #include <common/application_launcher.h>
45 #include <common/message_support.h>
46 #include <common/scheme.h>
48 #include <common/view_logic_apps_support.h>
49 #include <common/view_logic_custom_header_support.h>
50 #include <common/view_logic_security_support.h>
51 #include <common/view_logic_security_origin_support.h>
52 #include <common/view_logic_certificate_support.h>
53 #include <common/view_logic_storage_support.h>
54 #include <common/view_logic_uri_support.h>
55 #include <common/view_logic_vibration_support.h>
56 #include <view_logic_authentication_challenge_support.h>
57 #include <view_logic_certificate_confirm_support.h>
58 #include <view_logic_geolocation_support.h>
59 #include <view_logic_message_support.h>
60 #include <view_logic_orientation_support.h>
61 #include <view_logic_scheme_support.h>
62 #include <view_logic_usermedia_support.h>
63 #include <view_logic_web_notification_data.h>
64 #include <view_logic_web_notification_support.h>
65 #include <view_logic_web_notification_permission_support.h>
66 #include <view_logic_web_storage_support.h>
69 #include <dpl/localization/w3c_file_localization.h>
70 #include <js_overlay_types.h>
71 #include <dispatch_event_support.h>
72 #include <i_runnable_widget_object.h>
73 #include <profiling_util.h>
74 #include <wrt-commons/custom-handler-dao-ro/CustomHandlerDatabase.h>
75 #include <wrt-commons/custom-handler-dao-rw/custom_handler_dao.h>
76 #include <popup-runner/PopupInvoker.h>
77 #include <plugins-ipc-message/ipc_message_support.h>
82 const char * const IME_STATE_ON = "on";
83 const char * const IME_STATE_OFF = "off";
85 const char PROTOCOL_HANDLER_ASK_MSG[] = "Add protocol?";
86 const char PROTOCOL_HANDLER_ASK_TITLE[] = "Add protocol";
87 const char PROTOCOL_HANDLER_ASK_REMEMBER[] = "Remember dicision";
88 const char CONTENT_HANDLER_ASK_MSG[] = "Add content?";
89 const char CONTENT_HANDLER_ASK_TITLE[] = "Add content";
90 const char CONTENT_HANDLER_AKS_REMEMBER[] = "Remember dicision";
92 const char* const DEFAULT_ENCODING = "UTF-8";
94 const char* const DEFAULT_CSP_POLICY =
95 "default-src *; script-src 'self'; style-src 'self'; object-src 'none';";
98 const char * const SCHEME_BOX_SLASH = "box://";
99 const double ORIENTATION_THRESHOLD = 0.5;
100 } // anonymous namespace
102 std::map<const std::string,
103 const Evas_Smart_Cb> ViewLogic::m_ewkCallbacksMap = {
104 { "load,started", &ViewLogic::loadStartedCallback },
105 { "load,finished", &ViewLogic::loadFinishedCallback },
106 { "load,progress,started", &ViewLogic::loadProgressStartedCallback },
107 { "load,progress", &ViewLogic::loadProgressCallback },
108 { "load,progress,finished", &ViewLogic::loadProgressFinishedCallback },
109 { "process,crashed", &ViewLogic::processCrashedCallback },
111 { "create,window", &ViewLogic::createWindowCallback },
112 { "close,window", &ViewLogic::closeWindowCallback },
113 // WKPagePolicyClient
114 { "policy,navigation,decide", &ViewLogic::policyNavigationDecideCallback },
115 { "policy,newwindow,decide", &ViewLogic::policyNewWindowDecideCallback },
116 { "policy,response,decide", &ViewLogic::pageResponseDecideCallback },
117 // WKPageContextMenuClient
118 { "contextmenu,customize", &ViewLogic::contextmenuCustomizeCallback },
119 // EWK Geolocation Callback
120 { "geolocation,permission,request",
121 &ViewLogic::geolocationPermissionRequestCallback },
122 // EWK Notification Callback
123 { "notification,show", &ViewLogic::notificationShowCallback },
124 { "notification,cancel", &ViewLogic::notificationCancelCallback },
125 { "notification,permission,request",
126 &ViewLogic::notificationPermissionRequestCallback },
127 { "fullscreen,enterfullscreen", &ViewLogic::enterFullscreenCallback },
128 { "fullscreen,exitfullscreen", &ViewLogic::exitFullscreenCallback },
130 // when ime start to be showed on the webview,
131 // this callback will be called
132 { "inputmethod,changed", &ViewLogic::imeChangedCallback },
133 // this callback will be called
134 // when ime finishes to be showed on the webview
135 // "event_info" arg of this callback is always NULL point
136 // if web content should know size of ime,
137 // use "inputmethod,changed" instead of this.
139 { "editorclient,ime,opened", &ViewLogic::imeOpenedCallback },
140 // when ime finished to be hidden,
141 // this callback will be called
142 { "editorclient,ime,closed", &ViewLogic::imeClosedCallback },
143 // EWK Usermedia Callback
144 { "usermedia,permission,request",
145 &ViewLogic::usermediaPermissionRequestCallback },
147 { "protocolhandler,registration,requested",
148 &ViewLogic::protocolHandlerRegistrationCallback },
149 { "protocolhandler,isregistered",
150 &ViewLogic::protocolHandlerIsRegisteredCallback },
151 { "protocolhandler,unregistration,requested",
152 &ViewLogic::protocolHandlerUnregistrationCallback },
153 { "contenthandler,registration,requested",
154 &ViewLogic::contentHandlerRegistrationCallback },
155 { "contenthandler,isregistered",
156 &ViewLogic::contentHandlerIsRegisteredCallback },
157 { "contenthandler,unregistration,requested",
158 &ViewLogic::contentHandlerUnregistrationCallback },
159 { "request,certificate,confirm",
160 &ViewLogic::certificateConfirmRequestCallback },
161 { "authentication,challenge",
162 &ViewLogic::authenticationChallengeRequestCallback },
164 &ViewLogic::viewFrameRenderedCallback },
165 { "mediacontrol,rotate,horizontal",
166 &ViewLogic::mediacontrolRotateHorizontal },
167 { "mediacontrol,rotate,vertical",
168 &ViewLogic::mediacontrolRotateVertical },
169 { "mediacontrol,rotate,exit",
170 &ViewLogic::mediacontrolRotateExit },
171 { "popup,reply,wait,start",
172 &ViewLogic::popupReplyWaitStart },
173 { "popup,reply,wait,finish",
174 &ViewLogic::popupReplyWaitFinish },
177 ViewLogic::ViewLogic() :
179 m_attachedToCustomHandlerDao(false),
181 m_closedEwkView(NULL),
184 m_cbs(new WRT::UserDelegates),
187 m_isBackgroundReload(false),
188 m_isBackgroundSupport(false),
190 m_deferredRotateAngle(
191 ViewModule::OrientationSupport::DEFERRED_ORIENTATION_EMPTY),
192 m_orientationThresholdTimer(NULL),
193 m_isPopupReplyWait(false),
194 m_isFullscreenByPlatform(false),
195 m_appsSupport(new ViewModule::AppsSupport()),
196 m_vibrationSupport(new ViewModule::VibrationSupport()),
197 m_webNotificationSupport(new ViewModule::WebNotificationSupport())
199 ApplicationLauncherSingleton::Instance().Touch();
202 ViewLogic::~ViewLogic()
204 detachFromCustomHandlersDao();
207 bool ViewLogic::createWebView(Ewk_Context* context,
211 if (!context || !window) {
216 const char *theme = elm_theme_get(NULL);
219 LogDebug("theme is " << m_theme);
223 m_ewkContext = context;
226 Evas* canvas = evas_object_evas_get(m_window);
228 if (!createEwkView(canvas)) {
235 void ViewLogic::prepareView(WidgetModel* m, const std::string &startUrl)
237 LogDebug("View prepare");
241 m_startUrl = startUrl;
242 Assert(NULL != m_ewkContext);
245 ADD_PROFILING_POINT("initializeSupport", "start");
247 ADD_PROFILING_POINT("initializeSupport", "stop");
248 ewkClientInit(m_currentEwkView);
249 ADD_PROFILING_POINT("prepareEwkView", "start");
250 prepareEwkView(m_currentEwkView);
251 ADD_PROFILING_POINT("prepareEwkView", "stop");
252 initializePluginLoading();
253 initializeXwindowHandle();
256 void ViewLogic::showWidget()
258 LogDebug("showing widget");
259 Assert(NULL != m_currentEwkView && "ewk_view not created at this point");
261 ViewModule::UriSupport::getUri(m_model, m_startUrl);
263 LogError("Localized current URI doesn't exist");
266 LogDebug("url : " << url);
269 ewk_view_url_set(m_currentEwkView, url.c_str());
271 if (!m_cbs->bufferSet.empty()) {
272 m_cbs->bufferSet(m_currentEwkView);
276 void ViewLogic::hideWidget()
278 LogDebug("hiding widget");
279 ViewModule::StorageSupport::deinitializeStorage(m_model);
280 m_appsSupport->deinitialize();
281 m_vibrationSupport->deinitialize();
282 m_webNotificationSupport->deinitialize();
283 system_settings_unset_changed_cb(SYSTEM_SETTINGS_KEY_FONT_TYPE);
285 while (!m_ewkViewList.empty()) {
286 LogDebug("pop webview: " << m_ewkViewList.back());
287 removeEwkView(m_ewkViewList.back());
289 m_ewkViewList.clear();
292 void ViewLogic::suspendWidget()
294 LogDebug("Pausing widget");
297 if (!m_currentEwkView) {
298 LogWarning("Cannot suspend widget without view");
301 /* we don't really use the "suspend" logic yet, and it can
302 cause a race with the elm_win_raise() Wayland logic */
304 setEwkViewInvisible(m_currentEwkView);
307 if (!m_isBackgroundSupport) {
308 FOREACH(it, m_ewkViewList) {
309 if (*it != m_currentEwkView) {
314 suspendWebkit(m_currentEwkView);
318 // call user callback
319 if (!m_cbs->suspend.empty()) {
320 m_cbs->suspend(true);
324 void ViewLogic::resumeWidget()
326 LogDebug("Resume widget");
329 if (m_currentEwkView)
331 setEwkViewVisible(m_currentEwkView);
333 if (!m_isBackgroundSupport) {
334 FOREACH(it, m_ewkViewList) {
335 if (*it != m_currentEwkView) {
340 resumeWebkit(m_currentEwkView);
344 /* window system team recomend removing this win_raise code. */
347 * elm_win_raise(m_window);
351 // call user callback
352 if (!m_cbs->resume.empty()) {
357 void ViewLogic::resetWidget()
359 LogDebug("Resetting Widget");
361 // handling case of WebProcess is locked
362 if (m_isPopupReplyWait) {
363 // resume web application
364 LogDebug("WebProcess is locked");
365 if (m_currentEwkView) {
366 setEwkViewVisible(m_currentEwkView);
367 if (!m_isBackgroundSupport) {
368 resumeWebkit(m_currentEwkView);
372 elm_win_activate(m_window);
374 // call user callback
375 if (!m_cbs->reset.empty()) {
379 // reset web application
380 // destory all webview
381 while (!m_ewkViewList.empty()) {
382 LogDebug("pop webview: " << m_ewkViewList.back());
383 removeEwkView(m_ewkViewList.back());
385 m_ewkViewList.clear();
386 m_currentEwkView = NULL;
388 // create new webview
389 createEwkView(evas_object_evas_get(m_window));
390 ewkClientInit(m_currentEwkView);
391 prepareEwkView(m_currentEwkView);
393 // check if current url is service url for this tizen service
395 ViewModule::UriSupport::getUri(m_model, m_startUrl);
397 initializePluginLoading();
399 ewk_view_url_set(m_currentEwkView, url.c_str());
400 elm_win_activate(m_window);
402 // call user callback
403 if (!m_cbs->reset.empty()) {
406 if (!m_cbs->bufferSet.empty()) {
407 m_cbs->bufferSet(m_currentEwkView);
412 void ViewLogic::backward()
414 if (ewk_view_back_possible(m_currentEwkView)) {
415 ewk_view_back(m_currentEwkView);
417 if (1 >= m_ewkViewList.size()) {
418 // If there is no previous page, widget move to backgroud.
419 LogDebug("Widget move to backgroud");
420 elm_win_lower(m_window);
422 // Back to previous webview
423 LogDebug("Widget move to previous webview");
424 m_closedEwkView = m_currentEwkView;
425 ecore_idler_add(windowCloseIdlerCallback, this);
430 void ViewLogic::reloadStartPage()
432 LogDebug("Reload Start Page");
433 // prevent fail to load plugin bundle side
434 m_isBackgroundReload = true;
436 if (!m_ewkViewList.empty()) {
437 while (!m_ewkViewList.empty()) {
438 if (!m_cbs->bufferUnset.empty()) {
439 m_cbs->bufferUnset(m_currentEwkView);
441 removeEwkView(m_currentEwkView);
445 // create new webview
446 createEwkView(evas_object_evas_get(m_window));
447 ewkClientInit(m_currentEwkView);
449 prepareEwkView(m_currentEwkView);
450 initializePluginLoading();
453 std::string url = ViewModule::UriSupport::getUri(m_model, m_startUrl);
454 ewk_view_url_set(m_currentEwkView, url.c_str());
457 if (!m_cbs->bufferSet.empty()) {
458 m_cbs->bufferSet(m_currentEwkView);
460 LogDebug("Reloading Start Page is done!");
463 Evas_Object* ViewLogic::getCurrentWebview()
465 LogDebug("get current webview");
466 return m_currentEwkView;
469 void ViewLogic::fireJavascriptEvent(int event, void* data)
471 ViewLogicMessageSupport::dispatchJavaScriptEvent(
473 static_cast<WrtPlugins::W3C::CustomEventType>(event),
477 void ViewLogic::setUserCallbacks(const WRT::UserDelegatesPtr& cbs)
482 void ViewLogic::checkSyncMessageFromBundle(
484 const char* /*body*/,
487 LogDebug("didReceiveSynchronousMessage called");
490 LogDebug("received : " << name);
491 if (!strcmp(name, Message::TizenScheme::GET_WINDOW_HANDLE)) {
493 Ecore_X_Window handle = elm_win_xwindow_get(m_window);
495 std::stringstream ss;
497 std::string ret = ss.str();
499 *returnData = strdup(ret.c_str());
502 LogDebug("X window isn't exist");
508 void ViewLogic::checkAsyncMessageFromBundle(const char* name, const char* body)
511 _D("received : %s", name);
513 if (!strcmp(name, Message::ToUIProcess::BLOCKED_URL)) {
514 // Currently WebProcess informs obly about blocked
515 // URI - URI localization and security chekcs are
516 // done by WebProcess itself (see: wrt-injected-bundle.cpp
517 // and bundle_uri_handling.cpp)
518 requestUrlBlocked(std::string(body));
519 } else if (!strcmp(name, Message::TizenScheme::CLEAR_ALL_COOKIES)) {
520 Ewk_Cookie_Manager* cookieManager =
521 ewk_context_cookie_manager_get(m_ewkContext);
522 if (!cookieManager) {
523 _E("Fail to get cookieManager");
526 ewk_cookie_manager_cookies_clear(cookieManager);
527 } else if (!strcmp(name, IPCMessageSupport::TIZEN_CHANGE_USERAGENT)) {
528 std::string msgBody = (body) ? (body) : "";
530 std::string strId = msgBody.substr(0, msgBody.find_first_of('_'));
531 std::string strBody = msgBody.substr(msgBody.find_first_of('_')+1);
532 _D("Id: %s , Body %s", strId.c_str(), strBody.c_str());
534 ewk_view_user_agent_set(m_currentEwkView, strBody.c_str());
535 _D("get UA: %s", ewk_view_user_agent_get(m_currentEwkView));
537 IPCMessageSupport::replyAsyncMessageToWebProcess(m_ewkContext,
541 } else if (!strcmp(name, IPCMessageSupport::TIZEN_DELETE_ALL_COOKIES)) {
542 std::string msgBody = (body) ? (body) : "";
543 std::string strId = msgBody.substr(0, msgBody.find_first_of('_'));
544 std::string strBody = msgBody.substr(msgBody.find_first_of('_')+1);
546 Ewk_Cookie_Manager* cookieManager =
547 ewk_context_cookie_manager_get(m_ewkContext);
548 if (!cookieManager) {
549 _E("Fail to get cookieManager");
550 IPCMessageSupport::replyAsyncMessageToWebProcess(
556 ewk_cookie_manager_cookies_clear(cookieManager);
557 IPCMessageSupport::replyAsyncMessageToWebProcess(m_ewkContext,
561 } else if (!strcmp(name, IPCMessageSupport::TIZEN_EXIT) ||
562 !strcmp(name, IPCMessageSupport::TIZEN_HIDE) ||
563 !strcmp(name, IPCMessageSupport::TIZEN_LAUNCH))
566 ViewModule::SchemeSupport::HandleTizenScheme(name,
570 _E("Fail to handle tizen scheme %s", name);
572 // Not need to send reply
575 _W("Not defined message");
579 void ViewLogic::downloadData(const char* url)
585 m_appsSupport->downloadRequest(url, NULL, NULL);
588 void ViewLogic::activateVibration(bool on, uint64_t time)
592 m_vibrationSupport->startVibration(static_cast<long>(time));
594 m_vibrationSupport->stopVibration();
598 void ViewLogic::initializeSupport()
600 // background support
601 if (m_model->SettingList.Get().getBackgroundSupport()
602 == BackgroundSupport_Enable)
604 LogDebug("Background support enabled, set process active");
605 sysman_inform_active(getpid());
606 m_isBackgroundSupport = true;
608 system_settings_set_changed_cb(SYSTEM_SETTINGS_KEY_FONT_TYPE,
609 systemSettingsChangedCallback,
612 ViewModule::StorageSupport::initializeStorage(m_model);
613 m_appsSupport->initialize(m_model, elm_win_xwindow_get(m_window));
614 m_securityOriginSupport.reset(new ViewModule::SecurityOriginSupport(m_model));
615 m_certificateSupport.reset(new ViewModule::CertificateSupport(m_model));
616 m_vibrationSupport->initialize();
617 m_webNotificationSupport->initialize(m_model->TzPkgId.Get());
620 void ViewLogic::initializePluginLoading()
622 // inform wrt information for plugin loading to web process
623 ViewLogicMessageSupport::start(
626 elm_config_scale_get(),
627 ApplicationDataSingleton::Instance().getEncodedBundle(),
631 void ViewLogic::initializeXwindowHandle()
634 unsigned int handle = elm_win_xwindow_get(m_window);
635 ViewLogicMessageSupport::setXwindowHandle(
641 void ViewLogic::ewkClientInit(Evas_Object *wkView)
643 Assert(NULL != wkView && "ewk_view not created at this point");
645 FOREACH(it, m_ewkCallbacksMap)
647 evas_object_smart_callback_add(
653 // EWK Orientation Callback
654 ewk_view_orientation_lock_callback_set(
656 orientationLockCallback,
658 ewk_view_exceeded_database_quota_callback_set(
660 exceededDatabaseQuotaCallback,
662 ewk_view_exceeded_indexed_database_quota_callback_set(
664 exceededIndexedDatabaseQuotaCallback,
666 ewk_view_exceeded_local_file_system_quota_callback_set(
668 exceededLocalFileSystemQuotaCallback,
670 ea_object_event_callback_add(wkView,
674 ea_object_event_callback_add(wkView,
678 #if 0 // FIXME!!! elm_access_object_register has not landed yet
679 // Always register access object even application doesn't support
680 // accessibility. In case of accessibility isn't supported, efl_assist
681 // shows warning message by syspopup.
682 // initScreenReaderSupport is related method. (window_data.cpp)
683 elm_access_object_register(wkView, m_window);
687 void ViewLogic::ewkClientDeinit(Evas_Object *wkView)
689 LogDebug("ewkClientDeinit");
690 Assert(NULL != wkView && "ewk_view not created at this point");
692 FOREACH(it, m_ewkCallbacksMap)
694 evas_object_smart_callback_del(
699 ewk_view_orientation_lock_callback_set(wkView, NULL, NULL);
700 ewk_view_exceeded_database_quota_callback_set(wkView, NULL, NULL);
701 ewk_view_exceeded_indexed_database_quota_callback_set(wkView, NULL, NULL);
702 ewk_view_exceeded_local_file_system_quota_callback_set(wkView, NULL, NULL);
703 ea_object_event_callback_del(wkView,
706 ea_object_event_callback_del(wkView,
709 if (m_orientationThresholdTimer) {
710 ecore_timer_del(m_orientationThresholdTimer);
711 m_orientationThresholdTimer = NULL;
713 // FIXME!!!! elm_access_object_unregister has not landed in
714 // tizen 3.0 elementary yet
715 // elm_access_object_unregister(wkView);
718 bool ViewLogic::createEwkView(Evas* canvas)
720 LogDebug("createEwkView");
722 ADD_PROFILING_POINT("ewk_view_add_with_context", "start");
723 Evas_Object* newEwkView = ewk_view_add_with_context(
726 ADD_PROFILING_POINT("ewk_view_add_with_context", "stop");
729 LogError("View creation failed");
730 Wrt::Popup::PopupInvoker().showInfo(
731 "Info", "View creation failed", "close");
736 // even arguments pass the ewkContext, this API should be called
737 // after webkit Evas_Object is created
738 Ewk_Cookie_Manager *ewkCookieManager;
740 ewk_context_cookie_manager_get(m_ewkContext);
741 ewk_cookie_manager_accept_policy_set(ewkCookieManager,
742 EWK_COOKIE_ACCEPT_POLICY_ALWAYS);
744 if (m_currentEwkView) {
745 setEwkViewInvisible(m_currentEwkView);
748 LogDebug("push webview: " << newEwkView);
749 m_ewkViewList.push_back(newEwkView);
750 m_currentEwkView = newEwkView;
754 void ViewLogic::prepareEwkView(Evas_Object *wkView)
756 LogDebug("prepareEwkView called");
758 Ewk_Settings* settings = ewk_view_settings_get(wkView);
761 std::string customUserAgent = m_model->SettingList.Get().getUserAgent();
762 if (customUserAgent.empty()) {
763 LogDebug("Setting user agent as: default");
764 ewk_view_user_agent_set(wkView, NULL);
765 std::string defaultUA = ewk_view_user_agent_get(wkView);
766 LogDebug("webkit's UA: " << defaultUA);
768 LogDebug("Setting custom user agent as: " << customUserAgent);
769 ewk_view_user_agent_set(wkView, customUserAgent.c_str());
772 // set custom header : language
773 using namespace ViewModule::CustomHeaderSupport;
774 std::string customHeaderString = getValueByField(ACCEPT_LANGUAGE);
775 if (!customHeaderString.empty()) {
776 LogDebug("custom field=[" << ACCEPT_LANGUAGE << "]");
777 LogDebug("custom value=[" << customHeaderString << "]");
778 ewk_view_custom_header_add(wkView,
779 ACCEPT_LANGUAGE.c_str(),
780 customHeaderString.c_str());
783 // webkit NPAPI plugins is always on in wrt
784 ewk_settings_plugins_enabled_set(settings, EINA_TRUE);
785 ewk_settings_javascript_enabled_set(settings, EINA_TRUE);
786 ewk_settings_loads_images_automatically_set(settings, EINA_TRUE);
787 // WRT should not fit web contents to device width automatically as default.
788 // Fitting to device width should be handled by web content using viewport meta tag.
789 ewk_settings_auto_fitting_set(settings, EINA_FALSE);
790 ewk_settings_autofill_password_form_enabled_set(settings, EINA_TRUE);
791 ewk_settings_form_candidate_data_enabled_set(settings, EINA_TRUE);
793 ewk_view_page_visibility_state_set(wkView,
794 EWK_PAGE_VISIBILITY_STATE_VISIBLE,
797 std::string encoding = DEFAULT_ENCODING;
798 OptionalWidgetStartFileInfo fileInfo =
799 W3CFileLocalization::getStartFileInfo(m_model->TizenId);
800 #if 0 // FIXME!!!! ewk_settings_is_encoding_valid has not landed yet
801 if (!fileInfo.IsNull()) {
802 std::string file_encoding = DPL::ToUTF8String((*fileInfo).encoding);
804 if(EINA_TRUE == ewk_settings_is_encoding_valid(
805 file_encoding.c_str())){
806 encoding = file_encoding;
807 _D("Found custom encoding in DB: %s", encoding.c_str());
812 _D("Setting encoding: %s", encoding.c_str());
813 if (ewk_settings_default_encoding_set(settings,encoding.c_str())) {
814 _D("Encoding set properly");
816 _E("Error while setting encoding");
820 if (m_model->SecurityModelVersion.Get() ==
821 WrtDB::WidgetSecurityModelVersion::WIDGET_SECURITY_MODEL_V2)
823 // setting CSP policy rules
824 DPL::OptionalString policy = m_model->CspReportOnlyPolicy.Get();
825 if (!policy.IsNull()) {
826 LogDebug("CSP report only policy present in manifest: " << *policy);
827 ewk_view_content_security_policy_set(
829 DPL::ToUTF8String(*policy).c_str(),
833 policy = m_model->CspPolicy.Get();
834 if (!policy.IsNull()) {
835 LogDebug("CSP policy present in manifest: " << *policy);
836 ewk_view_content_security_policy_set(
838 DPL::ToUTF8String(*policy).c_str(),
841 ewk_view_content_security_policy_set(
850 void ViewLogic::removeEwkView(Evas_Object *wkView)
852 LogDebug("removeEwkView called");
854 Assert(0 != m_ewkViewList.size());
856 // unregister webview callbacks
857 ewkClientDeinit(wkView);
859 // suspend NPAPI plugin - Not implemented by Webkit2
860 // ewk_view_pause_or_resume_plugins();
861 evas_object_del(wkView);
862 m_ewkViewList.remove(wkView);
865 void ViewLogic::setEwkViewInvisible(Evas_Object *wkView)
867 LogDebug("setEwkViewInvisible called");
870 ewk_view_page_visibility_state_set(wkView,
871 EWK_PAGE_VISIBILITY_STATE_HIDDEN,
873 ewk_view_visibility_set(wkView, EINA_FALSE);
876 void ViewLogic::setEwkViewVisible(Evas_Object *wkView)
878 LogDebug("setEwkViewVisible called");
881 ewk_view_page_visibility_state_set(wkView,
882 EWK_PAGE_VISIBILITY_STATE_VISIBLE,
884 ewk_view_visibility_set(wkView, EINA_TRUE);
887 void ViewLogic::resumeWebkit(Evas_Object *wkView)
889 LogDebug("resumeWebkit : " << wkView);
892 ewk_view_resume(wkView);
894 Evas_Object *window = NULL;
895 window = evas_object_top_get(evas_object_evas_get(wkView));
896 if (window != NULL) {
897 elm_win_withdrawn_set(window, EINA_TRUE);
898 elm_win_withdrawn_set(window, EINA_FALSE);
904 void ViewLogic::suspendWebkit(Evas_Object *wkView)
906 LogDebug("suspendWebkit : " << wkView);
909 ewk_view_suspend(wkView);
914 void ViewLogic::loadStartedCallback(
919 LogDebug("loadStartedCallback called");
921 ViewLogic* This = static_cast<ViewLogic*>(data);
923 // call loadFinish callback to wrt-client
924 if (!This->m_cbs->loadStart.empty()) {
925 This->m_cbs->loadStart(obj);
929 void ViewLogic::loadFinishedCallback(
934 LogDebug("loadFinishedCallback called");
936 ViewLogic* This = static_cast<ViewLogic*>(data);
939 const char* url = ewk_view_url_get(This->m_currentEwkView);
940 if (NULL == url || strlen(url) == 0) {
941 LogError("url is empty");
945 // call loadFinish callback to wrt-client
946 if (!This->m_cbs->loadFinish.empty()) {
947 This->m_cbs->loadFinish(obj);
950 // set only encoded bundle
951 double scale = elm_config_scale_get();
952 ViewLogicMessageSupport::setCustomProperties(
955 ApplicationDataSingleton::Instance().getEncodedBundle());
957 // In this case, widget is reloaded in the background.
958 // After finished load, bundle should disconnent callback.
959 if (This->m_isBackgroundReload) {
960 ewk_view_suspend(This->m_currentEwkView);
961 This->m_isBackgroundReload = false;
965 void ViewLogic::loadProgressStartedCallback(
967 Evas_Object* /*obj*/,
970 _D("loadProgressStartedCallback called");
972 ViewLogic* This = static_cast<ViewLogic*>(data);
973 if (!This->m_cbs->progressStarted.empty()) {
974 This->m_cbs->progressStarted();
979 void ViewLogic::loadProgressCallback(
984 _D("loadProgressCallback called");
987 ViewLogic const * const view = static_cast<ViewLogic const * const>(data);
988 double* progress = static_cast<double*>(eventInfo);
989 LogDebug("didChangeProgressCallback progress = " << *progress);
990 if (!view->m_cbs->progress.empty()) {
992 view->m_cbs->progress(obj, *progress);
996 void ViewLogic::loadProgressFinishedCallback(
998 Evas_Object* /*obj*/,
1001 LogDebug("didFinishProgressCallback");
1003 ViewLogic const * const view = static_cast<ViewLogic const * const>(data);
1004 if (!view->m_cbs->progressFinish.empty()) {
1005 view->m_cbs->progressFinish();
1009 void ViewLogic::processCrashedCallback(
1011 Evas_Object* /*obj*/,
1014 LogDebug("processCrashedCallback");
1016 ViewLogic const * const view =
1017 static_cast<ViewLogic const * const>(data);
1018 if (!view->m_cbs->webCrash.empty()) {
1019 view->m_cbs->webCrash();
1021 // This flag will be prevented exit() call in the Webkit side
1022 if (NULL != eventInfo) {
1023 *(static_cast<Eina_Bool*>(eventInfo)) = EINA_TRUE;
1027 void ViewLogic::createWindowCallback(
1032 LogDebug("createWindowCallback");
1034 ViewLogic* This = static_cast<ViewLogic*>(data);
1036 // First, current webview should be handled by user callback
1037 if (!This->m_cbs->bufferUnset.empty()) {
1038 This->m_cbs->bufferUnset(obj);
1041 // this can be set by executable for specific purpose
1042 Evas* canvas = NULL;
1043 if (!This->m_cbs->windowCreateBefore.empty()) {
1044 // 'obj' is parent webview object
1045 This->m_cbs->windowCreateBefore(&canvas, obj);
1048 canvas = evas_object_evas_get(This->m_window);
1051 // create new ewkview
1052 This->createEwkView(canvas);
1053 Evas_Object* newEwkView = This->m_currentEwkView;
1055 // initialize new ewkview
1056 This->ewkClientInit(newEwkView);
1057 This->prepareEwkView(newEwkView);
1059 // Specific jobs of child, parent webview are handled by each executable
1060 if (!This->m_cbs->windowCreateAfter.empty()) {
1061 // 'obj' is parent webview, 'newEwkView' is child webview
1062 This->m_cbs->windowCreateAfter(obj, newEwkView);
1065 // Lastly, new webview should be handled by user callback
1066 if (!This->m_cbs->bufferSet.empty()) {
1067 This->m_cbs->bufferSet(newEwkView);
1069 *(static_cast<Evas_Object **>(eventInfo)) = newEwkView;
1072 void ViewLogic::closeWindowCallback(
1075 void* /*eventInfo*/)
1077 LogDebug("closeWindowCallback");
1078 ViewLogic* This = static_cast<ViewLogic*>(data);
1079 This->m_closedEwkView = obj;
1080 ecore_idler_add(windowCloseIdlerCallback, This);
1083 void ViewLogic::policyNavigationDecideCallback(
1088 LogDebug("policyNavigationDecideCallback called");
1090 ViewLogic* This = static_cast<ViewLogic*>(data);
1092 Ewk_Policy_Decision* policyDecision =
1093 static_cast<Ewk_Policy_Decision*>(eventInfo);
1095 // handle blocked url
1096 const char* url = ewk_policy_decision_url_get(policyDecision);
1098 // call user delegate callback
1099 if (!This->m_cbs->navigationDecide.empty()) {
1100 std::string navigationUri(url);
1101 This->m_cbs->navigationDecide(obj, navigationUri);
1102 if (!navigationUri.compare(0, 6, SCHEME_BOX_SLASH)) {
1103 ewk_policy_decision_ignore(policyDecision);
1108 if (url && strlen(url) != 0) {
1109 if (This->m_blockedUri == url) {
1110 LogDebug("Blocked url = " << url);
1111 This->m_blockedUri = std::string();
1112 ewk_policy_decision_ignore(policyDecision);
1117 if (ViewModule::SchemeSupport::filterURIByScheme(policyDecision,
1120 This->m_currentEwkView))
1123 ewk_policy_decision_use(policyDecision);
1125 // check whether this is new empty window
1126 const char* activeUrl = ewk_view_url_get(This->m_currentEwkView);
1127 if (!activeUrl || 0 == strlen(activeUrl)) {
1129 * The view is empty and scheme has been handled externally. When
1130 * user gets back from the external application he'd see blank page
1131 * and won't be able to navigate back. This happens when window.open
1132 * is used to handle schemes like sms/mms/mailto (for example in
1133 * WAC web standards tests: WS-15XX).
1135 * To solve the problem, the empty view is removed from the stack
1136 * and the previous one is shown. This is not an elegant solution
1137 * but we don't have a better one.
1139 LogDebug("Scheme has been handled externally. Removing empty view.");
1140 if (ewk_view_back_possible(This->m_currentEwkView)) {
1141 // go back to previous WKPage
1142 ewk_view_back(This->m_currentEwkView);
1144 // stop current WKPage
1145 ewk_view_stop(This->m_currentEwkView);
1146 This->m_closedEwkView = This->m_currentEwkView;
1147 ecore_idler_add(windowCloseIdlerCallback, This);
1152 ewk_policy_decision_ignore(policyDecision);
1156 void ViewLogic::policyNewWindowDecideCallback(
1158 Evas_Object* /*obj*/,
1161 LogDebug("policyNewWindowDecideCallback called");
1163 ViewLogic* This = static_cast<ViewLogic*>(data);
1165 Ewk_Policy_Decision* policyDecision =
1166 static_cast<Ewk_Policy_Decision*>(eventInfo);
1168 // handle blocked url
1169 const char* url = ewk_policy_decision_url_get(policyDecision);
1170 if (url && strlen(url) != 0) {
1171 if (This->m_blockedUri == url) {
1172 LogDebug("Blocked url = " << url);
1173 This->m_blockedUri = std::string();
1174 ewk_policy_decision_ignore(policyDecision);
1179 if (ViewModule::SchemeSupport::filterURIByScheme(policyDecision,
1182 This->m_currentEwkView))
1184 ewk_policy_decision_use(policyDecision);
1187 ewk_policy_decision_ignore(policyDecision);
1191 void ViewLogic::pageResponseDecideCallback(
1193 Evas_Object* /*obj*/,
1196 LogDebug("pageResponseDecideCallback called");
1198 ViewLogic* This = static_cast<ViewLogic*>(data);
1200 Ewk_Policy_Decision* policyDecision =
1201 static_cast<Ewk_Policy_Decision*>(eventInfo);
1202 Ewk_Policy_Decision_Type policyDecisionType =
1203 ewk_policy_decision_type_get(policyDecision);
1205 if (policyDecisionType == EWK_POLICY_DECISION_USE) {
1207 ewk_policy_decision_use(policyDecision);
1208 } else if (policyDecisionType == EWK_POLICY_DECISION_DOWNLOAD) {
1209 LogDebug("download");
1210 ewk_policy_decision_suspend(policyDecision);
1212 // get uri information
1213 const char* url = ewk_policy_decision_url_get(policyDecision);
1214 if (NULL == url || strlen(url) == 0) {
1215 LogDebug("url data is empty");
1216 ewk_policy_decision_use(policyDecision);
1219 LogDebug("url = [" << url << "]");
1221 // get content information
1222 const char* content =
1223 ewk_policy_decision_response_mime_get(policyDecision);
1224 LogDebug("content type = [" << content << "]");
1226 // get cookie information
1227 const char* cookie = ewk_policy_decision_cookie_get(policyDecision);
1228 LogDebug("cookie = [" << cookie << "]");
1230 LogDebug("Content not supported, will be opened in external app");
1231 This->m_appsSupport->downloadRequest(
1235 ewk_policy_decision_ignore(policyDecision);
1236 } else if (policyDecisionType == EWK_POLICY_DECISION_IGNORE) {
1238 ewk_policy_decision_ignore(policyDecision);
1240 LogDebug("Type isn't handled");
1241 ewk_policy_decision_ignore(policyDecision);
1245 void ViewLogic::contextmenuCustomizeCallback(
1247 Evas_Object* /*obj*/,
1250 LogDebug("contextmenuCustomizeCallback called");
1253 ViewLogic* This = static_cast<ViewLogic*>(const_cast<void*>(data));
1254 Ewk_Context_Menu* menu = static_cast<Ewk_Context_Menu*>(eventInfo);
1255 if ((This->m_model->Type.Get().appType == WrtDB::APP_TYPE_TIZENWEBAPP) &&
1256 (This->m_model->SettingList.Get().getContextMenu()
1257 == ContextMenu_Disable))
1259 LogDebug("ContextMenu Disable!!");
1260 for (unsigned int idx = 0; idx < ewk_context_menu_item_count(menu);) {
1261 Ewk_Context_Menu_Item* item = ewk_context_menu_nth_item_get(menu,
1264 ewk_context_menu_item_remove(menu, item);
1267 LogDebug("ContextMenu Enable!!");
1268 unsigned int menu_num = ewk_context_menu_item_count(menu);
1269 unsigned int idx = 0;
1271 Ewk_Context_Menu_Item* item = ewk_context_menu_nth_item_get(menu,
1277 Ewk_Context_Menu_Item_Tag tag = ewk_context_menu_item_tag_get(item);
1280 case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_IMAGE_IN_NEW_WINDOW:
1281 ewk_context_menu_item_remove(menu, item);
1284 case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_LINK_IN_NEW_WINDOW:
1285 ewk_context_menu_item_remove(menu, item);
1288 case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_FRAME_IN_NEW_WINDOW:
1289 ewk_context_menu_item_remove(menu, item);
1292 case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_MEDIA_IN_NEW_WINDOW:
1293 ewk_context_menu_item_remove(menu, item);
1296 case EWK_CONTEXT_MENU_ITEM_TAG_SEARCH_WEB:
1297 ewk_context_menu_item_remove(menu, item);
1300 case EWK_CONTEXT_MENU_ITEM_TAG_DOWNLOAD_IMAGE_TO_DISK:
1301 ewk_context_menu_item_remove(menu, item);
1308 } while (idx < menu_num);
1312 void ViewLogic::geolocationPermissionRequestCallback(
1314 Evas_Object* /*obj*/,
1318 ViewLogic* This = static_cast<ViewLogic*>(data);
1320 Ewk_Geolocation_Permission_Request* permissionRequest =
1321 static_cast<Ewk_Geolocation_Permission_Request*>(eventInfo);
1323 if (This->m_model->GeolocationUsage.Get() == WrtDB::SETTINGS_TYPE_OFF) {
1324 ewk_geolocation_permission_request_set(permissionRequest, EINA_FALSE);
1327 ViewModule::GeolocationSupport::geolocationPermissionRequest(
1328 This->m_currentEwkView,
1329 This->m_securityOriginSupport->getSecurityOriginDAO(),
1333 void ViewLogic::notificationShowCallback(
1335 Evas_Object* /*obj*/,
1339 Ewk_Notification* ewkNotification =
1340 static_cast<Ewk_Notification*>(eventInfo);
1341 ViewModule::WebNotificationDataPtr notiData(
1342 new ViewModule::WebNotificationData(ewkNotification));
1344 _D("notification id : %u", notiData->getEwkNotiId());
1345 _D("notification iconURL : %s", notiData->getIconUrl());
1346 _D("notification title : %s", notiData->getTitle());
1347 _D("notification body : %s", notiData->getBody());
1350 ViewLogic* This = static_cast<ViewLogic*>(data);
1351 if (This->m_webNotificationSupport->show(notiData)) {
1352 ewk_notification_showed(This->m_ewkContext, notiData->getEwkNotiId());
1356 void ViewLogic::notificationCancelCallback(
1362 uint64_t ewkNotiId = *static_cast<uint64_t*>(eventInfo);
1365 ViewLogic* This = static_cast<ViewLogic*>(data);
1366 Ewk_Notification* ewkNotification =
1367 static_cast<Ewk_Notification*>(
1368 This->m_webNotificationSupport->hide(ewkNotiId));
1369 if (ewkNotification) {
1371 Eina_List* list = NULL;
1372 list = eina_list_append(list, ewkNotification);
1373 ewk_view_notification_closed(obj, list);
1374 eina_list_free(list);
1378 void ViewLogic::notificationPermissionRequestCallback(
1380 Evas_Object* /*obj*/,
1383 LogDebug("notificationPermissionRequestCallback called");
1385 ViewLogic* This = static_cast<ViewLogic*>(data);
1388 ViewModule::WebNotificationPermissionSupport::permissionRequest(
1389 This->m_currentEwkView,
1390 This->m_securityOriginSupport->getSecurityOriginDAO(),
1395 // EWK Orientation Callback
1396 Eina_Bool ViewLogic::orientationLockCallback(
1402 LogDebug("orientationLockCallback called");
1404 ViewLogic* This = static_cast<ViewLogic*>(data);
1406 if (This->m_orientationThresholdTimer) {
1407 LogDebug("previous orientationLock isn't finished");
1408 // Previous API call isn't finished. Keep angle and run it.
1409 if (needLock == EINA_TRUE) {
1410 // Screen.lockOrientation
1411 This->m_deferredRotateAngle = orientation;
1413 // Screen.unlockOrientation
1414 This->m_deferredRotateAngle =
1415 ViewModule::OrientationSupport::DEFERRED_ORIENTATION_UNLOCK;
1420 This->m_rotateAngle = orientation;
1422 if (needLock == EINA_TRUE) {
1423 // Screen.lockOrientation
1425 ViewModule::OrientationSupport::getW3COrientationAngle(orientation);
1427 ViewModule::OrientationSupport::getWinOrientationAngle(orientation);
1428 ViewModule::OrientationSupport::setEwkOrientation(obj, w3cAngle);
1429 if (!This->m_cbs->setOrientation.empty()) {
1430 This->m_cbs->setOrientation(winAngle);
1433 // Screen.unlockOrientation
1434 if (This->m_model->SettingList.Get().getRotationValue() ==
1435 Screen_AutoRotation)
1437 if (!This->m_cbs->setOrientation.empty()) {
1438 This->m_cbs->setOrientation(OrientationAngle::Window::UNLOCK);
1440 This->m_rotateAngle = 0;
1446 // Fullscreen API callbacks
1447 void ViewLogic::enterFullscreenCallback(
1452 LogDebug("enterFullscreenCallback called");
1454 ViewLogic* This = static_cast<ViewLogic*>(data);
1455 ViewLogicMessageSupport::setViewmodes(
1460 This->m_isFullscreenByPlatform =
1461 *static_cast<Eina_Bool*>(eventInfo) == EINA_TRUE;
1463 if (!This->m_cbs->enterFullscreen.empty()) {
1464 This->m_cbs->enterFullscreen(obj);
1468 void ViewLogic::exitFullscreenCallback(
1471 void* /*eventInfo*/)
1473 LogDebug("exitFullscreenCallback called");
1475 ViewLogic* This = static_cast<ViewLogic*>(data);
1476 ViewLogicMessageSupport::setViewmodes(
1478 Message::ToInjectedBundle::SET_VIEWMODES_MSGBODY_EXIT);
1480 This->m_isFullscreenByPlatform = false;
1481 if (!This->m_cbs->exitFullscreen.empty()) {
1482 This->m_cbs->exitFullscreen(obj);
1486 void ViewLogic::imeChangedCallback(
1488 Evas_Object* /*obj*/,
1494 ViewLogic* This = static_cast<ViewLogic*>(data);
1495 Eina_Rectangle *rect = static_cast<Eina_Rectangle *>(eventInfo);
1496 This->m_imeWidth = rect->w;
1497 This->m_imeHeight = rect->h;
1500 void ViewLogic::imeOpenedCallback(
1502 Evas_Object* /*obj*/,
1503 void* /*eventInfo*/)
1507 ViewLogic* This = static_cast<ViewLogic*>(data);
1509 using namespace WrtPlugins::W3C;
1510 SoftKeyboardChangeArgs args;
1511 args.state = IME_STATE_ON;
1512 args.width = This->m_imeWidth;
1513 args.height = This->m_imeHeight;
1514 This->fireJavascriptEvent(
1515 static_cast<int>(SoftKeyboardChangeCustomEvent),
1519 void ViewLogic::imeClosedCallback(
1521 Evas_Object* /*obj*/,
1522 void* /*eventInfo*/)
1526 ViewLogic* This = static_cast<ViewLogic*>(data);
1528 using namespace WrtPlugins::W3C;
1529 SoftKeyboardChangeArgs args;
1530 args.state = IME_STATE_OFF;
1531 This->fireJavascriptEvent(
1532 static_cast<int>(SoftKeyboardChangeCustomEvent),
1536 void ViewLogic::usermediaPermissionRequestCallback(
1538 Evas_Object* /*obj*/,
1541 LogDebug("usermediaPermissionRequestCallback called");
1543 ViewLogic* This = static_cast<ViewLogic*>(data);
1544 ViewModule::UsermediaSupport::usermediaPermissionRequest(
1545 This->m_currentEwkView,
1546 This->m_securityOriginSupport->getSecurityOriginDAO(),
1551 CustomHandlerDB::CustomHandlerPtr getCustomHandlerFromData(void* data)
1554 Ewk_Custom_Handlers_Data* handler =
1555 static_cast<Ewk_Custom_Handlers_Data*>(data);
1556 CustomHandlerDB::CustomHandlerPtr customHandler(
1557 new CustomHandlerDB::CustomHandler());
1558 const char* base_url = ewk_custom_handlers_data_base_url_get(handler);
1560 LogDebug("base url: " << base_url);
1561 customHandler->base_url = DPL::FromASCIIString(string(base_url));
1563 const char* url = ewk_custom_handlers_data_url_get(handler);
1565 LogDebug("url: " << url);
1566 customHandler->url = DPL::FromASCIIString(string(url));
1568 const char* target = ewk_custom_handlers_data_target_get(handler);
1570 LogDebug("target: " << target);
1571 customHandler->target = DPL::FromASCIIString(string(target));
1573 const char* title = ewk_custom_handlers_data_title_get(handler);
1575 LogDebug("title: " << title);
1576 customHandler->title = DPL::FromASCIIString(string(title));
1578 return customHandler;
1581 void ViewLogic::attachToCustomHandlersDao()
1583 if (!m_attachedToCustomHandlerDao) {
1584 CustomHandlerDB::Interface::attachDatabaseRW();
1588 void ViewLogic::detachFromCustomHandlersDao()
1590 if (m_attachedToCustomHandlerDao) {
1591 CustomHandlerDB::Interface::detachDatabase();
1595 const int protocolWhiteListLenth = 15;
1596 char const * const protocolWhiteList[protocolWhiteListLenth] = {
1614 const int contentBlackListLenth = 14;
1615 char const * const contentBlackList[contentBlackListLenth] = {
1616 "application/x-www-form-urlencoded",
1617 "application/xhtml+xml",
1623 "multipart/x-mixed-replace",
1624 "text/cache-manifest",
1633 * Saves user's response from popup to custom handler. Saves Yes/No and remember
1636 * @param customHandler
1638 void saveUserResponse(Wrt::Popup::PopupResponse response,
1639 CustomHandlerDB::CustomHandlerPtr customHandler)
1642 case Wrt::Popup::YES_DO_REMEMBER:
1643 LogDebug("User allowed, remember");
1644 customHandler->user_decision =
1645 static_cast<CustomHandlerDB::HandlerState>
1646 (CustomHandlerDB::Agreed | CustomHandlerDB::DecisionSaved);
1648 case Wrt::Popup::YES_DONT_REMEMBER:
1649 LogDebug("User allowed, don't remember");
1650 customHandler->user_decision = CustomHandlerDB::Agreed;
1652 case Wrt::Popup::NO_DO_REMEMBER:
1653 LogDebug("User didn't allow, remember");
1654 customHandler->user_decision =
1655 static_cast<CustomHandlerDB::HandlerState>
1656 (CustomHandlerDB::Declined | CustomHandlerDB::DecisionSaved);
1658 case Wrt::Popup::NO_DONT_REMEMBER:
1659 LogDebug("User didn't allow, don't remember");
1660 customHandler->user_decision = CustomHandlerDB::Declined;
1665 //TODO registration, checking if registered and unregistration can be done in
1666 //common functions for both types of handlers. Only white and black lists
1667 //have to be separated
1668 //TODO attach database only one at the start (not in every callback?)
1669 void ViewLogic::protocolHandlerRegistrationCallback(void* data,
1670 Evas_Object* /*obj*/,
1675 CustomHandlerDB::CustomHandlerPtr customHandler =
1676 getCustomHandlerFromData(eventInfo);
1678 std::string scheme = DPL::ToUTF8String(customHandler->target);
1679 if (scheme.empty()) {
1680 LogError("No scheme provided");
1681 //TODO what about securityError?
1684 bool matched = false;
1685 //scheme on whiteList
1686 for (int i = 0; i < protocolWhiteListLenth; ++i) {
1687 if (0 == strcmp(protocolWhiteList[i], scheme.c_str())) {
1688 LogDebug("Match found, protocol can be handled");
1693 //starts with web+ and have at least 5 chars (lowercase ASCII)
1694 if (strncmp("web+", scheme.c_str(), 4) || scheme.length() < 5) {
1695 LogWarning("Scheme neither on whitelist nor starts with \"web+\"");
1696 //throw SecurityException
1702 if (c < 'a' || c > 'z') {
1703 LogWarning("Wrong char inside scheme. "
1704 << "Only lowercase ASCII letters accepted");
1705 //throw SecurityException
1712 ViewLogic* This = static_cast<ViewLogic*>(data);
1713 LogDebug("Creating handlers dao");
1714 This->attachToCustomHandlersDao();
1715 CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1716 CustomHandlerDB::CustomHandlerPtr handler =
1717 handlersDao.getProtocolHandler(customHandler->target,
1719 customHandler->base_url);
1720 if (handler && (handler->user_decision & CustomHandlerDB::DecisionSaved)) {
1721 LogDebug("Protocol already registered - nothing to do");
1723 LogDebug("Protocol handler not found");
1724 Wrt::Popup::PopupResponse response =
1725 GlobalSettings::PopupsTestModeEnabled() ? Wrt::Popup::
1727 Wrt::Popup::PopupInvoker().askYesNoCheckbox(
1728 PROTOCOL_HANDLER_ASK_TITLE,
1729 PROTOCOL_HANDLER_ASK_MSG,
1730 PROTOCOL_HANDLER_ASK_REMEMBER);
1731 saveUserResponse(response, customHandler);
1732 if (customHandler->user_decision == CustomHandlerDB::Declined) {
1735 if (customHandler->user_decision & CustomHandlerDB::Agreed) {
1736 //TODO remove old default handler somehow from appsvc
1737 LogDebug("Registering appservice entry");
1738 int ret = appsvc_set_defapp(APPSVC_OPERATION_VIEW,
1741 customHandler->target).c_str(),
1742 DPL::ToUTF8String(This->m_model->
1744 if (APPSVC_RET_OK != ret) {
1745 LogWarning("Appsvc entry failed: " << ret);
1746 //no database change
1750 handlersDao.registerProtocolHandler(*(customHandler.get()));
1752 LogDebug("Protocal saved");
1755 This->detachFromCustomHandlersDao();
1758 void ViewLogic::protocolHandlerIsRegisteredCallback(void* data,
1759 Evas_Object* /*obj*/,
1763 CustomHandlerDB::CustomHandlerPtr customHandler = getCustomHandlerFromData(
1765 ViewLogic* This = static_cast<ViewLogic*>(data);
1766 LogDebug("Creating handlers dao");
1767 This->attachToCustomHandlersDao();
1768 CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1769 CustomHandlerDB::CustomHandlerPtr handler =
1770 handlersDao.getProtocolHandler(customHandler->target,
1772 customHandler->base_url);
1774 if (handler->user_decision & CustomHandlerDB::Agreed) {
1775 ewk_custom_handlers_data_result_set(
1776 static_cast<Ewk_Custom_Handlers_Data*>(eventInfo),
1777 EWK_CUSTOM_HANDLERS_REGISTERED);
1779 ewk_custom_handlers_data_result_set(
1780 static_cast<Ewk_Custom_Handlers_Data*>(eventInfo),
1781 EWK_CUSTOM_HANDLERS_DECLINED);
1784 ewk_custom_handlers_data_result_set(
1785 static_cast<Ewk_Custom_Handlers_Data*>(eventInfo),
1786 EWK_CUSTOM_HANDLERS_NEW);
1788 This->detachFromCustomHandlersDao();
1791 void ViewLogic::protocolHandlerUnregistrationCallback(void* data,
1792 Evas_Object* /*obj*/,
1796 CustomHandlerDB::CustomHandlerPtr customHandler =
1797 getCustomHandlerFromData(eventInfo);
1798 ViewLogic* This = static_cast<ViewLogic*>(data);
1799 LogDebug("Creating handlers dao");
1800 This->attachToCustomHandlersDao();
1801 CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1802 CustomHandlerDB::CustomHandlerPtr handlerCheck =
1803 handlersDao.getProtocolHandler(customHandler->target,
1805 customHandler->base_url);
1806 This->detachFromCustomHandlersDao();
1808 if (handlerCheck->user_decision & CustomHandlerDB::Agreed) {
1809 int ret = appsvc_unset_defapp(
1810 DPL::ToUTF8String(This->m_model->TizenId).c_str());
1811 if (APPSVC_RET_OK != ret) {
1812 LogWarning("Failed to unregister appsvc entry");
1816 //if appsvc ok change custom_handlers_db
1817 handlersDao.unregisterProtocolHandler(customHandler->target,
1819 customHandler->base_url);
1821 LogDebug("Nothing to unregister");
1825 void ViewLogic::contentHandlerRegistrationCallback(void* data,
1826 Evas_Object* /*obj*/,
1831 CustomHandlerDB::CustomHandlerPtr customHandler =
1832 getCustomHandlerFromData(eventInfo);
1834 std::string mimeType = DPL::ToUTF8String(customHandler->target);
1835 if (mimeType.empty()) {
1836 LogError("No mimeType provided.");
1839 for (int i = 0; i < contentBlackListLenth; ++i) {
1840 if (0 == strcmp(contentBlackList[i], mimeType.c_str())) {
1841 LogWarning("mimeType blacklisted");
1842 //throw SecurityException
1847 ViewLogic* This = static_cast<ViewLogic*>(data);
1848 LogDebug("Creating handlers dao");
1849 This->attachToCustomHandlersDao();
1850 CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1851 CustomHandlerDB::CustomHandlerPtr handler =
1852 handlersDao.getContentHandler(customHandler->target,
1854 customHandler->base_url);
1855 if (handler && (handler->user_decision & CustomHandlerDB::DecisionSaved)) {
1856 LogDebug("Protocol already registered - nothing to do");
1858 LogDebug("Protocol handler not found");
1859 Wrt::Popup::PopupResponse response =
1860 GlobalSettings::PopupsTestModeEnabled() ? Wrt::Popup::
1862 Wrt::Popup::PopupInvoker().askYesNoCheckbox(
1863 CONTENT_HANDLER_ASK_TITLE,
1864 CONTENT_HANDLER_ASK_MSG,
1865 CONTENT_HANDLER_AKS_REMEMBER);
1866 saveUserResponse(response, customHandler);
1867 if (customHandler->user_decision == CustomHandlerDB::Declined) {
1870 if (customHandler->user_decision & CustomHandlerDB::Agreed) {
1871 //TODO remove old default handler somehow from appsvc
1872 LogDebug("Registering appservice entry");
1873 int ret = appsvc_set_defapp(APPSVC_OPERATION_VIEW,
1875 customHandler->target).c_str(),
1877 DPL::ToUTF8String(This->m_model->
1879 if (APPSVC_RET_OK != ret) {
1880 LogWarning("Appsvc entry failed: " << ret);
1884 handlersDao.registerContentHandler(*(customHandler.get()));
1885 LogDebug("Content saved");
1887 This->detachFromCustomHandlersDao();
1890 void ViewLogic::contentHandlerIsRegisteredCallback(void* data,
1891 Evas_Object* /*obj*/,
1895 CustomHandlerDB::CustomHandlerPtr customHandler =
1896 getCustomHandlerFromData(eventInfo);
1897 ViewLogic* This = static_cast<ViewLogic*>(data);
1898 LogDebug("Creating handlers dao");
1900 This->attachToCustomHandlersDao();
1901 CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1902 CustomHandlerDB::CustomHandlerPtr handler =
1903 handlersDao.getContentHandler(customHandler->target,
1905 customHandler->base_url);
1907 if (handler->user_decision & CustomHandlerDB::Agreed) {
1908 ewk_custom_handlers_data_result_set(
1909 static_cast<Ewk_Custom_Handlers_Data*>(eventInfo),
1910 EWK_CUSTOM_HANDLERS_REGISTERED);
1912 ewk_custom_handlers_data_result_set(
1913 static_cast<Ewk_Custom_Handlers_Data*>(eventInfo),
1914 EWK_CUSTOM_HANDLERS_DECLINED);
1917 ewk_custom_handlers_data_result_set(
1918 static_cast<Ewk_Custom_Handlers_Data*>(eventInfo),
1919 EWK_CUSTOM_HANDLERS_NEW);
1921 This->detachFromCustomHandlersDao();
1924 void ViewLogic::contentHandlerUnregistrationCallback(void* data,
1925 Evas_Object* /*obj*/,
1929 CustomHandlerDB::CustomHandlerPtr customHandler =
1930 getCustomHandlerFromData(eventInfo);
1931 ViewLogic* This = static_cast<ViewLogic*>(data);
1932 LogDebug("Creating handlers dao");
1933 This->attachToCustomHandlersDao();
1934 CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1935 CustomHandlerDB::CustomHandlerPtr handlerCheck =
1936 handlersDao.getContentHandler(customHandler->target,
1938 customHandler->base_url);
1939 This->detachFromCustomHandlersDao();
1941 if (handlerCheck->user_decision & CustomHandlerDB::Agreed) {
1942 int ret = appsvc_unset_defapp(
1943 DPL::ToUTF8String(This->m_model->TizenId).c_str());
1944 if (APPSVC_RET_OK != ret) {
1945 LogWarning("Failed to unregister mime handler from appsvc");
1949 handlersDao.unregisterContentHandler(customHandler->target,
1951 customHandler->base_url);
1953 LogDebug("Nothing to unregister");
1957 void ViewLogic::didRunJavaScriptCallback(
1958 Evas_Object* /*obj*/,
1962 LogDebug("didRunJavaScriptCallback called");
1963 LogDebug("result = " << result);
1966 void ViewLogic::eaKeyCallback(void* data, Evas_Object* obj, void* eventInfo)
1969 ViewLogic* This = static_cast<ViewLogic*>(data);
1971 Ea_Callback_Type keyType =
1972 static_cast<Ea_Callback_Type>(reinterpret_cast<intptr_t>(eventInfo));
1974 LogDebug("Key = [" << keyType << "]");
1976 std::string keyName;
1977 if (keyType == EA_CALLBACK_BACK) {
1979 #if 0 // FIXME!!!! ewk_view_text_selection_clear has not landed yet
1980 // Call fullscreen exit API
1981 // In case of fullscreen is entered by platform(default video tag),
1982 // automatically exit fullscreen when backkey is selected
1983 if (This->m_isFullscreenByPlatform) {
1984 ewk_view_fullscreen_exit(obj);
1988 // Call text selection clear API
1989 // In case of current state is selection mode,
1990 // application doesn't need to handle back key
1991 if (EINA_TRUE == ewk_view_text_selection_clear(obj)) {
1995 keyName = KeyName::BACK;
1996 } else if (keyType == EA_CALLBACK_MORE) {
1997 keyName = KeyName::MENU;
2002 if (This->m_model->SettingList.Get().getHWkeyEvent() == HWkeyEvent_Enable)
2004 DispatchEventSupport::dispatchHwKeyEvent(obj, keyName);
2006 This->m_cbs->hwkey(keyName);
2011 Eina_Bool ViewLogic::windowCloseIdlerCallback(void* data)
2013 LogDebug("closeIdlerCallback");
2014 ViewLogic* This = static_cast<ViewLogic*>(data);
2015 This->windowClose();
2016 return ECORE_CALLBACK_CANCEL;
2019 Eina_Bool ViewLogic::exceededDatabaseQuotaCallback(Evas_Object* obj,
2020 Ewk_Security_Origin* origin,
2022 unsigned long long ,
2025 LogDebug("exceededDatabaseQuotaCallback called");
2027 ViewLogic* This = static_cast<ViewLogic*>(data);
2030 if (This->m_model->WebStorageUsage.Get() == WrtDB::SETTINGS_TYPE_OFF) {
2031 ewk_view_exceeded_database_quota_reply(obj, EINA_FALSE);
2035 ViewModule::WebStorageSupport::createPermissionRequest(
2036 This->m_currentEwkView,
2037 This->m_securityOriginSupport->getSecurityOriginDAO(),
2040 ewk_view_exceeded_database_quota_reply);
2044 Eina_Bool ViewLogic::exceededIndexedDatabaseQuotaCallback(Evas_Object* obj,
2045 Ewk_Security_Origin* origin,
2049 LogDebug("exceededIndexedDatabaseQuotaCallback called");
2051 ViewLogic* This = static_cast<ViewLogic*>(data);
2054 if (This->m_model->WebStorageUsage.Get() == WrtDB::SETTINGS_TYPE_OFF) {
2055 ewk_view_exceeded_indexed_database_quota_reply(obj, EINA_FALSE);
2059 ViewModule::WebStorageSupport::createPermissionRequest(
2060 This->m_currentEwkView,
2061 This->m_securityOriginSupport->getSecurityOriginDAO(),
2064 ewk_view_exceeded_indexed_database_quota_reply);
2068 Eina_Bool ViewLogic::exceededLocalFileSystemQuotaCallback(Evas_Object* obj,
2069 Ewk_Security_Origin* origin,
2073 LogDebug("exceededLocalFileSystemQuotaCallback called");
2075 ViewLogic* This = static_cast<ViewLogic*>(data);
2079 if (This->m_model->WebStorageUsage.Get() == WrtDB::SETTINGS_TYPE_OFF) {
2080 ewk_view_exceeded_local_file_system_quota_reply(obj, EINA_FALSE);
2084 ViewModule::WebStorageSupport::createPermissionRequest(
2085 This->m_currentEwkView,
2086 This->m_securityOriginSupport->getSecurityOriginDAO(),
2089 ewk_view_exceeded_local_file_system_quota_reply);
2093 void ViewLogic::certificateConfirmRequestCallback(
2095 Evas_Object* /*obj*/,
2098 LogDebug("certificateConfirmRequestCallback called");
2101 ViewLogic* This = static_cast<ViewLogic*>(data);
2103 ViewModule::CertificateConfirmSupport::certificatePermissionRequest(
2104 This->m_currentEwkView,
2105 This->m_certificateSupport->getCertificateDAO(),
2109 void ViewLogic::authenticationChallengeRequestCallback(
2111 Evas_Object* /*obj*/,
2114 LogDebug("authenticationChallengeRequestCallback called");
2118 ViewLogic* This = static_cast<ViewLogic*>(data);
2119 const char* url = ewk_view_url_get(This->m_currentEwkView);
2120 if (!url || strlen(url) == 0) {
2121 Ewk_Auth_Challenge* authChallenge = static_cast<Ewk_Auth_Challenge*>(eventInfo);
2122 ewk_auth_challenge_credential_cancel(authChallenge);
2125 ViewModule::AuthenticationChallengeSupport::authenticationChallengeRequest(
2126 This->m_currentEwkView,
2131 void ViewLogic::viewFrameRenderedCallback(
2133 Evas_Object* /*obj*/,
2134 void* /*eventInfo*/)
2136 static bool logEnable = (getenv("WRT_FRAME_RENDERED_LOG_ENABLE") != NULL);
2144 void ViewLogic::mediacontrolRotateHorizontal(void* data,
2146 void* /*eventInfo*/)
2148 LogDebug("mediacontrolRotateHorizontal called");
2151 ViewLogic* This = static_cast<ViewLogic*>(data);
2152 ViewModule::OrientationSupport::setEwkOrientation(
2154 OrientationAngle::W3C::Landscape::PRIMARY);
2155 if (!This->m_cbs->setOrientation.empty()) {
2156 This->m_cbs->setOrientation(
2157 OrientationAngle::Window::Landscape::PRIMARY);
2161 void ViewLogic::mediacontrolRotateVertical(void* data,
2163 void* /*eventInfo*/)
2165 LogDebug("mediacontrolRotateVertical called");
2168 ViewLogic* This = static_cast<ViewLogic*>(data);
2169 ViewModule::OrientationSupport::setEwkOrientation(
2171 OrientationAngle::W3C::Portrait::PRIMARY);
2172 if (!This->m_cbs->setOrientation.empty()) {
2173 This->m_cbs->setOrientation(
2174 OrientationAngle::Window::Portrait::PRIMARY);
2178 void ViewLogic::mediacontrolRotateExit(void* data,
2180 void* /*eventInfo*/)
2182 LogDebug("mediacontrolRotateExit called");
2185 ViewLogic* This = static_cast<ViewLogic*>(data);
2189 if (This->m_rotateAngle == 0) {
2190 // application hasn't call orientation lock
2191 WidgetSettingScreenLock screenLock =
2192 This->m_model->SettingList.Get().getRotationValue();
2193 if (screenLock == Screen_Portrait) {
2194 w3cAngle = OrientationAngle::W3C::Portrait::PRIMARY;
2195 winAngle = OrientationAngle::Window::Portrait::PRIMARY;
2196 } else if (screenLock == Screen_Landscape) {
2197 w3cAngle = OrientationAngle::W3C::Landscape::PRIMARY;
2198 winAngle = OrientationAngle::Window::Landscape::PRIMARY;
2199 } else if (screenLock == Screen_AutoRotation) {
2200 if (!This->m_cbs->setOrientation.empty()) {
2201 This->m_cbs->setOrientation(OrientationAngle::Window::UNLOCK);
2206 // Restore previous orientation
2208 ViewModule::OrientationSupport::getW3COrientationAngle(
2209 This->m_rotateAngle);
2211 ViewModule::OrientationSupport::getWinOrientationAngle(
2212 This->m_rotateAngle);
2215 ViewModule::OrientationSupport::setEwkOrientation(obj, w3cAngle);
2216 if (!This->m_cbs->setOrientation.empty()) {
2217 This->m_cbs->setOrientation(winAngle);
2222 Eina_Bool ViewLogic::orientationThresholdTimerCallback(void* data)
2224 LogDebug("orientationThresholdTimerCallback");
2225 ViewLogic* This = static_cast<ViewLogic*>(data);
2227 if (This->m_deferredRotateAngle ==
2228 ViewModule::OrientationSupport::DEFERRED_ORIENTATION_EMPTY)
2230 // There is no defered orientation API call
2231 This->m_orientationThresholdTimer = NULL;
2232 return ECORE_CALLBACK_CANCEL;
2235 if (This->m_deferredRotateAngle != This->m_rotateAngle) {
2236 This->m_rotateAngle = This->m_deferredRotateAngle;
2239 if (This->m_rotateAngle == 0) {
2240 WidgetSettingScreenLock screenLock =
2241 This->m_model->SettingList.Get().getRotationValue();
2242 if (screenLock == Screen_Portrait) {
2243 w3cAngle = OrientationAngle::W3C::Portrait::PRIMARY;
2244 winAngle = OrientationAngle::Window::Portrait::PRIMARY;
2245 } else if (screenLock == Screen_Landscape) {
2246 w3cAngle = OrientationAngle::W3C::Landscape::PRIMARY;
2247 winAngle = OrientationAngle::Window::Landscape::PRIMARY;
2248 } else if (screenLock == Screen_AutoRotation) {
2249 if (!This->m_cbs->setOrientation.empty()) {
2250 This->m_cbs->setOrientation(OrientationAngle::Window::UNLOCK);
2252 This->m_orientationThresholdTimer = NULL;
2253 return ECORE_CALLBACK_CANCEL;
2256 // Restore previous orientation
2258 ViewModule::OrientationSupport::getW3COrientationAngle(
2259 This->m_rotateAngle);
2261 ViewModule::OrientationSupport::getWinOrientationAngle(
2262 This->m_rotateAngle);
2265 ViewModule::OrientationSupport::setEwkOrientation(
2266 This->m_currentEwkView,
2268 if (!This->m_cbs->setOrientation.empty()) {
2269 This->m_cbs->setOrientation(winAngle);
2271 This->m_deferredRotateAngle =
2272 ViewModule::OrientationSupport::DEFERRED_ORIENTATION_EMPTY;
2273 return ECORE_CALLBACK_RENEW;
2276 This->m_orientationThresholdTimer = NULL;
2277 return ECORE_CALLBACK_CANCEL;
2280 void ViewLogic::popupReplyWaitStart(void* data,
2281 Evas_Object* /*obj*/,
2282 void* /*eventInfo*/)
2286 ViewLogic* This = static_cast<ViewLogic*>(data);
2287 This->m_isPopupReplyWait = true;
2290 void ViewLogic::popupReplyWaitFinish(void* data,
2291 Evas_Object* /*obj*/,
2292 void* /*eventInfo*/)
2296 ViewLogic* This = static_cast<ViewLogic*>(data);
2297 This->m_isPopupReplyWait = false;
2300 void ViewLogic::requestUrlBlocked(const std::string& blockedUrl)
2304 // block this page and open it in browser
2305 LogDebug("Request was blocked : " << blockedUrl);
2306 service_h serviceHandle = NULL;
2307 service_create(&serviceHandle);
2308 service_set_operation(serviceHandle, SERVICE_OPERATION_VIEW);
2309 service_set_uri(serviceHandle, blockedUrl.c_str());
2310 CONTROLLER_POST_EVENT(
2311 ApplicationLauncher,
2312 ApplicationLauncherEvents::LaunchApplicationByAppService(
2316 // set block url. This is used on load finished callback
2317 m_blockedUri = blockedUrl;
2320 void ViewLogic::windowClose()
2322 LogDebug("windowClose");
2323 Assert(m_closedEwkView && "no closed webview");
2325 if (1 >= m_ewkViewList.size()) {
2326 if (!m_cbs->webkitExit.empty()) {
2327 m_cbs->webkitExit();
2330 // call user callbacks
2331 if (!m_cbs->bufferUnset.empty()) {
2332 m_cbs->bufferUnset(m_currentEwkView);
2334 if (!m_cbs->windowClose.empty()) {
2335 m_cbs->windowClose(m_closedEwkView);
2337 removeEwkView(m_closedEwkView);
2339 // get latest ewkView
2340 m_currentEwkView = m_ewkViewList.back();
2342 setEwkViewVisible(m_currentEwkView);
2345 if (!m_cbs->bufferSet.empty()) {
2346 m_cbs->bufferSet(m_currentEwkView);
2351 void ViewLogic::systemSettingsChangedCallback(system_settings_key_e key,
2354 LogDebug("systemSettingsChanged");
2355 LogDebug("System setting Key is [" << key << "]");
2358 ViewLogic* This = static_cast<ViewLogic*>(data);
2360 if (SYSTEM_SETTINGS_KEY_FONT_TYPE == key) {
2361 if (!This->m_currentEwkView) {
2362 LogError("ewkView isn't initialized");
2365 ewk_view_use_settings_font(This->m_currentEwkView);
2367 LogError("Unregister system callback is called");