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");
300 setEwkViewInvisible(m_currentEwkView);
302 if (!m_isBackgroundSupport) {
303 FOREACH(it, m_ewkViewList) {
304 if (*it != m_currentEwkView) {
309 suspendWebkit(m_currentEwkView);
313 // call user callback
314 if (!m_cbs->suspend.empty()) {
315 m_cbs->suspend(true);
319 void ViewLogic::resumeWidget()
321 LogDebug("Resume widget");
324 if (m_currentEwkView)
326 setEwkViewVisible(m_currentEwkView);
328 if (!m_isBackgroundSupport) {
329 FOREACH(it, m_ewkViewList) {
330 if (*it != m_currentEwkView) {
335 resumeWebkit(m_currentEwkView);
339 /* window system team recomend removing this win_raise code. */
342 * elm_win_raise(m_window);
346 // call user callback
347 if (!m_cbs->resume.empty()) {
352 void ViewLogic::resetWidget()
354 LogDebug("Resetting Widget");
356 // handling case of WebProcess is locked
357 if (m_isPopupReplyWait) {
358 // resume web application
359 LogDebug("WebProcess is locked");
360 if (m_currentEwkView) {
361 setEwkViewVisible(m_currentEwkView);
362 if (!m_isBackgroundSupport) {
363 resumeWebkit(m_currentEwkView);
367 elm_win_activate(m_window);
369 // call user callback
370 if (!m_cbs->reset.empty()) {
374 // reset web application
375 // destory all webview
376 while (!m_ewkViewList.empty()) {
377 LogDebug("pop webview: " << m_ewkViewList.back());
378 removeEwkView(m_ewkViewList.back());
380 m_ewkViewList.clear();
381 m_currentEwkView = NULL;
383 // create new webview
384 createEwkView(evas_object_evas_get(m_window));
385 ewkClientInit(m_currentEwkView);
386 prepareEwkView(m_currentEwkView);
388 // check if current url is service url for this tizen service
390 ViewModule::UriSupport::getUri(m_model, m_startUrl);
392 initializePluginLoading();
394 ewk_view_url_set(m_currentEwkView, url.c_str());
395 elm_win_activate(m_window);
397 // call user callback
398 if (!m_cbs->reset.empty()) {
401 if (!m_cbs->bufferSet.empty()) {
402 m_cbs->bufferSet(m_currentEwkView);
407 void ViewLogic::backward()
409 if (ewk_view_back_possible(m_currentEwkView)) {
410 ewk_view_back(m_currentEwkView);
412 if (1 >= m_ewkViewList.size()) {
413 // If there is no previous page, widget move to backgroud.
414 LogDebug("Widget move to backgroud");
415 elm_win_lower(m_window);
417 // Back to previous webview
418 LogDebug("Widget move to previous webview");
419 m_closedEwkView = m_currentEwkView;
420 ecore_idler_add(windowCloseIdlerCallback, this);
425 void ViewLogic::reloadStartPage()
427 LogDebug("Reload Start Page");
428 // prevent fail to load plugin bundle side
429 m_isBackgroundReload = true;
431 if (!m_ewkViewList.empty()) {
432 while (!m_ewkViewList.empty()) {
433 if (!m_cbs->bufferUnset.empty()) {
434 m_cbs->bufferUnset(m_currentEwkView);
436 removeEwkView(m_currentEwkView);
440 // create new webview
441 createEwkView(evas_object_evas_get(m_window));
442 ewkClientInit(m_currentEwkView);
444 prepareEwkView(m_currentEwkView);
445 initializePluginLoading();
448 std::string url = ViewModule::UriSupport::getUri(m_model, m_startUrl);
449 ewk_view_url_set(m_currentEwkView, url.c_str());
452 if (!m_cbs->bufferSet.empty()) {
453 m_cbs->bufferSet(m_currentEwkView);
455 LogDebug("Reloading Start Page is done!");
458 Evas_Object* ViewLogic::getCurrentWebview()
460 LogDebug("get current webview");
461 return m_currentEwkView;
464 void ViewLogic::fireJavascriptEvent(int event, void* data)
466 ViewLogicMessageSupport::dispatchJavaScriptEvent(
468 static_cast<WrtPlugins::W3C::CustomEventType>(event),
472 void ViewLogic::setUserCallbacks(const WRT::UserDelegatesPtr& cbs)
477 void ViewLogic::checkSyncMessageFromBundle(
479 const char* /*body*/,
482 LogDebug("didReceiveSynchronousMessage called");
485 LogDebug("received : " << name);
486 if (!strcmp(name, Message::TizenScheme::GET_WINDOW_HANDLE)) {
488 Ecore_X_Window handle = elm_win_xwindow_get(m_window);
490 std::stringstream ss;
492 std::string ret = ss.str();
494 *returnData = strdup(ret.c_str());
497 LogDebug("X window isn't exist");
503 void ViewLogic::checkAsyncMessageFromBundle(const char* name, const char* body)
506 _D("received : %s", name);
508 if (!strcmp(name, Message::ToUIProcess::BLOCKED_URL)) {
509 // Currently WebProcess informs obly about blocked
510 // URI - URI localization and security chekcs are
511 // done by WebProcess itself (see: wrt-injected-bundle.cpp
512 // and bundle_uri_handling.cpp)
513 requestUrlBlocked(std::string(body));
514 } else if (!strcmp(name, Message::TizenScheme::CLEAR_ALL_COOKIES)) {
515 Ewk_Cookie_Manager* cookieManager =
516 ewk_context_cookie_manager_get(m_ewkContext);
517 if (!cookieManager) {
518 _E("Fail to get cookieManager");
521 ewk_cookie_manager_cookies_clear(cookieManager);
522 } else if (!strcmp(name, IPCMessageSupport::TIZEN_CHANGE_USERAGENT)) {
523 std::string msgBody = (body) ? (body) : "";
525 std::string strId = msgBody.substr(0, msgBody.find_first_of('_'));
526 std::string strBody = msgBody.substr(msgBody.find_first_of('_')+1);
527 _D("Id: %s , Body %s", strId.c_str(), strBody.c_str());
529 ewk_view_user_agent_set(m_currentEwkView, strBody.c_str());
530 _D("get UA: %s", ewk_view_user_agent_get(m_currentEwkView));
532 IPCMessageSupport::replyAsyncMessageToWebProcess(m_ewkContext,
536 } else if (!strcmp(name, IPCMessageSupport::TIZEN_DELETE_ALL_COOKIES)) {
537 std::string msgBody = (body) ? (body) : "";
538 std::string strId = msgBody.substr(0, msgBody.find_first_of('_'));
539 std::string strBody = msgBody.substr(msgBody.find_first_of('_')+1);
541 Ewk_Cookie_Manager* cookieManager =
542 ewk_context_cookie_manager_get(m_ewkContext);
543 if (!cookieManager) {
544 _E("Fail to get cookieManager");
545 IPCMessageSupport::replyAsyncMessageToWebProcess(
551 ewk_cookie_manager_cookies_clear(cookieManager);
552 IPCMessageSupport::replyAsyncMessageToWebProcess(m_ewkContext,
556 } else if (!strcmp(name, IPCMessageSupport::TIZEN_EXIT) ||
557 !strcmp(name, IPCMessageSupport::TIZEN_HIDE))
560 ViewModule::SchemeSupport::HandleTizenScheme(name,
564 _E("Fail to handle tizen scheme %s", name);
566 // Not need to send reply
569 _W("Not defined message");
573 void ViewLogic::downloadData(const char* url)
579 m_appsSupport->downloadRequest(url, NULL, NULL);
582 void ViewLogic::activateVibration(bool on, uint64_t time)
586 m_vibrationSupport->startVibration(static_cast<long>(time));
588 m_vibrationSupport->stopVibration();
592 void ViewLogic::initializeSupport()
594 // background support
595 if (m_model->SettingList.Get().getBackgroundSupport()
596 == BackgroundSupport_Enable)
598 LogDebug("Background support enabled, set process active");
599 sysman_inform_active(getpid());
600 m_isBackgroundSupport = true;
602 system_settings_set_changed_cb(SYSTEM_SETTINGS_KEY_FONT_TYPE,
603 systemSettingsChangedCallback,
606 ViewModule::StorageSupport::initializeStorage(m_model);
607 m_appsSupport->initialize(m_model, elm_win_xwindow_get(m_window));
608 m_securityOriginSupport.reset(new ViewModule::SecurityOriginSupport(m_model));
609 m_certificateSupport.reset(new ViewModule::CertificateSupport(m_model));
610 m_vibrationSupport->initialize();
611 m_webNotificationSupport->initialize(m_model->TzPkgId.Get());
614 void ViewLogic::initializePluginLoading()
616 // inform wrt information for plugin loading to web process
617 ViewLogicMessageSupport::start(
620 elm_config_scale_get(),
621 ApplicationDataSingleton::Instance().getEncodedBundle(),
625 void ViewLogic::initializeXwindowHandle()
628 unsigned int handle = elm_win_xwindow_get(m_window);
629 ViewLogicMessageSupport::setXwindowHandle(
635 void ViewLogic::ewkClientInit(Evas_Object *wkView)
637 Assert(NULL != wkView && "ewk_view not created at this point");
639 FOREACH(it, m_ewkCallbacksMap)
641 evas_object_smart_callback_add(
647 // EWK Orientation Callback
648 ewk_view_orientation_lock_callback_set(
650 orientationLockCallback,
652 ewk_view_exceeded_database_quota_callback_set(
654 exceededDatabaseQuotaCallback,
656 ewk_view_exceeded_indexed_database_quota_callback_set(
658 exceededIndexedDatabaseQuotaCallback,
660 ewk_view_exceeded_local_file_system_quota_callback_set(
662 exceededLocalFileSystemQuotaCallback,
664 ea_object_event_callback_add(wkView,
668 ea_object_event_callback_add(wkView,
672 #if 0 // FIXME!!! elm_access_object_register has not landed yet
673 // Always register access object even application doesn't support
674 // accessibility. In case of accessibility isn't supported, efl_assist
675 // shows warning message by syspopup.
676 // initScreenReaderSupport is related method. (window_data.cpp)
677 elm_access_object_register(wkView, m_window);
681 void ViewLogic::ewkClientDeinit(Evas_Object *wkView)
683 LogDebug("ewkClientDeinit");
684 Assert(NULL != wkView && "ewk_view not created at this point");
686 FOREACH(it, m_ewkCallbacksMap)
688 evas_object_smart_callback_del(
693 ewk_view_orientation_lock_callback_set(wkView, NULL, NULL);
694 ewk_view_exceeded_database_quota_callback_set(wkView, NULL, NULL);
695 ewk_view_exceeded_indexed_database_quota_callback_set(wkView, NULL, NULL);
696 ewk_view_exceeded_local_file_system_quota_callback_set(wkView, NULL, NULL);
697 ea_object_event_callback_del(wkView,
700 ea_object_event_callback_del(wkView,
703 if (m_orientationThresholdTimer) {
704 ecore_timer_del(m_orientationThresholdTimer);
705 m_orientationThresholdTimer = NULL;
707 // FIXME!!!! elm_access_object_unregister has not landed in
708 // tizen 3.0 elementary yet
709 // elm_access_object_unregister(wkView);
712 bool ViewLogic::createEwkView(Evas* canvas)
714 LogDebug("createEwkView");
716 ADD_PROFILING_POINT("ewk_view_add_with_context", "start");
717 Evas_Object* newEwkView = ewk_view_add_with_context(
720 ADD_PROFILING_POINT("ewk_view_add_with_context", "stop");
723 LogError("View creation failed");
724 Wrt::Popup::PopupInvoker().showInfo(
725 "Info", "View creation failed", "close");
730 // even arguments pass the ewkContext, this API should be called
731 // after webkit Evas_Object is created
732 Ewk_Cookie_Manager *ewkCookieManager;
734 ewk_context_cookie_manager_get(m_ewkContext);
735 ewk_cookie_manager_accept_policy_set(ewkCookieManager,
736 EWK_COOKIE_ACCEPT_POLICY_ALWAYS);
738 if (m_currentEwkView) {
739 setEwkViewInvisible(m_currentEwkView);
742 LogDebug("push webview: " << newEwkView);
743 m_ewkViewList.push_back(newEwkView);
744 m_currentEwkView = newEwkView;
748 void ViewLogic::prepareEwkView(Evas_Object *wkView)
750 LogDebug("prepareEwkView called");
752 Ewk_Settings* settings = ewk_view_settings_get(wkView);
755 std::string customUserAgent = m_model->SettingList.Get().getUserAgent();
756 if (customUserAgent.empty()) {
757 LogDebug("Setting user agent as: default");
758 ewk_view_user_agent_set(wkView, NULL);
759 std::string defaultUA = ewk_view_user_agent_get(wkView);
760 LogDebug("webkit's UA: " << defaultUA);
762 LogDebug("Setting custom user agent as: " << customUserAgent);
763 ewk_view_user_agent_set(wkView, customUserAgent.c_str());
766 // set custom header : language
767 using namespace ViewModule::CustomHeaderSupport;
768 std::string customHeaderString = getValueByField(ACCEPT_LANGUAGE);
769 if (!customHeaderString.empty()) {
770 LogDebug("custom field=[" << ACCEPT_LANGUAGE << "]");
771 LogDebug("custom value=[" << customHeaderString << "]");
772 ewk_view_custom_header_add(wkView,
773 ACCEPT_LANGUAGE.c_str(),
774 customHeaderString.c_str());
777 // webkit NPAPI plugins is always on in wrt
778 ewk_settings_plugins_enabled_set(settings, EINA_TRUE);
779 ewk_settings_javascript_enabled_set(settings, EINA_TRUE);
780 ewk_settings_loads_images_automatically_set(settings, EINA_TRUE);
781 // WRT should not fit web contents to device width automatically as default.
782 // Fitting to device width should be handled by web content using viewport meta tag.
783 ewk_settings_auto_fitting_set(settings, EINA_FALSE);
784 ewk_settings_autofill_password_form_enabled_set(settings, EINA_TRUE);
785 ewk_settings_form_candidate_data_enabled_set(settings, EINA_TRUE);
787 ewk_view_page_visibility_state_set(wkView,
788 EWK_PAGE_VISIBILITY_STATE_VISIBLE,
791 std::string encoding = DEFAULT_ENCODING;
792 OptionalWidgetStartFileInfo fileInfo =
793 W3CFileLocalization::getStartFileInfo(m_model->TizenId);
794 #if 0 // FIXME!!!! ewk_settings_is_encoding_valid has not landed yet
795 if (!fileInfo.IsNull()) {
796 std::string file_encoding = DPL::ToUTF8String((*fileInfo).encoding);
798 if(EINA_TRUE == ewk_settings_is_encoding_valid(
799 file_encoding.c_str())){
800 encoding = file_encoding;
801 _D("Found custom encoding in DB: %s", encoding.c_str());
806 _D("Setting encoding: %s", encoding.c_str());
807 if (ewk_settings_default_encoding_set(settings,encoding.c_str())) {
808 _D("Encoding set properly");
810 _E("Error while setting encoding");
814 if (m_model->SecurityModelVersion.Get() ==
815 WrtDB::WidgetSecurityModelVersion::WIDGET_SECURITY_MODEL_V2)
817 // setting CSP policy rules
818 DPL::OptionalString policy = m_model->CspReportOnlyPolicy.Get();
819 if (!policy.IsNull()) {
820 LogDebug("CSP report only policy present in manifest: " << *policy);
821 ewk_view_content_security_policy_set(
823 DPL::ToUTF8String(*policy).c_str(),
827 policy = m_model->CspPolicy.Get();
828 if (!policy.IsNull()) {
829 LogDebug("CSP policy present in manifest: " << *policy);
830 ewk_view_content_security_policy_set(
832 DPL::ToUTF8String(*policy).c_str(),
835 ewk_view_content_security_policy_set(
844 void ViewLogic::removeEwkView(Evas_Object *wkView)
846 LogDebug("removeEwkView called");
848 Assert(0 != m_ewkViewList.size());
850 // unregister webview callbacks
851 ewkClientDeinit(wkView);
853 // suspend NPAPI plugin - Not implemented by Webkit2
854 // ewk_view_pause_or_resume_plugins();
855 evas_object_del(wkView);
856 m_ewkViewList.remove(wkView);
859 void ViewLogic::setEwkViewInvisible(Evas_Object *wkView)
861 LogDebug("setEwkViewInvisible called");
864 ewk_view_page_visibility_state_set(wkView,
865 EWK_PAGE_VISIBILITY_STATE_HIDDEN,
867 ewk_view_visibility_set(wkView, EINA_FALSE);
870 void ViewLogic::setEwkViewVisible(Evas_Object *wkView)
872 LogDebug("setEwkViewVisible called");
875 ewk_view_page_visibility_state_set(wkView,
876 EWK_PAGE_VISIBILITY_STATE_VISIBLE,
878 ewk_view_visibility_set(wkView, EINA_TRUE);
881 void ViewLogic::resumeWebkit(Evas_Object *wkView)
883 LogDebug("resumeWebkit : " << wkView);
886 ewk_view_resume(wkView);
887 // FIXME!!!! ewk_view_foreground_set has not landed yet
888 // ewk_view_foreground_set(wkView, true);
893 void ViewLogic::suspendWebkit(Evas_Object *wkView)
895 LogDebug("suspendWebkit : " << wkView);
898 ewk_view_suspend(wkView);
899 // FIXME!!!! ewk_view_foreground_set has not landed in the
900 // tizen 3.0 elementary project yet
901 // ewk_view_foreground_set(wkView, false);
906 void ViewLogic::loadStartedCallback(
911 LogDebug("loadStartedCallback called");
913 ViewLogic* This = static_cast<ViewLogic*>(data);
915 // call loadFinish callback to wrt-client
916 if (!This->m_cbs->loadStart.empty()) {
917 This->m_cbs->loadStart(obj);
921 void ViewLogic::loadFinishedCallback(
926 LogDebug("loadFinishedCallback called");
928 ViewLogic* This = static_cast<ViewLogic*>(data);
931 const char* url = ewk_view_url_get(This->m_currentEwkView);
932 if (NULL == url || strlen(url) == 0) {
933 LogError("url is empty");
937 // call loadFinish callback to wrt-client
938 if (!This->m_cbs->loadFinish.empty()) {
939 This->m_cbs->loadFinish(obj);
942 // set only encoded bundle
943 double scale = elm_config_scale_get();
944 ViewLogicMessageSupport::setCustomProperties(
947 ApplicationDataSingleton::Instance().getEncodedBundle());
949 // In this case, widget is reloaded in the background.
950 // After finished load, bundle should disconnent callback.
951 if (This->m_isBackgroundReload) {
952 ewk_view_suspend(This->m_currentEwkView);
953 This->m_isBackgroundReload = false;
957 void ViewLogic::loadProgressStartedCallback(
959 Evas_Object* /*obj*/,
962 _D("loadProgressStartedCallback called");
964 ViewLogic* This = static_cast<ViewLogic*>(data);
965 if (!This->m_cbs->progressStarted.empty()) {
966 This->m_cbs->progressStarted();
971 void ViewLogic::loadProgressCallback(
976 _D("loadProgressCallback called");
979 ViewLogic const * const view = static_cast<ViewLogic const * const>(data);
980 double* progress = static_cast<double*>(eventInfo);
981 LogDebug("didChangeProgressCallback progress = " << *progress);
982 if (!view->m_cbs->progress.empty()) {
984 view->m_cbs->progress(obj, *progress);
988 void ViewLogic::loadProgressFinishedCallback(
990 Evas_Object* /*obj*/,
993 LogDebug("didFinishProgressCallback");
995 ViewLogic const * const view = static_cast<ViewLogic const * const>(data);
996 if (!view->m_cbs->progressFinish.empty()) {
997 view->m_cbs->progressFinish();
1001 void ViewLogic::processCrashedCallback(
1003 Evas_Object* /*obj*/,
1006 LogDebug("processCrashedCallback");
1008 ViewLogic const * const view =
1009 static_cast<ViewLogic const * const>(data);
1010 if (!view->m_cbs->webCrash.empty()) {
1011 view->m_cbs->webCrash();
1013 // This flag will be prevented exit() call in the Webkit side
1014 if (NULL != eventInfo) {
1015 *(static_cast<Eina_Bool*>(eventInfo)) = EINA_TRUE;
1019 void ViewLogic::createWindowCallback(
1024 LogDebug("createWindowCallback");
1026 ViewLogic* This = static_cast<ViewLogic*>(data);
1028 // First, current webview should be handled by user callback
1029 if (!This->m_cbs->bufferUnset.empty()) {
1030 This->m_cbs->bufferUnset(obj);
1033 // this can be set by executable for specific purpose
1034 Evas* canvas = NULL;
1035 if (!This->m_cbs->windowCreateBefore.empty()) {
1036 // 'obj' is parent webview object
1037 This->m_cbs->windowCreateBefore(&canvas, obj);
1040 canvas = evas_object_evas_get(This->m_window);
1043 // create new ewkview
1044 This->createEwkView(canvas);
1045 Evas_Object* newEwkView = This->m_currentEwkView;
1047 // initialize new ewkview
1048 This->ewkClientInit(newEwkView);
1049 This->prepareEwkView(newEwkView);
1051 // Specific jobs of child, parent webview are handled by each executable
1052 if (!This->m_cbs->windowCreateAfter.empty()) {
1053 // 'obj' is parent webview, 'newEwkView' is child webview
1054 This->m_cbs->windowCreateAfter(obj, newEwkView);
1057 // Lastly, new webview should be handled by user callback
1058 if (!This->m_cbs->bufferSet.empty()) {
1059 This->m_cbs->bufferSet(newEwkView);
1061 *(static_cast<Evas_Object **>(eventInfo)) = newEwkView;
1064 void ViewLogic::closeWindowCallback(
1067 void* /*eventInfo*/)
1069 LogDebug("closeWindowCallback");
1070 ViewLogic* This = static_cast<ViewLogic*>(data);
1071 This->m_closedEwkView = obj;
1072 ecore_idler_add(windowCloseIdlerCallback, This);
1075 void ViewLogic::policyNavigationDecideCallback(
1080 LogDebug("policyNavigationDecideCallback called");
1082 ViewLogic* This = static_cast<ViewLogic*>(data);
1084 Ewk_Policy_Decision* policyDecision =
1085 static_cast<Ewk_Policy_Decision*>(eventInfo);
1087 // handle blocked url
1088 const char* url = ewk_policy_decision_url_get(policyDecision);
1090 // call user delegate callback
1091 if (!This->m_cbs->navigationDecide.empty()) {
1092 std::string navigationUri(url);
1093 This->m_cbs->navigationDecide(obj, navigationUri);
1094 if (!navigationUri.compare(0, 6, SCHEME_BOX_SLASH)) {
1095 ewk_policy_decision_ignore(policyDecision);
1100 if (url && strlen(url) != 0) {
1101 if (This->m_blockedUri == url) {
1102 LogDebug("Blocked url = " << url);
1103 This->m_blockedUri = std::string();
1104 ewk_policy_decision_ignore(policyDecision);
1109 if (ViewModule::SchemeSupport::filterURIByScheme(policyDecision,
1112 This->m_currentEwkView))
1115 ewk_policy_decision_use(policyDecision);
1117 // check whether this is new empty window
1118 const char* activeUrl = ewk_view_url_get(This->m_currentEwkView);
1119 if (!activeUrl || 0 == strlen(activeUrl)) {
1121 * The view is empty and scheme has been handled externally. When
1122 * user gets back from the external application he'd see blank page
1123 * and won't be able to navigate back. This happens when window.open
1124 * is used to handle schemes like sms/mms/mailto (for example in
1125 * WAC web standards tests: WS-15XX).
1127 * To solve the problem, the empty view is removed from the stack
1128 * and the previous one is shown. This is not an elegant solution
1129 * but we don't have a better one.
1131 LogDebug("Scheme has been handled externally. Removing empty view.");
1132 if (ewk_view_back_possible(This->m_currentEwkView)) {
1133 // go back to previous WKPage
1134 ewk_view_back(This->m_currentEwkView);
1136 // stop current WKPage
1137 ewk_view_stop(This->m_currentEwkView);
1138 This->m_closedEwkView = This->m_currentEwkView;
1139 ecore_idler_add(windowCloseIdlerCallback, This);
1144 ewk_policy_decision_ignore(policyDecision);
1148 void ViewLogic::policyNewWindowDecideCallback(
1150 Evas_Object* /*obj*/,
1153 LogDebug("policyNewWindowDecideCallback called");
1155 ViewLogic* This = static_cast<ViewLogic*>(data);
1157 Ewk_Policy_Decision* policyDecision =
1158 static_cast<Ewk_Policy_Decision*>(eventInfo);
1160 // handle blocked url
1161 const char* url = ewk_policy_decision_url_get(policyDecision);
1162 if (url && strlen(url) != 0) {
1163 if (This->m_blockedUri == url) {
1164 LogDebug("Blocked url = " << url);
1165 This->m_blockedUri = std::string();
1166 ewk_policy_decision_ignore(policyDecision);
1171 if (ViewModule::SchemeSupport::filterURIByScheme(policyDecision,
1174 This->m_currentEwkView))
1176 ewk_policy_decision_use(policyDecision);
1179 ewk_policy_decision_ignore(policyDecision);
1183 void ViewLogic::pageResponseDecideCallback(
1185 Evas_Object* /*obj*/,
1188 LogDebug("pageResponseDecideCallback called");
1190 ViewLogic* This = static_cast<ViewLogic*>(data);
1192 Ewk_Policy_Decision* policyDecision =
1193 static_cast<Ewk_Policy_Decision*>(eventInfo);
1194 Ewk_Policy_Decision_Type policyDecisionType =
1195 ewk_policy_decision_type_get(policyDecision);
1197 if (policyDecisionType == EWK_POLICY_DECISION_USE) {
1199 ewk_policy_decision_use(policyDecision);
1200 } else if (policyDecisionType == EWK_POLICY_DECISION_DOWNLOAD) {
1201 LogDebug("download");
1202 ewk_policy_decision_suspend(policyDecision);
1204 // get uri information
1205 const char* url = ewk_policy_decision_url_get(policyDecision);
1206 if (NULL == url || strlen(url) == 0) {
1207 LogDebug("url data is empty");
1208 ewk_policy_decision_use(policyDecision);
1211 LogDebug("url = [" << url << "]");
1213 // get content information
1214 const char* content =
1215 ewk_policy_decision_response_mime_get(policyDecision);
1216 LogDebug("content type = [" << content << "]");
1218 // get cookie information
1219 const char* cookie = ewk_policy_decision_cookie_get(policyDecision);
1220 LogDebug("cookie = [" << cookie << "]");
1222 LogDebug("Content not supported, will be opened in external app");
1223 This->m_appsSupport->downloadRequest(
1227 ewk_policy_decision_ignore(policyDecision);
1228 } else if (policyDecisionType == EWK_POLICY_DECISION_IGNORE) {
1230 ewk_policy_decision_ignore(policyDecision);
1232 LogDebug("Type isn't handled");
1233 ewk_policy_decision_ignore(policyDecision);
1237 void ViewLogic::contextmenuCustomizeCallback(
1239 Evas_Object* /*obj*/,
1242 LogDebug("contextmenuCustomizeCallback called");
1245 ViewLogic* This = static_cast<ViewLogic*>(const_cast<void*>(data));
1246 Ewk_Context_Menu* menu = static_cast<Ewk_Context_Menu*>(eventInfo);
1247 if ((This->m_model->Type.Get().appType == WrtDB::APP_TYPE_TIZENWEBAPP) &&
1248 (This->m_model->SettingList.Get().getContextMenu()
1249 == ContextMenu_Disable))
1251 LogDebug("ContextMenu Disable!!");
1252 for (unsigned int idx = 0; idx < ewk_context_menu_item_count(menu);) {
1253 Ewk_Context_Menu_Item* item = ewk_context_menu_nth_item_get(menu,
1256 ewk_context_menu_item_remove(menu, item);
1259 LogDebug("ContextMenu Enable!!");
1260 unsigned int menu_num = ewk_context_menu_item_count(menu);
1261 unsigned int idx = 0;
1263 Ewk_Context_Menu_Item* item = ewk_context_menu_nth_item_get(menu,
1269 Ewk_Context_Menu_Item_Tag tag = ewk_context_menu_item_tag_get(item);
1272 case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_IMAGE_IN_NEW_WINDOW:
1273 ewk_context_menu_item_remove(menu, item);
1276 case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_LINK_IN_NEW_WINDOW:
1277 ewk_context_menu_item_remove(menu, item);
1280 case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_FRAME_IN_NEW_WINDOW:
1281 ewk_context_menu_item_remove(menu, item);
1284 case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_MEDIA_IN_NEW_WINDOW:
1285 ewk_context_menu_item_remove(menu, item);
1288 case EWK_CONTEXT_MENU_ITEM_TAG_SEARCH_WEB:
1289 ewk_context_menu_item_remove(menu, item);
1292 case EWK_CONTEXT_MENU_ITEM_TAG_DOWNLOAD_IMAGE_TO_DISK:
1293 ewk_context_menu_item_remove(menu, item);
1300 } while (idx < menu_num);
1304 void ViewLogic::geolocationPermissionRequestCallback(
1306 Evas_Object* /*obj*/,
1310 ViewLogic* This = static_cast<ViewLogic*>(data);
1312 Ewk_Geolocation_Permission_Request* permissionRequest =
1313 static_cast<Ewk_Geolocation_Permission_Request*>(eventInfo);
1315 if (This->m_model->GeolocationUsage.Get() == WrtDB::SETTINGS_TYPE_OFF) {
1316 ewk_geolocation_permission_request_set(permissionRequest, EINA_FALSE);
1319 ViewModule::GeolocationSupport::geolocationPermissionRequest(
1320 This->m_currentEwkView,
1321 This->m_securityOriginSupport->getSecurityOriginDAO(),
1325 void ViewLogic::notificationShowCallback(
1327 Evas_Object* /*obj*/,
1331 Ewk_Notification* ewkNotification =
1332 static_cast<Ewk_Notification*>(eventInfo);
1333 ViewModule::WebNotificationDataPtr notiData(
1334 new ViewModule::WebNotificationData(ewkNotification));
1336 _D("notification id : %u", notiData->getEwkNotiId());
1337 _D("notification iconURL : %s", notiData->getIconUrl());
1338 _D("notification title : %s", notiData->getTitle());
1339 _D("notification body : %s", notiData->getBody());
1342 ViewLogic* This = static_cast<ViewLogic*>(data);
1343 if (This->m_webNotificationSupport->show(notiData)) {
1344 ewk_notification_showed(This->m_ewkContext, notiData->getEwkNotiId());
1348 void ViewLogic::notificationCancelCallback(
1354 uint64_t ewkNotiId = *static_cast<uint64_t*>(eventInfo);
1357 ViewLogic* This = static_cast<ViewLogic*>(data);
1358 Ewk_Notification* ewkNotification =
1359 static_cast<Ewk_Notification*>(
1360 This->m_webNotificationSupport->hide(ewkNotiId));
1361 if (ewkNotification) {
1363 Eina_List* list = NULL;
1364 list = eina_list_append(list, ewkNotification);
1365 ewk_view_notification_closed(obj, list);
1366 eina_list_free(list);
1370 void ViewLogic::notificationPermissionRequestCallback(
1372 Evas_Object* /*obj*/,
1375 LogDebug("notificationPermissionRequestCallback called");
1377 ViewLogic* This = static_cast<ViewLogic*>(data);
1380 ViewModule::WebNotificationPermissionSupport::permissionRequest(
1381 This->m_currentEwkView,
1382 This->m_securityOriginSupport->getSecurityOriginDAO(),
1387 // EWK Orientation Callback
1388 Eina_Bool ViewLogic::orientationLockCallback(
1394 LogDebug("orientationLockCallback called");
1396 ViewLogic* This = static_cast<ViewLogic*>(data);
1398 if (This->m_orientationThresholdTimer) {
1399 LogDebug("previous orientationLock isn't finished");
1400 // Previous API call isn't finished. Keep angle and run it.
1401 if (needLock == EINA_TRUE) {
1402 // Screen.lockOrientation
1403 This->m_deferredRotateAngle = orientation;
1405 // Screen.unlockOrientation
1406 This->m_deferredRotateAngle =
1407 ViewModule::OrientationSupport::DEFERRED_ORIENTATION_UNLOCK;
1412 This->m_rotateAngle = orientation;
1414 if (needLock == EINA_TRUE) {
1415 // Screen.lockOrientation
1417 ViewModule::OrientationSupport::getW3COrientationAngle(orientation);
1419 ViewModule::OrientationSupport::getWinOrientationAngle(orientation);
1420 ViewModule::OrientationSupport::setEwkOrientation(obj, w3cAngle);
1421 if (!This->m_cbs->setOrientation.empty()) {
1422 This->m_cbs->setOrientation(winAngle);
1425 // Screen.unlockOrientation
1426 if (This->m_model->SettingList.Get().getRotationValue() ==
1427 Screen_AutoRotation)
1429 if (!This->m_cbs->setOrientation.empty()) {
1430 This->m_cbs->setOrientation(OrientationAngle::Window::UNLOCK);
1432 This->m_rotateAngle = 0;
1438 // Fullscreen API callbacks
1439 void ViewLogic::enterFullscreenCallback(
1444 LogDebug("enterFullscreenCallback called");
1446 ViewLogic* This = static_cast<ViewLogic*>(data);
1447 ViewLogicMessageSupport::setViewmodes(
1452 This->m_isFullscreenByPlatform =
1453 *static_cast<Eina_Bool*>(eventInfo) == EINA_TRUE;
1455 if (!This->m_cbs->enterFullscreen.empty()) {
1456 This->m_cbs->enterFullscreen(obj);
1460 void ViewLogic::exitFullscreenCallback(
1463 void* /*eventInfo*/)
1465 LogDebug("exitFullscreenCallback called");
1467 ViewLogic* This = static_cast<ViewLogic*>(data);
1468 ViewLogicMessageSupport::setViewmodes(
1470 Message::ToInjectedBundle::SET_VIEWMODES_MSGBODY_EXIT);
1472 This->m_isFullscreenByPlatform = false;
1473 if (!This->m_cbs->exitFullscreen.empty()) {
1474 This->m_cbs->exitFullscreen(obj);
1478 void ViewLogic::imeChangedCallback(
1480 Evas_Object* /*obj*/,
1486 ViewLogic* This = static_cast<ViewLogic*>(data);
1487 Eina_Rectangle *rect = static_cast<Eina_Rectangle *>(eventInfo);
1488 This->m_imeWidth = rect->w;
1489 This->m_imeHeight = rect->h;
1492 void ViewLogic::imeOpenedCallback(
1494 Evas_Object* /*obj*/,
1495 void* /*eventInfo*/)
1499 ViewLogic* This = static_cast<ViewLogic*>(data);
1501 using namespace WrtPlugins::W3C;
1502 SoftKeyboardChangeArgs args;
1503 args.state = IME_STATE_ON;
1504 args.width = This->m_imeWidth;
1505 args.height = This->m_imeHeight;
1506 This->fireJavascriptEvent(
1507 static_cast<int>(SoftKeyboardChangeCustomEvent),
1511 void ViewLogic::imeClosedCallback(
1513 Evas_Object* /*obj*/,
1514 void* /*eventInfo*/)
1518 ViewLogic* This = static_cast<ViewLogic*>(data);
1520 using namespace WrtPlugins::W3C;
1521 SoftKeyboardChangeArgs args;
1522 args.state = IME_STATE_OFF;
1523 This->fireJavascriptEvent(
1524 static_cast<int>(SoftKeyboardChangeCustomEvent),
1528 void ViewLogic::usermediaPermissionRequestCallback(
1530 Evas_Object* /*obj*/,
1533 LogDebug("usermediaPermissionRequestCallback called");
1535 ViewLogic* This = static_cast<ViewLogic*>(data);
1536 ViewModule::UsermediaSupport::usermediaPermissionRequest(
1537 This->m_currentEwkView,
1538 This->m_securityOriginSupport->getSecurityOriginDAO(),
1543 CustomHandlerDB::CustomHandlerPtr getCustomHandlerFromData(void* data)
1546 Ewk_Custom_Handlers_Data* handler =
1547 static_cast<Ewk_Custom_Handlers_Data*>(data);
1548 CustomHandlerDB::CustomHandlerPtr customHandler(
1549 new CustomHandlerDB::CustomHandler());
1550 const char* base_url = ewk_custom_handlers_data_base_url_get(handler);
1552 LogDebug("base url: " << base_url);
1553 customHandler->base_url = DPL::FromASCIIString(string(base_url));
1555 const char* url = ewk_custom_handlers_data_url_get(handler);
1557 LogDebug("url: " << url);
1558 customHandler->url = DPL::FromASCIIString(string(url));
1560 const char* target = ewk_custom_handlers_data_target_get(handler);
1562 LogDebug("target: " << target);
1563 customHandler->target = DPL::FromASCIIString(string(target));
1565 const char* title = ewk_custom_handlers_data_title_get(handler);
1567 LogDebug("title: " << title);
1568 customHandler->title = DPL::FromASCIIString(string(title));
1570 return customHandler;
1573 void ViewLogic::attachToCustomHandlersDao()
1575 if (!m_attachedToCustomHandlerDao) {
1576 CustomHandlerDB::Interface::attachDatabaseRW();
1580 void ViewLogic::detachFromCustomHandlersDao()
1582 if (m_attachedToCustomHandlerDao) {
1583 CustomHandlerDB::Interface::detachDatabase();
1587 const int protocolWhiteListLenth = 15;
1588 char const * const protocolWhiteList[protocolWhiteListLenth] = {
1606 const int contentBlackListLenth = 14;
1607 char const * const contentBlackList[contentBlackListLenth] = {
1608 "application/x-www-form-urlencoded",
1609 "application/xhtml+xml",
1615 "multipart/x-mixed-replace",
1616 "text/cache-manifest",
1625 * Saves user's response from popup to custom handler. Saves Yes/No and remember
1628 * @param customHandler
1630 void saveUserResponse(Wrt::Popup::PopupResponse response,
1631 CustomHandlerDB::CustomHandlerPtr customHandler)
1634 case Wrt::Popup::YES_DO_REMEMBER:
1635 LogDebug("User allowed, remember");
1636 customHandler->user_decision =
1637 static_cast<CustomHandlerDB::HandlerState>
1638 (CustomHandlerDB::Agreed | CustomHandlerDB::DecisionSaved);
1640 case Wrt::Popup::YES_DONT_REMEMBER:
1641 LogDebug("User allowed, don't remember");
1642 customHandler->user_decision = CustomHandlerDB::Agreed;
1644 case Wrt::Popup::NO_DO_REMEMBER:
1645 LogDebug("User didn't allow, remember");
1646 customHandler->user_decision =
1647 static_cast<CustomHandlerDB::HandlerState>
1648 (CustomHandlerDB::Declined | CustomHandlerDB::DecisionSaved);
1650 case Wrt::Popup::NO_DONT_REMEMBER:
1651 LogDebug("User didn't allow, don't remember");
1652 customHandler->user_decision = CustomHandlerDB::Declined;
1657 //TODO registration, checking if registered and unregistration can be done in
1658 //common functions for both types of handlers. Only white and black lists
1659 //have to be separated
1660 //TODO attach database only one at the start (not in every callback?)
1661 void ViewLogic::protocolHandlerRegistrationCallback(void* data,
1662 Evas_Object* /*obj*/,
1667 CustomHandlerDB::CustomHandlerPtr customHandler =
1668 getCustomHandlerFromData(eventInfo);
1670 std::string scheme = DPL::ToUTF8String(customHandler->target);
1671 if (scheme.empty()) {
1672 LogError("No scheme provided");
1673 //TODO what about securityError?
1676 bool matched = false;
1677 //scheme on whiteList
1678 for (int i = 0; i < protocolWhiteListLenth; ++i) {
1679 if (0 == strcmp(protocolWhiteList[i], scheme.c_str())) {
1680 LogDebug("Match found, protocol can be handled");
1685 //starts with web+ and have at least 5 chars (lowercase ASCII)
1686 if (strncmp("web+", scheme.c_str(), 4) || scheme.length() < 5) {
1687 LogWarning("Scheme neither on whitelist nor starts with \"web+\"");
1688 //throw SecurityException
1694 if (c < 'a' || c > 'z') {
1695 LogWarning("Wrong char inside scheme. "
1696 << "Only lowercase ASCII letters accepted");
1697 //throw SecurityException
1704 ViewLogic* This = static_cast<ViewLogic*>(data);
1705 LogDebug("Creating handlers dao");
1706 This->attachToCustomHandlersDao();
1707 CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1708 CustomHandlerDB::CustomHandlerPtr handler =
1709 handlersDao.getProtocolHandler(customHandler->target,
1711 customHandler->base_url);
1712 if (handler && (handler->user_decision & CustomHandlerDB::DecisionSaved)) {
1713 LogDebug("Protocol already registered - nothing to do");
1715 LogDebug("Protocol handler not found");
1716 Wrt::Popup::PopupResponse response =
1717 GlobalSettings::PopupsTestModeEnabled() ? Wrt::Popup::
1719 Wrt::Popup::PopupInvoker().askYesNoCheckbox(
1720 PROTOCOL_HANDLER_ASK_TITLE,
1721 PROTOCOL_HANDLER_ASK_MSG,
1722 PROTOCOL_HANDLER_ASK_REMEMBER);
1723 saveUserResponse(response, customHandler);
1724 if (customHandler->user_decision == CustomHandlerDB::Declined) {
1727 if (customHandler->user_decision & CustomHandlerDB::Agreed) {
1728 //TODO remove old default handler somehow from appsvc
1729 LogDebug("Registering appservice entry");
1730 int ret = appsvc_set_defapp(APPSVC_OPERATION_VIEW,
1733 customHandler->target).c_str(),
1734 DPL::ToUTF8String(This->m_model->
1736 if (APPSVC_RET_OK != ret) {
1737 LogWarning("Appsvc entry failed: " << ret);
1738 //no database change
1742 handlersDao.registerProtocolHandler(*(customHandler.get()));
1744 LogDebug("Protocal saved");
1747 This->detachFromCustomHandlersDao();
1750 void ViewLogic::protocolHandlerIsRegisteredCallback(void* data,
1751 Evas_Object* /*obj*/,
1755 CustomHandlerDB::CustomHandlerPtr customHandler = getCustomHandlerFromData(
1757 ViewLogic* This = static_cast<ViewLogic*>(data);
1758 LogDebug("Creating handlers dao");
1759 This->attachToCustomHandlersDao();
1760 CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1761 CustomHandlerDB::CustomHandlerPtr handler =
1762 handlersDao.getProtocolHandler(customHandler->target,
1764 customHandler->base_url);
1766 if (handler->user_decision & CustomHandlerDB::Agreed) {
1767 ewk_custom_handlers_data_result_set(
1768 static_cast<Ewk_Custom_Handlers_Data*>(eventInfo),
1769 EWK_CUSTOM_HANDLERS_REGISTERED);
1771 ewk_custom_handlers_data_result_set(
1772 static_cast<Ewk_Custom_Handlers_Data*>(eventInfo),
1773 EWK_CUSTOM_HANDLERS_DECLINED);
1776 ewk_custom_handlers_data_result_set(
1777 static_cast<Ewk_Custom_Handlers_Data*>(eventInfo),
1778 EWK_CUSTOM_HANDLERS_NEW);
1780 This->detachFromCustomHandlersDao();
1783 void ViewLogic::protocolHandlerUnregistrationCallback(void* data,
1784 Evas_Object* /*obj*/,
1788 CustomHandlerDB::CustomHandlerPtr customHandler =
1789 getCustomHandlerFromData(eventInfo);
1790 ViewLogic* This = static_cast<ViewLogic*>(data);
1791 LogDebug("Creating handlers dao");
1792 This->attachToCustomHandlersDao();
1793 CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1794 CustomHandlerDB::CustomHandlerPtr handlerCheck =
1795 handlersDao.getProtocolHandler(customHandler->target,
1797 customHandler->base_url);
1798 This->detachFromCustomHandlersDao();
1800 if (handlerCheck->user_decision & CustomHandlerDB::Agreed) {
1801 int ret = appsvc_unset_defapp(
1802 DPL::ToUTF8String(This->m_model->TizenId).c_str());
1803 if (APPSVC_RET_OK != ret) {
1804 LogWarning("Failed to unregister appsvc entry");
1808 //if appsvc ok change custom_handlers_db
1809 handlersDao.unregisterProtocolHandler(customHandler->target,
1811 customHandler->base_url);
1813 LogDebug("Nothing to unregister");
1817 void ViewLogic::contentHandlerRegistrationCallback(void* data,
1818 Evas_Object* /*obj*/,
1823 CustomHandlerDB::CustomHandlerPtr customHandler =
1824 getCustomHandlerFromData(eventInfo);
1826 std::string mimeType = DPL::ToUTF8String(customHandler->target);
1827 if (mimeType.empty()) {
1828 LogError("No mimeType provided.");
1831 for (int i = 0; i < contentBlackListLenth; ++i) {
1832 if (0 == strcmp(contentBlackList[i], mimeType.c_str())) {
1833 LogWarning("mimeType blacklisted");
1834 //throw SecurityException
1839 ViewLogic* This = static_cast<ViewLogic*>(data);
1840 LogDebug("Creating handlers dao");
1841 This->attachToCustomHandlersDao();
1842 CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1843 CustomHandlerDB::CustomHandlerPtr handler =
1844 handlersDao.getContentHandler(customHandler->target,
1846 customHandler->base_url);
1847 if (handler && (handler->user_decision & CustomHandlerDB::DecisionSaved)) {
1848 LogDebug("Protocol already registered - nothing to do");
1850 LogDebug("Protocol handler not found");
1851 Wrt::Popup::PopupResponse response =
1852 GlobalSettings::PopupsTestModeEnabled() ? Wrt::Popup::
1854 Wrt::Popup::PopupInvoker().askYesNoCheckbox(
1855 CONTENT_HANDLER_ASK_TITLE,
1856 CONTENT_HANDLER_ASK_MSG,
1857 CONTENT_HANDLER_AKS_REMEMBER);
1858 saveUserResponse(response, customHandler);
1859 if (customHandler->user_decision == CustomHandlerDB::Declined) {
1862 if (customHandler->user_decision & CustomHandlerDB::Agreed) {
1863 //TODO remove old default handler somehow from appsvc
1864 LogDebug("Registering appservice entry");
1865 int ret = appsvc_set_defapp(APPSVC_OPERATION_VIEW,
1867 customHandler->target).c_str(),
1869 DPL::ToUTF8String(This->m_model->
1871 if (APPSVC_RET_OK != ret) {
1872 LogWarning("Appsvc entry failed: " << ret);
1876 handlersDao.registerContentHandler(*(customHandler.get()));
1877 LogDebug("Content saved");
1879 This->detachFromCustomHandlersDao();
1882 void ViewLogic::contentHandlerIsRegisteredCallback(void* data,
1883 Evas_Object* /*obj*/,
1887 CustomHandlerDB::CustomHandlerPtr customHandler =
1888 getCustomHandlerFromData(eventInfo);
1889 ViewLogic* This = static_cast<ViewLogic*>(data);
1890 LogDebug("Creating handlers dao");
1892 This->attachToCustomHandlersDao();
1893 CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1894 CustomHandlerDB::CustomHandlerPtr handler =
1895 handlersDao.getContentHandler(customHandler->target,
1897 customHandler->base_url);
1899 if (handler->user_decision & CustomHandlerDB::Agreed) {
1900 ewk_custom_handlers_data_result_set(
1901 static_cast<Ewk_Custom_Handlers_Data*>(eventInfo),
1902 EWK_CUSTOM_HANDLERS_REGISTERED);
1904 ewk_custom_handlers_data_result_set(
1905 static_cast<Ewk_Custom_Handlers_Data*>(eventInfo),
1906 EWK_CUSTOM_HANDLERS_DECLINED);
1909 ewk_custom_handlers_data_result_set(
1910 static_cast<Ewk_Custom_Handlers_Data*>(eventInfo),
1911 EWK_CUSTOM_HANDLERS_NEW);
1913 This->detachFromCustomHandlersDao();
1916 void ViewLogic::contentHandlerUnregistrationCallback(void* data,
1917 Evas_Object* /*obj*/,
1921 CustomHandlerDB::CustomHandlerPtr customHandler =
1922 getCustomHandlerFromData(eventInfo);
1923 ViewLogic* This = static_cast<ViewLogic*>(data);
1924 LogDebug("Creating handlers dao");
1925 This->attachToCustomHandlersDao();
1926 CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1927 CustomHandlerDB::CustomHandlerPtr handlerCheck =
1928 handlersDao.getContentHandler(customHandler->target,
1930 customHandler->base_url);
1931 This->detachFromCustomHandlersDao();
1933 if (handlerCheck->user_decision & CustomHandlerDB::Agreed) {
1934 int ret = appsvc_unset_defapp(
1935 DPL::ToUTF8String(This->m_model->TizenId).c_str());
1936 if (APPSVC_RET_OK != ret) {
1937 LogWarning("Failed to unregister mime handler from appsvc");
1941 handlersDao.unregisterContentHandler(customHandler->target,
1943 customHandler->base_url);
1945 LogDebug("Nothing to unregister");
1949 void ViewLogic::didRunJavaScriptCallback(
1950 Evas_Object* /*obj*/,
1954 LogDebug("didRunJavaScriptCallback called");
1955 LogDebug("result = " << result);
1958 void ViewLogic::eaKeyCallback(void* data, Evas_Object* obj, void* eventInfo)
1961 ViewLogic* This = static_cast<ViewLogic*>(data);
1963 Ea_Callback_Type keyType =
1964 static_cast<Ea_Callback_Type>(reinterpret_cast<intptr_t>(eventInfo));
1966 LogDebug("Key = [" << keyType << "]");
1968 std::string keyName;
1969 if (keyType == EA_CALLBACK_BACK) {
1971 #if 0 // FIXME!!!! ewk_view_text_selection_clear has not landed yet
1972 // Call fullscreen exit API
1973 // In case of fullscreen is entered by platform(default video tag),
1974 // automatically exit fullscreen when backkey is selected
1975 if (This->m_isFullscreenByPlatform) {
1976 ewk_view_fullscreen_exit(obj);
1980 // Call text selection clear API
1981 // In case of current state is selection mode,
1982 // application doesn't need to handle back key
1983 if (EINA_TRUE == ewk_view_text_selection_clear(obj)) {
1987 keyName = KeyName::BACK;
1988 } else if (keyType == EA_CALLBACK_MORE) {
1989 keyName = KeyName::MENU;
1994 if (This->m_model->SettingList.Get().getHWkeyEvent() == HWkeyEvent_Enable)
1996 DispatchEventSupport::dispatchHwKeyEvent(obj, keyName);
1998 This->m_cbs->hwkey(keyName);
2003 Eina_Bool ViewLogic::windowCloseIdlerCallback(void* data)
2005 LogDebug("closeIdlerCallback");
2006 ViewLogic* This = static_cast<ViewLogic*>(data);
2007 This->windowClose();
2008 return ECORE_CALLBACK_CANCEL;
2011 Eina_Bool ViewLogic::exceededDatabaseQuotaCallback(Evas_Object* obj,
2012 Ewk_Security_Origin* origin,
2014 unsigned long long ,
2017 LogDebug("exceededDatabaseQuotaCallback called");
2019 ViewLogic* This = static_cast<ViewLogic*>(data);
2022 if (This->m_model->WebStorageUsage.Get() == WrtDB::SETTINGS_TYPE_OFF) {
2023 ewk_view_exceeded_database_quota_reply(obj, EINA_FALSE);
2027 ViewModule::WebStorageSupport::createPermissionRequest(
2028 This->m_currentEwkView,
2029 This->m_securityOriginSupport->getSecurityOriginDAO(),
2032 ewk_view_exceeded_database_quota_reply);
2036 Eina_Bool ViewLogic::exceededIndexedDatabaseQuotaCallback(Evas_Object* obj,
2037 Ewk_Security_Origin* origin,
2041 LogDebug("exceededIndexedDatabaseQuotaCallback called");
2043 ViewLogic* This = static_cast<ViewLogic*>(data);
2046 if (This->m_model->WebStorageUsage.Get() == WrtDB::SETTINGS_TYPE_OFF) {
2047 ewk_view_exceeded_indexed_database_quota_reply(obj, EINA_FALSE);
2051 ViewModule::WebStorageSupport::createPermissionRequest(
2052 This->m_currentEwkView,
2053 This->m_securityOriginSupport->getSecurityOriginDAO(),
2056 ewk_view_exceeded_indexed_database_quota_reply);
2060 Eina_Bool ViewLogic::exceededLocalFileSystemQuotaCallback(Evas_Object* obj,
2061 Ewk_Security_Origin* origin,
2065 LogDebug("exceededLocalFileSystemQuotaCallback called");
2067 ViewLogic* This = static_cast<ViewLogic*>(data);
2071 if (This->m_model->WebStorageUsage.Get() == WrtDB::SETTINGS_TYPE_OFF) {
2072 ewk_view_exceeded_local_file_system_quota_reply(obj, EINA_FALSE);
2076 ViewModule::WebStorageSupport::createPermissionRequest(
2077 This->m_currentEwkView,
2078 This->m_securityOriginSupport->getSecurityOriginDAO(),
2081 ewk_view_exceeded_local_file_system_quota_reply);
2085 void ViewLogic::certificateConfirmRequestCallback(
2087 Evas_Object* /*obj*/,
2090 LogDebug("certificateConfirmRequestCallback called");
2093 ViewLogic* This = static_cast<ViewLogic*>(data);
2095 ViewModule::CertificateConfirmSupport::certificatePermissionRequest(
2096 This->m_currentEwkView,
2097 This->m_certificateSupport->getCertificateDAO(),
2101 void ViewLogic::authenticationChallengeRequestCallback(
2103 Evas_Object* /*obj*/,
2106 LogDebug("authenticationChallengeRequestCallback called");
2110 ViewLogic* This = static_cast<ViewLogic*>(data);
2111 const char* url = ewk_view_url_get(This->m_currentEwkView);
2112 if (!url || strlen(url) == 0) {
2113 Ewk_Auth_Challenge* authChallenge = static_cast<Ewk_Auth_Challenge*>(eventInfo);
2114 ewk_auth_challenge_credential_cancel(authChallenge);
2117 ViewModule::AuthenticationChallengeSupport::authenticationChallengeRequest(
2118 This->m_currentEwkView,
2123 void ViewLogic::viewFrameRenderedCallback(
2125 Evas_Object* /*obj*/,
2126 void* /*eventInfo*/)
2128 static bool logEnable = (getenv("WRT_FRAME_RENDERED_LOG_ENABLE") != NULL);
2136 void ViewLogic::mediacontrolRotateHorizontal(void* data,
2138 void* /*eventInfo*/)
2140 LogDebug("mediacontrolRotateHorizontal called");
2143 ViewLogic* This = static_cast<ViewLogic*>(data);
2144 ViewModule::OrientationSupport::setEwkOrientation(
2146 OrientationAngle::W3C::Landscape::PRIMARY);
2147 if (!This->m_cbs->setOrientation.empty()) {
2148 This->m_cbs->setOrientation(
2149 OrientationAngle::Window::Landscape::PRIMARY);
2153 void ViewLogic::mediacontrolRotateVertical(void* data,
2155 void* /*eventInfo*/)
2157 LogDebug("mediacontrolRotateVertical called");
2160 ViewLogic* This = static_cast<ViewLogic*>(data);
2161 ViewModule::OrientationSupport::setEwkOrientation(
2163 OrientationAngle::W3C::Portrait::PRIMARY);
2164 if (!This->m_cbs->setOrientation.empty()) {
2165 This->m_cbs->setOrientation(
2166 OrientationAngle::Window::Portrait::PRIMARY);
2170 void ViewLogic::mediacontrolRotateExit(void* data,
2172 void* /*eventInfo*/)
2174 LogDebug("mediacontrolRotateExit called");
2177 ViewLogic* This = static_cast<ViewLogic*>(data);
2181 if (This->m_rotateAngle == 0) {
2182 // application hasn't call orientation lock
2183 WidgetSettingScreenLock screenLock =
2184 This->m_model->SettingList.Get().getRotationValue();
2185 if (screenLock == Screen_Portrait) {
2186 w3cAngle = OrientationAngle::W3C::Portrait::PRIMARY;
2187 winAngle = OrientationAngle::Window::Portrait::PRIMARY;
2188 } else if (screenLock == Screen_Landscape) {
2189 w3cAngle = OrientationAngle::W3C::Landscape::PRIMARY;
2190 winAngle = OrientationAngle::Window::Landscape::PRIMARY;
2191 } else if (screenLock == Screen_AutoRotation) {
2192 if (!This->m_cbs->setOrientation.empty()) {
2193 This->m_cbs->setOrientation(OrientationAngle::Window::UNLOCK);
2198 // Restore previous orientation
2200 ViewModule::OrientationSupport::getW3COrientationAngle(
2201 This->m_rotateAngle);
2203 ViewModule::OrientationSupport::getWinOrientationAngle(
2204 This->m_rotateAngle);
2207 ViewModule::OrientationSupport::setEwkOrientation(obj, w3cAngle);
2208 if (!This->m_cbs->setOrientation.empty()) {
2209 This->m_cbs->setOrientation(winAngle);
2214 Eina_Bool ViewLogic::orientationThresholdTimerCallback(void* data)
2216 LogDebug("orientationThresholdTimerCallback");
2217 ViewLogic* This = static_cast<ViewLogic*>(data);
2219 if (This->m_deferredRotateAngle ==
2220 ViewModule::OrientationSupport::DEFERRED_ORIENTATION_EMPTY)
2222 // There is no defered orientation API call
2223 This->m_orientationThresholdTimer = NULL;
2224 return ECORE_CALLBACK_CANCEL;
2227 if (This->m_deferredRotateAngle != This->m_rotateAngle) {
2228 This->m_rotateAngle = This->m_deferredRotateAngle;
2231 if (This->m_rotateAngle == 0) {
2232 WidgetSettingScreenLock screenLock =
2233 This->m_model->SettingList.Get().getRotationValue();
2234 if (screenLock == Screen_Portrait) {
2235 w3cAngle = OrientationAngle::W3C::Portrait::PRIMARY;
2236 winAngle = OrientationAngle::Window::Portrait::PRIMARY;
2237 } else if (screenLock == Screen_Landscape) {
2238 w3cAngle = OrientationAngle::W3C::Landscape::PRIMARY;
2239 winAngle = OrientationAngle::Window::Landscape::PRIMARY;
2240 } else if (screenLock == Screen_AutoRotation) {
2241 if (!This->m_cbs->setOrientation.empty()) {
2242 This->m_cbs->setOrientation(OrientationAngle::Window::UNLOCK);
2244 This->m_orientationThresholdTimer = NULL;
2245 return ECORE_CALLBACK_CANCEL;
2248 // Restore previous orientation
2250 ViewModule::OrientationSupport::getW3COrientationAngle(
2251 This->m_rotateAngle);
2253 ViewModule::OrientationSupport::getWinOrientationAngle(
2254 This->m_rotateAngle);
2257 ViewModule::OrientationSupport::setEwkOrientation(
2258 This->m_currentEwkView,
2260 if (!This->m_cbs->setOrientation.empty()) {
2261 This->m_cbs->setOrientation(winAngle);
2263 This->m_deferredRotateAngle =
2264 ViewModule::OrientationSupport::DEFERRED_ORIENTATION_EMPTY;
2265 return ECORE_CALLBACK_RENEW;
2268 This->m_orientationThresholdTimer = NULL;
2269 return ECORE_CALLBACK_CANCEL;
2272 void ViewLogic::popupReplyWaitStart(void* data,
2273 Evas_Object* /*obj*/,
2274 void* /*eventInfo*/)
2278 ViewLogic* This = static_cast<ViewLogic*>(data);
2279 This->m_isPopupReplyWait = true;
2282 void ViewLogic::popupReplyWaitFinish(void* data,
2283 Evas_Object* /*obj*/,
2284 void* /*eventInfo*/)
2288 ViewLogic* This = static_cast<ViewLogic*>(data);
2289 This->m_isPopupReplyWait = false;
2292 void ViewLogic::requestUrlBlocked(const std::string& blockedUrl)
2296 // block this page and open it in browser
2297 LogDebug("Request was blocked : " << blockedUrl);
2298 service_h serviceHandle = NULL;
2299 service_create(&serviceHandle);
2300 service_set_operation(serviceHandle, SERVICE_OPERATION_VIEW);
2301 service_set_uri(serviceHandle, blockedUrl.c_str());
2302 CONTROLLER_POST_EVENT(
2303 ApplicationLauncher,
2304 ApplicationLauncherEvents::LaunchApplicationByAppService(
2308 // set block url. This is used on load finished callback
2309 m_blockedUri = blockedUrl;
2312 void ViewLogic::windowClose()
2314 LogDebug("windowClose");
2315 Assert(m_closedEwkView && "no closed webview");
2317 if (1 >= m_ewkViewList.size()) {
2318 if (!m_cbs->webkitExit.empty()) {
2319 m_cbs->webkitExit();
2322 // call user callbacks
2323 if (!m_cbs->bufferUnset.empty()) {
2324 m_cbs->bufferUnset(m_currentEwkView);
2326 if (!m_cbs->windowClose.empty()) {
2327 m_cbs->windowClose(m_closedEwkView);
2329 removeEwkView(m_closedEwkView);
2331 // get latest ewkView
2332 m_currentEwkView = m_ewkViewList.back();
2334 setEwkViewVisible(m_currentEwkView);
2337 if (!m_cbs->bufferSet.empty()) {
2338 m_cbs->bufferSet(m_currentEwkView);
2343 void ViewLogic::systemSettingsChangedCallback(system_settings_key_e key,
2346 LogDebug("systemSettingsChanged");
2347 LogDebug("System setting Key is [" << key << "]");
2350 ViewLogic* This = static_cast<ViewLogic*>(data);
2352 if (SYSTEM_SETTINGS_KEY_FONT_TYPE == key) {
2353 if (!This->m_currentEwkView) {
2354 LogError("ewkView isn't initialized");
2357 ewk_view_use_settings_font(This->m_currentEwkView);
2359 LogError("Unregister system callback is called");