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_geolocation_support_webkit2.h>
56 #include <view_logic_usermedia_support.h>
57 #include <view_logic_web_notification_support.h>
58 #include <view_logic_web_storage_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 { "request,geolocation,permission",
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 { "database,quota,exceeded",
131 &ViewLogic::databaseUsagePermissionRequestCallback },
132 { "fullscreen,enterfullscreen", &ViewLogic::enterFullscreenCallback },
133 { "fullscreen,exitfullscreen", &ViewLogic::exitFullscreenCallback },
135 // when ime start to be showed on the webview,
136 // this callback will be called
137 { "inputmethod,changed", &ViewLogic::imeChangedCallback },
138 // this callback will be called
139 // when ime finishes to be showed on the webview
140 // "event_info" arg of this callback is always NULL point
141 // if web content should know size of ime,
142 // use "inputmethod,changed" instead of this.
144 { "editorclient,ime,opened", &ViewLogic::imeOpenedCallback },
145 // when ime finished to be hidden,
146 // this callback will be called
147 { "editorclient,ime,closed", &ViewLogic::imeClosedCallback },
148 // EWK Usermedia Callback
149 { "usermedia,permission,request",
150 &ViewLogic::usermediaPermissionRequestCallback },
152 { "protocolhandler,registration,requested",
153 &ViewLogic::protocolHandlerRegistrationCallback },
154 { "protocolhandler,isregistered",
155 &ViewLogic::protocolHandlerIsRegisteredCallback },
156 { "protocolhandler,unregistration,requested",
157 &ViewLogic::protocolHandlerUnregistrationCallback },
158 { "contenthandler,registration,requested",
159 &ViewLogic::contentHandlerRegistrationCallback },
160 { "contenthandler,isregistered",
161 &ViewLogic::contentHandlerIsRegisteredCallback },
162 { "contenthandler,unregistration,requested",
163 &ViewLogic::contentHandlerUnregistrationCallback },
164 { "request,certificate,confirm",
165 &ViewLogic::certificateConfirmRequestCallback }
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 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.empty()) {
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.empty()) {
391 while (!m_ewkViewList.empty()) {
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 = ViewModule::UriSupport::getUri(m_model, 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 // WRT should not fit web contents to device width automatically as default.
656 // Fitting to device width should be handled by web content using viewport meta tag.
657 ewk_settings_auto_fitting_set(settings, EINA_FALSE);
659 // disable zoom option when user click the input field
660 // this option is useful with the normal website
661 // for the make user friendly, disable auto zoom in the webapp
662 // The followings are not implemeted yet by webkit2
663 // elm_webview_input_field_zoom_set(EINA_FALSE);
665 // set cookie database path
666 // The followings are not implemeted yet by webkit2
667 // ewk_cookies_file_set(dao.getCookieDatabasePath().c_str()));
669 // set visibility to WebCore. This value will be used for html5.
670 // also, this value will be changed in the suspend, resume
671 // or create window, close window.
672 ewk_view_page_visibility_state_set(wkView,
673 EWK_PAGE_VISIBILITY_STATE_VISIBLE,
677 void ViewLogic::removeEwkView(Evas_Object *wkView)
679 LogInfo("removeEwkView called");
681 Assert(0 != m_ewkViewList.size());
683 // unregister webview callbacks
684 ewkClientDeinit(wkView);
686 // suspend NPAPI plugin - Not implemented by Webkit2
687 // ewk_view_pause_or_resume_plugins();
688 evas_object_del(wkView);
689 m_ewkViewList.remove(wkView);
692 void ViewLogic::resumeEwkView(Evas_Object *wkView)
694 LogInfo("resumeEwkView called");
697 // register webview callback
698 ewkClientInit(wkView);
701 resumeWebkit(wkView);
706 void ViewLogic::suspendEwkView(Evas_Object *wkView)
708 LogInfo("suspendEwkView called");
712 suspendWebkit(wkView);
714 // unregister webview callbacks
715 ewkClientDeinit(wkView);
720 void ViewLogic::setEwkViewInvisible(Evas_Object *wkView)
722 LogInfo("setEwkViewInvisible called");
725 ewk_view_page_visibility_state_set(wkView,
726 EWK_PAGE_VISIBILITY_STATE_HIDDEN,
728 ewk_view_visibility_set(wkView, EINA_FALSE);
731 void ViewLogic::setEwkViewVisible(Evas_Object *wkView)
733 LogInfo("setEwkViewVisible called");
736 ewk_view_page_visibility_state_set(wkView,
737 EWK_PAGE_VISIBILITY_STATE_VISIBLE,
739 ewk_view_visibility_set(wkView, EINA_TRUE);
742 void ViewLogic::resumeWebkit(Evas_Object *wkView)
744 LogDebug("resumeWebkit");
747 // resume NPAPI plugin
748 // The followings are not implemeted yet by webkit2
749 // ewk_view_pause_or_resume_plugins(false);
750 // ewk_view_pause_or_resume_video_audio(false);
751 // ewk_view_javascript_resume();
752 // ewk_view_enable_render();
753 // ewk_view_reduce_plugins_frame_rate(false);
754 ewk_view_resume(wkView);
759 void ViewLogic::suspendWebkit(Evas_Object *wkView)
761 LogDebug("suspendWebkit");
764 // suspend the followings
765 // The followings are not implemeted yet by webkit2
766 // ewk_view_pause_or_resume_plugins(true);
767 // ewk_view_pause_or_resume_video_audio(true);
768 ewk_view_suspend(wkView);
773 void ViewLogic::loadStartedCallback(
778 LogDebug("loadStartedCallback called");
780 ViewLogic* This = static_cast<ViewLogic*>(data);
781 evas_object_focus_set(This->m_currentEwkView, EINA_TRUE);
783 // call loadFinish callback to wrt-client
784 if (!This->m_cbs->loadStart.empty()) {
785 This->m_cbs->loadStart(obj);
789 void ViewLogic::loadFinishedCallback(
794 LogDebug("loadFinishedCallback called");
796 ViewLogic* This = static_cast<ViewLogic*>(data);
799 const char* url = ewk_view_url_get(This->m_currentEwkView);
800 if (NULL == url || strlen(url) == 0) {
801 LogError("url is empty");
805 // check if this loading is for blocked url
806 if (This->m_blockedUri == url) {
807 if (ewk_view_back_possible(This->m_currentEwkView)) {
808 // go back to previous page
809 LogDebug("go to previous page");
810 ewk_view_back(This->m_currentEwkView);
813 LogDebug("remove current page");
814 ewk_view_stop(This->m_currentEwkView);
815 ecore_idler_add(windowCloseIdlerCallback, This);
817 This->m_blockedUri = std::string();
821 DPL::OptionalString jsOptionalString =
822 ViewModule::PasswordSupport::jsForAutoFillData(url);
823 if (jsOptionalString.IsNull()) {
824 LogError("Fail to get JS String");
826 std::string jsStr = DPL::ToUTF8String(*jsOptionalString).c_str();
828 if (EINA_FALSE == ewk_view_script_execute(
829 This->m_currentEwkView,
831 didRunJavaScriptCallback,
834 LogError("JS for auto fill data failed.");
838 // call loadFinish callback to wrt-client
839 if (!This->m_cbs->loadFinish.empty()) {
840 This->m_cbs->loadFinish(obj);
843 // set only encoded bundle
844 double scale = elm_config_scale_get();
845 PluginModuleSupport::setCustomProperties(
848 ApplicationDataSingleton::Instance().getEncodedBundle());
849 // check if 'appsevice' event is registed at the current frames.
850 // If so, dispatch the event to frames.
851 PluginModuleSupport::dispatchJavaScriptEvent(
853 WrtPlugins::W3C::ServiceCustomEvent,
856 // In this case, widget is reloaded in the background.
857 // After finished load, bundle should disconnent callback.
858 if (This->m_isBackgroundReload) {
859 PluginModuleSupport::suspend(This->m_ewkContext);
860 ewk_view_suspend(This->m_currentEwkView);
861 This->m_isBackgroundReload = false;
865 void ViewLogic::titleChangedCallback(
867 Evas_Object* /*obj*/,
870 LogDebug("titleChangedCallback called");
872 ViewLogic* This = static_cast<ViewLogic*>(data);
874 const char* title = static_cast<char*>(eventInfo);
876 if (0 == strlen(title)) {
877 LogDebug("title data is empty");
880 LogDebug("Title = [" << title << "]");
881 This->m_schemeSupport->HandleTizenScheme(title,
883 This->m_currentEwkView);
886 void ViewLogic::loadProgressCallback(
888 Evas_Object* /*obj*/,
891 double* progress = static_cast<double*>(eventInfo);
892 LogDebug("didChangeProgressCallback progress = " << *progress);
895 void ViewLogic::loadProgressFinishedCallback(
897 Evas_Object* /*obj*/,
900 LogDebug("didFinishProgressCallback");
902 ViewLogic const * const view = static_cast<ViewLogic const * const>(data);
903 if (!view->m_cbs->progressFinish.empty()) {
904 view->m_cbs->progressFinish();
908 void ViewLogic::processCrashedCallback(
910 Evas_Object* /*obj*/,
913 LogInfo("processCrashedCallback");
915 ViewLogic const * const view =
916 static_cast<ViewLogic const * const>(data);
917 if (!view->m_cbs->webCrash.empty()) {
918 view->m_cbs->webCrash();
920 // This flag will be prevented exit() call in the Webkit side
921 if (NULL != eventInfo) {
922 *(static_cast<Eina_Bool*>(eventInfo)) = EINA_TRUE;
926 void ViewLogic::createWindowCallback(
931 LogDebug("createWindowCallback");
933 ViewLogic* This = static_cast<ViewLogic*>(data);
935 // First, current webview should be handled by user callback
936 if (!This->m_cbs->bufferUnset.empty()) {
937 This->m_cbs->bufferUnset(obj);
940 // this can be set by executable for specific purpose
942 if (!This->m_cbs->windowCreateBefore.empty()) {
943 // 'obj' is parent webview object
944 This->m_cbs->windowCreateBefore(&canvas, obj);
947 canvas = evas_object_evas_get(This->m_window);
950 // create new ewkview
951 This->createEwkView(canvas);
952 Evas_Object* newEwkView = This->m_currentEwkView;
954 // initialize new ewkview
955 This->setStartPage();
956 This->ewkClientInit(newEwkView);
957 This->prepareEwkView(newEwkView);
959 // Specific jobs of child, parent webview are handled by each executable
960 if (!This->m_cbs->windowCreateAfter.empty()) {
961 // 'obj' is parent webview, 'newEwkView' is child webview
962 This->m_cbs->windowCreateAfter(obj, newEwkView);
965 // Lastly, new webview should be handled by user callback
966 if (!This->m_cbs->bufferSet.empty()) {
967 This->m_cbs->bufferSet(newEwkView);
969 *(static_cast<Evas_Object **>(eventInfo)) = newEwkView;
972 void ViewLogic::closeWindowCallback(
977 LogDebug("closeWindowCallback");
978 ViewLogic* This = static_cast<ViewLogic*>(data);
979 This->m_closedEwkView = obj;
980 ecore_idler_add(windowCloseIdlerCallback, This);
983 void ViewLogic::policyNavigationDecideCallback(
985 Evas_Object* /*obj*/,
988 LogDebug("policyNavigationDecideCallback called");
990 ViewLogic* This = static_cast<ViewLogic*>(data);
992 Ewk_Policy_Decision* policyDecision =
993 static_cast<Ewk_Policy_Decision*>(eventInfo);
995 if (This->m_schemeSupport->filterURIByScheme(policyDecision,
999 This->m_currentEwkView))
1002 ewk_policy_decision_use(policyDecision);
1004 // check whether this is new empty window
1005 const char* activeUrl = ewk_view_url_get(This->m_currentEwkView);
1006 if (!activeUrl || 0 == strlen(activeUrl)) {
1008 * The view is empty and scheme has been handled externally. When
1009 * user gets back from the external application he'd see blank page
1010 * and won't be able to navigate back. This happens when window.open
1011 * is used to handle schemes like sms/mms/mailto (for example in
1012 * WAC web standards tests: WS-15XX).
1014 * To solve the problem, the empty view is removed from the stack
1015 * and the previous one is shown. This is not an elegant solution
1016 * but we don't have a better one.
1018 LogInfo("Scheme has been handled externally. Removing empty view.");
1019 if (ewk_view_back_possible(This->m_currentEwkView)) {
1020 // go back to previous WKPage
1021 ewk_view_back(This->m_currentEwkView);
1023 // stop current WKPage
1024 ewk_view_stop(This->m_currentEwkView);
1025 ecore_idler_add(windowCloseIdlerCallback, This);
1030 ewk_policy_decision_ignore(policyDecision);
1034 void ViewLogic::policyNewWindowDecideCallback(
1036 Evas_Object* /*obj*/,
1039 LogDebug("policyNewWindowDecideCallback called");
1041 ViewLogic* This = static_cast<ViewLogic*>(data);
1043 Ewk_Policy_Decision* policyDecision =
1044 static_cast<Ewk_Policy_Decision*>(eventInfo);
1046 if (This->m_schemeSupport->filterURIByScheme(policyDecision,
1050 This->m_currentEwkView))
1052 ewk_policy_decision_use(policyDecision);
1055 ewk_policy_decision_ignore(policyDecision);
1059 void ViewLogic::pageResponseDecideCallback(
1061 Evas_Object* /*obj*/,
1064 LogDebug("pageResponseDecideCallback called");
1066 ViewLogic* This = static_cast<ViewLogic*>(data);
1068 Ewk_Policy_Decision* policyDecision =
1069 static_cast<Ewk_Policy_Decision*>(eventInfo);
1070 Ewk_Policy_Decision_Type policyDecisionType =
1071 ewk_policy_decision_type_get(policyDecision);
1073 if (policyDecisionType == EWK_POLICY_DECISION_USE) {
1075 ewk_policy_decision_use(policyDecision);
1076 } else if (policyDecisionType == EWK_POLICY_DECISION_DOWNLOAD) {
1077 LogDebug("download");
1078 ewk_policy_decision_suspend(policyDecision);
1080 // get uri information
1081 const char* url = ewk_policy_decision_url_get(policyDecision);
1082 if (NULL == url || strlen(url) == 0) {
1083 LogDebug("url data is empty");
1084 ewk_policy_decision_use(policyDecision);
1087 LogDebug("url = [" << url << "]");
1089 // get content information
1090 const char* content =
1091 ewk_policy_decision_response_mime_get(policyDecision);
1092 LogDebug("content type = [" << content << "]");
1094 // get cookie information
1095 const char* cookie = ewk_policy_decision_cookie_get(policyDecision);
1096 LogDebug("cookie = [" << cookie << "]");
1098 LogDebug("Content not supported, will be opened in external app");
1099 This->m_appsSupport->downloadRequest(
1103 ewk_policy_decision_ignore(policyDecision);
1104 } else if (policyDecisionType == EWK_POLICY_DECISION_IGNORE) {
1106 ewk_policy_decision_ignore(policyDecision);
1108 LogDebug("Type isn't handled");
1109 ewk_policy_decision_ignore(policyDecision);
1113 void ViewLogic::contextmenuCustomizeCallback(
1115 Evas_Object* /*obj*/,
1118 LogDebug("contextmenuCustomizeCallback called");
1121 ViewLogic* This = static_cast<ViewLogic*>(const_cast<void*>(data));
1122 Ewk_Context_Menu* menu = static_cast<Ewk_Context_Menu*>(eventInfo);
1123 if ((This->m_model->Type.Get().appType == WrtDB::APP_TYPE_TIZENWEBAPP) &&
1124 (This->m_model->SettingList.Get().getContextMenu()
1125 == ContextMenu_Disable))
1127 LogDebug("ContextMenu Disable!!");
1128 for (unsigned int idx = 0; idx < ewk_context_menu_item_count(menu);) {
1129 Ewk_Context_Menu_Item* item = ewk_context_menu_nth_item_get(menu,
1132 ewk_context_menu_item_remove(menu, item);
1135 LogDebug("ContextMenu Enable!!");
1136 unsigned int menu_num = ewk_context_menu_item_count(menu);
1137 unsigned int idx = 0;
1139 Ewk_Context_Menu_Item* item = ewk_context_menu_nth_item_get(menu,
1145 Ewk_Context_Menu_Item_Tag tag = ewk_context_menu_item_tag_get(item);
1148 case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_IMAGE_IN_NEW_WINDOW:
1149 ewk_context_menu_item_remove(menu, item);
1152 case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_LINK_IN_NEW_WINDOW:
1153 ewk_context_menu_item_remove(menu, item);
1156 case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_FRAME_IN_NEW_WINDOW:
1157 ewk_context_menu_item_remove(menu, item);
1160 case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_MEDIA_IN_NEW_WINDOW:
1161 ewk_context_menu_item_remove(menu, item);
1164 case EWK_CONTEXT_MENU_ITEM_TAG_SEARCH_WEB:
1165 ewk_context_menu_item_remove(menu, item);
1172 } while (idx < menu_num);
1176 void ViewLogic::formSubmitCallback(
1178 Evas_Object* /*obj*/,
1181 LogDebug("formSubmitCallback called");
1183 Ewk_Form_Data* formData = static_cast<Ewk_Form_Data*>(eventInfo);
1185 const char* uri = ewk_form_data_url_get(formData);
1187 LogError("URL is empty");
1191 Eina_Hash* userData = ewk_form_data_values_get(formData);
1192 ViewModule::PasswordSupport::submitClicked(uri, userData);
1195 void ViewLogic::geolocationPermissionRequestCallback(
1197 Evas_Object* /*obj*/,
1201 ViewLogic* This = static_cast<ViewLogic*>(data);
1203 Ewk_Geolocation_Permission_Data* permissionRequest =
1204 static_cast<Ewk_Geolocation_Permission_Data*>(eventInfo);
1206 if (This->m_securityOriginSupport->isNeedPermissionCheck(
1207 SecurityOriginDB::FEATURE_GEOLOCATION)
1208 == WrtDB::SETTINGS_TYPE_OFF)
1210 ewk_geolocation_permission_request_allow_set(
1211 ewk_geolocation_permission_request_get(permissionRequest),
1215 ViewModule::GeolocationSupport::Webkit2::geolocationPermissionRequest(
1217 This->m_securityOriginSupport->getSecurityOriginDAO(),
1221 void ViewLogic::notificationShowCallback(
1223 Evas_Object* /*obj*/,
1226 LogDebug("notificationShowCallback called");
1228 ViewLogic* This = static_cast<ViewLogic*>(data);
1231 Ewk_Notification* noti = static_cast<Ewk_Notification*>(eventInfo);
1233 using namespace ViewModule::WebNotification;
1235 WebNotificationDataPtr notiData(
1236 new WebNotificationData(
1238 ewk_notification_id_get(noti)));
1240 DPL::OptionalString string =
1241 DPL::FromUTF8String(ewk_notification_icon_url_get(noti));
1242 if (!string.IsNull()) {
1243 notiData->m_iconURL = DPL::ToUTF8String(*string);
1245 string = DPL::FromUTF8String(ewk_notification_title_get(noti));
1246 if (!string.IsNull()) {
1247 notiData->m_title = DPL::ToUTF8String(*string);
1249 string = DPL::FromUTF8String(ewk_notification_body_get(noti));
1250 if (!string.IsNull()) {
1251 notiData->m_body = DPL::ToUTF8String(*string);
1254 LogInfo("notification id : " << notiData->m_id);
1255 LogInfo("notification iconURL : " << notiData->m_iconURL);
1256 LogInfo("notification title : " << notiData->m_title);
1257 LogInfo("notification body : " << notiData->m_body);
1259 showWebNotification(notiData);
1260 ewk_notification_showed(This->m_ewkContext, ewk_notification_id_get(noti));
1263 void ViewLogic::notificationCancelCallback(
1265 Evas_Object* /*obj*/,
1266 void* /*eventInfo*/)
1268 LogDebug("notificationCancelCallback called");
1271 void ViewLogic::notificationPermissionRequestCallback(
1273 Evas_Object* /*obj*/,
1276 LogDebug("notificationPermissionRequestCallback called");
1278 ViewLogic* This = static_cast<ViewLogic*>(data);
1279 if (This->m_securityOriginSupport->isNeedPermissionCheck(
1280 SecurityOriginDB::FEATURE_WEB_NOTIFICATION)
1281 == WrtDB::SETTINGS_TYPE_OFF)
1283 Ewk_Notification_Permission_Request* request =
1284 static_cast<Ewk_Notification_Permission_Request*>(eventInfo);
1285 ewk_notification_permission_request_response(
1293 ViewModule::WebNotification::webNotificationPermissionRequest(
1295 This->m_securityOriginSupport->getSecurityOriginDAO(),
1301 // EWK Orientation Callback
1302 Eina_Bool ViewLogic::orientationLockCallback(
1304 Eina_Bool /*needLock*/,
1308 LogDebug("orientationLockCallback called");
1310 ViewLogic* This = static_cast<ViewLogic*>(data);
1312 if (orientation & EWK_SCREEN_ORIENTATION_PORTRAIT_PRIMARY) {
1313 LogDebug("orientation is portrait-primary");
1314 elm_win_rotation_with_resize_set(This->m_window, 0);
1315 ewk_view_orientation_send(obj, 0);
1316 } else if (orientation & EWK_SCREEN_ORIENTATION_LANDSCAPE_PRIMARY) {
1317 LogDebug("orientation is landscape-primary");
1318 elm_win_rotation_with_resize_set(This->m_window, 270);
1319 ewk_view_orientation_send(obj, 90);
1320 } else if (orientation & EWK_SCREEN_ORIENTATION_PORTRAIT_SECONDARY) {
1321 LogDebug("orientation is portrait-secondary");
1322 elm_win_rotation_with_resize_set(This->m_window, 180);
1323 ewk_view_orientation_send(obj, 180);
1324 } else if (orientation & EWK_SCREEN_ORIENTATION_LANDSCAPE_SECONDARY) {
1325 LogDebug("orientation is landscape-secondary");
1326 elm_win_rotation_with_resize_set(This->m_window, 90);
1327 ewk_view_orientation_send(obj, -90);
1329 LogDebug("Wrong orientation is set");
1335 // Fullscreen API callbacks
1336 void ViewLogic::enterFullscreenCallback(
1338 Evas_Object* /*obj*/,
1339 void* /*eventInfo*/)
1341 LogInfo("enterFullscreenCallback called");
1343 ViewLogic* This = static_cast<ViewLogic*>(data);
1344 if (!This->m_cbs->toggleFullscreen.empty()) {
1345 This->m_cbs->toggleFullscreen(true);
1348 void ViewLogic::exitFullscreenCallback(
1350 Evas_Object* /*obj*/,
1351 void* /*eventInfo*/)
1353 LogInfo("exitFullscreenCallback called");
1355 ViewLogic* This = static_cast<ViewLogic*>(data);
1356 if (!This->m_cbs->toggleFullscreen.empty()) {
1357 This->m_cbs->toggleFullscreen(false);
1361 void ViewLogic::imeChangedCallback(
1363 Evas_Object* /*obj*/,
1369 ViewLogic* This = static_cast<ViewLogic*>(data);
1370 Eina_Rectangle *rect = static_cast<Eina_Rectangle *>(eventInfo);
1371 This->m_imeWidth = rect->w;
1372 This->m_imeHeight = rect->h;
1375 void ViewLogic::imeOpenedCallback(
1377 Evas_Object* /*obj*/,
1378 void* /*eventInfo*/)
1382 ViewLogic* This = static_cast<ViewLogic*>(data);
1384 using namespace WrtPlugins::W3C;
1385 SoftKeyboardChangeArgs args;
1386 args.state = IME_STATE_ON;
1387 args.width = This->m_imeWidth;
1388 args.height = This->m_imeHeight;
1389 This->fireJavascriptEvent(
1390 static_cast<int>(SoftKeyboardChangeCustomEvent),
1394 void ViewLogic::imeClosedCallback(
1396 Evas_Object* /*obj*/,
1397 void* /*eventInfo*/)
1401 ViewLogic* This = static_cast<ViewLogic*>(data);
1403 using namespace WrtPlugins::W3C;
1404 SoftKeyboardChangeArgs args;
1405 args.state = IME_STATE_OFF;
1407 This->fireJavascriptEvent(
1408 static_cast<int>(SoftKeyboardChangeCustomEvent),
1412 void ViewLogic::usermediaPermissionRequestCallback(
1414 Evas_Object* /*obj*/,
1417 LogDebug("usermediaPermissionRequestCallback called");
1419 ViewLogic* This = static_cast<ViewLogic*>(data);
1420 ViewModule::UsermediaSupport::usermediaPermissionRequest(This->m_window,
1425 CustomHandlerDB::CustomHandlerPtr getCustomHandlerFromData(void* data)
1428 Ewk_Custom_Handlers_Data* handler =
1429 static_cast<Ewk_Custom_Handlers_Data*>(data);
1430 CustomHandlerDB::CustomHandlerPtr customHandler(
1431 new CustomHandlerDB::CustomHandler());
1432 const char* base_url = ewk_custom_handlers_data_base_url_get(handler);
1434 LogDebug("base url: " << base_url);
1435 customHandler->base_url = DPL::FromASCIIString(string(base_url));
1437 const char* url = ewk_custom_handlers_data_url_get(handler);
1439 LogDebug("url: " << url);
1440 customHandler->url = DPL::FromASCIIString(string(url));
1442 const char* target = ewk_custom_handlers_data_target_get(handler);
1444 LogDebug("target: " << target);
1445 customHandler->target = DPL::FromASCIIString(string(target));
1447 const char* title = ewk_custom_handlers_data_title_get(handler);
1449 LogDebug("title: " << title);
1450 customHandler->title = DPL::FromASCIIString(string(title));
1452 return customHandler;
1455 void ViewLogic::attachToCustomHandlersDao()
1457 if (!m_attachedToCustomHandlerDao) {
1458 CustomHandlerDB::Interface::attachDatabaseRW();
1462 void ViewLogic::detachFromCustomHandlersDao()
1464 if (m_attachedToCustomHandlerDao) {
1465 CustomHandlerDB::Interface::detachDatabase();
1469 const int protocolWhiteListLenth = 15;
1470 char const * const protocolWhiteList[protocolWhiteListLenth] = {
1488 const int contentBlackListLenth = 14;
1489 char const * const contentBlackList[contentBlackListLenth] = {
1490 "application/x-www-form-urlencoded",
1491 "application/xhtml+xml",
1497 "multipart/x-mixed-replace",
1498 "text/cache-manifest",
1507 * Saves user's response from popup to custom handler. Saves Yes/No and remember
1510 * @param customHandler
1512 void saveUserResponse(Wrt::Popup::PopupResponse response,
1513 CustomHandlerDB::CustomHandlerPtr customHandler)
1516 case Wrt::Popup::YES_DO_REMEMBER:
1517 LogDebug("User allowed, remember");
1518 customHandler->user_decision =
1519 static_cast<CustomHandlerDB::HandlerState>
1520 (CustomHandlerDB::Agreed | CustomHandlerDB::DecisionSaved);
1522 case Wrt::Popup::YES_DONT_REMEMBER:
1523 LogDebug("User allowed, don't remember");
1524 customHandler->user_decision = CustomHandlerDB::Agreed;
1526 case Wrt::Popup::NO_DO_REMEMBER:
1527 LogDebug("User didn't allow, remember");
1528 customHandler->user_decision =
1529 static_cast<CustomHandlerDB::HandlerState>
1530 (CustomHandlerDB::Declined | CustomHandlerDB::DecisionSaved);
1532 case Wrt::Popup::NO_DONT_REMEMBER:
1533 LogDebug("User didn't allow, don't remember");
1534 customHandler->user_decision = CustomHandlerDB::Declined;
1539 //TODO registration, checking if registered and unregistration can be done in
1540 //common functions for both types of handlers. Only white and black lists
1541 //have to be separated
1542 //TODO attach database only one at the start (not in every callback?)
1543 void ViewLogic::protocolHandlerRegistrationCallback(void* data,
1544 Evas_Object* /*obj*/,
1549 CustomHandlerDB::CustomHandlerPtr customHandler =
1550 getCustomHandlerFromData(eventInfo);
1552 std::string scheme = DPL::ToUTF8String(customHandler->target);
1553 if (scheme.empty()) {
1554 LogError("No scheme provided");
1555 //TODO what about securityError?
1558 bool matched = false;
1559 //scheme on whiteList
1560 for (int i = 0; i < protocolWhiteListLenth; ++i) {
1561 if (0 == strcmp(protocolWhiteList[i], scheme.c_str())) {
1562 LogDebug("Match found, protocol can be handled");
1567 //starts with web+ and have at least 5 chars (lowercase ASCII)
1568 if (strncmp("web+", scheme.c_str(), 4) || scheme.length() < 5) {
1569 LogWarning("Scheme neither on whitelist nor starts with \"web+\"");
1570 //throw SecurityException
1576 if (c < 'a' || c > 'z') {
1577 LogWarning("Wrong char inside scheme. "
1578 << "Only lowercase ASCII letters accepted");
1579 //throw SecurityException
1586 ViewLogic* This = static_cast<ViewLogic*>(data);
1587 LogDebug("Creating handlers dao");
1588 This->attachToCustomHandlersDao();
1589 CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1590 CustomHandlerDB::CustomHandlerPtr handler =
1591 handlersDao.getProtocolHandler(customHandler->target,
1593 customHandler->base_url);
1594 if (handler && (handler->user_decision & CustomHandlerDB::DecisionSaved)) {
1595 LogDebug("Protocol already registered - nothing to do");
1597 LogDebug("Protocol handler not found");
1598 Wrt::Popup::PopupResponse response =
1599 GlobalSettings::PopupsTestModeEnabled() ? Wrt::Popup::
1601 Wrt::Popup::PopupInvoker().askYesNoCheckbox(
1602 PROTOCOL_HANDLER_ASK_TITLE,
1603 PROTOCOL_HANDLER_ASK_MSG,
1604 PROTOCOL_HANDLER_ASK_REMEMBER);
1605 saveUserResponse(response, customHandler);
1606 if (customHandler->user_decision == CustomHandlerDB::Declined) {
1609 handlersDao.registerProtocolHandler(*(customHandler.get()));
1610 if (customHandler->user_decision & CustomHandlerDB::Agreed) {
1611 //TODO remove old default handler somehow from appsvc
1612 LogDebug("Registering appservice entry");
1613 int ret = appsvc_set_defapp(APPSVC_OPERATION_VIEW,
1616 customHandler->target).c_str(),
1617 DPL::ToUTF8String(This->m_model->
1619 if (APPSVC_RET_OK != ret) {
1620 LogWarning("Appsvc entry failed: " << ret);
1623 LogDebug("Protocal saved");
1626 This->detachFromCustomHandlersDao();
1629 void ViewLogic::protocolHandlerIsRegisteredCallback(void* data,
1630 Evas_Object* /*obj*/,
1634 CustomHandlerDB::CustomHandlerPtr customHandler = getCustomHandlerFromData(
1636 ViewLogic* This = static_cast<ViewLogic*>(data);
1637 LogDebug("Creating handlers dao");
1638 This->attachToCustomHandlersDao();
1639 CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1640 CustomHandlerDB::CustomHandlerPtr handler =
1641 handlersDao.getProtocolHandler(customHandler->target,
1643 customHandler->base_url);
1645 if (handler->user_decision & CustomHandlerDB::Agreed) {
1646 ewk_custom_handlers_data_result_set(
1647 static_cast<Ewk_Custom_Handlers_Data*>(data),
1648 EWK_CUSTOM_HANDLERS_REGISTERED);
1650 ewk_custom_handlers_data_result_set(
1651 static_cast<Ewk_Custom_Handlers_Data*>(data),
1652 EWK_CUSTOM_HANDLERS_DECLINED);
1655 ewk_custom_handlers_data_result_set(
1656 static_cast<Ewk_Custom_Handlers_Data*>(data),
1657 EWK_CUSTOM_HANDLERS_NEW);
1659 This->detachFromCustomHandlersDao();
1662 void ViewLogic::protocolHandlerUnregistrationCallback(void* data,
1663 Evas_Object* /*obj*/,
1667 CustomHandlerDB::CustomHandlerPtr customHandler =
1668 getCustomHandlerFromData(eventInfo);
1669 ViewLogic* This = static_cast<ViewLogic*>(data);
1670 LogDebug("Creating handlers dao");
1671 This->attachToCustomHandlersDao();
1672 CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1673 CustomHandlerDB::CustomHandlerPtr handlerCheck =
1674 handlersDao.getProtocolHandler(customHandler->target,
1676 customHandler->base_url);
1678 if (handlerCheck->user_decision & CustomHandlerDB::Agreed) {
1679 appsvc_unset_defapp(DPL::ToUTF8String(This->m_model->TizenId).c_str());
1682 handlersDao.unregisterProtocolHandler(customHandler->target,
1684 customHandler->base_url);
1686 LogDebug("Nothing to unregister");
1689 This->detachFromCustomHandlersDao();
1692 void ViewLogic::contentHandlerRegistrationCallback(void* data,
1693 Evas_Object* /*obj*/,
1698 CustomHandlerDB::CustomHandlerPtr customHandler =
1699 getCustomHandlerFromData(eventInfo);
1701 std::string mimeType = DPL::ToUTF8String(customHandler->target);
1702 if (mimeType.empty()) {
1703 LogError("No mimeType provided.");
1706 for (int i = 0; i < contentBlackListLenth; ++i) {
1707 if (0 == strcmp(contentBlackList[i], mimeType.c_str())) {
1708 LogWarning("mimeType blacklisted");
1709 //throw SecurityException
1714 ViewLogic* This = static_cast<ViewLogic*>(data);
1715 LogDebug("Creating handlers dao");
1716 This->attachToCustomHandlersDao();
1717 CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1718 CustomHandlerDB::CustomHandlerPtr handler =
1719 handlersDao.getContentHandler(customHandler->target,
1721 customHandler->base_url);
1722 if (handler && (handler->user_decision & CustomHandlerDB::DecisionSaved)) {
1723 LogDebug("Protocol already registered - nothing to do");
1725 LogDebug("Protocol handler not found");
1726 Wrt::Popup::PopupResponse response =
1727 GlobalSettings::PopupsTestModeEnabled() ? Wrt::Popup::
1729 Wrt::Popup::PopupInvoker().askYesNoCheckbox(
1730 CONTENT_HANDLER_ASK_TITLE,
1731 CONTENT_HANDLER_ASK_MSG,
1732 CONTENT_HANDLER_AKS_REMEMBER);
1733 saveUserResponse(response, customHandler);
1734 if (customHandler->user_decision == CustomHandlerDB::Declined) {
1737 handlersDao.registerContentHandler(*(customHandler.get()));
1738 if (customHandler->user_decision & CustomHandlerDB::Agreed) {
1739 //TODO remove old default handler somehow from appsvc
1740 LogDebug("Registering appservice entry");
1741 int ret = appsvc_set_defapp(APPSVC_OPERATION_VIEW,
1743 customHandler->target).c_str(),
1745 DPL::ToUTF8String(This->m_model->
1747 if (APPSVC_RET_OK != ret) {
1748 LogWarning("Appsvc entry failed: " << ret);
1751 LogDebug("Content saved");
1753 This->detachFromCustomHandlersDao();
1756 void ViewLogic::contentHandlerIsRegisteredCallback(void* data,
1757 Evas_Object* /*obj*/,
1761 CustomHandlerDB::CustomHandlerPtr customHandler =
1762 getCustomHandlerFromData(eventInfo);
1763 ViewLogic* This = static_cast<ViewLogic*>(data);
1764 LogDebug("Creating handlers dao");
1766 This->attachToCustomHandlersDao();
1767 CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1768 CustomHandlerDB::CustomHandlerPtr handler =
1769 handlersDao.getContentHandler(customHandler->target,
1771 customHandler->base_url);
1773 if (handler->user_decision & CustomHandlerDB::Agreed) {
1774 ewk_custom_handlers_data_result_set(
1775 static_cast<Ewk_Custom_Handlers_Data*>(data),
1776 EWK_CUSTOM_HANDLERS_REGISTERED);
1778 ewk_custom_handlers_data_result_set(
1779 static_cast<Ewk_Custom_Handlers_Data*>(data),
1780 EWK_CUSTOM_HANDLERS_DECLINED);
1783 ewk_custom_handlers_data_result_set(
1784 static_cast<Ewk_Custom_Handlers_Data*>(data),
1785 EWK_CUSTOM_HANDLERS_NEW);
1787 This->detachFromCustomHandlersDao();
1790 void ViewLogic::contentHandlerUnregistrationCallback(void* data,
1791 Evas_Object* /*obj*/,
1795 CustomHandlerDB::CustomHandlerPtr customHandler =
1796 getCustomHandlerFromData(eventInfo);
1797 ViewLogic* This = static_cast<ViewLogic*>(data);
1798 LogDebug("Creating handlers dao");
1799 This->attachToCustomHandlersDao();
1800 CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1801 CustomHandlerDB::CustomHandlerPtr handlerCheck =
1802 handlersDao.getContentHandler(customHandler->target,
1804 customHandler->base_url);
1806 if (handlerCheck->user_decision & CustomHandlerDB::Agreed) {
1807 appsvc_unset_defapp(DPL::ToUTF8String(This->m_model->TizenId).c_str());
1810 handlersDao.unregisterContentHandler(customHandler->target,
1812 customHandler->base_url);
1814 LogDebug("Nothing to unregister");
1816 This->detachFromCustomHandlersDao();
1819 void ViewLogic::didRunJavaScriptCallback(
1820 Evas_Object* /*obj*/,
1824 LogInfo("didRunJavaScriptCallback called");
1825 LogInfo("result = " << result);
1828 Eina_Bool ViewLogic::windowCloseIdlerCallback(void* data)
1830 LogDebug("closeIdlerCallback");
1831 ViewLogic* This = static_cast<ViewLogic*>(data);
1832 This->windowClose();
1833 return ECORE_CALLBACK_CANCEL;
1837 void ViewLogic::databaseUsagePermissionRequestCallback(
1839 Evas_Object* /*obj*/,
1842 LogDebug("databaseUsagePermissionRequestCallback called");
1844 ViewLogic* This = static_cast<ViewLogic*>(data);
1847 if (This->m_securityOriginSupport->isNeedPermissionCheck(
1848 SecurityOriginDB::FEATURE_WEB_DATABASE)
1849 == WrtDB::SETTINGS_TYPE_OFF)
1851 // default value is deny
1854 ViewModule::WebStorageSupport::webStorageCreatePermissionRequest(
1856 This->m_securityOriginSupport->getSecurityOriginDAO(),
1861 void ViewLogic::certificateConfirmRequestCallback(
1863 Evas_Object* /*obj*/,
1866 LogDebug("certificateConfirmRequestCallback called");
1869 ViewLogic* This = static_cast<ViewLogic*>(data);
1871 Ewk_Certificate_Policy_Decision* certificatePolicyDecision =
1872 static_cast<Ewk_Certificate_Policy_Decision*>(eventInfo);
1874 bool status = This->askUserForCertificateConfirm();
1876 ewk_certificate_policy_decision_allowed_set(
1877 certificatePolicyDecision,
1880 ewk_certificate_policy_decision_allowed_set(
1881 certificatePolicyDecision,
1886 bool ViewLogic::askUserForCertificateConfirm()
1888 return Wrt::Popup::PopupInvoker().askYesNo(
1889 CERTIFICATE_CONFIRM_REQUEST_ASK_TITLE,
1890 CERTIFICATE_CONFIRM_REQUEST_ASK_BODY);
1893 std::string ViewLogic::requestUrlBlocked(const std::string& blockedUrl)
1897 if (m_model->Type.Get().appType == WrtDB::APP_TYPE_TIZENWEBAPP) {
1898 // block this page and open it in browser
1899 LogDebug("Request was blocked by WARP: " << blockedUrl);
1900 LogDebug("open browser : " << blockedUrl);
1901 bundle* bundleData = bundle_create();
1902 appsvc_set_operation(bundleData, APPSVC_OPERATION_VIEW);
1903 appsvc_set_uri(bundleData, blockedUrl.c_str());
1904 CONTROLLER_POST_EVENT(
1905 ApplicationLauncher,
1906 ApplicationLauncherEvents::LaunchApplicationByAppService(
1912 // set block url. This is used on load finished callback
1913 m_blockedUri = blockedUrl;
1915 // This is used in case of returning previous page
1916 return URICHANGE_PLUGIN_NO_CHANGE;
1919 std::string ViewLogic::requestUrlChanged(const std::string& changedUrl)
1921 using namespace ViewModule::SecuritySupport;
1923 LogInfo("changed url: " << changedUrl);
1925 // Check if this url with 'http' or 'https' is included in whitelist,
1926 // which has lists of accessible external documents and
1927 // used for ONLY Tizen app
1928 std::string matchedScheme;
1929 std::string matchedUri;
1930 pcrecpp::RE(PATTERN_URI_CHANGE).PartialMatch(changedUrl.c_str(),
1933 ViewModule::Scheme scheme(matchedScheme);
1934 if (scheme.GetType() == ViewModule::Scheme::HTTP ||
1935 scheme.GetType() == ViewModule::Scheme::HTTPS)
1937 if (m_model->Type.Get().appType == WrtDB::APP_TYPE_TIZENWEBAPP) {
1938 if (!checkWhitelist(changedUrl.c_str())) {
1939 LogInfo("This uri is not included in white document list");
1940 return URICHANGE_PLUGIN_STOP_ONLY;
1942 LogInfo("This url is included in WhiteList");
1944 // For WAC app, WRT should block access of device api
1945 // for external documents
1946 return URICHANGE_PLUGIN_STOP_ONLY;
1950 m_currentUri = changedUrl;
1951 return URICHANGE_PLUGIN_RESTART;
1954 void ViewLogic::windowClose()
1956 LogDebug("windowClose");
1957 Assert(m_closedEwkView && "no closed webview");
1959 if (1 >= m_ewkViewList.size()) {
1960 if (!m_cbs->webkitExit.empty()) {
1961 m_cbs->webkitExit();
1964 // call user callbacks
1965 if (!m_cbs->bufferUnset.empty()) {
1966 m_cbs->bufferUnset(m_currentEwkView);
1968 if (!m_cbs->windowClose.empty()) {
1969 m_cbs->windowClose(m_closedEwkView);
1971 removeEwkView(m_closedEwkView);
1973 // get latest ewkView
1974 m_currentEwkView = m_ewkViewList.back();
1975 const char* uri = ewk_view_url_get(m_currentEwkView);
1976 if (NULL == uri || 0 == strlen(uri)) {
1977 m_currentUri.clear();
1983 /* In case we support many pages in parallel
1984 * then view is not suspended*/
1985 //resumeEwkView(m_currentEwkView);
1986 setEwkViewVisible(m_currentEwkView);
1989 if (!m_cbs->bufferSet.empty()) {
1990 m_cbs->bufferSet(m_currentEwkView);