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_scheme_support.h>
55 #include <view_logic_filesystem_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 <view_logic_web_storage_support.h>
60 #include "bundles/plugin_module_support.h"
61 #include <popup-runner/PopupInvoker.h>
64 #include <js_overlay_types.h>
65 #include <i_runnable_widget_object.h>
66 #include <profiling_util.h>
67 #include <wrt-commons/custom-handler-dao-ro/common_dao_types.h>
68 #include <wrt-commons/custom-handler-dao-ro/CustomHandlerDatabase.h>
69 #include <wrt-commons/custom-handler-dao-ro/custom_handler_dao_read_only.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 { "request,geolocation,permission",
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 { "database,quota,exceeded",
132 &ViewLogic::databaseUsagePermissionRequestCallback },
133 { "filesystem,permission,request",
134 &ViewLogic::fileSystemPermissionRequestCallback },
135 { "fullscreen,enterfullscreen", &ViewLogic::enterFullscreenCallback },
136 { "fullscreen,exitfullscreen", &ViewLogic::exitFullscreenCallback },
138 // when ime start to be showed on the webview,
139 // this callback will be called
140 { "inputmethod,changed", &ViewLogic::imeChangedCallback },
141 // this callback will be called
142 // when ime finishes to be showed on the webview
143 // "event_info" arg of this callback is always NULL point
144 // if web content should know size of ime,
145 // use "inputmethod,changed" instead of this.
147 { "editorclient,ime,opened", &ViewLogic::imeOpenedCallback },
148 // when ime finished to be hidden,
149 // this callback will be called
150 { "editorclient,ime,closed", &ViewLogic::imeClosedCallback },
151 // EWK Usermedia Callback
152 { "usermedia,permission,request",
153 &ViewLogic::usermediaPermissionRequestCallback },
155 { "protocolhandler,registration,requested",
156 &ViewLogic::protocolHandlerRegistrationCallback },
157 { "protocolhandler,isregistered",
158 &ViewLogic::protocolHandlerIsRegisteredCallback },
159 { "protocolhandler,unregistration,requested",
160 &ViewLogic::protocolHandlerUnregistrationCallback },
161 { "contenthandler,registration,requested",
162 &ViewLogic::contentHandlerRegistrationCallback },
163 { "contenthandler,isregistered",
164 &ViewLogic::contentHandlerIsRegisteredCallback },
165 { "contenthandler,unregistration,requested",
166 &ViewLogic::contentHandlerUnregistrationCallback },
167 { "request,certificate,confirm",
168 &ViewLogic::certificateConfirmRequestCallback }
171 ViewLogic::ViewLogic() :
176 m_cbs(new WRT::UserDelegates),
177 m_isBackgroundReload(false),
178 m_isBackgroundSupport(false),
179 m_appsSupport(new ViewModule::AppsSupport()),
180 m_vibrationSupport(new ViewModule::VibrationSupport()),
181 m_attachedToCustomHandlerDao(false)
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 = ViewModule::UriSupport::getUri(m_model, 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.size()) {
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 LogDebug("Request bundle to suspend");
275 PluginModuleSupport::suspend(m_ewkContext);
277 if (!m_currentEwkView) {
278 LogWarning("Cannot suspend widget without view");
280 setEwkViewInvisible(m_currentEwkView);
281 if (!m_isBackgroundSupport) {
282 suspendWebkit(m_currentEwkView);
286 evas_object_focus_set(m_currentEwkView, EINA_FALSE);
288 // call user callback
289 if (!m_cbs->suspend.empty()) {
290 m_cbs->suspend(true);
294 void ViewLogic::resumeWidget()
296 LogInfo("Resume widget");
299 LogDebug("Request bundle to resume");
300 PluginModuleSupport::resume(m_ewkContext);
302 if (m_currentEwkView) {
303 setEwkViewVisible(m_currentEwkView);
304 if (!m_isBackgroundSupport) {
305 resumeWebkit(m_currentEwkView);
309 /* window system team recomend removing this win_raise code. */
312 * elm_win_raise(m_window);
315 evas_object_focus_set(m_currentEwkView, EINA_TRUE);
317 // call user callback
318 if (!m_cbs->resume.empty()) {
323 void ViewLogic::resetWidget()
325 LogInfo("Resetting Widget");
327 // destory all webview
328 while (m_ewkViewList.size()) {
329 LogInfo("pop webview: " << m_ewkViewList.back());
330 removeEwkView(m_ewkViewList.back());
332 m_ewkViewList.clear();
334 // create new webview
335 createEwkView(evas_object_evas_get(m_window));
337 ewkClientInit(m_currentEwkView);
338 prepareEwkView(m_currentEwkView);
340 // check if current url is service url for this tizen service
341 std::string requestedUri =
342 ViewModule::UriSupport::getUri(m_model, m_startUrl);
343 DPL::OptionalString servicedUri = ViewModule::UriSupport::localizeURI(
344 DPL::FromUTF8String(requestedUri.c_str()),
347 initializePluginLoading();
350 PluginModuleSupport::resume(m_ewkContext);
351 m_currentUri = DPL::ToUTF8String(*servicedUri);
352 ewk_view_url_set(m_currentEwkView, m_currentUri.c_str());
353 elm_win_activate(m_window);
354 evas_object_focus_set(m_currentEwkView, EINA_TRUE);
356 // call user callback
357 if (!m_cbs->reset.empty()) {
360 if (!m_cbs->bufferSet.empty()) {
361 m_cbs->bufferSet(m_currentEwkView);
365 void ViewLogic::backward()
367 if (ewk_view_back_possible(m_currentEwkView)) {
368 ewk_view_back(m_currentEwkView);
370 if (1 >= m_ewkViewList.size()) {
371 // If there is no previous page, widget move to backgroud.
372 LogInfo("Widget move to backgroud");
373 elm_win_lower(m_window);
375 // Back to previous webview
376 LogInfo("Widget move to previous webview");
377 m_closedEwkView = m_currentEwkView;
378 ecore_idler_add(windowCloseIdlerCallback, this);
383 void ViewLogic::reloadStartPage()
385 LogInfo("Reload Start Page");
386 // prevent fail to load plugin bundle side
387 m_isBackgroundReload = true;
388 PluginModuleSupport::resume(m_ewkContext);
390 if (m_ewkViewList.size() != 0) {
391 while (m_ewkViewList.size() > 0) {
392 if (!m_cbs->bufferUnset.empty()) {
393 m_cbs->bufferUnset(m_currentEwkView);
395 removeEwkView(m_currentEwkView);
399 // create new webview
400 createEwkView(evas_object_evas_get(m_window));
401 ewkClientInit(m_currentEwkView);
404 prepareEwkView(m_currentEwkView);
405 initializePluginLoading();
408 ewk_view_url_set(m_currentEwkView, m_currentUri.c_str());
411 if (!m_cbs->bufferSet.empty()) {
412 m_cbs->bufferSet(m_currentEwkView);
414 LogInfo("Reloading Start Page is done!");
417 Evas_Object* ViewLogic::getCurrentWebview()
419 LogInfo("get current webview");
420 return m_currentEwkView;
423 void ViewLogic::fireJavascriptEvent(int event, void* data)
425 PluginModuleSupport::dispatchJavaScriptEvent(
427 static_cast<WrtPlugins::W3C::CustomEventType>(event),
431 void ViewLogic::setUserCallbacks(const WRT::UserDelegatesPtr& cbs)
436 void ViewLogic::checkSyncMessageFromBundle(
441 LogDebug("didReceiveSynchronousMessage called");
446 LogDebug("body is empty");
451 LogDebug("received : " << name);
453 if (!strcmp(name, uriBlockedMessageName)) {
454 // Currently WebProcess informs obly about blocked
455 // URI - URI localization and security chekcs are
456 // done by WebProcess itself (see: wrt-wk2-bundle.cpp
457 // and bundle_uri_handling.cpp)
458 result = requestUrlBlocked(std::string(body));
459 } else if (!strcmp(name, uriChangedMessageName)) {
460 result = requestUrlChanged(std::string(body));
463 *returnData = strdup(result.c_str());
466 void ViewLogic::downloadData(const char* url)
473 m_appsSupport->downloadRequest(url, NULL, NULL);
476 void ViewLogic::activateVibration(bool on, uint64_t time)
480 m_vibrationSupport->startVibration(static_cast<long>(time));
482 m_vibrationSupport->stopVibration();
486 void ViewLogic::initializeSupport()
488 // background support
489 if (m_model->SettingList.Get().getBackgroundSupport()
490 == BackgroundSupport_Enable)
492 LogDebug("Background support enabled, set process active");
493 pid_t pid = getpid();
494 sysman_inform_active(pid);
495 m_isBackgroundSupport = true;
497 #ifndef DEPRECATED_SETTING_STRING
499 WrtDB::WidgetDAOReadOnly dao(m_model->TizenId);
500 WrtDB::PropertyDAOReadOnly::WidgetPropertyValue bgEnableValue =
501 dao.getPropertyValue(DPL::String(BACKGROUND_ENABLED));
503 if (!bgEnableValue.IsNull() && !bgEnableValue->compare(L"true")) {
505 LogDebug("Background support enabled, set process active");
506 pid_t pid = getpid();
507 sysman_inform_active(pid);
508 m_isBackgroundSupport = true;
513 m_schemeSupport.reset(new SchemeSupport(m_model->Type.Get().appType));
514 ViewModule::StorageSupport::initializeStorage(m_model);
515 m_appsSupport->initialize(m_model);
516 m_securityOriginSupport.reset(new ViewModule::SecurityOriginSupport(m_model));
518 m_vibrationSupport->initialize();
521 void ViewLogic::initializePluginLoading()
523 // inform wrt information for plugin loading to web process
524 PluginModuleSupport::start(
527 elm_config_scale_get(),
528 ApplicationDataSingleton::Instance().getEncodedBundle(),
530 m_model->SettingList.Get().isEncrypted());
533 void ViewLogic::ewkClientInit(Evas_Object *wkView)
535 Assert(NULL != wkView && "ewk_view not created at this point");
537 FOREACH(it, m_ewkCallbacksMap) {
538 evas_object_smart_callback_add(
544 // EWK Orientation Callback
545 ewk_view_orientation_lock_callback_set(
547 orientationLockCallback,
551 void ViewLogic::ewkClientDeinit(Evas_Object *wkView)
553 LogDebug("ewkClientDeinit");
554 Assert(NULL != wkView && "ewk_view not created at this point");
556 FOREACH(it, m_ewkCallbacksMap) {
557 evas_object_smart_callback_del(
562 ewk_view_orientation_lock_callback_set(
568 bool ViewLogic::createEwkView(Evas* canvas)
570 LogDebug("createEwkVeiw");
572 ADD_PROFILING_POINT("ewk_view_add_with_context", "start");
573 Evas_Object* newEwkView = ewk_view_add_with_context(
576 ADD_PROFILING_POINT("ewk_view_add_with_context", "stop");
579 LogError("View creation failed");
580 Wrt::Popup::PopupInvoker().showInfo(
581 "Info", "View creation failed", "close");
586 // even arguments pass the ewkContext, this API should be called
587 // after webkit Evas_Object is created
588 Ewk_Cookie_Manager *ewkCookieManager;
590 ewk_context_cookie_manager_get(m_ewkContext);
591 ewk_cookie_manager_accept_policy_set(ewkCookieManager,
592 EWK_COOKIE_ACCEPT_POLICY_ALWAYS);
594 if (m_currentEwkView) {
595 setEwkViewInvisible(m_currentEwkView);
598 LogInfo("push webview: " << newEwkView);
599 m_ewkViewList.push_back(newEwkView);
600 m_currentEwkView = newEwkView;
604 void ViewLogic::setStartPage()
606 /* Start URI (as other uris) is now localized
607 * on WebProcess side */
608 m_currentUri = m_startUrl;
611 void ViewLogic::prepareEwkView(Evas_Object *wkView)
613 LogDebug("prepareEwkView called");
615 Ewk_Settings* settings = ewk_view_settings_get(wkView);
618 std::string customUserAgent = m_model->SettingList.Get().getUserAgent();
619 if (customUserAgent.empty()) {
620 auto userAgentString =
621 ViewModule::UserAgentSupport::getUserAgentFromVconf();
622 if (!userAgentString.empty()) {
623 LogDebug("Setting user agent as: " << userAgentString);
624 ewk_view_user_agent_set(wkView, userAgentString.c_str());
627 LogDebug("Setting custom user agent as: " << customUserAgent);
628 ewk_view_user_agent_set(wkView, customUserAgent.c_str());
631 // set custom header : language
632 using namespace ViewModule::CustomHeaderSupport;
633 std::string customHeaderString = getValueByField(ACCEPT_LANGUAGE);
634 if (!customHeaderString.empty()) {
635 LogDebug("custom field=[" << ACCEPT_LANGUAGE << "]");
636 LogDebug("custom value=[" << customHeaderString << "]");
637 ewk_view_custom_header_add(wkView,
638 ACCEPT_LANGUAGE.c_str(),
639 customHeaderString.c_str());
642 // webkit NPAPI plugins is always on in wrt
643 ewk_settings_plugins_enabled_set(settings, EINA_TRUE);
645 // The followings are not implemeted yet by webkit2
646 // ewk_view_setting_accelerated_compositing_enable_set(EINA_TRUE);
647 // ewk_view_mode_set();
648 // ewk_view_setting_enable_specified_plugin_set(EINA_TRUE,
650 // ewk_view_setting_html5video_external_player_enable_set(EINA_FALSE);
651 // ewk_view_show_ime_on_autofocus_set(EINA_TRUE);
652 // elm_webview_show_magnifier_set(EINA_FALSE);
653 ewk_settings_javascript_enabled_set(settings, EINA_TRUE);
654 ewk_settings_loads_images_automatically_set(settings, EINA_TRUE);
655 ewk_settings_auto_fitting_set(settings, EINA_TRUE);
657 // disable zoom option when user click the input field
658 // this option is useful with the normal website
659 // for the make user friendly, disable auto zoom in the webapp
660 // The followings are not implemeted yet by webkit2
661 // elm_webview_input_field_zoom_set(EINA_FALSE);
663 // set cookie database path
664 // The followings are not implemeted yet by webkit2
665 // ewk_cookies_file_set(dao.getCookieDatabasePath().c_str()));
667 // set visibility to WebCore. This value will be used for html5.
668 // also, this value will be changed in the suspend, resume
669 // or create window, close window.
670 ewk_view_page_visibility_state_set(wkView,
671 EWK_PAGE_VISIBILITY_STATE_VISIBLE,
675 void ViewLogic::removeEwkView(Evas_Object *wkView)
677 LogInfo("removeEwkView called");
679 Assert(0 != m_ewkViewList.size());
681 // unregister webview callbacks
682 ewkClientDeinit(wkView);
684 // suspend NPAPI plugin - Not implemented by Webkit2
685 // ewk_view_pause_or_resume_plugins();
686 evas_object_del(wkView);
687 m_ewkViewList.remove(wkView);
690 void ViewLogic::resumeEwkView(Evas_Object *wkView)
692 LogInfo("resumeEwkView called");
695 // register webview callback
696 ewkClientInit(wkView);
699 resumeWebkit(wkView);
704 void ViewLogic::suspendEwkView(Evas_Object *wkView)
706 LogInfo("suspendEwkView called");
710 suspendWebkit(wkView);
712 // unregister webview callbacks
713 ewkClientDeinit(wkView);
718 void ViewLogic::setEwkViewInvisible(Evas_Object *wkView)
720 LogInfo("setEwkViewInvisible called");
723 ewk_view_page_visibility_state_set(wkView,
724 EWK_PAGE_VISIBILITY_STATE_HIDDEN,
726 ewk_view_visibility_set(wkView, EINA_FALSE);
729 void ViewLogic::setEwkViewVisible(Evas_Object *wkView)
731 LogInfo("setEwkViewVisible called");
734 ewk_view_page_visibility_state_set(wkView,
735 EWK_PAGE_VISIBILITY_STATE_VISIBLE,
737 ewk_view_visibility_set(wkView, EINA_TRUE);
740 void ViewLogic::resumeWebkit(Evas_Object *wkView)
742 LogDebug("resumeWebkit");
745 // resume NPAPI plugin
746 // The followings are not implemeted yet by webkit2
747 // ewk_view_pause_or_resume_plugins(false);
748 // ewk_view_pause_or_resume_video_audio(false);
749 // ewk_view_javascript_resume();
750 // ewk_view_enable_render();
751 // ewk_view_reduce_plugins_frame_rate(false);
752 ewk_view_resume(wkView);
757 void ViewLogic::suspendWebkit(Evas_Object *wkView)
759 LogDebug("suspendWebkit");
762 // suspend the followings
763 // The followings are not implemeted yet by webkit2
764 // ewk_view_pause_or_resume_plugins(true);
765 // ewk_view_pause_or_resume_video_audio(true);
766 ewk_view_suspend(wkView);
771 void ViewLogic::loadStartedCallback(
776 LogDebug("loadStartedCallback called");
778 ViewLogic* This = static_cast<ViewLogic*>(data);
779 evas_object_focus_set(This->m_currentEwkView, EINA_TRUE);
781 // call loadFinish callback to wrt-client
782 if (!This->m_cbs->loadStart.empty()) {
783 This->m_cbs->loadStart(obj);
787 void ViewLogic::loadFinishedCallback(
792 LogDebug("loadFinishedCallback called");
794 ViewLogic* This = static_cast<ViewLogic*>(data);
797 const char* url = ewk_view_url_get(This->m_currentEwkView);
798 if (NULL == url || strlen(url) == 0) {
799 LogError("url is empty");
803 // check if this loading is for blocked url
804 if (This->m_blockedUri == url) {
805 if (ewk_view_back_possible(This->m_currentEwkView)) {
806 // go back to previous page
807 LogDebug("go to previous page");
808 ewk_view_back(This->m_currentEwkView);
811 LogDebug("remove current page");
812 ewk_view_stop(This->m_currentEwkView);
813 ecore_idler_add(windowCloseIdlerCallback, This);
815 This->m_blockedUri = std::string();
819 DPL::OptionalString jsOptionalString =
820 ViewModule::PasswordSupport::jsForAutoFillData(url);
821 if (jsOptionalString.IsNull()) {
822 LogError("Fail to get JS String");
824 std::string jsStr = DPL::ToUTF8String(*jsOptionalString).c_str();
826 if (EINA_FALSE == ewk_view_script_execute(
827 This->m_currentEwkView,
829 didRunJavaScriptCallback,
832 LogError("JS for auto fill data failed.");
836 // call loadFinish callback to wrt-client
837 if (!This->m_cbs->loadFinish.empty()) {
838 This->m_cbs->loadFinish(obj);
841 // set only encoded bundle
842 double scale = elm_config_scale_get();
843 PluginModuleSupport::setCustomProperties(
846 ApplicationDataSingleton::Instance().getEncodedBundle());
847 // check if 'appsevice' event is registed at the current frames.
848 // If so, dispatch the event to frames.
849 PluginModuleSupport::dispatchJavaScriptEvent(
851 WrtPlugins::W3C::ServiceCustomEvent,
854 // In this case, widget is reloaded in the background.
855 // After finished load, bundle should disconnent callback.
856 if (This->m_isBackgroundReload) {
857 PluginModuleSupport::suspend(This->m_ewkContext);
858 ewk_view_suspend(This->m_currentEwkView);
859 This->m_isBackgroundReload = false;
863 void ViewLogic::titleChangedCallback(
865 Evas_Object* /*obj*/,
868 LogDebug("titleChangedCallback called");
870 ViewLogic* This = static_cast<ViewLogic*>(data);
872 const char* title = static_cast<char*>(eventInfo);
874 if (0 == strlen(title)) {
875 LogDebug("title data is empty");
878 LogDebug("Title = [" << title << "]");
879 This->m_schemeSupport->HandleTizenScheme(title,
881 This->m_currentEwkView);
884 void ViewLogic::loadProgressCallback(
886 Evas_Object* /*obj*/,
889 double* progress = static_cast<double*>(eventInfo);
890 LogDebug("didChangeProgressCallback progress = " << *progress);
893 void ViewLogic::loadProgressFinishedCallback(
895 Evas_Object* /*obj*/,
898 LogDebug("didFinishProgressCallback");
900 ViewLogic const * const view = static_cast<ViewLogic const * const>(data);
901 if (!view->m_cbs->progressFinish.empty()) {
902 view->m_cbs->progressFinish();
906 void ViewLogic::processCrashedCallback(
908 Evas_Object* /*obj*/,
911 LogInfo("processCrashedCallback");
913 ViewLogic const * const view =
914 static_cast<ViewLogic const * const>(data);
915 if (!view->m_cbs->webCrash.empty()) {
916 view->m_cbs->webCrash();
918 // This flag will be prevented exit() call in the Webkit side
919 if (NULL != eventInfo) {
920 *(static_cast<Eina_Bool*>(eventInfo)) = EINA_TRUE;
924 void ViewLogic::createWindowCallback(
929 LogDebug("createWindowCallback");
931 ViewLogic* This = static_cast<ViewLogic*>(data);
933 // First, current webview should be handled by user callback
934 if (!This->m_cbs->bufferUnset.empty()) {
935 This->m_cbs->bufferUnset(obj);
938 // this can be set by executable for specific purpose
940 if (!This->m_cbs->windowCreateBefore.empty()) {
941 // 'obj' is parent webview object
942 This->m_cbs->windowCreateBefore(&canvas, obj);
945 canvas = evas_object_evas_get(This->m_window);
948 // create new ewkview
949 This->createEwkView(canvas);
950 Evas_Object* newEwkView = This->m_currentEwkView;
952 // initialize new ewkview
953 This->setStartPage();
954 This->ewkClientInit(newEwkView);
955 This->prepareEwkView(newEwkView);
957 // Specific jobs of child, parent webview are handled by each executable
958 if (!This->m_cbs->windowCreateAfter.empty()) {
959 // 'obj' is parent webview, 'newEwkView' is child webview
960 This->m_cbs->windowCreateAfter(obj, newEwkView);
963 // Lastly, new webview should be handled by user callback
964 if (!This->m_cbs->bufferSet.empty()) {
965 This->m_cbs->bufferSet(newEwkView);
967 *(static_cast<Evas_Object **>(eventInfo)) = newEwkView;
970 void ViewLogic::closeWindowCallback(
975 LogDebug("closeWindowCallback");
976 ViewLogic* This = static_cast<ViewLogic*>(data);
977 This->m_closedEwkView = obj;
978 ecore_idler_add(windowCloseIdlerCallback, This);
981 void ViewLogic::policyNavigationDecideCallback(
983 Evas_Object* /*obj*/,
986 LogDebug("policyNavigationDecideCallback called");
988 ViewLogic* This = static_cast<ViewLogic*>(data);
990 Ewk_Policy_Decision* policyDecision =
991 static_cast<Ewk_Policy_Decision*>(eventInfo);
993 if (This->m_schemeSupport->filterURIByScheme(policyDecision,
997 This->m_currentEwkView))
1000 ewk_policy_decision_use(policyDecision);
1002 // check whether this is new empty window
1003 const char* activeUrl = ewk_view_url_get(This->m_currentEwkView);
1004 if (!activeUrl || 0 == strlen(activeUrl)) {
1006 * The view is empty and scheme has been handled externally. When
1007 * user gets back from the external application he'd see blank page
1008 * and won't be able to navigate back. This happens when window.open
1009 * is used to handle schemes like sms/mms/mailto (for example in
1010 * WAC web standards tests: WS-15XX).
1012 * To solve the problem, the empty view is removed from the stack
1013 * and the previous one is shown. This is not an elegant solution
1014 * but we don't have a better one.
1016 LogInfo("Scheme has been handled externally. Removing empty view.");
1017 if (ewk_view_back_possible(This->m_currentEwkView)) {
1018 // go back to previous WKPage
1019 ewk_view_back(This->m_currentEwkView);
1021 // stop current WKPage
1022 ewk_view_stop(This->m_currentEwkView);
1023 ecore_idler_add(windowCloseIdlerCallback, This);
1028 ewk_policy_decision_ignore(policyDecision);
1032 void ViewLogic::policyNewWindowDecideCallback(
1034 Evas_Object* /*obj*/,
1037 LogDebug("policyNewWindowDecideCallback called");
1039 ViewLogic* This = static_cast<ViewLogic*>(data);
1041 Ewk_Policy_Decision* policyDecision =
1042 static_cast<Ewk_Policy_Decision*>(eventInfo);
1044 if (This->m_schemeSupport->filterURIByScheme(policyDecision,
1048 This->m_currentEwkView))
1050 ewk_policy_decision_use(policyDecision);
1053 ewk_policy_decision_ignore(policyDecision);
1057 void ViewLogic::pageResponseDecideCallback(
1059 Evas_Object* /*obj*/,
1062 LogDebug("pageResponseDecideCallback called");
1064 ViewLogic* This = static_cast<ViewLogic*>(data);
1066 Ewk_Policy_Decision* policyDecision =
1067 static_cast<Ewk_Policy_Decision*>(eventInfo);
1068 Ewk_Policy_Decision_Type policyDecisionType =
1069 ewk_policy_decision_type_get(policyDecision);
1071 if (policyDecisionType == EWK_POLICY_DECISION_USE) {
1073 ewk_policy_decision_use(policyDecision);
1074 } else if (policyDecisionType == EWK_POLICY_DECISION_DOWNLOAD) {
1075 LogDebug("download");
1076 ewk_policy_decision_suspend(policyDecision);
1078 // get uri information
1079 const char* url = ewk_policy_decision_url_get(policyDecision);
1080 if (NULL == url || strlen(url) == 0) {
1081 LogDebug("url data is empty");
1082 ewk_policy_decision_use(policyDecision);
1085 LogDebug("url = [" << url << "]");
1087 // get content information
1088 const char* content =
1089 ewk_policy_decision_response_mime_get(policyDecision);
1090 LogDebug("content type = [" << content << "]");
1092 // get cookie information
1093 const char* cookie = ewk_policy_decision_cookie_get(policyDecision);
1094 LogDebug("cookie = [" << cookie << "]");
1096 LogDebug("Content not supported, will be opened in external app");
1097 This->m_appsSupport->downloadRequest(
1101 ewk_policy_decision_ignore(policyDecision);
1102 } else if (policyDecisionType == EWK_POLICY_DECISION_IGNORE) {
1104 ewk_policy_decision_ignore(policyDecision);
1106 LogDebug("Type isn't handled");
1107 ewk_policy_decision_ignore(policyDecision);
1111 void ViewLogic::contextmenuCustomizeCallback(
1113 Evas_Object* /*obj*/,
1116 LogDebug("contextmenuCustomizeCallback called");
1119 ViewLogic* This = static_cast<ViewLogic*>(const_cast<void*>(data));
1120 Ewk_Context_Menu* menu = static_cast<Ewk_Context_Menu*>(eventInfo);
1121 if ((This->m_model->Type.Get().appType == WrtDB::APP_TYPE_TIZENWEBAPP) &&
1122 (This->m_model->SettingList.Get().getContextMenu()
1123 == ContextMenu_Disable))
1125 LogDebug("ContextMenu Disable!!");
1126 for (unsigned int idx = 0; idx < ewk_context_menu_item_count(menu);) {
1127 Ewk_Context_Menu_Item* item = ewk_context_menu_nth_item_get(menu,
1130 ewk_context_menu_item_remove(menu, item);
1133 LogDebug("ContextMenu Enable!!");
1134 unsigned int menu_num = ewk_context_menu_item_count(menu);
1135 unsigned int idx = 0;
1137 Ewk_Context_Menu_Item* item = ewk_context_menu_nth_item_get(menu,
1143 Ewk_Context_Menu_Item_Tag tag = ewk_context_menu_item_tag_get(item);
1146 case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_IMAGE_IN_NEW_WINDOW:
1147 ewk_context_menu_item_remove(menu, item);
1150 case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_LINK_IN_NEW_WINDOW:
1151 ewk_context_menu_item_remove(menu, item);
1154 case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_FRAME_IN_NEW_WINDOW:
1155 ewk_context_menu_item_remove(menu, item);
1158 case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_MEDIA_IN_NEW_WINDOW:
1159 ewk_context_menu_item_remove(menu, item);
1162 case EWK_CONTEXT_MENU_ITEM_TAG_SEARCH_WEB:
1163 ewk_context_menu_item_remove(menu, item);
1170 } while (idx < menu_num);
1174 void ViewLogic::formSubmitCallback(
1176 Evas_Object* /*obj*/,
1179 LogDebug("formSubmitCallback called");
1181 Ewk_Form_Data* formData = static_cast<Ewk_Form_Data*>(eventInfo);
1183 const char* uri = ewk_form_data_url_get(formData);
1185 LogError("URL is empty");
1189 Eina_Hash* userData = ewk_form_data_values_get(formData);
1190 ViewModule::PasswordSupport::submitClicked(uri, userData);
1193 void ViewLogic::geolocationPermissionRequestCallback(
1195 Evas_Object* /*obj*/,
1199 ViewLogic* This = static_cast<ViewLogic*>(data);
1201 Ewk_Geolocation_Permission_Data* permissionRequest =
1202 static_cast<Ewk_Geolocation_Permission_Data*>(eventInfo);
1204 if (This->m_securityOriginSupport->isNeedPermissionCheck(
1205 SecurityOriginDB::FEATURE_GEOLOCATION)
1206 == WrtDB::SETTINGS_TYPE_OFF)
1208 ewk_geolocation_permission_request_allow_set(
1209 ewk_geolocation_permission_request_get(permissionRequest),
1213 ViewModule::GeolocationSupport::Webkit2::geolocationPermissionRequest(
1215 This->m_securityOriginSupport->getSecurityOriginDAO(),
1219 void ViewLogic::notificationShowCallback(
1221 Evas_Object* /*obj*/,
1224 LogDebug("notificationShowCallback called");
1226 ViewLogic* This = static_cast<ViewLogic*>(data);
1229 Ewk_Notification* noti = static_cast<Ewk_Notification*>(eventInfo);
1231 using namespace ViewModule::WebNotification;
1233 WebNotificationDataPtr notiData(
1234 new WebNotificationData(
1236 ewk_notification_id_get(noti)));
1238 DPL::OptionalString string =
1239 DPL::FromUTF8String(ewk_notification_icon_url_get(noti));
1240 if (!string.IsNull()) {
1241 notiData->m_iconURL = DPL::ToUTF8String(*string);
1243 string = DPL::FromUTF8String(ewk_notification_title_get(noti));
1244 if (!string.IsNull()) {
1245 notiData->m_title = DPL::ToUTF8String(*string);
1247 string = DPL::FromUTF8String(ewk_notification_body_get(noti));
1248 if (!string.IsNull()) {
1249 notiData->m_body = DPL::ToUTF8String(*string);
1252 LogInfo("notification id : " << notiData->m_id);
1253 LogInfo("notification iconURL : " << notiData->m_iconURL);
1254 LogInfo("notification title : " << notiData->m_title);
1255 LogInfo("notification body : " << notiData->m_body);
1257 showWebNotification(notiData);
1258 ewk_notification_showed(This->m_ewkContext, ewk_notification_id_get(noti));
1261 void ViewLogic::notificationCancelCallback(
1263 Evas_Object* /*obj*/,
1264 void* /*eventInfo*/)
1266 LogDebug("notificationCancelCallback called");
1269 void ViewLogic::notificationPermissionRequestCallback(
1271 Evas_Object* /*obj*/,
1274 LogDebug("notificationPermissionRequestCallback called");
1276 ViewLogic* This = static_cast<ViewLogic*>(data);
1277 if (This->m_securityOriginSupport->isNeedPermissionCheck(
1278 SecurityOriginDB::FEATURE_WEB_NOTIFICATION)
1279 == WrtDB::SETTINGS_TYPE_OFF)
1281 Ewk_Notification_Permission_Request* request =
1282 static_cast<Ewk_Notification_Permission_Request*>(eventInfo);
1283 ewk_notification_permission_request_response(
1291 ViewModule::WebNotification::webNotificationPermissionRequest(
1293 This->m_securityOriginSupport->getSecurityOriginDAO(),
1299 // EWK Orientation Callback
1300 Eina_Bool ViewLogic::orientationLockCallback(
1302 Eina_Bool /*needLock*/,
1306 LogDebug("orientationLockCallback called");
1308 ViewLogic* This = static_cast<ViewLogic*>(data);
1310 if (orientation & EWK_SCREEN_ORIENTATION_PORTRAIT_PRIMARY) {
1311 LogDebug("orientation is portrait-primary");
1312 elm_win_rotation_with_resize_set(This->m_window, 0);
1313 ewk_view_orientation_send(obj, 0);
1314 } else if (orientation & EWK_SCREEN_ORIENTATION_LANDSCAPE_PRIMARY) {
1315 LogDebug("orientation is landscape-primary");
1316 elm_win_rotation_with_resize_set(This->m_window, 270);
1317 ewk_view_orientation_send(obj, 90);
1318 } else if (orientation & EWK_SCREEN_ORIENTATION_PORTRAIT_SECONDARY) {
1319 LogDebug("orientation is portrait-secondary");
1320 elm_win_rotation_with_resize_set(This->m_window, 180);
1321 ewk_view_orientation_send(obj, 180);
1322 } else if (orientation & EWK_SCREEN_ORIENTATION_LANDSCAPE_SECONDARY) {
1323 LogDebug("orientation is landscape-secondary");
1324 elm_win_rotation_with_resize_set(This->m_window, 90);
1325 ewk_view_orientation_send(obj, -90);
1327 LogDebug("Wrong orientation is set");
1333 // Fullscreen API callbacks
1334 void ViewLogic::enterFullscreenCallback(
1336 Evas_Object* /*obj*/,
1337 void* /*eventInfo*/)
1339 LogInfo("enterFullscreenCallback called");
1341 ViewLogic* This = static_cast<ViewLogic*>(data);
1342 if (!This->m_cbs->toggleFullscreen.empty()) {
1343 This->m_cbs->toggleFullscreen(true);
1346 void ViewLogic::exitFullscreenCallback(
1348 Evas_Object* /*obj*/,
1349 void* /*eventInfo*/)
1351 LogInfo("exitFullscreenCallback called");
1353 ViewLogic* This = static_cast<ViewLogic*>(data);
1354 if (!This->m_cbs->toggleFullscreen.empty()) {
1355 This->m_cbs->toggleFullscreen(false);
1359 void ViewLogic::imeChangedCallback(
1361 Evas_Object* /*obj*/,
1367 ViewLogic* This = static_cast<ViewLogic*>(data);
1368 Eina_Rectangle *rect = static_cast<Eina_Rectangle *>(eventInfo);
1369 This->m_imeWidth = rect->w;
1370 This->m_imeHeight = rect->h;
1373 void ViewLogic::imeOpenedCallback(
1375 Evas_Object* /*obj*/,
1376 void* /*eventInfo*/)
1380 ViewLogic* This = static_cast<ViewLogic*>(data);
1382 using namespace WrtPlugins::W3C;
1383 SoftKeyboardChangeArgs args;
1384 args.state = IME_STATE_ON;
1385 args.width = This->m_imeWidth;
1386 args.height = This->m_imeHeight;
1387 This->fireJavascriptEvent(
1388 static_cast<int>(SoftKeyboardChangeCustomEvent),
1392 void ViewLogic::imeClosedCallback(
1394 Evas_Object* /*obj*/,
1395 void* /*eventInfo*/)
1399 ViewLogic* This = static_cast<ViewLogic*>(data);
1401 using namespace WrtPlugins::W3C;
1402 SoftKeyboardChangeArgs args;
1403 args.state = IME_STATE_OFF;
1405 This->fireJavascriptEvent(
1406 static_cast<int>(SoftKeyboardChangeCustomEvent),
1410 void ViewLogic::usermediaPermissionRequestCallback(
1412 Evas_Object* /*obj*/,
1415 LogDebug("usermediaPermissionRequestCallback called");
1417 ViewLogic* This = static_cast<ViewLogic*>(data);
1418 ViewModule::UsermediaSupport::usermediaPermissionRequest(This->m_window,
1423 CustomHandlerDB::CustomHandlerPtr getCustomHandlerFromData(void* data)
1426 Ewk_Custom_Handlers_Data* handler =
1427 static_cast<Ewk_Custom_Handlers_Data*>(data);
1428 CustomHandlerDB::CustomHandlerPtr customHandler(
1429 new CustomHandlerDB::CustomHandler());
1430 const char* base_url = ewk_custom_handlers_data_base_url_get(handler);
1432 LogDebug("base url: " << base_url);
1433 customHandler->base_url = DPL::FromASCIIString(string(base_url));
1435 const char* url = ewk_custom_handlers_data_url_get(handler);
1437 LogDebug("url: " << url);
1438 customHandler->url = DPL::FromASCIIString(string(url));
1440 const char* target = ewk_custom_handlers_data_target_get(handler);
1442 LogDebug("target: " << target);
1443 customHandler->target = DPL::FromASCIIString(string(target));
1445 const char* title = ewk_custom_handlers_data_title_get(handler);
1447 LogDebug("title: " << title);
1448 customHandler->title = DPL::FromASCIIString(string(title));
1450 return customHandler;
1453 void ViewLogic::attachToCustomHandlersDao()
1455 if (!m_attachedToCustomHandlerDao) {
1456 CustomHandlerDB::Interface::attachDatabaseRW();
1460 void ViewLogic::detachFromCustomHandlersDao()
1462 if (m_attachedToCustomHandlerDao) {
1463 CustomHandlerDB::Interface::detachDatabase();
1467 const int protocolWhiteListLenth = 15;
1468 char const * const protocolWhiteList[protocolWhiteListLenth] = {
1486 const int contentBlackListLenth = 14;
1487 char const * const contentBlackList[contentBlackListLenth] = {
1488 "application/x-www-form-urlencoded",
1489 "application/xhtml+xml",
1495 "multipart/x-mixed-replace",
1496 "text/cache-manifest",
1505 * Saves user's response from popup to custom handler. Saves Yes/No and remember
1508 * @param customHandler
1510 void saveUserResponse(Wrt::Popup::PopupResponse response,
1511 CustomHandlerDB::CustomHandlerPtr customHandler)
1514 case Wrt::Popup::YES_DO_REMEMBER:
1515 LogDebug("User allowed, remember");
1516 customHandler->user_decision =
1517 static_cast<CustomHandlerDB::HandlerState>
1518 (CustomHandlerDB::Agreed | CustomHandlerDB::DecisionSaved);
1520 case Wrt::Popup::YES_DONT_REMEMBER:
1521 LogDebug("User allowed, don't remember");
1522 customHandler->user_decision = CustomHandlerDB::Agreed;
1524 case Wrt::Popup::NO_DO_REMEMBER:
1525 LogDebug("User didn't allow, remember");
1526 customHandler->user_decision =
1527 static_cast<CustomHandlerDB::HandlerState>
1528 (CustomHandlerDB::Declined | CustomHandlerDB::DecisionSaved);
1530 case Wrt::Popup::NO_DONT_REMEMBER:
1531 LogDebug("User didn't allow, don't remember");
1532 customHandler->user_decision = CustomHandlerDB::Declined;
1537 //TODO registration, checking if registered and unregistration can be done in
1538 //common functions for both types of handlers. Only white and black lists
1539 //have to be separated
1540 //TODO attach database only one at the start (not in every callback?)
1541 void ViewLogic::protocolHandlerRegistrationCallback(void* data,
1542 Evas_Object* /*obj*/,
1547 CustomHandlerDB::CustomHandlerPtr customHandler =
1548 getCustomHandlerFromData(eventInfo);
1550 std::string scheme = DPL::ToUTF8String(customHandler->target);
1551 if (scheme.empty()) {
1552 LogError("No scheme provided");
1553 //TODO what about securityError?
1556 bool matched = false;
1557 //scheme on whiteList
1558 for (int i = 0; i < protocolWhiteListLenth; ++i) {
1559 if (0 == strcmp(protocolWhiteList[i], scheme.c_str())) {
1560 LogDebug("Match found, protocol can be handled");
1565 //starts with web+ and have at least 5 chars (lowercase ASCII)
1566 if (strncmp("web+", scheme.c_str(), 4) || scheme.length() < 5) {
1567 LogWarning("Scheme neither on whitelist nor starts with \"web+\"");
1568 //throw SecurityException
1574 if (c < 'a' || c > 'z') {
1575 LogWarning("Wrong char inside scheme. "
1576 << "Only lowercase ASCII letters accepted");
1577 //throw SecurityException
1584 ViewLogic* This = static_cast<ViewLogic*>(data);
1585 LogDebug("Creating handlers dao");
1586 This->attachToCustomHandlersDao();
1587 CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1588 CustomHandlerDB::CustomHandlerPtr handler =
1589 handlersDao.getProtocolHandler(customHandler->target,
1591 customHandler->base_url);
1592 if (handler && (handler->user_decision & CustomHandlerDB::DecisionSaved)) {
1593 LogDebug("Protocol already registered - nothing to do");
1595 LogDebug("Protocol handler not found");
1596 Wrt::Popup::PopupResponse response =
1597 GlobalSettings::PopupsTestModeEnabled() ? Wrt::Popup::
1599 Wrt::Popup::PopupInvoker().askYesNoCheckbox(
1600 PROTOCOL_HANDLER_ASK_TITLE,
1601 PROTOCOL_HANDLER_ASK_MSG,
1602 PROTOCOL_HANDLER_ASK_REMEMBER);
1603 saveUserResponse(response, customHandler);
1604 if (customHandler->user_decision == CustomHandlerDB::Declined) {
1607 handlersDao.registerProtocolHandler(*(customHandler.get()));
1608 if (customHandler->user_decision & CustomHandlerDB::Agreed) {
1609 //TODO remove old default handler somehow from appsvc
1610 LogDebug("Registering appservice entry");
1611 int ret = appsvc_set_defapp(APPSVC_OPERATION_VIEW,
1614 customHandler->target).c_str(),
1615 DPL::ToUTF8String(This->m_model->
1617 if (APPSVC_RET_OK != ret) {
1618 LogWarning("Appsvc entry failed: " << ret);
1621 LogDebug("Protocal saved");
1624 This->detachFromCustomHandlersDao();
1627 void ViewLogic::protocolHandlerIsRegisteredCallback(void* data,
1628 Evas_Object* /*obj*/,
1632 CustomHandlerDB::CustomHandlerPtr customHandler = getCustomHandlerFromData(
1634 ViewLogic* This = static_cast<ViewLogic*>(data);
1635 LogDebug("Creating handlers dao");
1636 This->attachToCustomHandlersDao();
1637 CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1638 CustomHandlerDB::CustomHandlerPtr handler =
1639 handlersDao.getProtocolHandler(customHandler->target,
1641 customHandler->base_url);
1643 if (handler->user_decision & CustomHandlerDB::Agreed) {
1644 ewk_custom_handlers_data_result_set(
1645 static_cast<Ewk_Custom_Handlers_Data*>(data),
1646 EWK_CUSTOM_HANDLERS_REGISTERED);
1648 ewk_custom_handlers_data_result_set(
1649 static_cast<Ewk_Custom_Handlers_Data*>(data),
1650 EWK_CUSTOM_HANDLERS_DECLINED);
1653 ewk_custom_handlers_data_result_set(
1654 static_cast<Ewk_Custom_Handlers_Data*>(data),
1655 EWK_CUSTOM_HANDLERS_NEW);
1657 This->detachFromCustomHandlersDao();
1660 void ViewLogic::protocolHandlerUnregistrationCallback(void* data,
1661 Evas_Object* /*obj*/,
1665 CustomHandlerDB::CustomHandlerPtr customHandler =
1666 getCustomHandlerFromData(eventInfo);
1667 ViewLogic* This = static_cast<ViewLogic*>(data);
1668 LogDebug("Creating handlers dao");
1669 This->attachToCustomHandlersDao();
1670 CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1671 CustomHandlerDB::CustomHandlerPtr handlerCheck =
1672 handlersDao.getProtocolHandler(customHandler->target,
1674 customHandler->base_url);
1676 if (handlerCheck->user_decision & CustomHandlerDB::Agreed) {
1677 appsvc_unset_defapp(DPL::ToUTF8String(This->m_model->TizenId).c_str());
1680 handlersDao.unregisterProtocolHandler(customHandler->target,
1682 customHandler->base_url);
1684 LogDebug("Nothing to unregister");
1687 This->detachFromCustomHandlersDao();
1690 void ViewLogic::contentHandlerRegistrationCallback(void* data,
1691 Evas_Object* /*obj*/,
1696 CustomHandlerDB::CustomHandlerPtr customHandler =
1697 getCustomHandlerFromData(eventInfo);
1699 std::string mimeType = DPL::ToUTF8String(customHandler->target);
1700 if (mimeType.empty()) {
1701 LogError("No mimeType provided.");
1704 for (int i = 0; i < contentBlackListLenth; ++i) {
1705 if (0 == strcmp(contentBlackList[i], mimeType.c_str())) {
1706 LogWarning("mimeType blacklisted");
1707 //throw SecurityException
1712 ViewLogic* This = static_cast<ViewLogic*>(data);
1713 LogDebug("Creating handlers dao");
1714 This->attachToCustomHandlersDao();
1715 CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1716 CustomHandlerDB::CustomHandlerPtr handler =
1717 handlersDao.getContentHandler(customHandler->target,
1719 customHandler->base_url);
1720 if (handler && (handler->user_decision & CustomHandlerDB::DecisionSaved)) {
1721 LogDebug("Protocol already registered - nothing to do");
1723 LogDebug("Protocol handler not found");
1724 Wrt::Popup::PopupResponse response =
1725 GlobalSettings::PopupsTestModeEnabled() ? Wrt::Popup::
1727 Wrt::Popup::PopupInvoker().askYesNoCheckbox(
1728 CONTENT_HANDLER_ASK_TITLE,
1729 CONTENT_HANDLER_ASK_MSG,
1730 CONTENT_HANDLER_AKS_REMEMBER);
1731 saveUserResponse(response, customHandler);
1732 if (customHandler->user_decision == CustomHandlerDB::Declined) {
1735 handlersDao.registerContentHandler(*(customHandler.get()));
1736 if (customHandler->user_decision & CustomHandlerDB::Agreed) {
1737 //TODO remove old default handler somehow from appsvc
1738 LogDebug("Registering appservice entry");
1739 int ret = appsvc_set_defapp(APPSVC_OPERATION_VIEW,
1741 customHandler->target).c_str(),
1743 DPL::ToUTF8String(This->m_model->
1745 if (APPSVC_RET_OK != ret) {
1746 LogWarning("Appsvc entry failed: " << ret);
1749 LogDebug("Content saved");
1751 This->detachFromCustomHandlersDao();
1754 void ViewLogic::contentHandlerIsRegisteredCallback(void* data,
1755 Evas_Object* /*obj*/,
1759 CustomHandlerDB::CustomHandlerPtr customHandler =
1760 getCustomHandlerFromData(eventInfo);
1761 ViewLogic* This = static_cast<ViewLogic*>(data);
1762 LogDebug("Creating handlers dao");
1764 This->attachToCustomHandlersDao();
1765 CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1766 CustomHandlerDB::CustomHandlerPtr handler =
1767 handlersDao.getContentHandler(customHandler->target,
1769 customHandler->base_url);
1771 if (handler->user_decision & CustomHandlerDB::Agreed) {
1772 ewk_custom_handlers_data_result_set(
1773 static_cast<Ewk_Custom_Handlers_Data*>(data),
1774 EWK_CUSTOM_HANDLERS_REGISTERED);
1776 ewk_custom_handlers_data_result_set(
1777 static_cast<Ewk_Custom_Handlers_Data*>(data),
1778 EWK_CUSTOM_HANDLERS_DECLINED);
1781 ewk_custom_handlers_data_result_set(
1782 static_cast<Ewk_Custom_Handlers_Data*>(data),
1783 EWK_CUSTOM_HANDLERS_NEW);
1785 This->detachFromCustomHandlersDao();
1788 void ViewLogic::contentHandlerUnregistrationCallback(void* data,
1789 Evas_Object* /*obj*/,
1793 CustomHandlerDB::CustomHandlerPtr customHandler =
1794 getCustomHandlerFromData(eventInfo);
1795 ViewLogic* This = static_cast<ViewLogic*>(data);
1796 LogDebug("Creating handlers dao");
1797 This->attachToCustomHandlersDao();
1798 CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1799 CustomHandlerDB::CustomHandlerPtr handlerCheck =
1800 handlersDao.getContentHandler(customHandler->target,
1802 customHandler->base_url);
1804 if (handlerCheck->user_decision & CustomHandlerDB::Agreed) {
1805 appsvc_unset_defapp(DPL::ToUTF8String(This->m_model->TizenId).c_str());
1808 handlersDao.unregisterContentHandler(customHandler->target,
1810 customHandler->base_url);
1812 LogDebug("Nothing to unregister");
1814 This->detachFromCustomHandlersDao();
1817 void ViewLogic::didRunJavaScriptCallback(
1818 Evas_Object* /*obj*/,
1822 LogInfo("didRunJavaScriptCallback called");
1823 LogInfo("result = " << result);
1826 Eina_Bool ViewLogic::windowCloseIdlerCallback(void* data)
1828 LogDebug("closeIdlerCallback");
1829 ViewLogic* This = static_cast<ViewLogic*>(data);
1830 This->windowClose();
1831 return ECORE_CALLBACK_CANCEL;
1835 void ViewLogic::databaseUsagePermissionRequestCallback(
1837 Evas_Object* /*obj*/,
1840 LogDebug("databaseUsagePermissionRequestCallback called");
1842 ViewLogic* This = static_cast<ViewLogic*>(data);
1845 if (This->m_securityOriginSupport->isNeedPermissionCheck(
1846 SecurityOriginDB::FEATURE_WEB_DATABASE)
1847 == WrtDB::SETTINGS_TYPE_OFF)
1849 // default value is deny
1852 ViewModule::WebStorageSupport::webStorageCreatePermissionRequest(
1854 This->m_securityOriginSupport->getSecurityOriginDAO(),
1859 void ViewLogic::fileSystemPermissionRequestCallback(
1861 Evas_Object* /*obj*/,
1864 LogDebug("fileSystemPermissionRequestCallback called");
1866 ViewLogic* This = static_cast<ViewLogic*>(data);
1868 if (This->m_securityOriginSupport->isNeedPermissionCheck(
1869 SecurityOriginDB::FEATURE_FILE_SYSTEM_ACCESS)
1870 == WrtDB::SETTINGS_TYPE_OFF)
1872 Ewk_Context_File_System_Permission* fileSystemPermission =
1873 static_cast<Ewk_Context_File_System_Permission*>(eventInfo);
1874 ewk_context_file_system_permission_allow_set(fileSystemPermission,
1880 ViewModule::FileSystemSupport::fileSystemPermissionRequest(
1882 This->m_securityOriginSupport->getSecurityOriginDAO(),
1886 void ViewLogic::certificateConfirmRequestCallback(
1888 Evas_Object* /*obj*/,
1891 LogDebug("certificateConfirmRequestCallback called");
1894 ViewLogic* This = static_cast<ViewLogic*>(data);
1896 Ewk_Certificate_Policy_Decision* certificatePolicyDecision =
1897 static_cast<Ewk_Certificate_Policy_Decision*>(eventInfo);
1899 bool status = This->askUserForCertificateConfirm();
1901 ewk_certificate_policy_decision_allowed_set(
1902 certificatePolicyDecision,
1905 ewk_certificate_policy_decision_allowed_set(
1906 certificatePolicyDecision,
1911 bool ViewLogic::askUserForCertificateConfirm()
1913 return Wrt::Popup::PopupInvoker().askYesNo(
1914 CERTIFICATE_CONFIRM_REQUEST_ASK_TITLE,
1915 CERTIFICATE_CONFIRM_REQUEST_ASK_BODY);
1918 std::string ViewLogic::requestUrlBlocked(const std::string& blockedUrl)
1922 if (m_model->Type.Get().appType == WrtDB::APP_TYPE_TIZENWEBAPP) {
1923 // block this page and open it in browser
1924 LogDebug("Request was blocked by WARP: " << blockedUrl);
1925 LogDebug("open browser : " << blockedUrl);
1926 bundle* bundleData = bundle_create();
1927 appsvc_set_operation(bundleData, APPSVC_OPERATION_VIEW);
1928 appsvc_set_uri(bundleData, blockedUrl.c_str());
1929 CONTROLLER_POST_EVENT(
1930 ApplicationLauncher,
1931 ApplicationLauncherEvents::LaunchApplicationByAppService(
1937 // set block url. This is used on load finished callback
1938 m_blockedUri = blockedUrl;
1940 // This is used in case of returning previous page
1941 return URICHANGE_PLUGIN_NO_CHANGE;
1944 std::string ViewLogic::requestUrlChanged(const std::string& changedUrl)
1946 using namespace ViewModule::SecuritySupport;
1948 LogInfo("changed url: " << changedUrl);
1950 // Check if this url with 'http' or 'https' is included in whitelist,
1951 // which has lists of accessible external documents and
1952 // used for ONLY Tizen app
1953 std::string matchedScheme;
1954 std::string matchedUri;
1955 pcrecpp::RE(PATTERN_URI_CHANGE).PartialMatch(changedUrl.c_str(),
1958 ViewModule::Scheme scheme(matchedScheme);
1959 if (scheme.GetType() == ViewModule::Scheme::HTTP ||
1960 scheme.GetType() == ViewModule::Scheme::HTTPS)
1962 if (m_model->Type.Get().appType == WrtDB::APP_TYPE_TIZENWEBAPP) {
1963 if (!checkWhitelist(changedUrl.c_str())) {
1964 LogInfo("This uri is not included in white document list");
1965 return URICHANGE_PLUGIN_STOP_ONLY;
1967 LogInfo("This url is included in WhiteList");
1969 // For WAC app, WRT should block access of device api
1970 // for external documents
1971 return URICHANGE_PLUGIN_STOP_ONLY;
1975 m_currentUri = changedUrl;
1976 return URICHANGE_PLUGIN_RESTART;
1979 void ViewLogic::windowClose()
1981 LogDebug("windowClose");
1982 Assert(m_closedEwkView && "no closed webview");
1984 if (1 >= m_ewkViewList.size()) {
1985 if (!m_cbs->webkitExit.empty()) {
1986 m_cbs->webkitExit();
1989 // call user callbacks
1990 if (!m_cbs->bufferUnset.empty()) {
1991 m_cbs->bufferUnset(m_currentEwkView);
1993 if (!m_cbs->windowClose.empty()) {
1994 m_cbs->windowClose(m_closedEwkView);
1996 removeEwkView(m_closedEwkView);
1998 // get latest ewkView
1999 m_currentEwkView = m_ewkViewList.back();
2000 const char* uri = ewk_view_url_get(m_currentEwkView);
2001 if (NULL == uri || 0 == strlen(uri)) {
2002 m_currentUri.clear();
2008 /* In case we support many pages in parallel
2009 * then view is not suspended*/
2010 //resumeEwkView(m_currentEwkView);
2011 setEwkViewVisible(m_currentEwkView);
2014 if (!m_cbs->bufferSet.empty()) {
2015 m_cbs->bufferSet(m_currentEwkView);