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_storage_support.h>
51 #include <common/view_logic_uri_support.h>
52 #include <common/view_logic_user_agent_support.h>
53 #include <common/view_logic_vibration_support.h>
54 #include <view_logic_authentication_challenge_support.h>
55 #include <view_logic_scheme_support.h>
56 #include <view_logic_geolocation_support_webkit2.h>
57 #include <view_logic_usermedia_support.h>
58 #include <view_logic_web_notification_support.h>
59 #include "bundles/plugin_module_support.h"
60 #include <popup-runner/PopupInvoker.h>
63 #include <js_overlay_types.h>
64 #include <i_runnable_widget_object.h>
65 #include <profiling_util.h>
66 #include <wrt-commons/custom-handler-dao-ro/common_dao_types.h>
67 #include <wrt-commons/custom-handler-dao-ro/CustomHandlerDatabase.h>
68 #include <wrt-commons/custom-handler-dao-ro/custom_handler_dao_read_only.h>
69 #include <wrt-commons/custom-handler-dao-rw/custom_handler_dao.h>
70 #include <popup-runner/PopupInvoker.h>
72 #include <appsvc/appsvc.h>
75 const char * const bundlePath = "/usr/lib/wrt-wk2-bundles/libwrt-wk2-bundle.so";
76 const char * const uriBlockedMessageName = "uri_blocked_msg";
77 const char * const uriChangedMessageName = "uri_changed_msg";
78 const char * const URICHANGE_PLUGIN_STOP_ONLY = "plugin_stop_only";
79 const char * const URICHANGE_PLUGIN_RESTART = "plugin_restart";
80 const char * const URICHANGE_PLUGIN_NO_CHANGE = "plugin_no_change";
81 const char * const URICHANGE_BLOCKED_URL = "null";
82 const char* PATTERN_URI_CHANGE = "^(([^:/\\?#]+)://[^\\?#]*)";
83 const int MAX_NUM_CONTEXT_MENU_ITEMS = 10;
85 const char * const IME_STATE_ON = "on";
86 const char * const IME_STATE_OFF = "off";
88 const char PROTOCOL_HANDLER_ASK_MSG[] = "Add protocol?";
89 const char PROTOCOL_HANDLER_ASK_TITLE[] = "Add protocol";
90 const char PROTOCOL_HANDLER_ASK_REMEMBER[] = "Remember dicision";
91 const char CONTENT_HANDLER_ASK_MSG[] = "Add content?";
92 const char CONTENT_HANDLER_ASK_TITLE[] = "Add content";
93 const char CONTENT_HANDLER_AKS_REMEMBER[] = "Remember dicision";
94 const char * const CERTIFICATE_CONFIRM_REQUEST_ASK_TITLE =
96 const char * const CERTIFICATE_CONFIRM_REQUEST_ASK_BODY =
97 "This site's security certificate is not trusted! Do you acess this site?";
99 const wchar_t* BACKGROUND_ENABLED = L"background_enabled";
100 } // anonymous namespace
102 std::map<const std::string,
103 const Evas_Smart_Cb> ViewLogic::m_ewkCallbacksMap = {
104 { "load,started", &ViewLogic::loadStartedCallback },
105 { "load,finished", &ViewLogic::loadFinishedCallback },
106 { "title,changed", &ViewLogic::titleChangedCallback },
107 { "load,progress", &ViewLogic::loadProgressCallback },
108 { "load,progress,finished", &ViewLogic::loadProgressFinishedCallback },
109 { "process,crashed", &ViewLogic::processCrashedCallback },
111 { "create,window", &ViewLogic::createWindowCallback },
112 { "close,window", &ViewLogic::closeWindowCallback },
113 // WKPagePolicyClient
114 { "policy,navigation,decide", &ViewLogic::policyNavigationDecideCallback },
115 { "policy,newwindow,decide", &ViewLogic::policyNewWindowDecideCallback },
116 { "policy,response,decide", &ViewLogic::pageResponseDecideCallback },
117 // WKPageContextMenuClient
118 { "contextmenu,customize", &ViewLogic::contextmenuCustomizeCallback },
120 { "form,submit", &ViewLogic::formSubmitCallback },
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 },
130 { "fullscreen,enterfullscreen", &ViewLogic::enterFullscreenCallback },
131 { "fullscreen,exitfullscreen", &ViewLogic::exitFullscreenCallback },
133 // when ime start to be showed on the webview,
134 // this callback will be called
135 { "inputmethod,changed", &ViewLogic::imeChangedCallback },
136 // this callback will be called
137 // when ime finishes to be showed on the webview
138 // "event_info" arg of this callback is always NULL point
139 // if web content should know size of ime,
140 // use "inputmethod,changed" instead of this.
142 { "editorclient,ime,opened", &ViewLogic::imeOpenedCallback },
143 // when ime finished to be hidden,
144 // this callback will be called
145 { "editorclient,ime,closed", &ViewLogic::imeClosedCallback },
146 // EWK Usermedia Callback
147 { "usermedia,permission,request",
148 &ViewLogic::usermediaPermissionRequestCallback },
150 { "protocolhandler,registration,requested",
151 &ViewLogic::protocolHandlerRegistrationCallback },
152 { "protocolhandler,isregistered",
153 &ViewLogic::protocolHandlerIsRegisteredCallback },
154 { "protocolhandler,unregistration,requested",
155 &ViewLogic::protocolHandlerUnregistrationCallback },
156 { "contenthandler,registration,requested",
157 &ViewLogic::contentHandlerRegistrationCallback },
158 { "contenthandler,isregistered",
159 &ViewLogic::contentHandlerIsRegisteredCallback },
160 { "contenthandler,unregistration,requested",
161 &ViewLogic::contentHandlerUnregistrationCallback },
162 { "request,certificate,confirm",
163 &ViewLogic::certificateConfirmRequestCallback },
164 { "authentication,challenge",
165 &ViewLogic::authenticationChallengeRequestCallback }
168 ViewLogic::ViewLogic() :
170 m_attachedToCustomHandlerDao(false),
172 m_closedEwkView(NULL),
175 m_cbs(new WRT::UserDelegates),
178 m_isBackgroundReload(false),
179 m_isBackgroundSupport(false),
180 m_appsSupport(new ViewModule::AppsSupport()),
181 m_vibrationSupport(new ViewModule::VibrationSupport())
183 ApplicationLauncherSingleton::Instance().Touch();
186 ViewLogic::~ViewLogic()
188 detachFromCustomHandlersDao();
191 bool ViewLogic::createWebView(Ewk_Context* context,
195 if (!context || !window) {
200 const char *theme = elm_theme_get(NULL);
203 LogInfo("theme is " << m_theme);
207 m_ewkContext = context;
210 Evas* canvas = evas_object_evas_get(m_window);
211 return createEwkView(canvas);
214 void ViewLogic::prepareView(WidgetModel* m, const std::string &startUrl)
216 LogDebug("View prepare");
220 m_startUrl = startUrl;
221 Assert(NULL != m_ewkContext);
224 ADD_PROFILING_POINT("initializeSupport", "start");
226 ADD_PROFILING_POINT("initializeSupport", "stop");
228 ewkClientInit(m_currentEwkView);
229 ADD_PROFILING_POINT("prepareEwkView", "start");
230 prepareEwkView(m_currentEwkView);
231 ADD_PROFILING_POINT("prepareEwkView", "stop");
232 initializePluginLoading();
235 void ViewLogic::showWidget()
237 LogDebug("showing widget");
238 Assert(NULL != m_currentEwkView && "ewk_view not created at this point");
239 if (m_currentUri.empty()) {
240 LogError("Localized current URI doesn't exist");
244 LogInfo("m_currentUri: " << m_currentUri);
247 ewk_view_url_set(m_currentEwkView, m_currentUri.c_str());
249 if (!m_cbs->bufferSet.empty()) {
250 m_cbs->bufferSet(m_currentEwkView);
254 void ViewLogic::hideWidget()
256 LogDebug("hiding widget");
257 ViewModule::StorageSupport::deinitializeStorage(m_model);
258 m_appsSupport->deinitialize();
260 m_vibrationSupport->deinitialize();
262 while (!m_ewkViewList.empty()) {
263 LogInfo("pop webview: " << m_ewkViewList.back());
264 removeEwkView(m_ewkViewList.back());
266 m_ewkViewList.clear();
269 void ViewLogic::suspendWidget()
271 LogInfo("Pausing widget");
274 if (!m_currentEwkView) {
275 LogWarning("Cannot suspend widget without view");
277 setEwkViewInvisible(m_currentEwkView);
278 if (!m_isBackgroundSupport) {
279 suspendWebkit(m_currentEwkView);
283 evas_object_focus_set(m_currentEwkView, EINA_FALSE);
285 // call user callback
286 if (!m_cbs->suspend.empty()) {
287 m_cbs->suspend(true);
291 void ViewLogic::resumeWidget()
293 LogInfo("Resume widget");
296 if (m_currentEwkView) {
297 setEwkViewVisible(m_currentEwkView);
298 if (!m_isBackgroundSupport) {
299 resumeWebkit(m_currentEwkView);
303 /* window system team recomend removing this win_raise code. */
306 * elm_win_raise(m_window);
309 evas_object_focus_set(m_currentEwkView, EINA_TRUE);
311 // call user callback
312 if (!m_cbs->resume.empty()) {
317 void ViewLogic::resetWidget()
319 LogInfo("Resetting Widget");
321 // destory all webview
322 while (!m_ewkViewList.empty()) {
323 LogInfo("pop webview: " << m_ewkViewList.back());
324 removeEwkView(m_ewkViewList.back());
326 m_ewkViewList.clear();
328 // create new webview
329 createEwkView(evas_object_evas_get(m_window));
331 ewkClientInit(m_currentEwkView);
332 prepareEwkView(m_currentEwkView);
334 // check if current url is service url for this tizen service
335 std::string requestedUri =
336 ViewModule::UriSupport::getUri(m_model, m_startUrl);
337 DPL::OptionalString servicedUri = ViewModule::UriSupport::localizeURI(
338 DPL::FromUTF8String(requestedUri.c_str()),
341 initializePluginLoading();
344 m_currentUri = DPL::ToUTF8String(*servicedUri);
345 ewk_view_url_set(m_currentEwkView, m_currentUri.c_str());
346 elm_win_activate(m_window);
347 evas_object_focus_set(m_currentEwkView, EINA_TRUE);
349 // call user callback
350 if (!m_cbs->reset.empty()) {
353 if (!m_cbs->bufferSet.empty()) {
354 m_cbs->bufferSet(m_currentEwkView);
358 void ViewLogic::backward()
360 if (ewk_view_back_possible(m_currentEwkView)) {
361 ewk_view_back(m_currentEwkView);
363 if (1 >= m_ewkViewList.size()) {
364 // If there is no previous page, widget move to backgroud.
365 LogInfo("Widget move to backgroud");
366 elm_win_lower(m_window);
368 // Back to previous webview
369 LogInfo("Widget move to previous webview");
370 m_closedEwkView = m_currentEwkView;
371 ecore_idler_add(windowCloseIdlerCallback, this);
376 void ViewLogic::reloadStartPage()
378 LogInfo("Reload Start Page");
379 // prevent fail to load plugin bundle side
380 m_isBackgroundReload = true;
382 if (!m_ewkViewList.empty()) {
383 while (!m_ewkViewList.empty()) {
384 if (!m_cbs->bufferUnset.empty()) {
385 m_cbs->bufferUnset(m_currentEwkView);
387 removeEwkView(m_currentEwkView);
391 // create new webview
392 createEwkView(evas_object_evas_get(m_window));
393 ewkClientInit(m_currentEwkView);
396 prepareEwkView(m_currentEwkView);
397 initializePluginLoading();
400 ewk_view_url_set(m_currentEwkView, m_currentUri.c_str());
403 if (!m_cbs->bufferSet.empty()) {
404 m_cbs->bufferSet(m_currentEwkView);
406 LogInfo("Reloading Start Page is done!");
409 Evas_Object* ViewLogic::getCurrentWebview()
411 LogInfo("get current webview");
412 return m_currentEwkView;
415 void ViewLogic::fireJavascriptEvent(int event, void* data)
417 PluginModuleSupport::dispatchJavaScriptEvent(
419 static_cast<WrtPlugins::W3C::CustomEventType>(event),
423 void ViewLogic::setUserCallbacks(const WRT::UserDelegatesPtr& cbs)
428 void ViewLogic::checkSyncMessageFromBundle(
433 LogDebug("didReceiveSynchronousMessage called");
438 LogDebug("body is empty");
443 LogDebug("received : " << name);
445 if (!strcmp(name, uriBlockedMessageName)) {
446 // Currently WebProcess informs obly about blocked
447 // URI - URI localization and security chekcs are
448 // done by WebProcess itself (see: wrt-wk2-bundle.cpp
449 // and bundle_uri_handling.cpp)
450 result = requestUrlBlocked(std::string(body));
451 } else if (!strcmp(name, uriChangedMessageName)) {
452 result = requestUrlChanged(std::string(body));
455 *returnData = strdup(result.c_str());
458 void ViewLogic::downloadData(const char* url)
465 m_appsSupport->downloadRequest(url, NULL, NULL);
468 void ViewLogic::activateVibration(bool on, uint64_t time)
472 m_vibrationSupport->startVibration(static_cast<long>(time));
474 m_vibrationSupport->stopVibration();
478 void ViewLogic::initializeSupport()
480 // background support
481 if (m_model->SettingList.Get().getBackgroundSupport()
482 == BackgroundSupport_Enable)
484 LogDebug("Background support enabled, set process active");
485 pid_t pid = getpid();
486 sysman_inform_active(pid);
487 m_isBackgroundSupport = true;
489 #ifndef DEPRECATED_SETTING_STRING
491 WrtDB::WidgetDAOReadOnly dao(m_model->TizenId);
492 WrtDB::PropertyDAOReadOnly::WidgetPropertyValue bgEnableValue =
493 dao.getPropertyValue(DPL::String(BACKGROUND_ENABLED));
495 if (!bgEnableValue.IsNull() && !bgEnableValue->compare(L"true")) {
497 LogDebug("Background support enabled, set process active");
498 pid_t pid = getpid();
499 sysman_inform_active(pid);
500 m_isBackgroundSupport = true;
505 m_schemeSupport.reset(new SchemeSupport(m_model->Type.Get().appType));
506 ViewModule::StorageSupport::initializeStorage(m_model);
507 m_appsSupport->initialize(m_model);
508 m_securityOriginSupport.reset(new ViewModule::SecurityOriginSupport(m_model));
510 m_vibrationSupport->initialize();
513 void ViewLogic::initializePluginLoading()
515 // inform wrt information for plugin loading to web process
516 PluginModuleSupport::start(
519 elm_config_scale_get(),
520 ApplicationDataSingleton::Instance().getEncodedBundle(),
522 m_model->SettingList.Get().isEncrypted());
525 void ViewLogic::ewkClientInit(Evas_Object *wkView)
527 Assert(NULL != wkView && "ewk_view not created at this point");
529 FOREACH(it, m_ewkCallbacksMap) {
530 evas_object_smart_callback_add(
536 // EWK Orientation Callback
537 ewk_view_orientation_lock_callback_set(
539 orientationLockCallback,
543 void ViewLogic::ewkClientDeinit(Evas_Object *wkView)
545 LogDebug("ewkClientDeinit");
546 Assert(NULL != wkView && "ewk_view not created at this point");
548 FOREACH(it, m_ewkCallbacksMap) {
549 evas_object_smart_callback_del(
554 ewk_view_orientation_lock_callback_set(
560 bool ViewLogic::createEwkView(Evas* canvas)
562 LogDebug("createEwkVeiw");
564 ADD_PROFILING_POINT("ewk_view_add_with_context", "start");
565 Evas_Object* newEwkView = ewk_view_add_with_context(
568 ADD_PROFILING_POINT("ewk_view_add_with_context", "stop");
571 LogError("View creation failed");
572 Wrt::Popup::PopupInvoker().showInfo(
573 "Info", "View creation failed", "close");
578 // even arguments pass the ewkContext, this API should be called
579 // after webkit Evas_Object is created
580 Ewk_Cookie_Manager *ewkCookieManager;
582 ewk_context_cookie_manager_get(m_ewkContext);
583 ewk_cookie_manager_accept_policy_set(ewkCookieManager,
584 EWK_COOKIE_ACCEPT_POLICY_ALWAYS);
586 if (m_currentEwkView) {
587 setEwkViewInvisible(m_currentEwkView);
590 LogInfo("push webview: " << newEwkView);
591 m_ewkViewList.push_back(newEwkView);
592 m_currentEwkView = newEwkView;
596 void ViewLogic::setStartPage()
598 /* Start URI (as other uris) is now localized
599 * on WebProcess side */
600 m_currentUri = ViewModule::UriSupport::getUri(m_model, m_startUrl);
603 void ViewLogic::prepareEwkView(Evas_Object *wkView)
605 LogDebug("prepareEwkView called");
607 Ewk_Settings* settings = ewk_view_settings_get(wkView);
610 std::string customUserAgent = m_model->SettingList.Get().getUserAgent();
611 if (customUserAgent.empty()) {
612 auto userAgentString =
613 ViewModule::UserAgentSupport::getUserAgentFromVconf();
614 if (!userAgentString.empty()) {
615 LogDebug("Setting user agent as: " << userAgentString);
616 ewk_view_user_agent_set(wkView, userAgentString.c_str());
619 LogDebug("Setting custom user agent as: " << customUserAgent);
620 ewk_view_user_agent_set(wkView, customUserAgent.c_str());
623 // set custom header : language
624 using namespace ViewModule::CustomHeaderSupport;
625 std::string customHeaderString = getValueByField(ACCEPT_LANGUAGE);
626 if (!customHeaderString.empty()) {
627 LogDebug("custom field=[" << ACCEPT_LANGUAGE << "]");
628 LogDebug("custom value=[" << customHeaderString << "]");
629 ewk_view_custom_header_add(wkView,
630 ACCEPT_LANGUAGE.c_str(),
631 customHeaderString.c_str());
634 // webkit NPAPI plugins is always on in wrt
635 ewk_settings_plugins_enabled_set(settings, EINA_TRUE);
637 // The followings are not implemeted yet by webkit2
638 // ewk_view_setting_accelerated_compositing_enable_set(EINA_TRUE);
639 // ewk_view_mode_set();
640 // ewk_view_setting_enable_specified_plugin_set(EINA_TRUE,
642 // ewk_view_setting_html5video_external_player_enable_set(EINA_FALSE);
643 // ewk_view_show_ime_on_autofocus_set(EINA_TRUE);
644 // elm_webview_show_magnifier_set(EINA_FALSE);
645 ewk_settings_javascript_enabled_set(settings, EINA_TRUE);
646 ewk_settings_loads_images_automatically_set(settings, EINA_TRUE);
647 // WRT should not fit web contents to device width automatically as default.
648 // Fitting to device width should be handled by web content using viewport meta tag.
649 ewk_settings_auto_fitting_set(settings, EINA_FALSE);
651 // disable zoom option when user click the input field
652 // this option is useful with the normal website
653 // for the make user friendly, disable auto zoom in the webapp
654 // The followings are not implemeted yet by webkit2
655 // elm_webview_input_field_zoom_set(EINA_FALSE);
657 // set cookie database path
658 // The followings are not implemeted yet by webkit2
659 // ewk_cookies_file_set(dao.getCookieDatabasePath().c_str()));
661 // set visibility to WebCore. This value will be used for html5.
662 // also, this value will be changed in the suspend, resume
663 // or create window, close window.
664 ewk_view_page_visibility_state_set(wkView,
665 EWK_PAGE_VISIBILITY_STATE_VISIBLE,
669 void ViewLogic::removeEwkView(Evas_Object *wkView)
671 LogInfo("removeEwkView called");
673 Assert(0 != m_ewkViewList.size());
675 // unregister webview callbacks
676 ewkClientDeinit(wkView);
678 // suspend NPAPI plugin - Not implemented by Webkit2
679 // ewk_view_pause_or_resume_plugins();
680 evas_object_del(wkView);
681 m_ewkViewList.remove(wkView);
684 void ViewLogic::resumeEwkView(Evas_Object *wkView)
686 LogInfo("resumeEwkView called");
689 // register webview callback
690 ewkClientInit(wkView);
693 resumeWebkit(wkView);
698 void ViewLogic::suspendEwkView(Evas_Object *wkView)
700 LogInfo("suspendEwkView called");
704 suspendWebkit(wkView);
706 // unregister webview callbacks
707 ewkClientDeinit(wkView);
712 void ViewLogic::setEwkViewInvisible(Evas_Object *wkView)
714 LogInfo("setEwkViewInvisible called");
717 ewk_view_page_visibility_state_set(wkView,
718 EWK_PAGE_VISIBILITY_STATE_HIDDEN,
720 ewk_view_visibility_set(wkView, EINA_FALSE);
723 void ViewLogic::setEwkViewVisible(Evas_Object *wkView)
725 LogInfo("setEwkViewVisible called");
728 ewk_view_page_visibility_state_set(wkView,
729 EWK_PAGE_VISIBILITY_STATE_VISIBLE,
731 ewk_view_visibility_set(wkView, EINA_TRUE);
734 void ViewLogic::resumeWebkit(Evas_Object *wkView)
736 LogDebug("resumeWebkit");
739 // resume NPAPI plugin
740 // The followings are not implemeted yet by webkit2
741 // ewk_view_pause_or_resume_plugins(false);
742 // ewk_view_pause_or_resume_video_audio(false);
743 // ewk_view_javascript_resume();
744 // ewk_view_enable_render();
745 // ewk_view_reduce_plugins_frame_rate(false);
746 ewk_view_resume(wkView);
751 void ViewLogic::suspendWebkit(Evas_Object *wkView)
753 LogDebug("suspendWebkit");
756 // suspend the followings
757 // The followings are not implemeted yet by webkit2
758 // ewk_view_pause_or_resume_plugins(true);
759 // ewk_view_pause_or_resume_video_audio(true);
760 ewk_view_suspend(wkView);
765 void ViewLogic::loadStartedCallback(
770 LogDebug("loadStartedCallback called");
772 ViewLogic* This = static_cast<ViewLogic*>(data);
773 evas_object_focus_set(This->m_currentEwkView, EINA_TRUE);
775 // call loadFinish callback to wrt-client
776 if (!This->m_cbs->loadStart.empty()) {
777 This->m_cbs->loadStart(obj);
781 void ViewLogic::loadFinishedCallback(
786 LogDebug("loadFinishedCallback called");
788 ViewLogic* This = static_cast<ViewLogic*>(data);
791 const char* url = ewk_view_url_get(This->m_currentEwkView);
792 if (NULL == url || strlen(url) == 0) {
793 LogError("url is empty");
797 // check if this loading is for blocked url
798 if (This->m_blockedUri == url) {
799 if (ewk_view_back_possible(This->m_currentEwkView)) {
800 // go back to previous page
801 LogDebug("go to previous page");
802 ewk_view_back(This->m_currentEwkView);
805 LogDebug("remove current page");
806 ewk_view_stop(This->m_currentEwkView);
807 ecore_idler_add(windowCloseIdlerCallback, This);
809 This->m_blockedUri = std::string();
813 DPL::OptionalString jsOptionalString =
814 ViewModule::PasswordSupport::jsForAutoFillData(url);
815 if (jsOptionalString.IsNull()) {
816 LogError("Fail to get JS String");
818 std::string jsStr = DPL::ToUTF8String(*jsOptionalString).c_str();
820 if (EINA_FALSE == ewk_view_script_execute(
821 This->m_currentEwkView,
823 didRunJavaScriptCallback,
826 LogError("JS for auto fill data failed.");
830 // call loadFinish callback to wrt-client
831 if (!This->m_cbs->loadFinish.empty()) {
832 This->m_cbs->loadFinish(obj);
835 // set only encoded bundle
836 double scale = elm_config_scale_get();
837 PluginModuleSupport::setCustomProperties(
840 ApplicationDataSingleton::Instance().getEncodedBundle());
841 // check if 'appsevice' event is registed at the current frames.
842 // If so, dispatch the event to frames.
843 PluginModuleSupport::dispatchJavaScriptEvent(
845 WrtPlugins::W3C::ServiceCustomEvent,
848 // In this case, widget is reloaded in the background.
849 // After finished load, bundle should disconnent callback.
850 if (This->m_isBackgroundReload) {
851 ewk_view_suspend(This->m_currentEwkView);
852 This->m_isBackgroundReload = false;
856 void ViewLogic::titleChangedCallback(
858 Evas_Object* /*obj*/,
861 LogDebug("titleChangedCallback called");
863 ViewLogic* This = static_cast<ViewLogic*>(data);
865 const char* title = static_cast<char*>(eventInfo);
867 if (0 == strlen(title)) {
868 LogDebug("title data is empty");
871 LogDebug("Title = [" << title << "]");
872 This->m_schemeSupport->HandleTizenScheme(title,
874 This->m_currentEwkView);
877 void ViewLogic::loadProgressCallback(
879 Evas_Object* /*obj*/,
882 double* progress = static_cast<double*>(eventInfo);
883 LogDebug("didChangeProgressCallback progress = " << *progress);
886 void ViewLogic::loadProgressFinishedCallback(
888 Evas_Object* /*obj*/,
891 LogDebug("didFinishProgressCallback");
893 ViewLogic const * const view = static_cast<ViewLogic const * const>(data);
894 if (!view->m_cbs->progressFinish.empty()) {
895 view->m_cbs->progressFinish();
899 void ViewLogic::processCrashedCallback(
901 Evas_Object* /*obj*/,
904 LogInfo("processCrashedCallback");
906 ViewLogic const * const view =
907 static_cast<ViewLogic const * const>(data);
908 if (!view->m_cbs->webCrash.empty()) {
909 view->m_cbs->webCrash();
911 // This flag will be prevented exit() call in the Webkit side
912 if (NULL != eventInfo) {
913 *(static_cast<Eina_Bool*>(eventInfo)) = EINA_TRUE;
917 void ViewLogic::createWindowCallback(
922 LogDebug("createWindowCallback");
924 ViewLogic* This = static_cast<ViewLogic*>(data);
926 // First, current webview should be handled by user callback
927 if (!This->m_cbs->bufferUnset.empty()) {
928 This->m_cbs->bufferUnset(obj);
931 // this can be set by executable for specific purpose
933 if (!This->m_cbs->windowCreateBefore.empty()) {
934 // 'obj' is parent webview object
935 This->m_cbs->windowCreateBefore(&canvas, obj);
938 canvas = evas_object_evas_get(This->m_window);
941 // create new ewkview
942 This->createEwkView(canvas);
943 Evas_Object* newEwkView = This->m_currentEwkView;
945 // initialize new ewkview
946 This->setStartPage();
947 This->ewkClientInit(newEwkView);
948 This->prepareEwkView(newEwkView);
950 // Specific jobs of child, parent webview are handled by each executable
951 if (!This->m_cbs->windowCreateAfter.empty()) {
952 // 'obj' is parent webview, 'newEwkView' is child webview
953 This->m_cbs->windowCreateAfter(obj, newEwkView);
956 // Lastly, new webview should be handled by user callback
957 if (!This->m_cbs->bufferSet.empty()) {
958 This->m_cbs->bufferSet(newEwkView);
960 *(static_cast<Evas_Object **>(eventInfo)) = newEwkView;
963 void ViewLogic::closeWindowCallback(
968 LogDebug("closeWindowCallback");
969 ViewLogic* This = static_cast<ViewLogic*>(data);
970 This->m_closedEwkView = obj;
971 ecore_idler_add(windowCloseIdlerCallback, This);
974 void ViewLogic::policyNavigationDecideCallback(
976 Evas_Object* /*obj*/,
979 LogDebug("policyNavigationDecideCallback called");
981 ViewLogic* This = static_cast<ViewLogic*>(data);
983 Ewk_Policy_Decision* policyDecision =
984 static_cast<Ewk_Policy_Decision*>(eventInfo);
986 if (This->m_schemeSupport->filterURIByScheme(policyDecision,
990 This->m_currentEwkView))
993 ewk_policy_decision_use(policyDecision);
995 // check whether this is new empty window
996 const char* activeUrl = ewk_view_url_get(This->m_currentEwkView);
997 if (!activeUrl || 0 == strlen(activeUrl)) {
999 * The view is empty and scheme has been handled externally. When
1000 * user gets back from the external application he'd see blank page
1001 * and won't be able to navigate back. This happens when window.open
1002 * is used to handle schemes like sms/mms/mailto (for example in
1003 * WAC web standards tests: WS-15XX).
1005 * To solve the problem, the empty view is removed from the stack
1006 * and the previous one is shown. This is not an elegant solution
1007 * but we don't have a better one.
1009 LogInfo("Scheme has been handled externally. Removing empty view.");
1010 if (ewk_view_back_possible(This->m_currentEwkView)) {
1011 // go back to previous WKPage
1012 ewk_view_back(This->m_currentEwkView);
1014 // stop current WKPage
1015 ewk_view_stop(This->m_currentEwkView);
1016 ecore_idler_add(windowCloseIdlerCallback, This);
1021 ewk_policy_decision_ignore(policyDecision);
1025 void ViewLogic::policyNewWindowDecideCallback(
1027 Evas_Object* /*obj*/,
1030 LogDebug("policyNewWindowDecideCallback called");
1032 ViewLogic* This = static_cast<ViewLogic*>(data);
1034 Ewk_Policy_Decision* policyDecision =
1035 static_cast<Ewk_Policy_Decision*>(eventInfo);
1037 if (This->m_schemeSupport->filterURIByScheme(policyDecision,
1041 This->m_currentEwkView))
1043 ewk_policy_decision_use(policyDecision);
1046 ewk_policy_decision_ignore(policyDecision);
1050 void ViewLogic::pageResponseDecideCallback(
1052 Evas_Object* /*obj*/,
1055 LogDebug("pageResponseDecideCallback called");
1057 ViewLogic* This = static_cast<ViewLogic*>(data);
1059 Ewk_Policy_Decision* policyDecision =
1060 static_cast<Ewk_Policy_Decision*>(eventInfo);
1061 Ewk_Policy_Decision_Type policyDecisionType =
1062 ewk_policy_decision_type_get(policyDecision);
1064 if (policyDecisionType == EWK_POLICY_DECISION_USE) {
1066 ewk_policy_decision_use(policyDecision);
1067 } else if (policyDecisionType == EWK_POLICY_DECISION_DOWNLOAD) {
1068 LogDebug("download");
1069 ewk_policy_decision_suspend(policyDecision);
1071 // get uri information
1072 const char* url = ewk_policy_decision_url_get(policyDecision);
1073 if (NULL == url || strlen(url) == 0) {
1074 LogDebug("url data is empty");
1075 ewk_policy_decision_use(policyDecision);
1078 LogDebug("url = [" << url << "]");
1080 // get content information
1081 const char* content =
1082 ewk_policy_decision_response_mime_get(policyDecision);
1083 LogDebug("content type = [" << content << "]");
1085 // get cookie information
1086 const char* cookie = ewk_policy_decision_cookie_get(policyDecision);
1087 LogDebug("cookie = [" << cookie << "]");
1089 LogDebug("Content not supported, will be opened in external app");
1090 This->m_appsSupport->downloadRequest(
1094 ewk_policy_decision_ignore(policyDecision);
1095 } else if (policyDecisionType == EWK_POLICY_DECISION_IGNORE) {
1097 ewk_policy_decision_ignore(policyDecision);
1099 LogDebug("Type isn't handled");
1100 ewk_policy_decision_ignore(policyDecision);
1104 void ViewLogic::contextmenuCustomizeCallback(
1106 Evas_Object* /*obj*/,
1109 LogDebug("contextmenuCustomizeCallback called");
1112 ViewLogic* This = static_cast<ViewLogic*>(const_cast<void*>(data));
1113 Ewk_Context_Menu* menu = static_cast<Ewk_Context_Menu*>(eventInfo);
1114 if ((This->m_model->Type.Get().appType == WrtDB::APP_TYPE_TIZENWEBAPP) &&
1115 (This->m_model->SettingList.Get().getContextMenu()
1116 == ContextMenu_Disable))
1118 LogDebug("ContextMenu Disable!!");
1119 for (unsigned int idx = 0; idx < ewk_context_menu_item_count(menu);) {
1120 Ewk_Context_Menu_Item* item = ewk_context_menu_nth_item_get(menu,
1123 ewk_context_menu_item_remove(menu, item);
1126 LogDebug("ContextMenu Enable!!");
1127 unsigned int menu_num = ewk_context_menu_item_count(menu);
1128 unsigned int idx = 0;
1130 Ewk_Context_Menu_Item* item = ewk_context_menu_nth_item_get(menu,
1136 Ewk_Context_Menu_Item_Tag tag = ewk_context_menu_item_tag_get(item);
1139 case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_IMAGE_IN_NEW_WINDOW:
1140 ewk_context_menu_item_remove(menu, item);
1143 case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_LINK_IN_NEW_WINDOW:
1144 ewk_context_menu_item_remove(menu, item);
1147 case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_FRAME_IN_NEW_WINDOW:
1148 ewk_context_menu_item_remove(menu, item);
1151 case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_MEDIA_IN_NEW_WINDOW:
1152 ewk_context_menu_item_remove(menu, item);
1155 case EWK_CONTEXT_MENU_ITEM_TAG_SEARCH_WEB:
1156 ewk_context_menu_item_remove(menu, item);
1163 } while (idx < menu_num);
1167 void ViewLogic::formSubmitCallback(
1169 Evas_Object* /*obj*/,
1172 LogDebug("formSubmitCallback called");
1174 Ewk_Form_Data* formData = static_cast<Ewk_Form_Data*>(eventInfo);
1176 const char* uri = ewk_form_data_url_get(formData);
1178 LogError("URL is empty");
1182 Eina_Hash* userData = ewk_form_data_values_get(formData);
1183 ViewModule::PasswordSupport::submitClicked(uri, userData);
1186 void ViewLogic::geolocationPermissionRequestCallback(
1188 Evas_Object* /*obj*/,
1192 ViewLogic* This = static_cast<ViewLogic*>(data);
1194 Ewk_Geolocation_Permission_Request* permissionRequest =
1195 static_cast<Ewk_Geolocation_Permission_Request*>(eventInfo);
1197 if (This->m_securityOriginSupport->isNeedPermissionCheck(
1198 SecurityOriginDB::FEATURE_GEOLOCATION)
1199 == WrtDB::SETTINGS_TYPE_OFF)
1201 ewk_geolocation_permission_request_set(permissionRequest, EINA_FALSE);
1204 ViewModule::GeolocationSupport::Webkit2::geolocationPermissionRequest(
1206 This->m_securityOriginSupport->getSecurityOriginDAO(),
1210 void ViewLogic::notificationShowCallback(
1212 Evas_Object* /*obj*/,
1215 LogDebug("notificationShowCallback called");
1217 ViewLogic* This = static_cast<ViewLogic*>(data);
1220 Ewk_Notification* noti = static_cast<Ewk_Notification*>(eventInfo);
1222 using namespace ViewModule::WebNotification;
1224 WebNotificationDataPtr notiData(
1225 new WebNotificationData(
1227 ewk_notification_id_get(noti)));
1229 DPL::OptionalString string =
1230 DPL::FromUTF8String(ewk_notification_icon_url_get(noti));
1231 if (!string.IsNull()) {
1232 notiData->m_iconURL = DPL::ToUTF8String(*string);
1234 string = DPL::FromUTF8String(ewk_notification_title_get(noti));
1235 if (!string.IsNull()) {
1236 notiData->m_title = DPL::ToUTF8String(*string);
1238 string = DPL::FromUTF8String(ewk_notification_body_get(noti));
1239 if (!string.IsNull()) {
1240 notiData->m_body = DPL::ToUTF8String(*string);
1243 LogInfo("notification id : " << notiData->m_id);
1244 LogInfo("notification iconURL : " << notiData->m_iconURL);
1245 LogInfo("notification title : " << notiData->m_title);
1246 LogInfo("notification body : " << notiData->m_body);
1248 showWebNotification(notiData);
1249 ewk_notification_showed(This->m_ewkContext, ewk_notification_id_get(noti));
1252 void ViewLogic::notificationCancelCallback(
1254 Evas_Object* /*obj*/,
1255 void* /*eventInfo*/)
1257 LogDebug("notificationCancelCallback called");
1260 void ViewLogic::notificationPermissionRequestCallback(
1262 Evas_Object* /*obj*/,
1265 LogDebug("notificationPermissionRequestCallback called");
1267 ViewLogic* This = static_cast<ViewLogic*>(data);
1268 if (This->m_securityOriginSupport->isNeedPermissionCheck(
1269 SecurityOriginDB::FEATURE_WEB_NOTIFICATION)
1270 == WrtDB::SETTINGS_TYPE_OFF)
1272 Ewk_Notification_Permission_Request* request =
1273 static_cast<Ewk_Notification_Permission_Request*>(eventInfo);
1274 ewk_notification_permission_request_response(
1282 ViewModule::WebNotification::webNotificationPermissionRequest(
1284 This->m_securityOriginSupport->getSecurityOriginDAO(),
1290 // EWK Orientation Callback
1291 Eina_Bool ViewLogic::orientationLockCallback(
1293 Eina_Bool /*needLock*/,
1297 LogDebug("orientationLockCallback called");
1299 ViewLogic* This = static_cast<ViewLogic*>(data);
1301 if (orientation & EWK_SCREEN_ORIENTATION_PORTRAIT_PRIMARY) {
1302 LogDebug("orientation is portrait-primary");
1303 elm_win_rotation_with_resize_set(This->m_window, 0);
1304 ewk_view_orientation_send(obj, 0);
1305 } else if (orientation & EWK_SCREEN_ORIENTATION_LANDSCAPE_PRIMARY) {
1306 LogDebug("orientation is landscape-primary");
1307 elm_win_rotation_with_resize_set(This->m_window, 270);
1308 ewk_view_orientation_send(obj, 90);
1309 } else if (orientation & EWK_SCREEN_ORIENTATION_PORTRAIT_SECONDARY) {
1310 LogDebug("orientation is portrait-secondary");
1311 elm_win_rotation_with_resize_set(This->m_window, 180);
1312 ewk_view_orientation_send(obj, 180);
1313 } else if (orientation & EWK_SCREEN_ORIENTATION_LANDSCAPE_SECONDARY) {
1314 LogDebug("orientation is landscape-secondary");
1315 elm_win_rotation_with_resize_set(This->m_window, 90);
1316 ewk_view_orientation_send(obj, -90);
1318 LogDebug("Wrong orientation is set");
1324 // Fullscreen API callbacks
1325 void ViewLogic::enterFullscreenCallback(
1327 Evas_Object* /*obj*/,
1328 void* /*eventInfo*/)
1330 LogInfo("enterFullscreenCallback called");
1332 ViewLogic* This = static_cast<ViewLogic*>(data);
1333 if (!This->m_cbs->toggleFullscreen.empty()) {
1334 This->m_cbs->toggleFullscreen(true);
1337 void ViewLogic::exitFullscreenCallback(
1339 Evas_Object* /*obj*/,
1340 void* /*eventInfo*/)
1342 LogInfo("exitFullscreenCallback called");
1344 ViewLogic* This = static_cast<ViewLogic*>(data);
1345 if (!This->m_cbs->toggleFullscreen.empty()) {
1346 This->m_cbs->toggleFullscreen(false);
1350 void ViewLogic::imeChangedCallback(
1352 Evas_Object* /*obj*/,
1358 ViewLogic* This = static_cast<ViewLogic*>(data);
1359 Eina_Rectangle *rect = static_cast<Eina_Rectangle *>(eventInfo);
1360 This->m_imeWidth = rect->w;
1361 This->m_imeHeight = rect->h;
1364 void ViewLogic::imeOpenedCallback(
1366 Evas_Object* /*obj*/,
1367 void* /*eventInfo*/)
1371 ViewLogic* This = static_cast<ViewLogic*>(data);
1373 using namespace WrtPlugins::W3C;
1374 SoftKeyboardChangeArgs args;
1375 args.state = IME_STATE_ON;
1376 args.width = This->m_imeWidth;
1377 args.height = This->m_imeHeight;
1378 This->fireJavascriptEvent(
1379 static_cast<int>(SoftKeyboardChangeCustomEvent),
1383 void ViewLogic::imeClosedCallback(
1385 Evas_Object* /*obj*/,
1386 void* /*eventInfo*/)
1390 ViewLogic* This = static_cast<ViewLogic*>(data);
1392 using namespace WrtPlugins::W3C;
1393 SoftKeyboardChangeArgs args;
1394 args.state = IME_STATE_OFF;
1396 This->fireJavascriptEvent(
1397 static_cast<int>(SoftKeyboardChangeCustomEvent),
1401 void ViewLogic::usermediaPermissionRequestCallback(
1403 Evas_Object* /*obj*/,
1406 LogDebug("usermediaPermissionRequestCallback called");
1408 ViewLogic* This = static_cast<ViewLogic*>(data);
1409 ViewModule::UsermediaSupport::usermediaPermissionRequest(This->m_window,
1414 CustomHandlerDB::CustomHandlerPtr getCustomHandlerFromData(void* data)
1417 Ewk_Custom_Handlers_Data* handler =
1418 static_cast<Ewk_Custom_Handlers_Data*>(data);
1419 CustomHandlerDB::CustomHandlerPtr customHandler(
1420 new CustomHandlerDB::CustomHandler());
1421 const char* base_url = ewk_custom_handlers_data_base_url_get(handler);
1423 LogDebug("base url: " << base_url);
1424 customHandler->base_url = DPL::FromASCIIString(string(base_url));
1426 const char* url = ewk_custom_handlers_data_url_get(handler);
1428 LogDebug("url: " << url);
1429 customHandler->url = DPL::FromASCIIString(string(url));
1431 const char* target = ewk_custom_handlers_data_target_get(handler);
1433 LogDebug("target: " << target);
1434 customHandler->target = DPL::FromASCIIString(string(target));
1436 const char* title = ewk_custom_handlers_data_title_get(handler);
1438 LogDebug("title: " << title);
1439 customHandler->title = DPL::FromASCIIString(string(title));
1441 return customHandler;
1444 void ViewLogic::attachToCustomHandlersDao()
1446 if (!m_attachedToCustomHandlerDao) {
1447 CustomHandlerDB::Interface::attachDatabaseRW();
1451 void ViewLogic::detachFromCustomHandlersDao()
1453 if (m_attachedToCustomHandlerDao) {
1454 CustomHandlerDB::Interface::detachDatabase();
1458 const int protocolWhiteListLenth = 15;
1459 char const * const protocolWhiteList[protocolWhiteListLenth] = {
1477 const int contentBlackListLenth = 14;
1478 char const * const contentBlackList[contentBlackListLenth] = {
1479 "application/x-www-form-urlencoded",
1480 "application/xhtml+xml",
1486 "multipart/x-mixed-replace",
1487 "text/cache-manifest",
1496 * Saves user's response from popup to custom handler. Saves Yes/No and remember
1499 * @param customHandler
1501 void saveUserResponse(Wrt::Popup::PopupResponse response,
1502 CustomHandlerDB::CustomHandlerPtr customHandler)
1505 case Wrt::Popup::YES_DO_REMEMBER:
1506 LogDebug("User allowed, remember");
1507 customHandler->user_decision =
1508 static_cast<CustomHandlerDB::HandlerState>
1509 (CustomHandlerDB::Agreed | CustomHandlerDB::DecisionSaved);
1511 case Wrt::Popup::YES_DONT_REMEMBER:
1512 LogDebug("User allowed, don't remember");
1513 customHandler->user_decision = CustomHandlerDB::Agreed;
1515 case Wrt::Popup::NO_DO_REMEMBER:
1516 LogDebug("User didn't allow, remember");
1517 customHandler->user_decision =
1518 static_cast<CustomHandlerDB::HandlerState>
1519 (CustomHandlerDB::Declined | CustomHandlerDB::DecisionSaved);
1521 case Wrt::Popup::NO_DONT_REMEMBER:
1522 LogDebug("User didn't allow, don't remember");
1523 customHandler->user_decision = CustomHandlerDB::Declined;
1528 //TODO registration, checking if registered and unregistration can be done in
1529 //common functions for both types of handlers. Only white and black lists
1530 //have to be separated
1531 //TODO attach database only one at the start (not in every callback?)
1532 void ViewLogic::protocolHandlerRegistrationCallback(void* data,
1533 Evas_Object* /*obj*/,
1538 CustomHandlerDB::CustomHandlerPtr customHandler =
1539 getCustomHandlerFromData(eventInfo);
1541 std::string scheme = DPL::ToUTF8String(customHandler->target);
1542 if (scheme.empty()) {
1543 LogError("No scheme provided");
1544 //TODO what about securityError?
1547 bool matched = false;
1548 //scheme on whiteList
1549 for (int i = 0; i < protocolWhiteListLenth; ++i) {
1550 if (0 == strcmp(protocolWhiteList[i], scheme.c_str())) {
1551 LogDebug("Match found, protocol can be handled");
1556 //starts with web+ and have at least 5 chars (lowercase ASCII)
1557 if (strncmp("web+", scheme.c_str(), 4) || scheme.length() < 5) {
1558 LogWarning("Scheme neither on whitelist nor starts with \"web+\"");
1559 //throw SecurityException
1565 if (c < 'a' || c > 'z') {
1566 LogWarning("Wrong char inside scheme. "
1567 << "Only lowercase ASCII letters accepted");
1568 //throw SecurityException
1575 ViewLogic* This = static_cast<ViewLogic*>(data);
1576 LogDebug("Creating handlers dao");
1577 This->attachToCustomHandlersDao();
1578 CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1579 CustomHandlerDB::CustomHandlerPtr handler =
1580 handlersDao.getProtocolHandler(customHandler->target,
1582 customHandler->base_url);
1583 if (handler && (handler->user_decision & CustomHandlerDB::DecisionSaved)) {
1584 LogDebug("Protocol already registered - nothing to do");
1586 LogDebug("Protocol handler not found");
1587 Wrt::Popup::PopupResponse response =
1588 GlobalSettings::PopupsTestModeEnabled() ? Wrt::Popup::
1590 Wrt::Popup::PopupInvoker().askYesNoCheckbox(
1591 PROTOCOL_HANDLER_ASK_TITLE,
1592 PROTOCOL_HANDLER_ASK_MSG,
1593 PROTOCOL_HANDLER_ASK_REMEMBER);
1594 saveUserResponse(response, customHandler);
1595 if (customHandler->user_decision == CustomHandlerDB::Declined) {
1598 handlersDao.registerProtocolHandler(*(customHandler.get()));
1599 if (customHandler->user_decision & CustomHandlerDB::Agreed) {
1600 //TODO remove old default handler somehow from appsvc
1601 LogDebug("Registering appservice entry");
1602 int ret = appsvc_set_defapp(APPSVC_OPERATION_VIEW,
1605 customHandler->target).c_str(),
1606 DPL::ToUTF8String(This->m_model->
1608 if (APPSVC_RET_OK != ret) {
1609 LogWarning("Appsvc entry failed: " << ret);
1612 LogDebug("Protocal saved");
1615 This->detachFromCustomHandlersDao();
1618 void ViewLogic::protocolHandlerIsRegisteredCallback(void* data,
1619 Evas_Object* /*obj*/,
1623 CustomHandlerDB::CustomHandlerPtr customHandler = getCustomHandlerFromData(
1625 ViewLogic* This = static_cast<ViewLogic*>(data);
1626 LogDebug("Creating handlers dao");
1627 This->attachToCustomHandlersDao();
1628 CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1629 CustomHandlerDB::CustomHandlerPtr handler =
1630 handlersDao.getProtocolHandler(customHandler->target,
1632 customHandler->base_url);
1634 if (handler->user_decision & CustomHandlerDB::Agreed) {
1635 ewk_custom_handlers_data_result_set(
1636 static_cast<Ewk_Custom_Handlers_Data*>(data),
1637 EWK_CUSTOM_HANDLERS_REGISTERED);
1639 ewk_custom_handlers_data_result_set(
1640 static_cast<Ewk_Custom_Handlers_Data*>(data),
1641 EWK_CUSTOM_HANDLERS_DECLINED);
1644 ewk_custom_handlers_data_result_set(
1645 static_cast<Ewk_Custom_Handlers_Data*>(data),
1646 EWK_CUSTOM_HANDLERS_NEW);
1648 This->detachFromCustomHandlersDao();
1651 void ViewLogic::protocolHandlerUnregistrationCallback(void* data,
1652 Evas_Object* /*obj*/,
1656 CustomHandlerDB::CustomHandlerPtr customHandler =
1657 getCustomHandlerFromData(eventInfo);
1658 ViewLogic* This = static_cast<ViewLogic*>(data);
1659 LogDebug("Creating handlers dao");
1660 This->attachToCustomHandlersDao();
1661 CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1662 CustomHandlerDB::CustomHandlerPtr handlerCheck =
1663 handlersDao.getProtocolHandler(customHandler->target,
1665 customHandler->base_url);
1667 if (handlerCheck->user_decision & CustomHandlerDB::Agreed) {
1668 appsvc_unset_defapp(DPL::ToUTF8String(This->m_model->TizenId).c_str());
1671 handlersDao.unregisterProtocolHandler(customHandler->target,
1673 customHandler->base_url);
1675 LogDebug("Nothing to unregister");
1678 This->detachFromCustomHandlersDao();
1681 void ViewLogic::contentHandlerRegistrationCallback(void* data,
1682 Evas_Object* /*obj*/,
1687 CustomHandlerDB::CustomHandlerPtr customHandler =
1688 getCustomHandlerFromData(eventInfo);
1690 std::string mimeType = DPL::ToUTF8String(customHandler->target);
1691 if (mimeType.empty()) {
1692 LogError("No mimeType provided.");
1695 for (int i = 0; i < contentBlackListLenth; ++i) {
1696 if (0 == strcmp(contentBlackList[i], mimeType.c_str())) {
1697 LogWarning("mimeType blacklisted");
1698 //throw SecurityException
1703 ViewLogic* This = static_cast<ViewLogic*>(data);
1704 LogDebug("Creating handlers dao");
1705 This->attachToCustomHandlersDao();
1706 CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1707 CustomHandlerDB::CustomHandlerPtr handler =
1708 handlersDao.getContentHandler(customHandler->target,
1710 customHandler->base_url);
1711 if (handler && (handler->user_decision & CustomHandlerDB::DecisionSaved)) {
1712 LogDebug("Protocol already registered - nothing to do");
1714 LogDebug("Protocol handler not found");
1715 Wrt::Popup::PopupResponse response =
1716 GlobalSettings::PopupsTestModeEnabled() ? Wrt::Popup::
1718 Wrt::Popup::PopupInvoker().askYesNoCheckbox(
1719 CONTENT_HANDLER_ASK_TITLE,
1720 CONTENT_HANDLER_ASK_MSG,
1721 CONTENT_HANDLER_AKS_REMEMBER);
1722 saveUserResponse(response, customHandler);
1723 if (customHandler->user_decision == CustomHandlerDB::Declined) {
1726 handlersDao.registerContentHandler(*(customHandler.get()));
1727 if (customHandler->user_decision & CustomHandlerDB::Agreed) {
1728 //TODO remove old default handler somehow from appsvc
1729 LogDebug("Registering appservice entry");
1730 int ret = appsvc_set_defapp(APPSVC_OPERATION_VIEW,
1732 customHandler->target).c_str(),
1734 DPL::ToUTF8String(This->m_model->
1736 if (APPSVC_RET_OK != ret) {
1737 LogWarning("Appsvc entry failed: " << ret);
1740 LogDebug("Content saved");
1742 This->detachFromCustomHandlersDao();
1745 void ViewLogic::contentHandlerIsRegisteredCallback(void* data,
1746 Evas_Object* /*obj*/,
1750 CustomHandlerDB::CustomHandlerPtr customHandler =
1751 getCustomHandlerFromData(eventInfo);
1752 ViewLogic* This = static_cast<ViewLogic*>(data);
1753 LogDebug("Creating handlers dao");
1755 This->attachToCustomHandlersDao();
1756 CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1757 CustomHandlerDB::CustomHandlerPtr handler =
1758 handlersDao.getContentHandler(customHandler->target,
1760 customHandler->base_url);
1762 if (handler->user_decision & CustomHandlerDB::Agreed) {
1763 ewk_custom_handlers_data_result_set(
1764 static_cast<Ewk_Custom_Handlers_Data*>(data),
1765 EWK_CUSTOM_HANDLERS_REGISTERED);
1767 ewk_custom_handlers_data_result_set(
1768 static_cast<Ewk_Custom_Handlers_Data*>(data),
1769 EWK_CUSTOM_HANDLERS_DECLINED);
1772 ewk_custom_handlers_data_result_set(
1773 static_cast<Ewk_Custom_Handlers_Data*>(data),
1774 EWK_CUSTOM_HANDLERS_NEW);
1776 This->detachFromCustomHandlersDao();
1779 void ViewLogic::contentHandlerUnregistrationCallback(void* data,
1780 Evas_Object* /*obj*/,
1784 CustomHandlerDB::CustomHandlerPtr customHandler =
1785 getCustomHandlerFromData(eventInfo);
1786 ViewLogic* This = static_cast<ViewLogic*>(data);
1787 LogDebug("Creating handlers dao");
1788 This->attachToCustomHandlersDao();
1789 CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1790 CustomHandlerDB::CustomHandlerPtr handlerCheck =
1791 handlersDao.getContentHandler(customHandler->target,
1793 customHandler->base_url);
1795 if (handlerCheck->user_decision & CustomHandlerDB::Agreed) {
1796 appsvc_unset_defapp(DPL::ToUTF8String(This->m_model->TizenId).c_str());
1799 handlersDao.unregisterContentHandler(customHandler->target,
1801 customHandler->base_url);
1803 LogDebug("Nothing to unregister");
1805 This->detachFromCustomHandlersDao();
1808 void ViewLogic::didRunJavaScriptCallback(
1809 Evas_Object* /*obj*/,
1813 LogInfo("didRunJavaScriptCallback called");
1814 LogInfo("result = " << result);
1817 Eina_Bool ViewLogic::windowCloseIdlerCallback(void* data)
1819 LogDebug("closeIdlerCallback");
1820 ViewLogic* This = static_cast<ViewLogic*>(data);
1821 This->windowClose();
1822 return ECORE_CALLBACK_CANCEL;
1825 void ViewLogic::certificateConfirmRequestCallback(
1827 Evas_Object* /*obj*/,
1830 LogDebug("certificateConfirmRequestCallback called");
1833 ViewLogic* This = static_cast<ViewLogic*>(data);
1835 Ewk_Certificate_Policy_Decision* certificatePolicyDecision =
1836 static_cast<Ewk_Certificate_Policy_Decision*>(eventInfo);
1838 bool status = This->askUserForCertificateConfirm();
1840 ewk_certificate_policy_decision_allowed_set(
1841 certificatePolicyDecision,
1844 ewk_certificate_policy_decision_allowed_set(
1845 certificatePolicyDecision,
1850 bool ViewLogic::askUserForCertificateConfirm()
1852 return Wrt::Popup::PopupInvoker().askYesNo(
1853 CERTIFICATE_CONFIRM_REQUEST_ASK_TITLE,
1854 CERTIFICATE_CONFIRM_REQUEST_ASK_BODY);
1857 void ViewLogic::authenticationChallengeRequestCallback(
1859 Evas_Object* /*obj*/,
1862 LogDebug("authenticationChallengeRequestCallback called");
1865 ViewLogic* This = static_cast<ViewLogic*>(data);
1866 const char* url = ewk_view_url_get(This->m_currentEwkView);
1867 if (!url || strlen(url) == 0) {
1868 url = This->m_currentUri.c_str();
1871 ViewModule::AuthenticationChallengeSupport::authenticationChallengeRequest(
1872 This->m_currentEwkView,
1877 std::string ViewLogic::requestUrlBlocked(const std::string& blockedUrl)
1881 if (m_model->Type.Get().appType == WrtDB::APP_TYPE_TIZENWEBAPP) {
1882 // block this page and open it in browser
1883 LogDebug("Request was blocked by WARP: " << blockedUrl);
1884 LogDebug("open browser : " << blockedUrl);
1885 bundle* bundleData = bundle_create();
1886 appsvc_set_operation(bundleData, APPSVC_OPERATION_VIEW);
1887 appsvc_set_uri(bundleData, blockedUrl.c_str());
1888 CONTROLLER_POST_EVENT(
1889 ApplicationLauncher,
1890 ApplicationLauncherEvents::LaunchApplicationByAppService(
1896 // set block url. This is used on load finished callback
1897 m_blockedUri = blockedUrl;
1899 // This is used in case of returning previous page
1900 return URICHANGE_PLUGIN_NO_CHANGE;
1903 std::string ViewLogic::requestUrlChanged(const std::string& changedUrl)
1905 using namespace ViewModule::SecuritySupport;
1907 LogInfo("changed url: " << changedUrl);
1909 // Check if this url with 'http' or 'https' is included in whitelist,
1910 // which has lists of accessible external documents and
1911 // used for ONLY Tizen app
1912 std::string matchedScheme;
1913 std::string matchedUri;
1914 pcrecpp::RE(PATTERN_URI_CHANGE).PartialMatch(changedUrl.c_str(),
1917 ViewModule::Scheme scheme(matchedScheme);
1918 if (scheme.GetType() == ViewModule::Scheme::HTTP ||
1919 scheme.GetType() == ViewModule::Scheme::HTTPS)
1921 if (m_model->Type.Get().appType == WrtDB::APP_TYPE_TIZENWEBAPP) {
1922 if (!checkWhitelist(changedUrl.c_str())) {
1923 LogInfo("This uri is not included in white document list");
1924 return URICHANGE_PLUGIN_STOP_ONLY;
1926 LogInfo("This url is included in WhiteList");
1928 // For WAC app, WRT should block access of device api
1929 // for external documents
1930 return URICHANGE_PLUGIN_STOP_ONLY;
1934 m_currentUri = changedUrl;
1935 return URICHANGE_PLUGIN_RESTART;
1938 void ViewLogic::windowClose()
1940 LogDebug("windowClose");
1941 Assert(m_closedEwkView && "no closed webview");
1943 if (1 >= m_ewkViewList.size()) {
1944 if (!m_cbs->webkitExit.empty()) {
1945 m_cbs->webkitExit();
1948 // call user callbacks
1949 if (!m_cbs->bufferUnset.empty()) {
1950 m_cbs->bufferUnset(m_currentEwkView);
1952 if (!m_cbs->windowClose.empty()) {
1953 m_cbs->windowClose(m_closedEwkView);
1955 removeEwkView(m_closedEwkView);
1957 // get latest ewkView
1958 m_currentEwkView = m_ewkViewList.back();
1959 const char* uri = ewk_view_url_get(m_currentEwkView);
1960 if (NULL == uri || 0 == strlen(uri)) {
1961 m_currentUri.clear();
1967 /* In case we support many pages in parallel
1968 * then view is not suspended*/
1969 //resumeEwkView(m_currentEwkView);
1970 setEwkViewVisible(m_currentEwkView);
1973 if (!m_cbs->bufferSet.empty()) {
1974 m_cbs->bufferSet(m_currentEwkView);