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>
36 #include <widget_model.h>
37 #include <dpl/wrt-dao-ro/widget_dao_read_only.h>
38 #include <dpl/wrt-dao-ro/vconf_config.h>
39 #include <dpl/utils/wrt_global_settings.h>
41 #include <common/application_data.h>
42 #include <common/application_launcher.h>
43 #include <common/scheme.h>
45 #include <common/view_logic_apps_support.h>
46 #include <common/view_logic_custom_header_support.h>
47 #include <common/view_logic_password_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_user_agent_support.h>
54 #include <common/view_logic_vibration_support.h>
55 #include <view_logic_authentication_challenge_support.h>
56 #include <view_logic_scheme_support.h>
57 #include <view_logic_geolocation_support_webkit2.h>
58 #include <view_logic_usermedia_support.h>
59 #include <view_logic_web_notification_support.h>
61 #include <view_logic_certificate_confirm_support.h>
62 #include "bundles/plugin_module_support.h"
63 #include <popup-runner/PopupInvoker.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>
76 const char * const bundlePath = "/usr/lib/wrt-wk2-bundles/libwrt-wk2-bundle.so";
77 const char * const uriBlockedMessageName = "uri_blocked_msg";
78 const char * const uriChangedMessageName = "uri_changed_msg";
79 const char * const URICHANGE_PLUGIN_STOP_ONLY = "plugin_stop_only";
80 const char * const URICHANGE_PLUGIN_RESTART = "plugin_restart";
81 const char * const URICHANGE_PLUGIN_NO_CHANGE = "plugin_no_change";
82 const char * const URICHANGE_BLOCKED_URL = "null";
83 const char* PATTERN_URI_CHANGE = "^(([^:/\\?#]+)://[^\\?#]*)";
84 const int MAX_NUM_CONTEXT_MENU_ITEMS = 10;
86 const char * const IME_STATE_ON = "on";
87 const char * const IME_STATE_OFF = "off";
89 const char PROTOCOL_HANDLER_ASK_MSG[] = "Add protocol?";
90 const char PROTOCOL_HANDLER_ASK_TITLE[] = "Add protocol";
91 const char PROTOCOL_HANDLER_ASK_REMEMBER[] = "Remember dicision";
92 const char CONTENT_HANDLER_ASK_MSG[] = "Add content?";
93 const char CONTENT_HANDLER_ASK_TITLE[] = "Add content";
94 const char CONTENT_HANDLER_AKS_REMEMBER[] = "Remember dicision";
95 const char * const CERTIFICATE_CONFIRM_REQUEST_ASK_TITLE =
97 const char * const CERTIFICATE_CONFIRM_REQUEST_ASK_BODY =
98 "This site's security certificate is not trusted! Do you acess this site?";
100 const wchar_t* BACKGROUND_ENABLED = L"background_enabled";
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", &ViewLogic::loadProgressCallback },
109 { "load,progress,finished", &ViewLogic::loadProgressFinishedCallback },
110 { "process,crashed", &ViewLogic::processCrashedCallback },
112 { "create,window", &ViewLogic::createWindowCallback },
113 { "close,window", &ViewLogic::closeWindowCallback },
114 // WKPagePolicyClient
115 { "policy,navigation,decide", &ViewLogic::policyNavigationDecideCallback },
116 { "policy,newwindow,decide", &ViewLogic::policyNewWindowDecideCallback },
117 { "policy,response,decide", &ViewLogic::pageResponseDecideCallback },
118 // WKPageContextMenuClient
119 { "contextmenu,customize", &ViewLogic::contextmenuCustomizeCallback },
121 { "form,submit", &ViewLogic::formSubmitCallback },
122 // EWK Geolocation Callback
123 { "geolocation,permission,request",
124 &ViewLogic::geolocationPermissionRequestCallback },
125 // EWK Notification Callback
126 { "notification,show", &ViewLogic::notificationShowCallback },
127 { "notification,cancel", &ViewLogic::notificationCancelCallback },
128 { "notification,permission,request",
129 &ViewLogic::notificationPermissionRequestCallback },
131 { "fullscreen,enterfullscreen", &ViewLogic::enterFullscreenCallback },
132 { "fullscreen,exitfullscreen", &ViewLogic::exitFullscreenCallback },
134 // when ime start to be showed on the webview,
135 // this callback will be called
136 { "inputmethod,changed", &ViewLogic::imeChangedCallback },
137 // this callback will be called
138 // when ime finishes to be showed on the webview
139 // "event_info" arg of this callback is always NULL point
140 // if web content should know size of ime,
141 // use "inputmethod,changed" instead of this.
143 { "editorclient,ime,opened", &ViewLogic::imeOpenedCallback },
144 // when ime finished to be hidden,
145 // this callback will be called
146 { "editorclient,ime,closed", &ViewLogic::imeClosedCallback },
147 // EWK Usermedia Callback
148 { "usermedia,permission,request",
149 &ViewLogic::usermediaPermissionRequestCallback },
151 { "protocolhandler,registration,requested",
152 &ViewLogic::protocolHandlerRegistrationCallback },
153 { "protocolhandler,isregistered",
154 &ViewLogic::protocolHandlerIsRegisteredCallback },
155 { "protocolhandler,unregistration,requested",
156 &ViewLogic::protocolHandlerUnregistrationCallback },
157 { "contenthandler,registration,requested",
158 &ViewLogic::contentHandlerRegistrationCallback },
159 { "contenthandler,isregistered",
160 &ViewLogic::contentHandlerIsRegisteredCallback },
161 { "contenthandler,unregistration,requested",
162 &ViewLogic::contentHandlerUnregistrationCallback },
163 { "request,certificate,confirm",
164 &ViewLogic::certificateConfirmRequestCallback },
165 { "authentication,challenge",
166 &ViewLogic::authenticationChallengeRequestCallback }
169 ViewLogic::ViewLogic() :
171 m_attachedToCustomHandlerDao(false),
173 m_closedEwkView(NULL),
176 m_cbs(new WRT::UserDelegates),
179 m_isBackgroundReload(false),
180 m_isBackgroundSupport(false),
181 m_appsSupport(new ViewModule::AppsSupport()),
182 m_vibrationSupport(new ViewModule::VibrationSupport())
184 ApplicationLauncherSingleton::Instance().Touch();
187 ViewLogic::~ViewLogic()
189 detachFromCustomHandlersDao();
192 bool ViewLogic::createWebView(Ewk_Context* context,
196 if (!context || !window) {
201 const char *theme = elm_theme_get(NULL);
204 LogInfo("theme is " << m_theme);
208 m_ewkContext = context;
211 Evas* canvas = evas_object_evas_get(m_window);
212 return createEwkView(canvas);
215 void ViewLogic::prepareView(WidgetModel* m, const std::string &startUrl)
217 LogDebug("View prepare");
221 m_startUrl = startUrl;
222 Assert(NULL != m_ewkContext);
225 ADD_PROFILING_POINT("initializeSupport", "start");
227 ADD_PROFILING_POINT("initializeSupport", "stop");
229 ewkClientInit(m_currentEwkView);
230 ADD_PROFILING_POINT("prepareEwkView", "start");
231 prepareEwkView(m_currentEwkView);
232 ADD_PROFILING_POINT("prepareEwkView", "stop");
233 initializePluginLoading();
236 void ViewLogic::showWidget()
238 LogDebug("showing widget");
239 Assert(NULL != m_currentEwkView && "ewk_view not created at this point");
240 if (m_currentUri.empty()) {
241 LogError("Localized current URI doesn't exist");
245 LogInfo("m_currentUri: " << m_currentUri);
248 ewk_view_url_set(m_currentEwkView, m_currentUri.c_str());
250 if (!m_cbs->bufferSet.empty()) {
251 m_cbs->bufferSet(m_currentEwkView);
255 void ViewLogic::hideWidget()
257 LogDebug("hiding widget");
258 ViewModule::StorageSupport::deinitializeStorage(m_model);
259 m_appsSupport->deinitialize();
261 m_vibrationSupport->deinitialize();
263 while (!m_ewkViewList.empty()) {
264 LogInfo("pop webview: " << m_ewkViewList.back());
265 removeEwkView(m_ewkViewList.back());
267 m_ewkViewList.clear();
270 void ViewLogic::suspendWidget()
272 LogInfo("Pausing widget");
275 if (!m_currentEwkView) {
276 LogWarning("Cannot suspend widget without view");
278 setEwkViewInvisible(m_currentEwkView);
279 if (!m_isBackgroundSupport) {
280 suspendWebkit(m_currentEwkView);
284 evas_object_focus_set(m_currentEwkView, EINA_FALSE);
286 // call user callback
287 if (!m_cbs->suspend.empty()) {
288 m_cbs->suspend(true);
292 void ViewLogic::resumeWidget()
294 LogInfo("Resume widget");
297 if (m_currentEwkView) {
298 setEwkViewVisible(m_currentEwkView);
299 if (!m_isBackgroundSupport) {
300 resumeWebkit(m_currentEwkView);
304 /* window system team recomend removing this win_raise code. */
307 * elm_win_raise(m_window);
310 evas_object_focus_set(m_currentEwkView, EINA_TRUE);
312 // call user callback
313 if (!m_cbs->resume.empty()) {
318 void ViewLogic::resetWidget()
320 LogInfo("Resetting Widget");
322 // destory all webview
323 while (!m_ewkViewList.empty()) {
324 LogInfo("pop webview: " << m_ewkViewList.back());
325 removeEwkView(m_ewkViewList.back());
327 m_ewkViewList.clear();
329 // create new webview
330 createEwkView(evas_object_evas_get(m_window));
332 ewkClientInit(m_currentEwkView);
333 prepareEwkView(m_currentEwkView);
335 // check if current url is service url for this tizen service
336 std::string requestedUri =
337 ViewModule::UriSupport::getUri(m_model, m_startUrl);
338 DPL::OptionalString servicedUri = ViewModule::UriSupport::localizeURI(
339 DPL::FromUTF8String(requestedUri.c_str()),
342 initializePluginLoading();
345 m_currentUri = DPL::ToUTF8String(*servicedUri);
346 ewk_view_url_set(m_currentEwkView, m_currentUri.c_str());
347 elm_win_activate(m_window);
348 evas_object_focus_set(m_currentEwkView, EINA_TRUE);
350 // call user callback
351 if (!m_cbs->reset.empty()) {
354 if (!m_cbs->bufferSet.empty()) {
355 m_cbs->bufferSet(m_currentEwkView);
359 void ViewLogic::backward()
361 if (ewk_view_back_possible(m_currentEwkView)) {
362 ewk_view_back(m_currentEwkView);
364 if (1 >= m_ewkViewList.size()) {
365 // If there is no previous page, widget move to backgroud.
366 LogInfo("Widget move to backgroud");
367 elm_win_lower(m_window);
369 // Back to previous webview
370 LogInfo("Widget move to previous webview");
371 m_closedEwkView = m_currentEwkView;
372 ecore_idler_add(windowCloseIdlerCallback, this);
377 void ViewLogic::reloadStartPage()
379 LogInfo("Reload Start Page");
380 // prevent fail to load plugin bundle side
381 m_isBackgroundReload = true;
383 if (!m_ewkViewList.empty()) {
384 while (!m_ewkViewList.empty()) {
385 if (!m_cbs->bufferUnset.empty()) {
386 m_cbs->bufferUnset(m_currentEwkView);
388 removeEwkView(m_currentEwkView);
392 // create new webview
393 createEwkView(evas_object_evas_get(m_window));
394 ewkClientInit(m_currentEwkView);
397 prepareEwkView(m_currentEwkView);
398 initializePluginLoading();
401 ewk_view_url_set(m_currentEwkView, m_currentUri.c_str());
404 if (!m_cbs->bufferSet.empty()) {
405 m_cbs->bufferSet(m_currentEwkView);
407 LogInfo("Reloading Start Page is done!");
410 Evas_Object* ViewLogic::getCurrentWebview()
412 LogInfo("get current webview");
413 return m_currentEwkView;
416 void ViewLogic::fireJavascriptEvent(int event, void* data)
418 PluginModuleSupport::dispatchJavaScriptEvent(
420 static_cast<WrtPlugins::W3C::CustomEventType>(event),
424 void ViewLogic::setUserCallbacks(const WRT::UserDelegatesPtr& cbs)
429 void ViewLogic::checkSyncMessageFromBundle(
434 LogDebug("didReceiveSynchronousMessage called");
439 LogDebug("body is empty");
444 LogDebug("received : " << name);
446 if (!strcmp(name, uriBlockedMessageName)) {
447 // Currently WebProcess informs obly about blocked
448 // URI - URI localization and security chekcs are
449 // done by WebProcess itself (see: wrt-wk2-bundle.cpp
450 // and bundle_uri_handling.cpp)
451 result = requestUrlBlocked(std::string(body));
452 } else if (!strcmp(name, uriChangedMessageName)) {
453 result = requestUrlChanged(std::string(body));
456 *returnData = strdup(result.c_str());
459 void ViewLogic::downloadData(const char* url)
466 m_appsSupport->downloadRequest(url, NULL, NULL);
469 void ViewLogic::activateVibration(bool on, uint64_t time)
473 m_vibrationSupport->startVibration(static_cast<long>(time));
475 m_vibrationSupport->stopVibration();
479 void ViewLogic::initializeSupport()
481 // background support
482 if (m_model->SettingList.Get().getBackgroundSupport()
483 == BackgroundSupport_Enable)
485 LogDebug("Background support enabled, set process active");
486 pid_t pid = getpid();
487 sysman_inform_active(pid);
488 m_isBackgroundSupport = true;
490 #ifndef DEPRECATED_SETTING_STRING
492 WrtDB::WidgetDAOReadOnly dao(m_model->TizenId);
493 WrtDB::PropertyDAOReadOnly::WidgetPropertyValue bgEnableValue =
494 dao.getPropertyValue(DPL::String(BACKGROUND_ENABLED));
496 if (!bgEnableValue.IsNull() && !bgEnableValue->compare(L"true")) {
498 LogDebug("Background support enabled, set process active");
499 pid_t pid = getpid();
500 sysman_inform_active(pid);
501 m_isBackgroundSupport = true;
506 m_schemeSupport.reset(new SchemeSupport(m_model->Type.Get().appType));
507 ViewModule::StorageSupport::initializeStorage(m_model);
508 m_appsSupport->initialize(m_model);
509 m_securityOriginSupport.reset(new ViewModule::SecurityOriginSupport(m_model));
510 m_certificateSupport.reset(new ViewModule::CertificateSupport(m_model));
512 m_vibrationSupport->initialize();
515 void ViewLogic::initializePluginLoading()
517 // inform wrt information for plugin loading to web process
518 PluginModuleSupport::start(
521 elm_config_scale_get(),
522 ApplicationDataSingleton::Instance().getEncodedBundle(),
524 m_model->SettingList.Get().isEncrypted());
527 void ViewLogic::ewkClientInit(Evas_Object *wkView)
529 Assert(NULL != wkView && "ewk_view not created at this point");
531 FOREACH(it, m_ewkCallbacksMap)
533 evas_object_smart_callback_add(
539 // EWK Orientation Callback
540 ewk_view_orientation_lock_callback_set(
542 orientationLockCallback,
546 void ViewLogic::ewkClientDeinit(Evas_Object *wkView)
548 LogDebug("ewkClientDeinit");
549 Assert(NULL != wkView && "ewk_view not created at this point");
551 FOREACH(it, m_ewkCallbacksMap)
553 evas_object_smart_callback_del(
558 ewk_view_orientation_lock_callback_set(
564 bool ViewLogic::createEwkView(Evas* canvas)
566 LogDebug("createEwkVeiw");
568 ADD_PROFILING_POINT("ewk_view_add_with_context", "start");
569 Evas_Object* newEwkView = ewk_view_add_with_context(
572 ADD_PROFILING_POINT("ewk_view_add_with_context", "stop");
575 LogError("View creation failed");
576 Wrt::Popup::PopupInvoker().showInfo(
577 "Info", "View creation failed", "close");
582 // even arguments pass the ewkContext, this API should be called
583 // after webkit Evas_Object is created
584 Ewk_Cookie_Manager *ewkCookieManager;
586 ewk_context_cookie_manager_get(m_ewkContext);
587 ewk_cookie_manager_accept_policy_set(ewkCookieManager,
588 EWK_COOKIE_ACCEPT_POLICY_ALWAYS);
590 if (m_currentEwkView) {
591 setEwkViewInvisible(m_currentEwkView);
594 LogInfo("push webview: " << newEwkView);
595 m_ewkViewList.push_back(newEwkView);
596 m_currentEwkView = newEwkView;
600 void ViewLogic::setStartPage()
602 /* Start URI (as other uris) is now localized
603 * on WebProcess side */
604 m_currentUri = ViewModule::UriSupport::getUri(m_model, m_startUrl);
607 void ViewLogic::prepareEwkView(Evas_Object *wkView)
609 LogDebug("prepareEwkView called");
613 LogInfo("Setting CSP default policy");
614 ewk_context_tizen_extensible_api_set(
615 m_ewkContext, EWK_EXTENSIBLE_API_CSP, true);
616 // setting CSP policy rules
617 // temporary turn off
618 //ewk_view_content_security_policy_set(
620 // "default-src '*'; script-src 'self'; style-src 'self'; object-src 'none';",
621 // EWK_ENFORCE_POLICY);
622 //LogInfo("Default policy set");
624 DPL::OptionalString policy = m_model->CspReportOnlyPolicy.Get();
626 if (!(policy.IsNull()))
628 LogDebug("CSP report only policy present in manifest: " << *policy);
629 ewk_view_content_security_policy_set(
630 wkView, DPL::ToUTF8String(*policy).c_str(), EWK_REPORT_ONLY);
632 LogDebug("Config CSP report only policy is not present");
635 policy = m_model->CspPolicy.Get();
637 if (!(policy.IsNull()))
639 LogDebug("CSP policy present in manifest: " << *policy);
640 ewk_view_content_security_policy_set(
641 wkView, DPL::ToUTF8String(*policy).c_str(), EWK_ENFORCE_POLICY);
643 LogDebug("Config CSP policy is not present");
650 Ewk_Settings* settings = ewk_view_settings_get(wkView);
653 std::string customUserAgent = m_model->SettingList.Get().getUserAgent();
654 if (customUserAgent.empty()) {
655 auto userAgentString =
656 ViewModule::UserAgentSupport::getUserAgentFromVconf();
657 if (!userAgentString.empty()) {
658 LogDebug("Setting user agent as: " << userAgentString);
659 ewk_view_user_agent_set(wkView, userAgentString.c_str());
662 LogDebug("Setting custom user agent as: " << customUserAgent);
663 ewk_view_user_agent_set(wkView, customUserAgent.c_str());
666 // set custom header : language
667 using namespace ViewModule::CustomHeaderSupport;
668 std::string customHeaderString = getValueByField(ACCEPT_LANGUAGE);
669 if (!customHeaderString.empty()) {
670 LogDebug("custom field=[" << ACCEPT_LANGUAGE << "]");
671 LogDebug("custom value=[" << customHeaderString << "]");
672 ewk_view_custom_header_add(wkView,
673 ACCEPT_LANGUAGE.c_str(),
674 customHeaderString.c_str());
677 // webkit NPAPI plugins is always on in wrt
678 ewk_settings_plugins_enabled_set(settings, EINA_TRUE);
680 // The followings are not implemeted yet by webkit2
681 // ewk_view_setting_accelerated_compositing_enable_set(EINA_TRUE);
682 // ewk_view_mode_set();
683 // ewk_view_setting_enable_specified_plugin_set(EINA_TRUE,
685 // ewk_view_setting_html5video_external_player_enable_set(EINA_FALSE);
686 // ewk_view_show_ime_on_autofocus_set(EINA_TRUE);
687 // elm_webview_show_magnifier_set(EINA_FALSE);
688 ewk_settings_javascript_enabled_set(settings, EINA_TRUE);
689 ewk_settings_loads_images_automatically_set(settings, EINA_TRUE);
690 // WRT should not fit web contents to device width automatically as default.
691 // Fitting to device width should be handled by web content using viewport meta tag.
692 ewk_settings_auto_fitting_set(settings, EINA_FALSE);
694 // disable zoom option when user click the input field
695 // this option is useful with the normal website
696 // for the make user friendly, disable auto zoom in the webapp
697 // The followings are not implemeted yet by webkit2
698 // elm_webview_input_field_zoom_set(EINA_FALSE);
700 // set cookie database path
701 // The followings are not implemeted yet by webkit2
702 // ewk_cookies_file_set(dao.getCookieDatabasePath().c_str()));
704 // set visibility to WebCore. This value will be used for html5.
705 // also, this value will be changed in the suspend, resume
706 // or create window, close window.
707 ewk_view_page_visibility_state_set(wkView,
708 EWK_PAGE_VISIBILITY_STATE_VISIBLE,
712 void ViewLogic::removeEwkView(Evas_Object *wkView)
714 LogInfo("removeEwkView called");
716 Assert(0 != m_ewkViewList.size());
718 // unregister webview callbacks
719 ewkClientDeinit(wkView);
721 // suspend NPAPI plugin - Not implemented by Webkit2
722 // ewk_view_pause_or_resume_plugins();
723 evas_object_del(wkView);
724 m_ewkViewList.remove(wkView);
727 void ViewLogic::resumeEwkView(Evas_Object *wkView)
729 LogInfo("resumeEwkView called");
732 // register webview callback
733 ewkClientInit(wkView);
736 resumeWebkit(wkView);
741 void ViewLogic::suspendEwkView(Evas_Object *wkView)
743 LogInfo("suspendEwkView called");
747 suspendWebkit(wkView);
749 // unregister webview callbacks
750 ewkClientDeinit(wkView);
754 void ViewLogic::setEwkViewInvisible(Evas_Object *wkView)
756 LogInfo("setEwkViewInvisible called");
759 ewk_view_page_visibility_state_set(wkView,
760 EWK_PAGE_VISIBILITY_STATE_HIDDEN,
762 ewk_view_visibility_set(wkView, EINA_FALSE);
765 void ViewLogic::setEwkViewVisible(Evas_Object *wkView)
767 LogInfo("setEwkViewVisible called");
770 ewk_view_page_visibility_state_set(wkView,
771 EWK_PAGE_VISIBILITY_STATE_VISIBLE,
773 ewk_view_visibility_set(wkView, EINA_TRUE);
776 void ViewLogic::resumeWebkit(Evas_Object *wkView)
778 LogDebug("resumeWebkit");
781 // resume NPAPI plugin
782 // The followings are not implemeted yet by webkit2
783 // ewk_view_pause_or_resume_plugins(false);
784 // ewk_view_pause_or_resume_video_audio(false);
785 // ewk_view_javascript_resume();
786 // ewk_view_enable_render();
787 // ewk_view_reduce_plugins_frame_rate(false);
788 ewk_view_resume(wkView);
793 void ViewLogic::suspendWebkit(Evas_Object *wkView)
795 LogDebug("suspendWebkit");
798 // suspend the followings
799 // The followings are not implemeted yet by webkit2
800 // ewk_view_pause_or_resume_plugins(true);
801 // ewk_view_pause_or_resume_video_audio(true);
802 ewk_view_suspend(wkView);
807 void ViewLogic::loadStartedCallback(
812 LogDebug("loadStartedCallback called");
814 ViewLogic* This = static_cast<ViewLogic*>(data);
815 evas_object_focus_set(This->m_currentEwkView, EINA_TRUE);
817 // call loadFinish callback to wrt-client
818 if (!This->m_cbs->loadStart.empty()) {
819 This->m_cbs->loadStart(obj);
823 void ViewLogic::loadFinishedCallback(
828 LogDebug("loadFinishedCallback called");
830 ViewLogic* This = static_cast<ViewLogic*>(data);
833 const char* url = ewk_view_url_get(This->m_currentEwkView);
834 if (NULL == url || strlen(url) == 0) {
835 LogError("url is empty");
839 DPL::OptionalString jsOptionalString =
840 ViewModule::PasswordSupport::jsForAutoFillData(url);
841 if (jsOptionalString.IsNull()) {
842 LogError("Fail to get JS String");
844 std::string jsStr = DPL::ToUTF8String(*jsOptionalString).c_str();
846 if (EINA_FALSE == ewk_view_script_execute(
847 This->m_currentEwkView,
849 didRunJavaScriptCallback,
852 LogError("JS for auto fill data failed.");
856 // call loadFinish callback to wrt-client
857 if (!This->m_cbs->loadFinish.empty()) {
858 This->m_cbs->loadFinish(obj);
861 // set only encoded bundle
862 double scale = elm_config_scale_get();
863 PluginModuleSupport::setCustomProperties(
866 ApplicationDataSingleton::Instance().getEncodedBundle());
867 // check if 'appsevice' event is registed at the current frames.
868 // If so, dispatch the event to frames.
869 PluginModuleSupport::dispatchJavaScriptEvent(
871 WrtPlugins::W3C::ServiceCustomEvent,
874 // In this case, widget is reloaded in the background.
875 // After finished load, bundle should disconnent callback.
876 if (This->m_isBackgroundReload) {
877 ewk_view_suspend(This->m_currentEwkView);
878 This->m_isBackgroundReload = false;
882 void ViewLogic::titleChangedCallback(
887 LogDebug("titleChangedCallback called");
889 ViewLogic* This = static_cast<ViewLogic*>(data);
891 const char* title = static_cast<char*>(eventInfo);
893 if (0 == strlen(title)) {
894 LogDebug("title data is empty");
895 This->m_currentTitle = std::string();
898 LogDebug("Title = [" << title << "]");
899 bool ret = This->m_schemeSupport->HandleTizenScheme(
902 This->m_currentEwkView);
903 // if result is true, this is tizen scheme
904 // and then, title is reset to page's real title
906 std::string script = "document.title = \"";
907 script += This->m_currentTitle;
909 ewk_view_script_execute(obj, script.c_str(), didRunJavaScriptCallback, This);
911 This->m_currentTitle = std::string(title);
915 void ViewLogic::loadProgressCallback(
917 Evas_Object* /*obj*/,
920 double* progress = static_cast<double*>(eventInfo);
921 LogDebug("didChangeProgressCallback progress = " << *progress);
924 void ViewLogic::loadProgressFinishedCallback(
926 Evas_Object* /*obj*/,
929 LogDebug("didFinishProgressCallback");
931 ViewLogic const * const view = static_cast<ViewLogic const * const>(data);
932 if (!view->m_cbs->progressFinish.empty()) {
933 view->m_cbs->progressFinish();
937 void ViewLogic::processCrashedCallback(
939 Evas_Object* /*obj*/,
942 LogInfo("processCrashedCallback");
944 ViewLogic const * const view =
945 static_cast<ViewLogic const * const>(data);
946 if (!view->m_cbs->webCrash.empty()) {
947 view->m_cbs->webCrash();
949 // This flag will be prevented exit() call in the Webkit side
950 if (NULL != eventInfo) {
951 *(static_cast<Eina_Bool*>(eventInfo)) = EINA_TRUE;
955 void ViewLogic::createWindowCallback(
960 LogDebug("createWindowCallback");
962 ViewLogic* This = static_cast<ViewLogic*>(data);
964 // First, current webview should be handled by user callback
965 if (!This->m_cbs->bufferUnset.empty()) {
966 This->m_cbs->bufferUnset(obj);
969 // this can be set by executable for specific purpose
971 if (!This->m_cbs->windowCreateBefore.empty()) {
972 // 'obj' is parent webview object
973 This->m_cbs->windowCreateBefore(&canvas, obj);
976 canvas = evas_object_evas_get(This->m_window);
979 // create new ewkview
980 This->createEwkView(canvas);
981 Evas_Object* newEwkView = This->m_currentEwkView;
983 // initialize new ewkview
984 This->setStartPage();
985 This->ewkClientInit(newEwkView);
986 This->prepareEwkView(newEwkView);
988 // Specific jobs of child, parent webview are handled by each executable
989 if (!This->m_cbs->windowCreateAfter.empty()) {
990 // 'obj' is parent webview, 'newEwkView' is child webview
991 This->m_cbs->windowCreateAfter(obj, newEwkView);
994 // Lastly, new webview should be handled by user callback
995 if (!This->m_cbs->bufferSet.empty()) {
996 This->m_cbs->bufferSet(newEwkView);
998 *(static_cast<Evas_Object **>(eventInfo)) = newEwkView;
1001 void ViewLogic::closeWindowCallback(
1004 void* /*eventInfo*/)
1006 LogDebug("closeWindowCallback");
1007 ViewLogic* This = static_cast<ViewLogic*>(data);
1008 This->m_closedEwkView = obj;
1009 ecore_idler_add(windowCloseIdlerCallback, This);
1012 void ViewLogic::policyNavigationDecideCallback(
1014 Evas_Object* /*obj*/,
1017 LogDebug("policyNavigationDecideCallback called");
1019 ViewLogic* This = static_cast<ViewLogic*>(data);
1021 Ewk_Policy_Decision* policyDecision =
1022 static_cast<Ewk_Policy_Decision*>(eventInfo);
1024 // handle blocked url
1025 const char* url = ewk_policy_decision_url_get(policyDecision);
1026 if (url && strlen(url) != 0) {
1027 if (This->m_blockedUri == url) {
1028 LogDebug("Blocked url = " << url);
1029 This->m_blockedUri = std::string();
1030 ewk_policy_decision_ignore(policyDecision);
1035 if (This->m_schemeSupport->filterURIByScheme(policyDecision,
1039 This->m_currentEwkView))
1042 ewk_policy_decision_use(policyDecision);
1044 // check whether this is new empty window
1045 const char* activeUrl = ewk_view_url_get(This->m_currentEwkView);
1046 if (!activeUrl || 0 == strlen(activeUrl)) {
1048 * The view is empty and scheme has been handled externally. When
1049 * user gets back from the external application he'd see blank page
1050 * and won't be able to navigate back. This happens when window.open
1051 * is used to handle schemes like sms/mms/mailto (for example in
1052 * WAC web standards tests: WS-15XX).
1054 * To solve the problem, the empty view is removed from the stack
1055 * and the previous one is shown. This is not an elegant solution
1056 * but we don't have a better one.
1058 LogInfo("Scheme has been handled externally. Removing empty view.");
1059 if (ewk_view_back_possible(This->m_currentEwkView)) {
1060 // go back to previous WKPage
1061 ewk_view_back(This->m_currentEwkView);
1063 // stop current WKPage
1064 ewk_view_stop(This->m_currentEwkView);
1065 This->m_closedEwkView = This->m_currentEwkView;
1066 ecore_idler_add(windowCloseIdlerCallback, This);
1071 ewk_policy_decision_ignore(policyDecision);
1075 void ViewLogic::policyNewWindowDecideCallback(
1077 Evas_Object* /*obj*/,
1080 LogDebug("policyNewWindowDecideCallback called");
1082 ViewLogic* This = static_cast<ViewLogic*>(data);
1084 Ewk_Policy_Decision* policyDecision =
1085 static_cast<Ewk_Policy_Decision*>(eventInfo);
1087 if (This->m_schemeSupport->filterURIByScheme(policyDecision,
1091 This->m_currentEwkView))
1093 ewk_policy_decision_use(policyDecision);
1096 ewk_policy_decision_ignore(policyDecision);
1100 void ViewLogic::pageResponseDecideCallback(
1102 Evas_Object* /*obj*/,
1105 LogDebug("pageResponseDecideCallback called");
1107 ViewLogic* This = static_cast<ViewLogic*>(data);
1109 Ewk_Policy_Decision* policyDecision =
1110 static_cast<Ewk_Policy_Decision*>(eventInfo);
1111 Ewk_Policy_Decision_Type policyDecisionType =
1112 ewk_policy_decision_type_get(policyDecision);
1114 if (policyDecisionType == EWK_POLICY_DECISION_USE) {
1116 ewk_policy_decision_use(policyDecision);
1117 } else if (policyDecisionType == EWK_POLICY_DECISION_DOWNLOAD) {
1118 LogDebug("download");
1119 ewk_policy_decision_suspend(policyDecision);
1121 // get uri information
1122 const char* url = ewk_policy_decision_url_get(policyDecision);
1123 if (NULL == url || strlen(url) == 0) {
1124 LogDebug("url data is empty");
1125 ewk_policy_decision_use(policyDecision);
1128 LogDebug("url = [" << url << "]");
1130 // get content information
1131 const char* content =
1132 ewk_policy_decision_response_mime_get(policyDecision);
1133 LogDebug("content type = [" << content << "]");
1135 // get cookie information
1136 const char* cookie = ewk_policy_decision_cookie_get(policyDecision);
1137 LogDebug("cookie = [" << cookie << "]");
1139 LogDebug("Content not supported, will be opened in external app");
1140 This->m_appsSupport->downloadRequest(
1144 ewk_policy_decision_ignore(policyDecision);
1145 } else if (policyDecisionType == EWK_POLICY_DECISION_IGNORE) {
1147 ewk_policy_decision_ignore(policyDecision);
1149 LogDebug("Type isn't handled");
1150 ewk_policy_decision_ignore(policyDecision);
1154 void ViewLogic::contextmenuCustomizeCallback(
1156 Evas_Object* /*obj*/,
1159 LogDebug("contextmenuCustomizeCallback called");
1162 ViewLogic* This = static_cast<ViewLogic*>(const_cast<void*>(data));
1163 Ewk_Context_Menu* menu = static_cast<Ewk_Context_Menu*>(eventInfo);
1164 if ((This->m_model->Type.Get().appType == WrtDB::APP_TYPE_TIZENWEBAPP) &&
1165 (This->m_model->SettingList.Get().getContextMenu()
1166 == ContextMenu_Disable))
1168 LogDebug("ContextMenu Disable!!");
1169 for (unsigned int idx = 0; idx < ewk_context_menu_item_count(menu);) {
1170 Ewk_Context_Menu_Item* item = ewk_context_menu_nth_item_get(menu,
1173 ewk_context_menu_item_remove(menu, item);
1176 LogDebug("ContextMenu Enable!!");
1177 unsigned int menu_num = ewk_context_menu_item_count(menu);
1178 unsigned int idx = 0;
1180 Ewk_Context_Menu_Item* item = ewk_context_menu_nth_item_get(menu,
1186 Ewk_Context_Menu_Item_Tag tag = ewk_context_menu_item_tag_get(item);
1189 case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_IMAGE_IN_NEW_WINDOW:
1190 ewk_context_menu_item_remove(menu, item);
1193 case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_LINK_IN_NEW_WINDOW:
1194 ewk_context_menu_item_remove(menu, item);
1197 case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_FRAME_IN_NEW_WINDOW:
1198 ewk_context_menu_item_remove(menu, item);
1201 case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_MEDIA_IN_NEW_WINDOW:
1202 ewk_context_menu_item_remove(menu, item);
1205 case EWK_CONTEXT_MENU_ITEM_TAG_SEARCH_WEB:
1206 ewk_context_menu_item_remove(menu, item);
1213 } while (idx < menu_num);
1217 void ViewLogic::formSubmitCallback(
1219 Evas_Object* /*obj*/,
1222 LogDebug("formSubmitCallback called");
1224 Ewk_Form_Data* formData = static_cast<Ewk_Form_Data*>(eventInfo);
1226 const char* uri = ewk_form_data_url_get(formData);
1228 LogError("URL is empty");
1232 Eina_Hash* userData = ewk_form_data_values_get(formData);
1233 // Temporary block until fixed random generate & pipe issue
1234 //ViewModule::PasswordSupport::submitClicked(uri, userData);
1237 void ViewLogic::geolocationPermissionRequestCallback(
1239 Evas_Object* /*obj*/,
1243 ViewLogic* This = static_cast<ViewLogic*>(data);
1245 Ewk_Geolocation_Permission_Request* permissionRequest =
1246 static_cast<Ewk_Geolocation_Permission_Request*>(eventInfo);
1248 if (This->m_securityOriginSupport->isNeedPermissionCheck(
1249 WrtDB::FEATURE_GEOLOCATION)
1250 == WrtDB::SETTINGS_TYPE_OFF)
1252 ewk_geolocation_permission_request_set(permissionRequest, EINA_FALSE);
1255 ViewModule::GeolocationSupport::Webkit2::geolocationPermissionRequest(
1257 This->m_securityOriginSupport->getSecurityOriginDAO(),
1261 void ViewLogic::notificationShowCallback(
1263 Evas_Object* /*obj*/,
1266 LogDebug("notificationShowCallback called");
1268 ViewLogic* This = static_cast<ViewLogic*>(data);
1271 Ewk_Notification* noti = static_cast<Ewk_Notification*>(eventInfo);
1273 using namespace ViewModule::WebNotification;
1275 WebNotificationDataPtr notiData(
1276 new WebNotificationData(
1278 ewk_notification_id_get(noti)));
1280 DPL::OptionalString string =
1281 DPL::FromUTF8String(ewk_notification_icon_url_get(noti));
1282 if (!string.IsNull()) {
1283 notiData->m_iconURL = DPL::ToUTF8String(*string);
1285 string = DPL::FromUTF8String(ewk_notification_title_get(noti));
1286 if (!string.IsNull()) {
1287 notiData->m_title = DPL::ToUTF8String(*string);
1289 string = DPL::FromUTF8String(ewk_notification_body_get(noti));
1290 if (!string.IsNull()) {
1291 notiData->m_body = DPL::ToUTF8String(*string);
1294 LogInfo("notification id : " << notiData->m_id);
1295 LogInfo("notification iconURL : " << notiData->m_iconURL);
1296 LogInfo("notification title : " << notiData->m_title);
1297 LogInfo("notification body : " << notiData->m_body);
1299 showWebNotification(notiData);
1300 ewk_notification_showed(This->m_ewkContext, ewk_notification_id_get(noti));
1303 void ViewLogic::notificationCancelCallback(
1305 Evas_Object* /*obj*/,
1306 void* /*eventInfo*/)
1308 LogDebug("notificationCancelCallback called");
1311 void ViewLogic::notificationPermissionRequestCallback(
1313 Evas_Object* /*obj*/,
1316 LogDebug("notificationPermissionRequestCallback called");
1318 ViewLogic* This = static_cast<ViewLogic*>(data);
1319 if (This->m_securityOriginSupport->isNeedPermissionCheck(
1320 WrtDB::FEATURE_WEB_NOTIFICATION)
1321 == WrtDB::SETTINGS_TYPE_OFF)
1323 Ewk_Notification_Permission_Request* request =
1324 static_cast<Ewk_Notification_Permission_Request*>(eventInfo);
1325 ewk_notification_permission_request_set(
1332 ViewModule::WebNotification::webNotificationPermissionRequest(
1334 This->m_securityOriginSupport->getSecurityOriginDAO(),
1339 // EWK Orientation Callback
1340 Eina_Bool ViewLogic::orientationLockCallback(
1342 Eina_Bool /*needLock*/,
1346 LogDebug("orientationLockCallback called");
1348 ViewLogic* This = static_cast<ViewLogic*>(data);
1350 if (orientation & EWK_SCREEN_ORIENTATION_PORTRAIT_PRIMARY) {
1351 LogDebug("orientation is portrait-primary");
1352 elm_win_rotation_with_resize_set(This->m_window, 0);
1353 ewk_view_orientation_send(obj, 0);
1354 } else if (orientation & EWK_SCREEN_ORIENTATION_LANDSCAPE_PRIMARY) {
1355 LogDebug("orientation is landscape-primary");
1356 elm_win_rotation_with_resize_set(This->m_window, 270);
1357 ewk_view_orientation_send(obj, 90);
1358 } else if (orientation & EWK_SCREEN_ORIENTATION_PORTRAIT_SECONDARY) {
1359 LogDebug("orientation is portrait-secondary");
1360 elm_win_rotation_with_resize_set(This->m_window, 180);
1361 ewk_view_orientation_send(obj, 180);
1362 } else if (orientation & EWK_SCREEN_ORIENTATION_LANDSCAPE_SECONDARY) {
1363 LogDebug("orientation is landscape-secondary");
1364 elm_win_rotation_with_resize_set(This->m_window, 90);
1365 ewk_view_orientation_send(obj, -90);
1367 LogDebug("Wrong orientation is set");
1373 // Fullscreen API callbacks
1374 void ViewLogic::enterFullscreenCallback(
1376 Evas_Object* /*obj*/,
1377 void* /*eventInfo*/)
1379 LogInfo("enterFullscreenCallback called");
1381 ViewLogic* This = static_cast<ViewLogic*>(data);
1382 if (!This->m_cbs->toggleFullscreen.empty()) {
1383 This->m_cbs->toggleFullscreen(true);
1386 void ViewLogic::exitFullscreenCallback(
1388 Evas_Object* /*obj*/,
1389 void* /*eventInfo*/)
1391 LogInfo("exitFullscreenCallback called");
1393 ViewLogic* This = static_cast<ViewLogic*>(data);
1394 if (!This->m_cbs->toggleFullscreen.empty()) {
1395 This->m_cbs->toggleFullscreen(false);
1399 void ViewLogic::imeChangedCallback(
1401 Evas_Object* /*obj*/,
1407 ViewLogic* This = static_cast<ViewLogic*>(data);
1408 Eina_Rectangle *rect = static_cast<Eina_Rectangle *>(eventInfo);
1409 This->m_imeWidth = rect->w;
1410 This->m_imeHeight = rect->h;
1413 void ViewLogic::imeOpenedCallback(
1415 Evas_Object* /*obj*/,
1416 void* /*eventInfo*/)
1420 ViewLogic* This = static_cast<ViewLogic*>(data);
1422 using namespace WrtPlugins::W3C;
1423 SoftKeyboardChangeArgs args;
1424 args.state = IME_STATE_ON;
1425 args.width = This->m_imeWidth;
1426 args.height = This->m_imeHeight;
1427 This->fireJavascriptEvent(
1428 static_cast<int>(SoftKeyboardChangeCustomEvent),
1432 void ViewLogic::imeClosedCallback(
1434 Evas_Object* /*obj*/,
1435 void* /*eventInfo*/)
1439 ViewLogic* This = static_cast<ViewLogic*>(data);
1441 using namespace WrtPlugins::W3C;
1442 SoftKeyboardChangeArgs args;
1443 args.state = IME_STATE_OFF;
1445 This->fireJavascriptEvent(
1446 static_cast<int>(SoftKeyboardChangeCustomEvent),
1450 void ViewLogic::usermediaPermissionRequestCallback(
1452 Evas_Object* /*obj*/,
1455 LogDebug("usermediaPermissionRequestCallback called");
1457 ViewLogic* This = static_cast<ViewLogic*>(data);
1458 ViewModule::UsermediaSupport::usermediaPermissionRequest(
1460 This->m_securityOriginSupport->getSecurityOriginDAO(),
1465 CustomHandlerDB::CustomHandlerPtr getCustomHandlerFromData(void* data)
1468 Ewk_Custom_Handlers_Data* handler =
1469 static_cast<Ewk_Custom_Handlers_Data*>(data);
1470 CustomHandlerDB::CustomHandlerPtr customHandler(
1471 new CustomHandlerDB::CustomHandler());
1472 const char* base_url = ewk_custom_handlers_data_base_url_get(handler);
1474 LogDebug("base url: " << base_url);
1475 customHandler->base_url = DPL::FromASCIIString(string(base_url));
1477 const char* url = ewk_custom_handlers_data_url_get(handler);
1479 LogDebug("url: " << url);
1480 customHandler->url = DPL::FromASCIIString(string(url));
1482 const char* target = ewk_custom_handlers_data_target_get(handler);
1484 LogDebug("target: " << target);
1485 customHandler->target = DPL::FromASCIIString(string(target));
1487 const char* title = ewk_custom_handlers_data_title_get(handler);
1489 LogDebug("title: " << title);
1490 customHandler->title = DPL::FromASCIIString(string(title));
1492 return customHandler;
1495 void ViewLogic::attachToCustomHandlersDao()
1497 if (!m_attachedToCustomHandlerDao) {
1498 CustomHandlerDB::Interface::attachDatabaseRW();
1502 void ViewLogic::detachFromCustomHandlersDao()
1504 if (m_attachedToCustomHandlerDao) {
1505 CustomHandlerDB::Interface::detachDatabase();
1509 const int protocolWhiteListLenth = 15;
1510 char const * const protocolWhiteList[protocolWhiteListLenth] = {
1528 const int contentBlackListLenth = 14;
1529 char const * const contentBlackList[contentBlackListLenth] = {
1530 "application/x-www-form-urlencoded",
1531 "application/xhtml+xml",
1537 "multipart/x-mixed-replace",
1538 "text/cache-manifest",
1547 * Saves user's response from popup to custom handler. Saves Yes/No and remember
1550 * @param customHandler
1552 void saveUserResponse(Wrt::Popup::PopupResponse response,
1553 CustomHandlerDB::CustomHandlerPtr customHandler)
1556 case Wrt::Popup::YES_DO_REMEMBER:
1557 LogDebug("User allowed, remember");
1558 customHandler->user_decision =
1559 static_cast<CustomHandlerDB::HandlerState>
1560 (CustomHandlerDB::Agreed | CustomHandlerDB::DecisionSaved);
1562 case Wrt::Popup::YES_DONT_REMEMBER:
1563 LogDebug("User allowed, don't remember");
1564 customHandler->user_decision = CustomHandlerDB::Agreed;
1566 case Wrt::Popup::NO_DO_REMEMBER:
1567 LogDebug("User didn't allow, remember");
1568 customHandler->user_decision =
1569 static_cast<CustomHandlerDB::HandlerState>
1570 (CustomHandlerDB::Declined | CustomHandlerDB::DecisionSaved);
1572 case Wrt::Popup::NO_DONT_REMEMBER:
1573 LogDebug("User didn't allow, don't remember");
1574 customHandler->user_decision = CustomHandlerDB::Declined;
1579 //TODO registration, checking if registered and unregistration can be done in
1580 //common functions for both types of handlers. Only white and black lists
1581 //have to be separated
1582 //TODO attach database only one at the start (not in every callback?)
1583 void ViewLogic::protocolHandlerRegistrationCallback(void* data,
1584 Evas_Object* /*obj*/,
1589 CustomHandlerDB::CustomHandlerPtr customHandler =
1590 getCustomHandlerFromData(eventInfo);
1592 std::string scheme = DPL::ToUTF8String(customHandler->target);
1593 if (scheme.empty()) {
1594 LogError("No scheme provided");
1595 //TODO what about securityError?
1598 bool matched = false;
1599 //scheme on whiteList
1600 for (int i = 0; i < protocolWhiteListLenth; ++i) {
1601 if (0 == strcmp(protocolWhiteList[i], scheme.c_str())) {
1602 LogDebug("Match found, protocol can be handled");
1607 //starts with web+ and have at least 5 chars (lowercase ASCII)
1608 if (strncmp("web+", scheme.c_str(), 4) || scheme.length() < 5) {
1609 LogWarning("Scheme neither on whitelist nor starts with \"web+\"");
1610 //throw SecurityException
1616 if (c < 'a' || c > 'z') {
1617 LogWarning("Wrong char inside scheme. "
1618 << "Only lowercase ASCII letters accepted");
1619 //throw SecurityException
1626 ViewLogic* This = static_cast<ViewLogic*>(data);
1627 LogDebug("Creating handlers dao");
1628 This->attachToCustomHandlersDao();
1629 CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1630 CustomHandlerDB::CustomHandlerPtr handler =
1631 handlersDao.getProtocolHandler(customHandler->target,
1633 customHandler->base_url);
1634 if (handler && (handler->user_decision & CustomHandlerDB::DecisionSaved)) {
1635 LogDebug("Protocol already registered - nothing to do");
1637 LogDebug("Protocol handler not found");
1638 Wrt::Popup::PopupResponse response =
1639 GlobalSettings::PopupsTestModeEnabled() ? Wrt::Popup::
1641 Wrt::Popup::PopupInvoker().askYesNoCheckbox(
1642 PROTOCOL_HANDLER_ASK_TITLE,
1643 PROTOCOL_HANDLER_ASK_MSG,
1644 PROTOCOL_HANDLER_ASK_REMEMBER);
1645 saveUserResponse(response, customHandler);
1646 if (customHandler->user_decision == CustomHandlerDB::Declined) {
1649 if (customHandler->user_decision & CustomHandlerDB::Agreed) {
1650 //TODO remove old default handler somehow from appsvc
1651 LogDebug("Registering appservice entry");
1652 int ret = appsvc_set_defapp(APPSVC_OPERATION_VIEW,
1655 customHandler->target).c_str(),
1656 DPL::ToUTF8String(This->m_model->
1658 if (APPSVC_RET_OK != ret) {
1659 LogWarning("Appsvc entry failed: " << ret);
1660 //no database change
1664 handlersDao.registerProtocolHandler(*(customHandler.get()));
1666 LogDebug("Protocal saved");
1669 This->detachFromCustomHandlersDao();
1672 void ViewLogic::protocolHandlerIsRegisteredCallback(void* data,
1673 Evas_Object* /*obj*/,
1677 CustomHandlerDB::CustomHandlerPtr customHandler = getCustomHandlerFromData(
1679 ViewLogic* This = static_cast<ViewLogic*>(data);
1680 LogDebug("Creating handlers dao");
1681 This->attachToCustomHandlersDao();
1682 CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1683 CustomHandlerDB::CustomHandlerPtr handler =
1684 handlersDao.getProtocolHandler(customHandler->target,
1686 customHandler->base_url);
1688 if (handler->user_decision & CustomHandlerDB::Agreed) {
1689 ewk_custom_handlers_data_result_set(
1690 static_cast<Ewk_Custom_Handlers_Data*>(eventInfo),
1691 EWK_CUSTOM_HANDLERS_REGISTERED);
1693 ewk_custom_handlers_data_result_set(
1694 static_cast<Ewk_Custom_Handlers_Data*>(eventInfo),
1695 EWK_CUSTOM_HANDLERS_DECLINED);
1698 ewk_custom_handlers_data_result_set(
1699 static_cast<Ewk_Custom_Handlers_Data*>(eventInfo),
1700 EWK_CUSTOM_HANDLERS_NEW);
1702 This->detachFromCustomHandlersDao();
1705 void ViewLogic::protocolHandlerUnregistrationCallback(void* data,
1706 Evas_Object* /*obj*/,
1710 CustomHandlerDB::CustomHandlerPtr customHandler =
1711 getCustomHandlerFromData(eventInfo);
1712 ViewLogic* This = static_cast<ViewLogic*>(data);
1713 LogDebug("Creating handlers dao");
1714 This->attachToCustomHandlersDao();
1715 CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1716 CustomHandlerDB::CustomHandlerPtr handlerCheck =
1717 handlersDao.getProtocolHandler(customHandler->target,
1719 customHandler->base_url);
1720 This->detachFromCustomHandlersDao();
1722 if (handlerCheck->user_decision & CustomHandlerDB::Agreed) {
1723 int ret = appsvc_unset_defapp(
1724 DPL::ToUTF8String(This->m_model->TizenId).c_str());
1725 if (APPSVC_RET_OK != ret) {
1726 LogWarning("Failed to unregister appsvc entry");
1730 //if appsvc ok change custom_handlers_db
1731 handlersDao.unregisterProtocolHandler(customHandler->target,
1733 customHandler->base_url);
1735 LogDebug("Nothing to unregister");
1739 void ViewLogic::contentHandlerRegistrationCallback(void* data,
1740 Evas_Object* /*obj*/,
1745 CustomHandlerDB::CustomHandlerPtr customHandler =
1746 getCustomHandlerFromData(eventInfo);
1748 std::string mimeType = DPL::ToUTF8String(customHandler->target);
1749 if (mimeType.empty()) {
1750 LogError("No mimeType provided.");
1753 for (int i = 0; i < contentBlackListLenth; ++i) {
1754 if (0 == strcmp(contentBlackList[i], mimeType.c_str())) {
1755 LogWarning("mimeType blacklisted");
1756 //throw SecurityException
1761 ViewLogic* This = static_cast<ViewLogic*>(data);
1762 LogDebug("Creating handlers dao");
1763 This->attachToCustomHandlersDao();
1764 CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1765 CustomHandlerDB::CustomHandlerPtr handler =
1766 handlersDao.getContentHandler(customHandler->target,
1768 customHandler->base_url);
1769 if (handler && (handler->user_decision & CustomHandlerDB::DecisionSaved)) {
1770 LogDebug("Protocol already registered - nothing to do");
1772 LogDebug("Protocol handler not found");
1773 Wrt::Popup::PopupResponse response =
1774 GlobalSettings::PopupsTestModeEnabled() ? Wrt::Popup::
1776 Wrt::Popup::PopupInvoker().askYesNoCheckbox(
1777 CONTENT_HANDLER_ASK_TITLE,
1778 CONTENT_HANDLER_ASK_MSG,
1779 CONTENT_HANDLER_AKS_REMEMBER);
1780 saveUserResponse(response, customHandler);
1781 if (customHandler->user_decision == CustomHandlerDB::Declined) {
1784 if (customHandler->user_decision & CustomHandlerDB::Agreed) {
1785 //TODO remove old default handler somehow from appsvc
1786 LogDebug("Registering appservice entry");
1787 int ret = appsvc_set_defapp(APPSVC_OPERATION_VIEW,
1789 customHandler->target).c_str(),
1791 DPL::ToUTF8String(This->m_model->
1793 if (APPSVC_RET_OK != ret) {
1794 LogWarning("Appsvc entry failed: " << ret);
1798 handlersDao.registerContentHandler(*(customHandler.get()));
1799 LogDebug("Content saved");
1801 This->detachFromCustomHandlersDao();
1804 void ViewLogic::contentHandlerIsRegisteredCallback(void* data,
1805 Evas_Object* /*obj*/,
1809 CustomHandlerDB::CustomHandlerPtr customHandler =
1810 getCustomHandlerFromData(eventInfo);
1811 ViewLogic* This = static_cast<ViewLogic*>(data);
1812 LogDebug("Creating handlers dao");
1814 This->attachToCustomHandlersDao();
1815 CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1816 CustomHandlerDB::CustomHandlerPtr handler =
1817 handlersDao.getContentHandler(customHandler->target,
1819 customHandler->base_url);
1821 if (handler->user_decision & CustomHandlerDB::Agreed) {
1822 ewk_custom_handlers_data_result_set(
1823 static_cast<Ewk_Custom_Handlers_Data*>(eventInfo),
1824 EWK_CUSTOM_HANDLERS_REGISTERED);
1826 ewk_custom_handlers_data_result_set(
1827 static_cast<Ewk_Custom_Handlers_Data*>(eventInfo),
1828 EWK_CUSTOM_HANDLERS_DECLINED);
1831 ewk_custom_handlers_data_result_set(
1832 static_cast<Ewk_Custom_Handlers_Data*>(eventInfo),
1833 EWK_CUSTOM_HANDLERS_NEW);
1835 This->detachFromCustomHandlersDao();
1838 void ViewLogic::contentHandlerUnregistrationCallback(void* data,
1839 Evas_Object* /*obj*/,
1843 CustomHandlerDB::CustomHandlerPtr customHandler =
1844 getCustomHandlerFromData(eventInfo);
1845 ViewLogic* This = static_cast<ViewLogic*>(data);
1846 LogDebug("Creating handlers dao");
1847 This->attachToCustomHandlersDao();
1848 CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1849 CustomHandlerDB::CustomHandlerPtr handlerCheck =
1850 handlersDao.getContentHandler(customHandler->target,
1852 customHandler->base_url);
1853 This->detachFromCustomHandlersDao();
1855 if (handlerCheck->user_decision & CustomHandlerDB::Agreed) {
1856 int ret = appsvc_unset_defapp(
1857 DPL::ToUTF8String(This->m_model->TizenId).c_str());
1858 if (APPSVC_RET_OK != ret) {
1859 LogWarning("Failed to unregister mime handler from appsvc");
1863 handlersDao.unregisterContentHandler(customHandler->target,
1865 customHandler->base_url);
1867 LogDebug("Nothing to unregister");
1871 void ViewLogic::didRunJavaScriptCallback(
1872 Evas_Object* /*obj*/,
1876 LogInfo("didRunJavaScriptCallback called");
1877 LogInfo("result = " << result);
1880 Eina_Bool ViewLogic::windowCloseIdlerCallback(void* data)
1882 LogDebug("closeIdlerCallback");
1883 ViewLogic* This = static_cast<ViewLogic*>(data);
1884 This->windowClose();
1885 return ECORE_CALLBACK_CANCEL;
1888 void ViewLogic::certificateConfirmRequestCallback(
1890 Evas_Object* /*obj*/,
1893 LogDebug("certificateConfirmRequestCallback called");
1896 ViewLogic* This = static_cast<ViewLogic*>(data);
1898 ViewModule::CertificateConfirmSupport::certificatePermissionRequest(
1900 This->m_certificateSupport->getCertificateDAO(),
1904 void ViewLogic::authenticationChallengeRequestCallback(
1906 Evas_Object* /*obj*/,
1909 LogDebug("authenticationChallengeRequestCallback called");
1912 ViewLogic* This = static_cast<ViewLogic*>(data);
1913 const char* url = ewk_view_url_get(This->m_currentEwkView);
1914 if (!url || strlen(url) == 0) {
1915 url = This->m_currentUri.c_str();
1918 ViewModule::AuthenticationChallengeSupport::authenticationChallengeRequest(
1919 This->m_currentEwkView,
1924 std::string ViewLogic::requestUrlBlocked(const std::string& blockedUrl)
1928 if (m_model->Type.Get().appType == WrtDB::APP_TYPE_TIZENWEBAPP) {
1929 // block this page and open it in browser
1930 LogDebug("Request was blocked by WARP: " << blockedUrl);
1931 LogDebug("open browser : " << blockedUrl);
1932 bundle* bundleData = bundle_create();
1933 appsvc_set_operation(bundleData, APPSVC_OPERATION_VIEW);
1934 appsvc_set_uri(bundleData, blockedUrl.c_str());
1935 CONTROLLER_POST_EVENT(
1936 ApplicationLauncher,
1937 ApplicationLauncherEvents::LaunchApplicationByAppService(
1943 // set block url. This is used on load finished callback
1944 m_blockedUri = blockedUrl;
1946 // This is used in case of returning previous page
1947 return URICHANGE_PLUGIN_NO_CHANGE;
1950 std::string ViewLogic::requestUrlChanged(const std::string& changedUrl)
1952 using namespace ViewModule::SecuritySupport;
1954 LogInfo("changed url: " << changedUrl);
1956 // Check if this url with 'http' or 'https' is included in whitelist,
1957 // which has lists of accessible external documents and
1958 // used for ONLY Tizen app
1959 std::string matchedScheme;
1960 std::string matchedUri;
1961 pcrecpp::RE(PATTERN_URI_CHANGE).PartialMatch(changedUrl.c_str(),
1964 ViewModule::Scheme scheme(matchedScheme);
1965 if (scheme.GetType() == ViewModule::Scheme::HTTP ||
1966 scheme.GetType() == ViewModule::Scheme::HTTPS)
1968 if (m_model->Type.Get().appType == WrtDB::APP_TYPE_TIZENWEBAPP) {
1969 if (!checkWhitelist(changedUrl.c_str())) {
1970 LogInfo("This uri is not included in white document list");
1971 return URICHANGE_PLUGIN_STOP_ONLY;
1973 LogInfo("This url is included in WhiteList");
1975 // For WAC app, WRT should block access of device api
1976 // for external documents
1977 return URICHANGE_PLUGIN_STOP_ONLY;
1981 m_currentUri = changedUrl;
1982 return URICHANGE_PLUGIN_RESTART;
1985 void ViewLogic::windowClose()
1987 LogDebug("windowClose");
1988 Assert(m_closedEwkView && "no closed webview");
1990 if (1 >= m_ewkViewList.size()) {
1991 if (!m_cbs->webkitExit.empty()) {
1992 m_cbs->webkitExit();
1995 // call user callbacks
1996 if (!m_cbs->bufferUnset.empty()) {
1997 m_cbs->bufferUnset(m_currentEwkView);
1999 if (!m_cbs->windowClose.empty()) {
2000 m_cbs->windowClose(m_closedEwkView);
2002 removeEwkView(m_closedEwkView);
2004 // get latest ewkView
2005 m_currentEwkView = m_ewkViewList.back();
2006 const char* uri = ewk_view_url_get(m_currentEwkView);
2007 if (NULL == uri || 0 == strlen(uri)) {
2008 m_currentUri.clear();
2014 /* In case we support many pages in parallel
2015 * then view is not suspended*/
2016 //resumeEwkView(m_currentEwkView);
2017 setEwkViewVisible(m_currentEwkView);
2020 if (!m_cbs->bufferSet.empty()) {
2021 m_cbs->bufferSet(m_currentEwkView);