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>
36 #include <widget_model.h>
37 #include <system_settings.h>
38 #include <dpl/wrt-dao-ro/widget_dao_read_only.h>
39 #include <dpl/utils/wrt_global_settings.h>
41 #include <common/application_data.h>
42 #include <common/application_launcher.h>
43 #include <common/message_support.h>
44 #include <common/scheme.h>
46 #include <common/view_logic_apps_support.h>
47 #include <common/view_logic_custom_header_support.h>
48 #include <common/view_logic_security_support.h>
49 #include <common/view_logic_security_origin_support.h>
50 #include <common/view_logic_certificate_support.h>
51 #include <common/view_logic_storage_support.h>
52 #include <common/view_logic_uri_support.h>
53 #include <common/view_logic_vibration_support.h>
54 #include <view_logic_authentication_challenge_support.h>
55 #include <view_logic_certificate_confirm_support.h>
56 #include <view_logic_geolocation_support.h>
57 #include <view_logic_message_support.h>
58 #include <view_logic_orientation_support.h>
59 #include <view_logic_scheme_support.h>
60 #include <view_logic_usermedia_support.h>
61 #include <view_logic_web_notification_support.h>
62 #include <view_logic_web_storage_support.h>
65 #include <dpl/localization/w3c_file_localization.h>
66 #include <js_overlay_types.h>
67 #include <i_runnable_widget_object.h>
68 #include <profiling_util.h>
69 #include <wrt-commons/custom-handler-dao-ro/CustomHandlerDatabase.h>
70 #include <wrt-commons/custom-handler-dao-rw/custom_handler_dao.h>
71 #include <popup-runner/PopupInvoker.h>
73 #include <appsvc/appsvc.h>
75 #ifdef MULTIPROCESS_SERVICE_SUPPORT_INLINE
76 #include "view_logic_service_support.h"
78 extern "C" int appsvc_allow_transient_app(bundle *b, Ecore_X_Window id);
79 extern "C" int appsvc_request_transient_app(bundle *b, Ecore_X_Window callee_id, appsvc_host_res_fn cbfunc, void *data);
84 const char * const IME_STATE_ON = "on";
85 const char * const IME_STATE_OFF = "off";
87 const char PROTOCOL_HANDLER_ASK_MSG[] = "Add protocol?";
88 const char PROTOCOL_HANDLER_ASK_TITLE[] = "Add protocol";
89 const char PROTOCOL_HANDLER_ASK_REMEMBER[] = "Remember dicision";
90 const char CONTENT_HANDLER_ASK_MSG[] = "Add content?";
91 const char CONTENT_HANDLER_ASK_TITLE[] = "Add content";
92 const char CONTENT_HANDLER_AKS_REMEMBER[] = "Remember dicision";
94 const char* const DEFAULT_ENCODING = "UTF-8";
96 const char* const DEFAULT_CSP_POLICY =
97 "default-src '*'; script-src 'self'; style-src 'self'; object-src 'none';";
100 const char * const SCHEME_BOX_SLASH = "box://";
101 } // anonymous namespace
103 std::map<const std::string,
104 const Evas_Smart_Cb> ViewLogic::m_ewkCallbacksMap = {
105 { "load,started", &ViewLogic::loadStartedCallback },
106 { "load,finished", &ViewLogic::loadFinishedCallback },
107 { "title,changed", &ViewLogic::titleChangedCallback },
108 { "load,progress,started", &ViewLogic::loadProgressStartedCallback },
109 { "load,progress", &ViewLogic::loadProgressCallback },
110 { "load,progress,finished", &ViewLogic::loadProgressFinishedCallback },
111 { "process,crashed", &ViewLogic::processCrashedCallback },
113 { "create,window", &ViewLogic::createWindowCallback },
114 { "close,window", &ViewLogic::closeWindowCallback },
115 // WKPagePolicyClient
116 { "policy,navigation,decide", &ViewLogic::policyNavigationDecideCallback },
117 { "policy,newwindow,decide", &ViewLogic::policyNewWindowDecideCallback },
118 { "policy,response,decide", &ViewLogic::pageResponseDecideCallback },
119 // WKPageContextMenuClient
120 { "contextmenu,customize", &ViewLogic::contextmenuCustomizeCallback },
121 // EWK Geolocation Callback
122 { "geolocation,permission,request",
123 &ViewLogic::geolocationPermissionRequestCallback },
124 // EWK Notification Callback
125 { "notification,show", &ViewLogic::notificationShowCallback },
126 { "notification,cancel", &ViewLogic::notificationCancelCallback },
127 { "notification,permission,request",
128 &ViewLogic::notificationPermissionRequestCallback },
129 { "fullscreen,enterfullscreen", &ViewLogic::enterFullscreenCallback },
130 { "fullscreen,exitfullscreen", &ViewLogic::exitFullscreenCallback },
132 // when ime start to be showed on the webview,
133 // this callback will be called
134 { "inputmethod,changed", &ViewLogic::imeChangedCallback },
135 // this callback will be called
136 // when ime finishes to be showed on the webview
137 // "event_info" arg of this callback is always NULL point
138 // if web content should know size of ime,
139 // use "inputmethod,changed" instead of this.
141 { "editorclient,ime,opened", &ViewLogic::imeOpenedCallback },
142 // when ime finished to be hidden,
143 // this callback will be called
144 { "editorclient,ime,closed", &ViewLogic::imeClosedCallback },
145 // EWK Usermedia Callback
146 { "usermedia,permission,request",
147 &ViewLogic::usermediaPermissionRequestCallback },
149 { "protocolhandler,registration,requested",
150 &ViewLogic::protocolHandlerRegistrationCallback },
151 { "protocolhandler,isregistered",
152 &ViewLogic::protocolHandlerIsRegisteredCallback },
153 { "protocolhandler,unregistration,requested",
154 &ViewLogic::protocolHandlerUnregistrationCallback },
155 { "contenthandler,registration,requested",
156 &ViewLogic::contentHandlerRegistrationCallback },
157 { "contenthandler,isregistered",
158 &ViewLogic::contentHandlerIsRegisteredCallback },
159 { "contenthandler,unregistration,requested",
160 &ViewLogic::contentHandlerUnregistrationCallback },
161 { "request,certificate,confirm",
162 &ViewLogic::certificateConfirmRequestCallback },
163 { "authentication,challenge",
164 &ViewLogic::authenticationChallengeRequestCallback },
166 &ViewLogic::viewFrameRenderedCallback },
167 { "mediacontrol,rotate,horizontal",
168 &ViewLogic::mediacontrolRotateHorizontal },
169 { "mediacontrol,rotate,vertical",
170 &ViewLogic::mediacontrolRotateVertical },
171 { "mediacontrol,rotate,exit",
172 &ViewLogic::mediacontrolRotateExit }
175 ViewLogic::ViewLogic() :
177 m_attachedToCustomHandlerDao(false),
179 m_closedEwkView(NULL),
182 m_cbs(new WRT::UserDelegates),
185 m_isBackgroundReload(false),
186 m_isBackgroundSupport(false),
188 m_appsSupport(new ViewModule::AppsSupport()),
189 m_vibrationSupport(new ViewModule::VibrationSupport())
191 ApplicationLauncherSingleton::Instance().Touch();
194 ViewLogic::~ViewLogic()
196 detachFromCustomHandlersDao();
199 bool ViewLogic::createWebView(Ewk_Context* context,
203 if (!context || !window) {
208 const char *theme = elm_theme_get(NULL);
211 LogInfo("theme is " << m_theme);
215 m_ewkContext = context;
218 Evas* canvas = evas_object_evas_get(m_window);
220 if (!createEwkView(canvas)) {
224 elm_access_object_register(m_currentEwkView, window);
228 #ifdef MULTIPROCESS_SERVICE_SUPPORT_INLINE
229 int ViewLogic::appServiceCallerIsKilled(void *data)
232 ViewLogic *This = static_cast<ViewLogic *>(data);
233 if (!This->m_cbs->webkitExit.empty()) {
234 This->m_cbs->webkitExit();
240 void ViewLogic::prepareView(WidgetModel* m, const std::string &startUrl)
242 LogDebug("View prepare");
246 m_startUrl = startUrl;
247 Assert(NULL != m_ewkContext);
250 #ifdef MULTIPROCESS_SERVICE_SUPPORT_INLINE
251 if (ServiceSupport::isService(m_model))
253 bundle *b = ApplicationDataSingleton::Instance().getBundle();
254 if (ServiceSupport::Disposition::INLINE == ServiceSupport::disposition(m_model))
256 LogDebug("Set up INLINE disposition");
257 int pid = ServiceSupport::callerPID(b);
259 unsigned windowId = ServiceSupport::xWindowByPid(pid);
260 appsvc_allow_transient_app(b, windowId);
261 appsvc_request_transient_app(b, elm_win_xwindow_get(m_window), appServiceCallerIsKilled, this);
266 LogDebug("Set up WINDOW disposition");
271 LogDebug("Starting regular widget");
275 ADD_PROFILING_POINT("initializeSupport", "start");
277 ADD_PROFILING_POINT("initializeSupport", "stop");
278 ewkClientInit(m_currentEwkView);
279 ADD_PROFILING_POINT("prepareEwkView", "start");
280 prepareEwkView(m_currentEwkView);
281 ADD_PROFILING_POINT("prepareEwkView", "stop");
282 initializePluginLoading();
283 initializeXwindowHandle();
286 void ViewLogic::showWidget()
288 LogDebug("showing widget");
289 Assert(NULL != m_currentEwkView && "ewk_view not created at this point");
291 ViewModule::UriSupport::getUri(m_model, m_startUrl);
293 LogError("Localized current URI doesn't exist");
296 LogInfo("url : " << url);
299 ewk_view_url_set(m_currentEwkView, url.c_str());
301 if (!m_cbs->bufferSet.empty()) {
302 m_cbs->bufferSet(m_currentEwkView);
306 void ViewLogic::hideWidget()
308 LogDebug("hiding widget");
309 ViewModule::StorageSupport::deinitializeStorage(m_model);
310 m_appsSupport->deinitialize();
311 m_vibrationSupport->deinitialize();
312 system_settings_unset_changed_cb(SYSTEM_SETTINGS_KEY_FONT_TYPE);
314 while (!m_ewkViewList.empty()) {
315 LogInfo("pop webview: " << m_ewkViewList.back());
316 removeEwkView(m_ewkViewList.back());
318 m_ewkViewList.clear();
321 void ViewLogic::suspendWidget()
323 LogInfo("Pausing widget");
326 if (!m_currentEwkView) {
327 LogWarning("Cannot suspend widget without view");
329 setEwkViewInvisible(m_currentEwkView);
330 if (!m_isBackgroundSupport) {
331 suspendWebkit(m_currentEwkView);
335 evas_object_focus_set(m_currentEwkView, EINA_FALSE);
337 // call user callback
338 if (!m_cbs->suspend.empty()) {
339 m_cbs->suspend(true);
343 void ViewLogic::resumeWidget()
345 LogInfo("Resume widget");
348 if (m_currentEwkView) {
349 setEwkViewVisible(m_currentEwkView);
350 if (!m_isBackgroundSupport) {
351 resumeWebkit(m_currentEwkView);
355 /* window system team recomend removing this win_raise code. */
358 * elm_win_raise(m_window);
361 evas_object_focus_set(m_currentEwkView, EINA_TRUE);
363 // call user callback
364 if (!m_cbs->resume.empty()) {
369 void ViewLogic::resetWidget()
371 LogInfo("Resetting Widget");
373 // destory all webview
374 while (!m_ewkViewList.empty()) {
375 LogInfo("pop webview: " << m_ewkViewList.back());
376 removeEwkView(m_ewkViewList.back());
378 m_ewkViewList.clear();
380 // create new webview
381 createEwkView(evas_object_evas_get(m_window));
382 ewkClientInit(m_currentEwkView);
383 prepareEwkView(m_currentEwkView);
385 // check if current url is service url for this tizen service
387 ViewModule::UriSupport::getUri(m_model, m_startUrl);
389 initializePluginLoading();
392 ewk_view_url_set(m_currentEwkView, url.c_str());
393 elm_win_activate(m_window);
394 evas_object_focus_set(m_currentEwkView, EINA_TRUE);
396 // call user callback
397 if (!m_cbs->reset.empty()) {
400 if (!m_cbs->bufferSet.empty()) {
401 m_cbs->bufferSet(m_currentEwkView);
405 void ViewLogic::backward()
407 if (ewk_view_back_possible(m_currentEwkView)) {
408 ewk_view_back(m_currentEwkView);
410 if (1 >= m_ewkViewList.size()) {
411 // If there is no previous page, widget move to backgroud.
412 LogInfo("Widget move to backgroud");
413 elm_win_lower(m_window);
415 // Back to previous webview
416 LogInfo("Widget move to previous webview");
417 m_closedEwkView = m_currentEwkView;
418 ecore_idler_add(windowCloseIdlerCallback, this);
423 void ViewLogic::reloadStartPage()
425 LogInfo("Reload Start Page");
426 // prevent fail to load plugin bundle side
427 m_isBackgroundReload = true;
429 if (!m_ewkViewList.empty()) {
430 while (!m_ewkViewList.empty()) {
431 if (!m_cbs->bufferUnset.empty()) {
432 m_cbs->bufferUnset(m_currentEwkView);
434 removeEwkView(m_currentEwkView);
438 // create new webview
439 createEwkView(evas_object_evas_get(m_window));
440 ewkClientInit(m_currentEwkView);
442 prepareEwkView(m_currentEwkView);
443 initializePluginLoading();
446 std::string url = ViewModule::UriSupport::getUri(m_model, m_startUrl);
447 ewk_view_url_set(m_currentEwkView, url.c_str());
450 if (!m_cbs->bufferSet.empty()) {
451 m_cbs->bufferSet(m_currentEwkView);
453 LogInfo("Reloading Start Page is done!");
456 Evas_Object* ViewLogic::getCurrentWebview()
458 LogInfo("get current webview");
459 return m_currentEwkView;
462 void ViewLogic::fireJavascriptEvent(int event, void* data)
464 ViewLogicMessageSupport::dispatchJavaScriptEvent(
466 static_cast<WrtPlugins::W3C::CustomEventType>(event),
470 void ViewLogic::setUserCallbacks(const WRT::UserDelegatesPtr& cbs)
475 void ViewLogic::checkSyncMessageFromBundle(
480 LogDebug("didReceiveSynchronousMessage called");
483 LogDebug("received : " << name);
485 if (!strcmp(name, Message::ToUIProcess::BLOCKED_URL)) {
486 // Currently WebProcess informs obly about blocked
487 // URI - URI localization and security chekcs are
488 // done by WebProcess itself (see: wrt-injected-bundle.cpp
489 // and bundle_uri_handling.cpp)
490 requestUrlBlocked(std::string(body));
492 #ifdef MULTIPROCESS_SERVICE_SUPPORT_INLINE
493 else if (!strcmp(name, Message::ToUIProcess::SEND_WEBPROCESS_PID)) {
494 std::stringstream ss(body);
495 unsigned int pid = 0;
497 ServiceSupport::setWebProcessPidWindowProperty(
498 elm_win_xwindow_get(m_window),
502 else if (!strcmp(name, Message::TizenScheme::GET_WINDOW_HANDLE)) {
504 Ecore_X_Window handle = elm_win_xwindow_get(m_window);
506 std::stringstream ss;
508 std::string ret = ss.str();
510 *returnData = strdup(ret.c_str());
513 LogInfo("X window isn't exist");
519 void ViewLogic::downloadData(const char* url)
525 m_appsSupport->downloadRequest(url, NULL, NULL);
528 void ViewLogic::activateVibration(bool on, uint64_t time)
532 m_vibrationSupport->startVibration(static_cast<long>(time));
534 m_vibrationSupport->stopVibration();
538 void ViewLogic::initializeSupport()
540 // background support
541 if (m_model->SettingList.Get().getBackgroundSupport()
542 == BackgroundSupport_Enable)
544 LogDebug("Background support enabled, set process active");
545 pid_t pid = getpid();
546 sysman_inform_active(pid);
547 m_isBackgroundSupport = true;
549 system_settings_set_changed_cb(SYSTEM_SETTINGS_KEY_FONT_TYPE,
550 systemSettingsChangedCallback,
553 m_schemeSupport.reset(new SchemeSupport(m_model->Type.Get().appType));
554 ViewModule::StorageSupport::initializeStorage(m_model);
555 m_appsSupport->initialize(m_model, elm_win_xwindow_get(m_window));
556 m_securityOriginSupport.reset(new ViewModule::SecurityOriginSupport(m_model));
557 m_certificateSupport.reset(new ViewModule::CertificateSupport(m_model));
558 m_vibrationSupport->initialize();
561 void ViewLogic::initializePluginLoading()
563 // inform wrt information for plugin loading to web process
564 ViewLogicMessageSupport::start(
567 elm_config_scale_get(),
568 ApplicationDataSingleton::Instance().getEncodedBundle(),
572 void ViewLogic::initializeXwindowHandle()
575 unsigned int handle = elm_win_xwindow_get(m_window);
576 ViewLogicMessageSupport::setXwindowHandle(
582 void ViewLogic::ewkClientInit(Evas_Object *wkView)
584 Assert(NULL != wkView && "ewk_view not created at this point");
586 FOREACH(it, m_ewkCallbacksMap)
588 evas_object_smart_callback_add(
594 // EWK Orientation Callback
595 ewk_view_orientation_lock_callback_set(
597 orientationLockCallback,
599 ewk_view_exceeded_database_quota_callback_set(
601 exceededDatabaseQuotaCallback,
603 ewk_view_exceeded_indexed_database_quota_callback_set(
605 exceededIndexedDatabaseQuotaCallback,
607 ewk_view_exceeded_local_file_system_quota_callback_set(
609 exceededLocalFileSystemQuotaCallback,
613 void ViewLogic::ewkClientDeinit(Evas_Object *wkView)
615 LogDebug("ewkClientDeinit");
616 Assert(NULL != wkView && "ewk_view not created at this point");
618 FOREACH(it, m_ewkCallbacksMap)
620 evas_object_smart_callback_del(
625 ewk_view_orientation_lock_callback_set(wkView, NULL, NULL);
626 ewk_view_exceeded_database_quota_callback_set(wkView, NULL, NULL);
627 ewk_view_exceeded_indexed_database_quota_callback_set(wkView, NULL, NULL);
628 ewk_view_exceeded_local_file_system_quota_callback_set(wkView, NULL, NULL);
631 bool ViewLogic::createEwkView(Evas* canvas)
633 LogDebug("createEwkView");
635 ADD_PROFILING_POINT("ewk_view_add_with_context", "start");
636 Evas_Object* newEwkView = ewk_view_add_with_context(
639 ADD_PROFILING_POINT("ewk_view_add_with_context", "stop");
642 LogError("View creation failed");
643 Wrt::Popup::PopupInvoker().showInfo(
644 "Info", "View creation failed", "close");
649 // even arguments pass the ewkContext, this API should be called
650 // after webkit Evas_Object is created
651 Ewk_Cookie_Manager *ewkCookieManager;
653 ewk_context_cookie_manager_get(m_ewkContext);
654 ewk_cookie_manager_accept_policy_set(ewkCookieManager,
655 EWK_COOKIE_ACCEPT_POLICY_ALWAYS);
657 if (m_currentEwkView) {
658 setEwkViewInvisible(m_currentEwkView);
661 LogInfo("push webview: " << newEwkView);
662 m_ewkViewList.push_back(newEwkView);
663 m_currentEwkView = newEwkView;
667 void ViewLogic::prepareEwkView(Evas_Object *wkView)
669 LogDebug("prepareEwkView called");
671 Ewk_Settings* settings = ewk_view_settings_get(wkView);
674 std::string customUserAgent = m_model->SettingList.Get().getUserAgent();
675 if (customUserAgent.empty()) {
676 LogDebug("Setting user agent as: default");
677 ewk_view_user_agent_set(wkView, NULL);
678 std::string defaultUA = ewk_view_user_agent_get(wkView);
679 LogDebug("webkit's UA: " << defaultUA);
681 LogDebug("Setting custom user agent as: " << customUserAgent);
682 ewk_view_user_agent_set(wkView, customUserAgent.c_str());
685 // set custom header : language
686 using namespace ViewModule::CustomHeaderSupport;
687 std::string customHeaderString = getValueByField(ACCEPT_LANGUAGE);
688 if (!customHeaderString.empty()) {
689 LogDebug("custom field=[" << ACCEPT_LANGUAGE << "]");
690 LogDebug("custom value=[" << customHeaderString << "]");
691 ewk_view_custom_header_add(wkView,
692 ACCEPT_LANGUAGE.c_str(),
693 customHeaderString.c_str());
696 // webkit NPAPI plugins is always on in wrt
697 ewk_settings_plugins_enabled_set(settings, EINA_TRUE);
698 ewk_settings_javascript_enabled_set(settings, EINA_TRUE);
699 ewk_settings_loads_images_automatically_set(settings, EINA_TRUE);
700 // WRT should not fit web contents to device width automatically as default.
701 // Fitting to device width should be handled by web content using viewport meta tag.
702 ewk_settings_auto_fitting_set(settings, EINA_FALSE);
703 ewk_settings_autofill_password_form_enabled_set(settings, EINA_TRUE);
704 ewk_settings_form_candidate_data_enabled_set(settings, EINA_TRUE);
706 ewk_view_page_visibility_state_set(wkView,
707 EWK_PAGE_VISIBILITY_STATE_VISIBLE,
710 std::string encoding = DEFAULT_ENCODING;
711 OptionalWidgetStartFileInfo fileInfo =
712 W3CFileLocalization::getStartFileInfo(m_model->TizenId);
713 if (!fileInfo.IsNull()) {
714 encoding = DPL::ToUTF8String((*fileInfo).encoding);
715 LogInfo("Found custom encoding in DB: " << encoding);
717 LogInfo("Setting encoding: " << encoding);
718 if (ewk_settings_default_encoding_set(settings,encoding.c_str())) {
719 LogInfo("Encoding set properly");
721 LogError("Error while setting encoding");
725 if (m_model->SecurityModelVersion.Get() ==
726 WrtDB::WidgetSecurityModelVersion::WIDGET_SECURITY_MODEL_V2)
728 // setting CSP policy rules
729 DPL::OptionalString policy = m_model->CspReportOnlyPolicy.Get();
730 if (!policy.IsNull()) {
731 LogDebug("CSP report only policy present in manifest: " << *policy);
732 ewk_view_content_security_policy_set(
734 DPL::ToUTF8String(*policy).c_str(),
738 policy = m_model->CspPolicy.Get();
739 if (!policy.IsNull()) {
740 LogDebug("CSP policy present in manifest: " << *policy);
741 ewk_view_content_security_policy_set(
743 DPL::ToUTF8String(*policy).c_str(),
746 ewk_view_content_security_policy_set(
755 void ViewLogic::removeEwkView(Evas_Object *wkView)
757 LogInfo("removeEwkView called");
759 Assert(0 != m_ewkViewList.size());
761 // unregister webview callbacks
762 ewkClientDeinit(wkView);
764 // suspend NPAPI plugin - Not implemented by Webkit2
765 // ewk_view_pause_or_resume_plugins();
766 evas_object_del(wkView);
767 m_ewkViewList.remove(wkView);
770 void ViewLogic::resumeEwkView(Evas_Object *wkView)
772 LogInfo("resumeEwkView called");
775 // register webview callback
776 ewkClientInit(wkView);
779 resumeWebkit(wkView);
784 void ViewLogic::suspendEwkView(Evas_Object *wkView)
786 LogInfo("suspendEwkView called");
790 suspendWebkit(wkView);
792 // unregister webview callbacks
793 ewkClientDeinit(wkView);
797 void ViewLogic::setEwkViewInvisible(Evas_Object *wkView)
799 LogInfo("setEwkViewInvisible called");
802 ewk_view_page_visibility_state_set(wkView,
803 EWK_PAGE_VISIBILITY_STATE_HIDDEN,
805 ewk_view_visibility_set(wkView, EINA_FALSE);
808 void ViewLogic::setEwkViewVisible(Evas_Object *wkView)
810 LogInfo("setEwkViewVisible called");
813 ewk_view_page_visibility_state_set(wkView,
814 EWK_PAGE_VISIBILITY_STATE_VISIBLE,
816 ewk_view_visibility_set(wkView, EINA_TRUE);
819 void ViewLogic::resumeWebkit(Evas_Object *wkView)
821 LogDebug("resumeWebkit");
824 ewk_view_resume(wkView);
829 void ViewLogic::suspendWebkit(Evas_Object *wkView)
831 LogDebug("suspendWebkit");
834 ewk_view_suspend(wkView);
839 void ViewLogic::loadStartedCallback(
844 LogDebug("loadStartedCallback called");
846 ViewLogic* This = static_cast<ViewLogic*>(data);
848 // call loadFinish callback to wrt-client
849 if (!This->m_cbs->loadStart.empty()) {
850 This->m_cbs->loadStart(obj);
854 void ViewLogic::loadFinishedCallback(
859 LogDebug("loadFinishedCallback called");
861 ViewLogic* This = static_cast<ViewLogic*>(data);
862 evas_object_focus_set(This->m_currentEwkView, EINA_TRUE);
865 const char* url = ewk_view_url_get(This->m_currentEwkView);
866 if (NULL == url || strlen(url) == 0) {
867 LogError("url is empty");
871 // call loadFinish callback to wrt-client
872 if (!This->m_cbs->loadFinish.empty()) {
873 This->m_cbs->loadFinish(obj);
876 // set only encoded bundle
877 double scale = elm_config_scale_get();
878 ViewLogicMessageSupport::setCustomProperties(
881 ApplicationDataSingleton::Instance().getEncodedBundle());
883 // In this case, widget is reloaded in the background.
884 // After finished load, bundle should disconnent callback.
885 if (This->m_isBackgroundReload) {
886 ewk_view_suspend(This->m_currentEwkView);
887 This->m_isBackgroundReload = false;
891 void ViewLogic::titleChangedCallback(
896 LogDebug("titleChangedCallback called");
898 ViewLogic* This = static_cast<ViewLogic*>(data);
900 const char* title = static_cast<char*>(eventInfo);
902 if (0 == strlen(title)) {
903 LogDebug("title data is empty");
904 This->m_currentTitle = std::string();
907 LogDebug("Title = [" << title << "]");
908 bool ret = This->m_schemeSupport->HandleTizenScheme(
911 This->m_currentEwkView);
912 // if result is true, this is tizen scheme
913 // and then, title is reset to page's real title
915 std::string script = "document.title = \"";
916 script += This->m_currentTitle;
918 ewk_view_script_execute(obj, script.c_str(), didRunJavaScriptCallback, This);
920 This->m_currentTitle = std::string(title);
924 void ViewLogic::loadProgressStartedCallback(
926 Evas_Object* /*obj*/,
929 LogDebug("loadProgressStartedCallback called");
931 ViewLogic* This = static_cast<ViewLogic*>(data);
932 if (!This->m_cbs->progressStarted.empty()) {
933 This->m_cbs->progressStarted();
938 void ViewLogic::loadProgressCallback(
943 LogDebug("loadProgressCallback called");
946 ViewLogic const * const view = static_cast<ViewLogic const * const>(data);
947 double* progress = static_cast<double*>(eventInfo);
948 LogDebug("didChangeProgressCallback progress = " << *progress);
949 if (!view->m_cbs->progress.empty()) {
951 view->m_cbs->progress(obj, *progress);
955 void ViewLogic::loadProgressFinishedCallback(
957 Evas_Object* /*obj*/,
960 LogDebug("didFinishProgressCallback");
962 ViewLogic const * const view = static_cast<ViewLogic const * const>(data);
963 if (!view->m_cbs->progressFinish.empty()) {
964 view->m_cbs->progressFinish();
968 void ViewLogic::processCrashedCallback(
970 Evas_Object* /*obj*/,
973 LogInfo("processCrashedCallback");
975 ViewLogic const * const view =
976 static_cast<ViewLogic const * const>(data);
977 if (!view->m_cbs->webCrash.empty()) {
978 view->m_cbs->webCrash();
980 // This flag will be prevented exit() call in the Webkit side
981 if (NULL != eventInfo) {
982 *(static_cast<Eina_Bool*>(eventInfo)) = EINA_TRUE;
986 void ViewLogic::createWindowCallback(
991 LogDebug("createWindowCallback");
993 ViewLogic* This = static_cast<ViewLogic*>(data);
995 // First, current webview should be handled by user callback
996 if (!This->m_cbs->bufferUnset.empty()) {
997 This->m_cbs->bufferUnset(obj);
1000 // this can be set by executable for specific purpose
1001 Evas* canvas = NULL;
1002 if (!This->m_cbs->windowCreateBefore.empty()) {
1003 // 'obj' is parent webview object
1004 This->m_cbs->windowCreateBefore(&canvas, obj);
1007 canvas = evas_object_evas_get(This->m_window);
1010 // create new ewkview
1011 This->createEwkView(canvas);
1012 Evas_Object* newEwkView = This->m_currentEwkView;
1014 // initialize new ewkview
1015 This->ewkClientInit(newEwkView);
1016 This->prepareEwkView(newEwkView);
1018 // Specific jobs of child, parent webview are handled by each executable
1019 if (!This->m_cbs->windowCreateAfter.empty()) {
1020 // 'obj' is parent webview, 'newEwkView' is child webview
1021 This->m_cbs->windowCreateAfter(obj, newEwkView);
1024 // Lastly, new webview should be handled by user callback
1025 if (!This->m_cbs->bufferSet.empty()) {
1026 This->m_cbs->bufferSet(newEwkView);
1028 *(static_cast<Evas_Object **>(eventInfo)) = newEwkView;
1031 void ViewLogic::closeWindowCallback(
1034 void* /*eventInfo*/)
1036 LogDebug("closeWindowCallback");
1037 ViewLogic* This = static_cast<ViewLogic*>(data);
1038 This->m_closedEwkView = obj;
1039 ecore_idler_add(windowCloseIdlerCallback, This);
1042 void ViewLogic::policyNavigationDecideCallback(
1047 LogDebug("policyNavigationDecideCallback called");
1049 ViewLogic* This = static_cast<ViewLogic*>(data);
1051 Ewk_Policy_Decision* policyDecision =
1052 static_cast<Ewk_Policy_Decision*>(eventInfo);
1054 // handle blocked url
1055 const char* url = ewk_policy_decision_url_get(policyDecision);
1057 // call user delegate callback
1058 if (!This->m_cbs->navigationDecide.empty()) {
1059 std::string navigationUri(url);
1060 This->m_cbs->navigationDecide(obj, navigationUri);
1061 if (!navigationUri.compare(0, 6, SCHEME_BOX_SLASH)) {
1062 ewk_policy_decision_ignore(policyDecision);
1067 if (url && strlen(url) != 0) {
1068 if (This->m_blockedUri == url) {
1069 LogDebug("Blocked url = " << url);
1070 This->m_blockedUri = std::string();
1071 ewk_policy_decision_ignore(policyDecision);
1076 if (This->m_schemeSupport->filterURIByScheme(policyDecision,
1080 This->m_currentEwkView))
1083 ewk_policy_decision_use(policyDecision);
1085 // check whether this is new empty window
1086 const char* activeUrl = ewk_view_url_get(This->m_currentEwkView);
1087 if (!activeUrl || 0 == strlen(activeUrl)) {
1089 * The view is empty and scheme has been handled externally. When
1090 * user gets back from the external application he'd see blank page
1091 * and won't be able to navigate back. This happens when window.open
1092 * is used to handle schemes like sms/mms/mailto (for example in
1093 * WAC web standards tests: WS-15XX).
1095 * To solve the problem, the empty view is removed from the stack
1096 * and the previous one is shown. This is not an elegant solution
1097 * but we don't have a better one.
1099 LogInfo("Scheme has been handled externally. Removing empty view.");
1100 if (ewk_view_back_possible(This->m_currentEwkView)) {
1101 // go back to previous WKPage
1102 ewk_view_back(This->m_currentEwkView);
1104 // stop current WKPage
1105 ewk_view_stop(This->m_currentEwkView);
1106 This->m_closedEwkView = This->m_currentEwkView;
1107 ecore_idler_add(windowCloseIdlerCallback, This);
1112 ewk_policy_decision_ignore(policyDecision);
1116 void ViewLogic::policyNewWindowDecideCallback(
1118 Evas_Object* /*obj*/,
1121 LogDebug("policyNewWindowDecideCallback called");
1123 ViewLogic* This = static_cast<ViewLogic*>(data);
1125 Ewk_Policy_Decision* policyDecision =
1126 static_cast<Ewk_Policy_Decision*>(eventInfo);
1128 // handle blocked url
1129 const char* url = ewk_policy_decision_url_get(policyDecision);
1130 if (url && strlen(url) != 0) {
1131 if (This->m_blockedUri == url) {
1132 LogDebug("Blocked url = " << url);
1133 This->m_blockedUri = std::string();
1134 ewk_policy_decision_ignore(policyDecision);
1139 if (This->m_schemeSupport->filterURIByScheme(policyDecision,
1143 This->m_currentEwkView))
1145 ewk_policy_decision_use(policyDecision);
1148 ewk_policy_decision_ignore(policyDecision);
1152 void ViewLogic::pageResponseDecideCallback(
1154 Evas_Object* /*obj*/,
1157 LogDebug("pageResponseDecideCallback called");
1159 ViewLogic* This = static_cast<ViewLogic*>(data);
1161 Ewk_Policy_Decision* policyDecision =
1162 static_cast<Ewk_Policy_Decision*>(eventInfo);
1163 Ewk_Policy_Decision_Type policyDecisionType =
1164 ewk_policy_decision_type_get(policyDecision);
1166 if (policyDecisionType == EWK_POLICY_DECISION_USE) {
1168 ewk_policy_decision_use(policyDecision);
1169 } else if (policyDecisionType == EWK_POLICY_DECISION_DOWNLOAD) {
1170 LogDebug("download");
1171 ewk_policy_decision_suspend(policyDecision);
1173 // get uri information
1174 const char* url = ewk_policy_decision_url_get(policyDecision);
1175 if (NULL == url || strlen(url) == 0) {
1176 LogDebug("url data is empty");
1177 ewk_policy_decision_use(policyDecision);
1180 LogDebug("url = [" << url << "]");
1182 // get content information
1183 const char* content =
1184 ewk_policy_decision_response_mime_get(policyDecision);
1185 LogDebug("content type = [" << content << "]");
1187 // get cookie information
1188 const char* cookie = ewk_policy_decision_cookie_get(policyDecision);
1189 LogDebug("cookie = [" << cookie << "]");
1191 LogDebug("Content not supported, will be opened in external app");
1192 This->m_appsSupport->downloadRequest(
1196 ewk_policy_decision_ignore(policyDecision);
1197 } else if (policyDecisionType == EWK_POLICY_DECISION_IGNORE) {
1199 ewk_policy_decision_ignore(policyDecision);
1201 LogDebug("Type isn't handled");
1202 ewk_policy_decision_ignore(policyDecision);
1206 void ViewLogic::contextmenuCustomizeCallback(
1208 Evas_Object* /*obj*/,
1211 LogDebug("contextmenuCustomizeCallback called");
1214 ViewLogic* This = static_cast<ViewLogic*>(const_cast<void*>(data));
1215 Ewk_Context_Menu* menu = static_cast<Ewk_Context_Menu*>(eventInfo);
1216 if ((This->m_model->Type.Get().appType == WrtDB::APP_TYPE_TIZENWEBAPP) &&
1217 (This->m_model->SettingList.Get().getContextMenu()
1218 == ContextMenu_Disable))
1220 LogDebug("ContextMenu Disable!!");
1221 for (unsigned int idx = 0; idx < ewk_context_menu_item_count(menu);) {
1222 Ewk_Context_Menu_Item* item = ewk_context_menu_nth_item_get(menu,
1225 ewk_context_menu_item_remove(menu, item);
1228 LogDebug("ContextMenu Enable!!");
1229 unsigned int menu_num = ewk_context_menu_item_count(menu);
1230 unsigned int idx = 0;
1232 Ewk_Context_Menu_Item* item = ewk_context_menu_nth_item_get(menu,
1238 Ewk_Context_Menu_Item_Tag tag = ewk_context_menu_item_tag_get(item);
1241 case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_IMAGE_IN_NEW_WINDOW:
1242 ewk_context_menu_item_remove(menu, item);
1245 case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_LINK_IN_NEW_WINDOW:
1246 ewk_context_menu_item_remove(menu, item);
1249 case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_FRAME_IN_NEW_WINDOW:
1250 ewk_context_menu_item_remove(menu, item);
1253 case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_MEDIA_IN_NEW_WINDOW:
1254 ewk_context_menu_item_remove(menu, item);
1257 case EWK_CONTEXT_MENU_ITEM_TAG_SEARCH_WEB:
1258 ewk_context_menu_item_remove(menu, item);
1265 } while (idx < menu_num);
1269 void ViewLogic::geolocationPermissionRequestCallback(
1271 Evas_Object* /*obj*/,
1275 ViewLogic* This = static_cast<ViewLogic*>(data);
1277 Ewk_Geolocation_Permission_Request* permissionRequest =
1278 static_cast<Ewk_Geolocation_Permission_Request*>(eventInfo);
1280 if (This->m_model->GeolocationUsage.Get() == WrtDB::SETTINGS_TYPE_OFF) {
1281 ewk_geolocation_permission_request_set(permissionRequest, EINA_FALSE);
1284 ViewModule::GeolocationSupport::geolocationPermissionRequest(
1285 This->m_currentEwkView,
1286 This->m_securityOriginSupport->getSecurityOriginDAO(),
1290 void ViewLogic::notificationShowCallback(
1292 Evas_Object* /*obj*/,
1295 LogDebug("notificationShowCallback called");
1297 ViewLogic* This = static_cast<ViewLogic*>(data);
1300 Ewk_Notification* noti = static_cast<Ewk_Notification*>(eventInfo);
1302 using namespace ViewModule::WebNotification;
1304 WebNotificationDataPtr notiData(
1305 new WebNotificationData(
1307 ewk_notification_id_get(noti)));
1309 DPL::OptionalString string =
1310 DPL::FromUTF8String(ewk_notification_icon_url_get(noti));
1311 if (!string.IsNull()) {
1312 notiData->m_iconURL = DPL::ToUTF8String(*string);
1314 string = DPL::FromUTF8String(ewk_notification_title_get(noti));
1315 if (!string.IsNull()) {
1316 notiData->m_title = DPL::ToUTF8String(*string);
1318 string = DPL::FromUTF8String(ewk_notification_body_get(noti));
1319 if (!string.IsNull()) {
1320 notiData->m_body = DPL::ToUTF8String(*string);
1323 LogInfo("notification id : " << notiData->m_id);
1324 LogInfo("notification iconURL : " << notiData->m_iconURL);
1325 LogInfo("notification title : " << notiData->m_title);
1326 LogInfo("notification body : " << notiData->m_body);
1328 showWebNotification(notiData);
1329 ewk_notification_showed(This->m_ewkContext, ewk_notification_id_get(noti));
1332 void ViewLogic::notificationCancelCallback(
1334 Evas_Object* /*obj*/,
1335 void* /*eventInfo*/)
1337 LogDebug("notificationCancelCallback called");
1340 void ViewLogic::notificationPermissionRequestCallback(
1342 Evas_Object* /*obj*/,
1345 LogDebug("notificationPermissionRequestCallback called");
1347 ViewLogic* This = static_cast<ViewLogic*>(data);
1348 if (This->m_model->WebNotificationUsage.Get() == WrtDB::SETTINGS_TYPE_OFF) {
1349 Ewk_Notification_Permission_Request* request =
1350 static_cast<Ewk_Notification_Permission_Request*>(eventInfo);
1351 ewk_notification_permission_request_set(
1358 ViewModule::WebNotification::webNotificationPermissionRequest(
1359 This->m_currentEwkView,
1360 This->m_securityOriginSupport->getSecurityOriginDAO(),
1365 // EWK Orientation Callback
1366 Eina_Bool ViewLogic::orientationLockCallback(
1372 LogDebug("orientationLockCallback called");
1374 ViewLogic* This = static_cast<ViewLogic*>(data);
1375 This->m_rotateAngle = orientation;
1377 if (needLock == EINA_TRUE) {
1378 // Screen.lockOrientation
1379 ViewModule::OrientationSupport::setOrientation(
1384 // Screen.unlockOrientation
1385 if (This->m_model->SettingList.Get().getRotationValue() ==
1386 Screen_AutoRotation)
1388 elm_win_wm_rotation_preferred_rotation_set(
1390 OrientationAngle::Window::UNLOCK);
1391 This->m_rotateAngle = 0;
1397 // Fullscreen API callbacks
1398 void ViewLogic::enterFullscreenCallback(
1400 Evas_Object* /*obj*/,
1401 void* /*eventInfo*/)
1403 LogInfo("enterFullscreenCallback called");
1405 ViewLogic* This = static_cast<ViewLogic*>(data);
1406 if (!This->m_cbs->toggleFullscreen.empty()) {
1407 This->m_cbs->toggleFullscreen(true);
1410 void ViewLogic::exitFullscreenCallback(
1412 Evas_Object* /*obj*/,
1413 void* /*eventInfo*/)
1415 LogInfo("exitFullscreenCallback called");
1417 ViewLogic* This = static_cast<ViewLogic*>(data);
1418 if (!This->m_cbs->toggleFullscreen.empty()) {
1419 This->m_cbs->toggleFullscreen(false);
1423 void ViewLogic::imeChangedCallback(
1425 Evas_Object* /*obj*/,
1431 ViewLogic* This = static_cast<ViewLogic*>(data);
1432 Eina_Rectangle *rect = static_cast<Eina_Rectangle *>(eventInfo);
1433 This->m_imeWidth = rect->w;
1434 This->m_imeHeight = rect->h;
1437 void ViewLogic::imeOpenedCallback(
1439 Evas_Object* /*obj*/,
1440 void* /*eventInfo*/)
1444 ViewLogic* This = static_cast<ViewLogic*>(data);
1446 using namespace WrtPlugins::W3C;
1447 SoftKeyboardChangeArgs args;
1448 args.state = IME_STATE_ON;
1449 args.width = This->m_imeWidth;
1450 args.height = This->m_imeHeight;
1451 This->fireJavascriptEvent(
1452 static_cast<int>(SoftKeyboardChangeCustomEvent),
1455 if (!This->m_cbs->editorClientIme.empty()) {
1456 This->m_cbs->editorClientIme(true);
1460 void ViewLogic::imeClosedCallback(
1462 Evas_Object* /*obj*/,
1463 void* /*eventInfo*/)
1467 ViewLogic* This = static_cast<ViewLogic*>(data);
1469 using namespace WrtPlugins::W3C;
1470 SoftKeyboardChangeArgs args;
1471 args.state = IME_STATE_OFF;
1472 This->fireJavascriptEvent(
1473 static_cast<int>(SoftKeyboardChangeCustomEvent),
1475 if (!This->m_cbs->editorClientIme.empty()) {
1476 This->m_cbs->editorClientIme(false);
1480 void ViewLogic::usermediaPermissionRequestCallback(
1482 Evas_Object* /*obj*/,
1485 LogDebug("usermediaPermissionRequestCallback called");
1487 ViewLogic* This = static_cast<ViewLogic*>(data);
1488 ViewModule::UsermediaSupport::usermediaPermissionRequest(
1489 This->m_currentEwkView,
1490 This->m_securityOriginSupport->getSecurityOriginDAO(),
1495 CustomHandlerDB::CustomHandlerPtr getCustomHandlerFromData(void* data)
1498 Ewk_Custom_Handlers_Data* handler =
1499 static_cast<Ewk_Custom_Handlers_Data*>(data);
1500 CustomHandlerDB::CustomHandlerPtr customHandler(
1501 new CustomHandlerDB::CustomHandler());
1502 const char* base_url = ewk_custom_handlers_data_base_url_get(handler);
1504 LogDebug("base url: " << base_url);
1505 customHandler->base_url = DPL::FromASCIIString(string(base_url));
1507 const char* url = ewk_custom_handlers_data_url_get(handler);
1509 LogDebug("url: " << url);
1510 customHandler->url = DPL::FromASCIIString(string(url));
1512 const char* target = ewk_custom_handlers_data_target_get(handler);
1514 LogDebug("target: " << target);
1515 customHandler->target = DPL::FromASCIIString(string(target));
1517 const char* title = ewk_custom_handlers_data_title_get(handler);
1519 LogDebug("title: " << title);
1520 customHandler->title = DPL::FromASCIIString(string(title));
1522 return customHandler;
1525 void ViewLogic::attachToCustomHandlersDao()
1527 if (!m_attachedToCustomHandlerDao) {
1528 CustomHandlerDB::Interface::attachDatabaseRW();
1532 void ViewLogic::detachFromCustomHandlersDao()
1534 if (m_attachedToCustomHandlerDao) {
1535 CustomHandlerDB::Interface::detachDatabase();
1539 const int protocolWhiteListLenth = 15;
1540 char const * const protocolWhiteList[protocolWhiteListLenth] = {
1558 const int contentBlackListLenth = 14;
1559 char const * const contentBlackList[contentBlackListLenth] = {
1560 "application/x-www-form-urlencoded",
1561 "application/xhtml+xml",
1567 "multipart/x-mixed-replace",
1568 "text/cache-manifest",
1577 * Saves user's response from popup to custom handler. Saves Yes/No and remember
1580 * @param customHandler
1582 void saveUserResponse(Wrt::Popup::PopupResponse response,
1583 CustomHandlerDB::CustomHandlerPtr customHandler)
1586 case Wrt::Popup::YES_DO_REMEMBER:
1587 LogDebug("User allowed, remember");
1588 customHandler->user_decision =
1589 static_cast<CustomHandlerDB::HandlerState>
1590 (CustomHandlerDB::Agreed | CustomHandlerDB::DecisionSaved);
1592 case Wrt::Popup::YES_DONT_REMEMBER:
1593 LogDebug("User allowed, don't remember");
1594 customHandler->user_decision = CustomHandlerDB::Agreed;
1596 case Wrt::Popup::NO_DO_REMEMBER:
1597 LogDebug("User didn't allow, remember");
1598 customHandler->user_decision =
1599 static_cast<CustomHandlerDB::HandlerState>
1600 (CustomHandlerDB::Declined | CustomHandlerDB::DecisionSaved);
1602 case Wrt::Popup::NO_DONT_REMEMBER:
1603 LogDebug("User didn't allow, don't remember");
1604 customHandler->user_decision = CustomHandlerDB::Declined;
1609 //TODO registration, checking if registered and unregistration can be done in
1610 //common functions for both types of handlers. Only white and black lists
1611 //have to be separated
1612 //TODO attach database only one at the start (not in every callback?)
1613 void ViewLogic::protocolHandlerRegistrationCallback(void* data,
1614 Evas_Object* /*obj*/,
1619 CustomHandlerDB::CustomHandlerPtr customHandler =
1620 getCustomHandlerFromData(eventInfo);
1622 std::string scheme = DPL::ToUTF8String(customHandler->target);
1623 if (scheme.empty()) {
1624 LogError("No scheme provided");
1625 //TODO what about securityError?
1628 bool matched = false;
1629 //scheme on whiteList
1630 for (int i = 0; i < protocolWhiteListLenth; ++i) {
1631 if (0 == strcmp(protocolWhiteList[i], scheme.c_str())) {
1632 LogDebug("Match found, protocol can be handled");
1637 //starts with web+ and have at least 5 chars (lowercase ASCII)
1638 if (strncmp("web+", scheme.c_str(), 4) || scheme.length() < 5) {
1639 LogWarning("Scheme neither on whitelist nor starts with \"web+\"");
1640 //throw SecurityException
1646 if (c < 'a' || c > 'z') {
1647 LogWarning("Wrong char inside scheme. "
1648 << "Only lowercase ASCII letters accepted");
1649 //throw SecurityException
1656 ViewLogic* This = static_cast<ViewLogic*>(data);
1657 LogDebug("Creating handlers dao");
1658 This->attachToCustomHandlersDao();
1659 CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1660 CustomHandlerDB::CustomHandlerPtr handler =
1661 handlersDao.getProtocolHandler(customHandler->target,
1663 customHandler->base_url);
1664 if (handler && (handler->user_decision & CustomHandlerDB::DecisionSaved)) {
1665 LogDebug("Protocol already registered - nothing to do");
1667 LogDebug("Protocol handler not found");
1668 Wrt::Popup::PopupResponse response =
1669 GlobalSettings::PopupsTestModeEnabled() ? Wrt::Popup::
1671 Wrt::Popup::PopupInvoker().askYesNoCheckbox(
1672 PROTOCOL_HANDLER_ASK_TITLE,
1673 PROTOCOL_HANDLER_ASK_MSG,
1674 PROTOCOL_HANDLER_ASK_REMEMBER);
1675 saveUserResponse(response, customHandler);
1676 if (customHandler->user_decision == CustomHandlerDB::Declined) {
1679 if (customHandler->user_decision & CustomHandlerDB::Agreed) {
1680 //TODO remove old default handler somehow from appsvc
1681 LogDebug("Registering appservice entry");
1682 int ret = appsvc_set_defapp(APPSVC_OPERATION_VIEW,
1685 customHandler->target).c_str(),
1686 DPL::ToUTF8String(This->m_model->
1688 if (APPSVC_RET_OK != ret) {
1689 LogWarning("Appsvc entry failed: " << ret);
1690 //no database change
1694 handlersDao.registerProtocolHandler(*(customHandler.get()));
1696 LogDebug("Protocal saved");
1699 This->detachFromCustomHandlersDao();
1702 void ViewLogic::protocolHandlerIsRegisteredCallback(void* data,
1703 Evas_Object* /*obj*/,
1707 CustomHandlerDB::CustomHandlerPtr customHandler = getCustomHandlerFromData(
1709 ViewLogic* This = static_cast<ViewLogic*>(data);
1710 LogDebug("Creating handlers dao");
1711 This->attachToCustomHandlersDao();
1712 CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1713 CustomHandlerDB::CustomHandlerPtr handler =
1714 handlersDao.getProtocolHandler(customHandler->target,
1716 customHandler->base_url);
1718 if (handler->user_decision & CustomHandlerDB::Agreed) {
1719 ewk_custom_handlers_data_result_set(
1720 static_cast<Ewk_Custom_Handlers_Data*>(eventInfo),
1721 EWK_CUSTOM_HANDLERS_REGISTERED);
1723 ewk_custom_handlers_data_result_set(
1724 static_cast<Ewk_Custom_Handlers_Data*>(eventInfo),
1725 EWK_CUSTOM_HANDLERS_DECLINED);
1728 ewk_custom_handlers_data_result_set(
1729 static_cast<Ewk_Custom_Handlers_Data*>(eventInfo),
1730 EWK_CUSTOM_HANDLERS_NEW);
1732 This->detachFromCustomHandlersDao();
1735 void ViewLogic::protocolHandlerUnregistrationCallback(void* data,
1736 Evas_Object* /*obj*/,
1740 CustomHandlerDB::CustomHandlerPtr customHandler =
1741 getCustomHandlerFromData(eventInfo);
1742 ViewLogic* This = static_cast<ViewLogic*>(data);
1743 LogDebug("Creating handlers dao");
1744 This->attachToCustomHandlersDao();
1745 CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1746 CustomHandlerDB::CustomHandlerPtr handlerCheck =
1747 handlersDao.getProtocolHandler(customHandler->target,
1749 customHandler->base_url);
1750 This->detachFromCustomHandlersDao();
1752 if (handlerCheck->user_decision & CustomHandlerDB::Agreed) {
1753 int ret = appsvc_unset_defapp(
1754 DPL::ToUTF8String(This->m_model->TizenId).c_str());
1755 if (APPSVC_RET_OK != ret) {
1756 LogWarning("Failed to unregister appsvc entry");
1760 //if appsvc ok change custom_handlers_db
1761 handlersDao.unregisterProtocolHandler(customHandler->target,
1763 customHandler->base_url);
1765 LogDebug("Nothing to unregister");
1769 void ViewLogic::contentHandlerRegistrationCallback(void* data,
1770 Evas_Object* /*obj*/,
1775 CustomHandlerDB::CustomHandlerPtr customHandler =
1776 getCustomHandlerFromData(eventInfo);
1778 std::string mimeType = DPL::ToUTF8String(customHandler->target);
1779 if (mimeType.empty()) {
1780 LogError("No mimeType provided.");
1783 for (int i = 0; i < contentBlackListLenth; ++i) {
1784 if (0 == strcmp(contentBlackList[i], mimeType.c_str())) {
1785 LogWarning("mimeType blacklisted");
1786 //throw SecurityException
1791 ViewLogic* This = static_cast<ViewLogic*>(data);
1792 LogDebug("Creating handlers dao");
1793 This->attachToCustomHandlersDao();
1794 CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1795 CustomHandlerDB::CustomHandlerPtr handler =
1796 handlersDao.getContentHandler(customHandler->target,
1798 customHandler->base_url);
1799 if (handler && (handler->user_decision & CustomHandlerDB::DecisionSaved)) {
1800 LogDebug("Protocol already registered - nothing to do");
1802 LogDebug("Protocol handler not found");
1803 Wrt::Popup::PopupResponse response =
1804 GlobalSettings::PopupsTestModeEnabled() ? Wrt::Popup::
1806 Wrt::Popup::PopupInvoker().askYesNoCheckbox(
1807 CONTENT_HANDLER_ASK_TITLE,
1808 CONTENT_HANDLER_ASK_MSG,
1809 CONTENT_HANDLER_AKS_REMEMBER);
1810 saveUserResponse(response, customHandler);
1811 if (customHandler->user_decision == CustomHandlerDB::Declined) {
1814 if (customHandler->user_decision & CustomHandlerDB::Agreed) {
1815 //TODO remove old default handler somehow from appsvc
1816 LogDebug("Registering appservice entry");
1817 int ret = appsvc_set_defapp(APPSVC_OPERATION_VIEW,
1819 customHandler->target).c_str(),
1821 DPL::ToUTF8String(This->m_model->
1823 if (APPSVC_RET_OK != ret) {
1824 LogWarning("Appsvc entry failed: " << ret);
1828 handlersDao.registerContentHandler(*(customHandler.get()));
1829 LogDebug("Content saved");
1831 This->detachFromCustomHandlersDao();
1834 void ViewLogic::contentHandlerIsRegisteredCallback(void* data,
1835 Evas_Object* /*obj*/,
1839 CustomHandlerDB::CustomHandlerPtr customHandler =
1840 getCustomHandlerFromData(eventInfo);
1841 ViewLogic* This = static_cast<ViewLogic*>(data);
1842 LogDebug("Creating handlers dao");
1844 This->attachToCustomHandlersDao();
1845 CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1846 CustomHandlerDB::CustomHandlerPtr handler =
1847 handlersDao.getContentHandler(customHandler->target,
1849 customHandler->base_url);
1851 if (handler->user_decision & CustomHandlerDB::Agreed) {
1852 ewk_custom_handlers_data_result_set(
1853 static_cast<Ewk_Custom_Handlers_Data*>(eventInfo),
1854 EWK_CUSTOM_HANDLERS_REGISTERED);
1856 ewk_custom_handlers_data_result_set(
1857 static_cast<Ewk_Custom_Handlers_Data*>(eventInfo),
1858 EWK_CUSTOM_HANDLERS_DECLINED);
1861 ewk_custom_handlers_data_result_set(
1862 static_cast<Ewk_Custom_Handlers_Data*>(eventInfo),
1863 EWK_CUSTOM_HANDLERS_NEW);
1865 This->detachFromCustomHandlersDao();
1868 void ViewLogic::contentHandlerUnregistrationCallback(void* data,
1869 Evas_Object* /*obj*/,
1873 CustomHandlerDB::CustomHandlerPtr customHandler =
1874 getCustomHandlerFromData(eventInfo);
1875 ViewLogic* This = static_cast<ViewLogic*>(data);
1876 LogDebug("Creating handlers dao");
1877 This->attachToCustomHandlersDao();
1878 CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1879 CustomHandlerDB::CustomHandlerPtr handlerCheck =
1880 handlersDao.getContentHandler(customHandler->target,
1882 customHandler->base_url);
1883 This->detachFromCustomHandlersDao();
1885 if (handlerCheck->user_decision & CustomHandlerDB::Agreed) {
1886 int ret = appsvc_unset_defapp(
1887 DPL::ToUTF8String(This->m_model->TizenId).c_str());
1888 if (APPSVC_RET_OK != ret) {
1889 LogWarning("Failed to unregister mime handler from appsvc");
1893 handlersDao.unregisterContentHandler(customHandler->target,
1895 customHandler->base_url);
1897 LogDebug("Nothing to unregister");
1901 void ViewLogic::didRunJavaScriptCallback(
1902 Evas_Object* /*obj*/,
1906 LogInfo("didRunJavaScriptCallback called");
1907 LogInfo("result = " << result);
1910 Eina_Bool ViewLogic::windowCloseIdlerCallback(void* data)
1912 LogDebug("closeIdlerCallback");
1913 ViewLogic* This = static_cast<ViewLogic*>(data);
1914 This->windowClose();
1915 return ECORE_CALLBACK_CANCEL;
1918 Eina_Bool ViewLogic::exceededDatabaseQuotaCallback(Evas_Object* obj,
1919 Ewk_Security_Origin* origin,
1920 const char* /*databaseName*/,
1921 unsigned long long expectedQuota,
1924 LogDebug("exceededDatabaseQuotaCallback called");
1926 ViewLogic* This = static_cast<ViewLogic*>(data);
1929 if (This->m_model->WebStorageUsage.Get() == WrtDB::SETTINGS_TYPE_OFF) {
1930 ewk_view_exceeded_database_quota_reply(obj, EINA_FALSE);
1934 ViewModule::WebStorageSupport::createPermissionRequest(
1935 This->m_currentEwkView,
1936 This->m_securityOriginSupport->getSecurityOriginDAO(),
1940 ewk_view_exceeded_database_quota_reply);
1944 Eina_Bool ViewLogic::exceededIndexedDatabaseQuotaCallback(Evas_Object* obj,
1945 Ewk_Security_Origin* origin,
1946 long long expectedQuota,
1949 LogDebug("exceededIndexedDatabaseQuotaCallback called");
1951 ViewLogic* This = static_cast<ViewLogic*>(data);
1954 if (This->m_model->WebStorageUsage.Get() == WrtDB::SETTINGS_TYPE_OFF) {
1955 ewk_view_exceeded_indexed_database_quota_reply(obj, EINA_FALSE);
1959 ViewModule::WebStorageSupport::createPermissionRequest(
1960 This->m_currentEwkView,
1961 This->m_securityOriginSupport->getSecurityOriginDAO(),
1965 ewk_view_exceeded_indexed_database_quota_reply);
1969 Eina_Bool ViewLogic::exceededLocalFileSystemQuotaCallback(Evas_Object* obj,
1970 Ewk_Security_Origin* origin,
1971 long long expectedQuota,
1974 LogDebug("exceededLocalFileSystemQuotaCallback called");
1976 ViewLogic* This = static_cast<ViewLogic*>(data);
1980 if (This->m_model->WebStorageUsage.Get() == WrtDB::SETTINGS_TYPE_OFF) {
1981 ewk_view_exceeded_local_file_system_quota_reply(obj, EINA_FALSE);
1985 ViewModule::WebStorageSupport::createPermissionRequest(
1986 This->m_currentEwkView,
1987 This->m_securityOriginSupport->getSecurityOriginDAO(),
1991 ewk_view_exceeded_local_file_system_quota_reply);
1995 void ViewLogic::certificateConfirmRequestCallback(
1997 Evas_Object* /*obj*/,
2000 LogDebug("certificateConfirmRequestCallback called");
2003 ViewLogic* This = static_cast<ViewLogic*>(data);
2005 ViewModule::CertificateConfirmSupport::certificatePermissionRequest(
2006 This->m_currentEwkView,
2007 This->m_certificateSupport->getCertificateDAO(),
2011 void ViewLogic::authenticationChallengeRequestCallback(
2013 Evas_Object* /*obj*/,
2016 LogDebug("authenticationChallengeRequestCallback called");
2020 ViewLogic* This = static_cast<ViewLogic*>(data);
2021 const char* url = ewk_view_url_get(This->m_currentEwkView);
2022 if (!url || strlen(url) == 0) {
2023 Ewk_Auth_Challenge* authChallenge = static_cast<Ewk_Auth_Challenge*>(eventInfo);
2024 ewk_auth_challenge_credential_cancel(authChallenge);
2027 ViewModule::AuthenticationChallengeSupport::authenticationChallengeRequest(
2028 This->m_currentEwkView,
2033 void ViewLogic::viewFrameRenderedCallback(
2035 Evas_Object* /*obj*/,
2036 void* /*eventInfo*/)
2041 void ViewLogic::mediacontrolRotateHorizontal(void* data,
2043 void* /*eventInfo*/)
2045 LogInfo("mediacontrolRotateHorizontal called");
2048 ViewLogic* This = static_cast<ViewLogic*>(data);
2049 ViewModule::OrientationSupport::setOrientation(
2052 ViewModule::OrientationSupport::Mode::LANDSCAPE_PRIMARY);
2055 void ViewLogic::mediacontrolRotateVertical(void* data,
2057 void* /*eventInfo*/)
2059 LogInfo("mediacontrolRotateVertical called");
2062 ViewLogic* This = static_cast<ViewLogic*>(data);
2063 ViewModule::OrientationSupport::setOrientation(
2066 ViewModule::OrientationSupport::Mode::PORTRAIT_PRIMARY);
2069 void ViewLogic::mediacontrolRotateExit(void* data,
2071 void* /*eventInfo*/)
2073 LogInfo("mediacontrolRotateExit called");
2076 ViewLogic* This = static_cast<ViewLogic*>(data);
2077 if (This->m_rotateAngle == 0) {
2078 // application hasn't call orientation lock
2079 WidgetSettingScreenLock screenLock =
2080 This->m_model->SettingList.Get().getRotationValue();
2081 if (screenLock == Screen_Portrait) {
2082 ViewModule::OrientationSupport::setOrientation(
2085 ViewModule::OrientationSupport::Mode::PORTRAIT_PRIMARY);
2086 } else if (screenLock == Screen_Landscape) {
2087 ViewModule::OrientationSupport::setOrientation(
2090 ViewModule::OrientationSupport::Mode::LANDSCAPE_PRIMARY);
2091 } else if (screenLock == Screen_AutoRotation) {
2092 elm_win_wm_rotation_preferred_rotation_set(
2094 OrientationAngle::Window::UNLOCK);
2097 // Restore previous orientation
2098 ViewModule::OrientationSupport::setOrientation(
2101 This->m_rotateAngle);
2105 void ViewLogic::requestUrlBlocked(const std::string& blockedUrl)
2109 // block this page and open it in browser
2110 LogDebug("Request was blocked : " << blockedUrl);
2111 service_h serviceHandle = NULL;
2112 service_create(&serviceHandle);
2113 service_set_operation(serviceHandle, SERVICE_OPERATION_VIEW);
2114 service_set_uri(serviceHandle, blockedUrl.c_str());
2115 CONTROLLER_POST_EVENT(
2116 ApplicationLauncher,
2117 ApplicationLauncherEvents::LaunchApplicationByAppService(
2121 // set block url. This is used on load finished callback
2122 m_blockedUri = blockedUrl;
2125 void ViewLogic::windowClose()
2127 LogDebug("windowClose");
2128 Assert(m_closedEwkView && "no closed webview");
2130 if (1 >= m_ewkViewList.size()) {
2131 if (!m_cbs->webkitExit.empty()) {
2132 m_cbs->webkitExit();
2135 // call user callbacks
2136 if (!m_cbs->bufferUnset.empty()) {
2137 m_cbs->bufferUnset(m_currentEwkView);
2139 if (!m_cbs->windowClose.empty()) {
2140 m_cbs->windowClose(m_closedEwkView);
2142 removeEwkView(m_closedEwkView);
2144 // get latest ewkView
2145 m_currentEwkView = m_ewkViewList.back();
2148 /* In case we support many pages in parallel
2149 * then view is not suspended*/
2150 //resumeEwkView(m_currentEwkView);
2151 setEwkViewVisible(m_currentEwkView);
2154 if (!m_cbs->bufferSet.empty()) {
2155 m_cbs->bufferSet(m_currentEwkView);
2160 void ViewLogic::systemSettingsChangedCallback(system_settings_key_e key,
2163 LogDebug("systemSettingsChanged");
2164 LogDebug("System setting Key is [" << key << "]");
2167 ViewLogic* This = static_cast<ViewLogic*>(data);
2169 if (SYSTEM_SETTINGS_KEY_FONT_TYPE == key) {
2170 if (!This->m_currentEwkView) {
2171 LogError("ewkView isn't initialized");
2174 ewk_view_use_settings_font(This->m_currentEwkView);
2176 LogError("Unregister system callback is called");