2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 * @file view_logic.cpp
18 * @author Pawel Sikorski (p.sikorsk@samsung.com)
19 * @author Lukasz Wrzosek (l.wrzosek@samsung.com)
20 * @author Yunchan Cho (yunchan.cho@samsung.com)
21 * @brief View logic for Webkit2
23 #include "view_logic.h"
27 #include <dpl/assert.h>
28 #include <dpl/log/log.h>
29 #include <dpl/optional.h>
30 #include <dpl/string.h>
31 #include <dpl/foreach.h>
36 #include <widget_model.h>
37 #include <dpl/wrt-dao-ro/widget_dao_read_only.h>
38 #include <dpl/wrt-dao-ro/vconf_config.h>
39 #include <dpl/utils/wrt_global_settings.h>
41 #include <common/application_data.h>
42 #include <common/application_launcher.h>
43 #include <common/scheme.h>
45 #include <common/view_logic_apps_support.h>
46 #include <common/view_logic_custom_header_support.h>
47 #include <common/view_logic_password_support.h>
48 #include <common/view_logic_security_support.h>
49 #include <common/view_logic_security_origin_support.h>
50 #include <common/view_logic_certificate_support.h>
51 #include <common/view_logic_storage_support.h>
52 #include <common/view_logic_uri_support.h>
53 #include <common/view_logic_user_agent_support.h>
54 #include <common/view_logic_vibration_support.h>
55 #include <view_logic_authentication_challenge_support.h>
56 #include <view_logic_scheme_support.h>
57 #include <view_logic_geolocation_support_webkit2.h>
58 #include <view_logic_usermedia_support.h>
59 #include <view_logic_web_notification_support.h>
61 #include <view_logic_certificate_confirm_support.h>
62 #include "bundles/plugin_module_support.h"
63 #include <popup-runner/PopupInvoker.h>
66 #include <js_overlay_types.h>
67 #include <i_runnable_widget_object.h>
68 #include <profiling_util.h>
69 #include <wrt-commons/custom-handler-dao-ro/common_dao_types.h>
70 #include <wrt-commons/custom-handler-dao-ro/CustomHandlerDatabase.h>
71 #include <wrt-commons/custom-handler-dao-ro/custom_handler_dao_read_only.h>
72 #include <wrt-commons/custom-handler-dao-rw/custom_handler_dao.h>
73 #include <popup-runner/PopupInvoker.h>
75 #include <appsvc/appsvc.h>
78 const char * const bundlePath = "/usr/lib/wrt-wk2-bundles/libwrt-wk2-bundle.so";
79 const char * const uriBlockedMessageName = "uri_blocked_msg";
80 const char * const uriChangedMessageName = "uri_changed_msg";
81 const char * const URICHANGE_PLUGIN_STOP_ONLY = "plugin_stop_only";
82 const char * const URICHANGE_PLUGIN_RESTART = "plugin_restart";
83 const char * const URICHANGE_PLUGIN_NO_CHANGE = "plugin_no_change";
84 const char * const URICHANGE_BLOCKED_URL = "null";
85 const char* PATTERN_URI_CHANGE = "^(([^:/\\?#]+)://[^\\?#]*)";
86 const int MAX_NUM_CONTEXT_MENU_ITEMS = 10;
88 const char * const IME_STATE_ON = "on";
89 const char * const IME_STATE_OFF = "off";
91 const char PROTOCOL_HANDLER_ASK_MSG[] = "Add protocol?";
92 const char PROTOCOL_HANDLER_ASK_TITLE[] = "Add protocol";
93 const char PROTOCOL_HANDLER_ASK_REMEMBER[] = "Remember dicision";
94 const char CONTENT_HANDLER_ASK_MSG[] = "Add content?";
95 const char CONTENT_HANDLER_ASK_TITLE[] = "Add content";
96 const char CONTENT_HANDLER_AKS_REMEMBER[] = "Remember dicision";
97 const char * const CERTIFICATE_CONFIRM_REQUEST_ASK_TITLE =
99 const char * const CERTIFICATE_CONFIRM_REQUEST_ASK_BODY =
100 "This site's security certificate is not trusted! Do you acess this site?";
102 const wchar_t* BACKGROUND_ENABLED = L"background_enabled";
103 } // anonymous namespace
105 std::map<const std::string,
106 const Evas_Smart_Cb> ViewLogic::m_ewkCallbacksMap = {
107 { "load,started", &ViewLogic::loadStartedCallback },
108 { "load,finished", &ViewLogic::loadFinishedCallback },
109 { "title,changed", &ViewLogic::titleChangedCallback },
110 { "load,progress", &ViewLogic::loadProgressCallback },
111 { "load,progress,finished", &ViewLogic::loadProgressFinishedCallback },
112 { "process,crashed", &ViewLogic::processCrashedCallback },
114 { "create,window", &ViewLogic::createWindowCallback },
115 { "close,window", &ViewLogic::closeWindowCallback },
116 // WKPagePolicyClient
117 { "policy,navigation,decide", &ViewLogic::policyNavigationDecideCallback },
118 { "policy,newwindow,decide", &ViewLogic::policyNewWindowDecideCallback },
119 { "policy,response,decide", &ViewLogic::pageResponseDecideCallback },
120 // WKPageContextMenuClient
121 { "contextmenu,customize", &ViewLogic::contextmenuCustomizeCallback },
123 { "form,submit", &ViewLogic::formSubmitCallback },
124 // EWK Geolocation Callback
125 { "geolocation,permission,request",
126 &ViewLogic::geolocationPermissionRequestCallback },
127 // EWK Notification Callback
128 { "notification,show", &ViewLogic::notificationShowCallback },
129 { "notification,cancel", &ViewLogic::notificationCancelCallback },
130 { "notification,permission,request",
131 &ViewLogic::notificationPermissionRequestCallback },
133 { "fullscreen,enterfullscreen", &ViewLogic::enterFullscreenCallback },
134 { "fullscreen,exitfullscreen", &ViewLogic::exitFullscreenCallback },
136 // when ime start to be showed on the webview,
137 // this callback will be called
138 { "inputmethod,changed", &ViewLogic::imeChangedCallback },
139 // this callback will be called
140 // when ime finishes to be showed on the webview
141 // "event_info" arg of this callback is always NULL point
142 // if web content should know size of ime,
143 // use "inputmethod,changed" instead of this.
145 { "editorclient,ime,opened", &ViewLogic::imeOpenedCallback },
146 // when ime finished to be hidden,
147 // this callback will be called
148 { "editorclient,ime,closed", &ViewLogic::imeClosedCallback },
149 // EWK Usermedia Callback
150 { "usermedia,permission,request",
151 &ViewLogic::usermediaPermissionRequestCallback },
153 { "protocolhandler,registration,requested",
154 &ViewLogic::protocolHandlerRegistrationCallback },
155 { "protocolhandler,isregistered",
156 &ViewLogic::protocolHandlerIsRegisteredCallback },
157 { "protocolhandler,unregistration,requested",
158 &ViewLogic::protocolHandlerUnregistrationCallback },
159 { "contenthandler,registration,requested",
160 &ViewLogic::contentHandlerRegistrationCallback },
161 { "contenthandler,isregistered",
162 &ViewLogic::contentHandlerIsRegisteredCallback },
163 { "contenthandler,unregistration,requested",
164 &ViewLogic::contentHandlerUnregistrationCallback },
165 { "request,certificate,confirm",
166 &ViewLogic::certificateConfirmRequestCallback },
167 { "authentication,challenge",
168 &ViewLogic::authenticationChallengeRequestCallback }
171 ViewLogic::ViewLogic() :
173 m_attachedToCustomHandlerDao(false),
175 m_closedEwkView(NULL),
178 m_cbs(new WRT::UserDelegates),
181 m_isBackgroundReload(false),
182 m_isBackgroundSupport(false),
183 m_appsSupport(new ViewModule::AppsSupport()),
184 m_vibrationSupport(new ViewModule::VibrationSupport())
186 ApplicationLauncherSingleton::Instance().Touch();
189 ViewLogic::~ViewLogic()
191 detachFromCustomHandlersDao();
194 bool ViewLogic::createWebView(Ewk_Context* context,
198 if (!context || !window) {
203 const char *theme = elm_theme_get(NULL);
206 LogInfo("theme is " << m_theme);
210 m_ewkContext = context;
213 Evas* canvas = evas_object_evas_get(m_window);
214 return createEwkView(canvas);
217 void ViewLogic::prepareView(WidgetModel* m, const std::string &startUrl)
219 LogDebug("View prepare");
223 m_startUrl = startUrl;
224 Assert(NULL != m_ewkContext);
227 ADD_PROFILING_POINT("initializeSupport", "start");
229 ADD_PROFILING_POINT("initializeSupport", "stop");
231 ewkClientInit(m_currentEwkView);
232 ADD_PROFILING_POINT("prepareEwkView", "start");
233 prepareEwkView(m_currentEwkView);
234 ADD_PROFILING_POINT("prepareEwkView", "stop");
235 initializePluginLoading();
238 void ViewLogic::showWidget()
240 LogDebug("showing widget");
241 Assert(NULL != m_currentEwkView && "ewk_view not created at this point");
242 if (m_currentUri.empty()) {
243 LogError("Localized current URI doesn't exist");
247 LogInfo("m_currentUri: " << m_currentUri);
250 ewk_view_url_set(m_currentEwkView, m_currentUri.c_str());
252 if (!m_cbs->bufferSet.empty()) {
253 m_cbs->bufferSet(m_currentEwkView);
257 void ViewLogic::hideWidget()
259 LogDebug("hiding widget");
260 ViewModule::StorageSupport::deinitializeStorage(m_model);
261 m_appsSupport->deinitialize();
263 m_vibrationSupport->deinitialize();
265 while (!m_ewkViewList.empty()) {
266 LogInfo("pop webview: " << m_ewkViewList.back());
267 removeEwkView(m_ewkViewList.back());
269 m_ewkViewList.clear();
272 void ViewLogic::suspendWidget()
274 LogInfo("Pausing widget");
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 if (m_currentEwkView) {
300 setEwkViewVisible(m_currentEwkView);
301 if (!m_isBackgroundSupport) {
302 resumeWebkit(m_currentEwkView);
306 /* window system team recomend removing this win_raise code. */
309 * elm_win_raise(m_window);
312 evas_object_focus_set(m_currentEwkView, EINA_TRUE);
314 // call user callback
315 if (!m_cbs->resume.empty()) {
320 void ViewLogic::resetWidget()
322 LogInfo("Resetting Widget");
324 // destory all webview
325 while (!m_ewkViewList.empty()) {
326 LogInfo("pop webview: " << m_ewkViewList.back());
327 removeEwkView(m_ewkViewList.back());
329 m_ewkViewList.clear();
331 // create new webview
332 createEwkView(evas_object_evas_get(m_window));
334 ewkClientInit(m_currentEwkView);
335 prepareEwkView(m_currentEwkView);
337 // check if current url is service url for this tizen service
338 std::string requestedUri =
339 ViewModule::UriSupport::getUri(m_model, m_startUrl);
340 DPL::OptionalString servicedUri = ViewModule::UriSupport::localizeURI(
341 DPL::FromUTF8String(requestedUri.c_str()),
344 initializePluginLoading();
347 m_currentUri = DPL::ToUTF8String(*servicedUri);
348 ewk_view_url_set(m_currentEwkView, m_currentUri.c_str());
349 elm_win_activate(m_window);
350 evas_object_focus_set(m_currentEwkView, EINA_TRUE);
352 // call user callback
353 if (!m_cbs->reset.empty()) {
356 if (!m_cbs->bufferSet.empty()) {
357 m_cbs->bufferSet(m_currentEwkView);
361 void ViewLogic::backward()
363 if (ewk_view_back_possible(m_currentEwkView)) {
364 ewk_view_back(m_currentEwkView);
366 if (1 >= m_ewkViewList.size()) {
367 // If there is no previous page, widget move to backgroud.
368 LogInfo("Widget move to backgroud");
369 elm_win_lower(m_window);
371 // Back to previous webview
372 LogInfo("Widget move to previous webview");
373 m_closedEwkView = m_currentEwkView;
374 ecore_idler_add(windowCloseIdlerCallback, this);
379 void ViewLogic::reloadStartPage()
381 LogInfo("Reload Start Page");
382 // prevent fail to load plugin bundle side
383 m_isBackgroundReload = true;
385 if (!m_ewkViewList.empty()) {
386 while (!m_ewkViewList.empty()) {
387 if (!m_cbs->bufferUnset.empty()) {
388 m_cbs->bufferUnset(m_currentEwkView);
390 removeEwkView(m_currentEwkView);
394 // create new webview
395 createEwkView(evas_object_evas_get(m_window));
396 ewkClientInit(m_currentEwkView);
399 prepareEwkView(m_currentEwkView);
400 initializePluginLoading();
403 ewk_view_url_set(m_currentEwkView, m_currentUri.c_str());
406 if (!m_cbs->bufferSet.empty()) {
407 m_cbs->bufferSet(m_currentEwkView);
409 LogInfo("Reloading Start Page is done!");
412 Evas_Object* ViewLogic::getCurrentWebview()
414 LogInfo("get current webview");
415 return m_currentEwkView;
418 void ViewLogic::fireJavascriptEvent(int event, void* data)
420 PluginModuleSupport::dispatchJavaScriptEvent(
422 static_cast<WrtPlugins::W3C::CustomEventType>(event),
426 void ViewLogic::setUserCallbacks(const WRT::UserDelegatesPtr& cbs)
431 void ViewLogic::checkSyncMessageFromBundle(
436 LogDebug("didReceiveSynchronousMessage called");
441 LogDebug("body is empty");
446 LogDebug("received : " << name);
448 if (!strcmp(name, uriBlockedMessageName)) {
449 // Currently WebProcess informs obly about blocked
450 // URI - URI localization and security chekcs are
451 // done by WebProcess itself (see: wrt-wk2-bundle.cpp
452 // and bundle_uri_handling.cpp)
453 result = requestUrlBlocked(std::string(body));
454 } else if (!strcmp(name, uriChangedMessageName)) {
455 result = requestUrlChanged(std::string(body));
458 *returnData = strdup(result.c_str());
461 void ViewLogic::downloadData(const char* url)
468 m_appsSupport->downloadRequest(url, NULL, NULL);
471 void ViewLogic::activateVibration(bool on, uint64_t time)
475 m_vibrationSupport->startVibration(static_cast<long>(time));
477 m_vibrationSupport->stopVibration();
481 void ViewLogic::initializeSupport()
483 // background support
484 if (m_model->SettingList.Get().getBackgroundSupport()
485 == BackgroundSupport_Enable)
487 LogDebug("Background support enabled, set process active");
488 pid_t pid = getpid();
489 sysman_inform_active(pid);
490 m_isBackgroundSupport = true;
492 #ifndef DEPRECATED_SETTING_STRING
494 WrtDB::WidgetDAOReadOnly dao(m_model->TizenId);
495 WrtDB::PropertyDAOReadOnly::WidgetPropertyValue bgEnableValue =
496 dao.getPropertyValue(DPL::String(BACKGROUND_ENABLED));
498 if (!bgEnableValue.IsNull() && !bgEnableValue->compare(L"true")) {
500 LogDebug("Background support enabled, set process active");
501 pid_t pid = getpid();
502 sysman_inform_active(pid);
503 m_isBackgroundSupport = true;
508 m_schemeSupport.reset(new SchemeSupport(m_model->Type.Get().appType));
509 ViewModule::StorageSupport::initializeStorage(m_model);
510 m_appsSupport->initialize(m_model);
511 m_securityOriginSupport.reset(new ViewModule::SecurityOriginSupport(m_model));
512 m_certificateSupport.reset(new ViewModule::CertificateSupport(m_model));
514 m_vibrationSupport->initialize();
517 void ViewLogic::initializePluginLoading()
519 // inform wrt information for plugin loading to web process
520 PluginModuleSupport::start(
523 elm_config_scale_get(),
524 ApplicationDataSingleton::Instance().getEncodedBundle(),
526 m_model->SettingList.Get().isEncrypted());
529 void ViewLogic::ewkClientInit(Evas_Object *wkView)
531 Assert(NULL != wkView && "ewk_view not created at this point");
533 FOREACH(it, m_ewkCallbacksMap) {
534 evas_object_smart_callback_add(
540 // EWK Orientation Callback
541 ewk_view_orientation_lock_callback_set(
543 orientationLockCallback,
547 void ViewLogic::ewkClientDeinit(Evas_Object *wkView)
549 LogDebug("ewkClientDeinit");
550 Assert(NULL != wkView && "ewk_view not created at this point");
552 FOREACH(it, m_ewkCallbacksMap) {
553 evas_object_smart_callback_del(
558 ewk_view_orientation_lock_callback_set(
564 bool ViewLogic::createEwkView(Evas* canvas)
566 LogDebug("createEwkVeiw");
568 ADD_PROFILING_POINT("ewk_view_add_with_context", "start");
569 Evas_Object* newEwkView = ewk_view_add_with_context(
572 ADD_PROFILING_POINT("ewk_view_add_with_context", "stop");
575 LogError("View creation failed");
576 Wrt::Popup::PopupInvoker().showInfo(
577 "Info", "View creation failed", "close");
582 // even arguments pass the ewkContext, this API should be called
583 // after webkit Evas_Object is created
584 Ewk_Cookie_Manager *ewkCookieManager;
586 ewk_context_cookie_manager_get(m_ewkContext);
587 ewk_cookie_manager_accept_policy_set(ewkCookieManager,
588 EWK_COOKIE_ACCEPT_POLICY_ALWAYS);
590 if (m_currentEwkView) {
591 setEwkViewInvisible(m_currentEwkView);
594 LogInfo("push webview: " << newEwkView);
595 m_ewkViewList.push_back(newEwkView);
596 m_currentEwkView = newEwkView;
600 void ViewLogic::setStartPage()
602 /* Start URI (as other uris) is now localized
603 * on WebProcess side */
604 m_currentUri = ViewModule::UriSupport::getUri(m_model, m_startUrl);
607 void ViewLogic::prepareEwkView(Evas_Object *wkView)
609 LogDebug("prepareEwkView called");
611 Ewk_Settings* settings = ewk_view_settings_get(wkView);
614 std::string customUserAgent = m_model->SettingList.Get().getUserAgent();
615 if (customUserAgent.empty()) {
616 auto userAgentString =
617 ViewModule::UserAgentSupport::getUserAgentFromVconf();
618 if (!userAgentString.empty()) {
619 LogDebug("Setting user agent as: " << userAgentString);
620 ewk_view_user_agent_set(wkView, userAgentString.c_str());
623 LogDebug("Setting custom user agent as: " << customUserAgent);
624 ewk_view_user_agent_set(wkView, customUserAgent.c_str());
627 // set custom header : language
628 using namespace ViewModule::CustomHeaderSupport;
629 std::string customHeaderString = getValueByField(ACCEPT_LANGUAGE);
630 if (!customHeaderString.empty()) {
631 LogDebug("custom field=[" << ACCEPT_LANGUAGE << "]");
632 LogDebug("custom value=[" << customHeaderString << "]");
633 ewk_view_custom_header_add(wkView,
634 ACCEPT_LANGUAGE.c_str(),
635 customHeaderString.c_str());
638 // webkit NPAPI plugins is always on in wrt
639 ewk_settings_plugins_enabled_set(settings, EINA_TRUE);
641 // The followings are not implemeted yet by webkit2
642 // ewk_view_setting_accelerated_compositing_enable_set(EINA_TRUE);
643 // ewk_view_mode_set();
644 // ewk_view_setting_enable_specified_plugin_set(EINA_TRUE,
646 // ewk_view_setting_html5video_external_player_enable_set(EINA_FALSE);
647 // ewk_view_show_ime_on_autofocus_set(EINA_TRUE);
648 // elm_webview_show_magnifier_set(EINA_FALSE);
649 ewk_settings_javascript_enabled_set(settings, EINA_TRUE);
650 ewk_settings_loads_images_automatically_set(settings, EINA_TRUE);
651 // WRT should not fit web contents to device width automatically as default.
652 // Fitting to device width should be handled by web content using viewport meta tag.
653 ewk_settings_auto_fitting_set(settings, EINA_FALSE);
655 // disable zoom option when user click the input field
656 // this option is useful with the normal website
657 // for the make user friendly, disable auto zoom in the webapp
658 // The followings are not implemeted yet by webkit2
659 // elm_webview_input_field_zoom_set(EINA_FALSE);
661 // set cookie database path
662 // The followings are not implemeted yet by webkit2
663 // ewk_cookies_file_set(dao.getCookieDatabasePath().c_str()));
665 // set visibility to WebCore. This value will be used for html5.
666 // also, this value will be changed in the suspend, resume
667 // or create window, close window.
668 ewk_view_page_visibility_state_set(wkView,
669 EWK_PAGE_VISIBILITY_STATE_VISIBLE,
673 void ViewLogic::removeEwkView(Evas_Object *wkView)
675 LogInfo("removeEwkView called");
677 Assert(0 != m_ewkViewList.size());
679 // unregister webview callbacks
680 ewkClientDeinit(wkView);
682 // suspend NPAPI plugin - Not implemented by Webkit2
683 // ewk_view_pause_or_resume_plugins();
684 evas_object_del(wkView);
685 m_ewkViewList.remove(wkView);
688 void ViewLogic::resumeEwkView(Evas_Object *wkView)
690 LogInfo("resumeEwkView called");
693 // register webview callback
694 ewkClientInit(wkView);
697 resumeWebkit(wkView);
702 void ViewLogic::suspendEwkView(Evas_Object *wkView)
704 LogInfo("suspendEwkView called");
708 suspendWebkit(wkView);
710 // unregister webview callbacks
711 ewkClientDeinit(wkView);
716 void ViewLogic::setEwkViewInvisible(Evas_Object *wkView)
718 LogInfo("setEwkViewInvisible called");
721 ewk_view_page_visibility_state_set(wkView,
722 EWK_PAGE_VISIBILITY_STATE_HIDDEN,
724 ewk_view_visibility_set(wkView, EINA_FALSE);
727 void ViewLogic::setEwkViewVisible(Evas_Object *wkView)
729 LogInfo("setEwkViewVisible called");
732 ewk_view_page_visibility_state_set(wkView,
733 EWK_PAGE_VISIBILITY_STATE_VISIBLE,
735 ewk_view_visibility_set(wkView, EINA_TRUE);
738 void ViewLogic::resumeWebkit(Evas_Object *wkView)
740 LogDebug("resumeWebkit");
743 // resume NPAPI plugin
744 // The followings are not implemeted yet by webkit2
745 // ewk_view_pause_or_resume_plugins(false);
746 // ewk_view_pause_or_resume_video_audio(false);
747 // ewk_view_javascript_resume();
748 // ewk_view_enable_render();
749 // ewk_view_reduce_plugins_frame_rate(false);
750 ewk_view_resume(wkView);
755 void ViewLogic::suspendWebkit(Evas_Object *wkView)
757 LogDebug("suspendWebkit");
760 // suspend the followings
761 // The followings are not implemeted yet by webkit2
762 // ewk_view_pause_or_resume_plugins(true);
763 // ewk_view_pause_or_resume_video_audio(true);
764 ewk_view_suspend(wkView);
769 void ViewLogic::loadStartedCallback(
774 LogDebug("loadStartedCallback called");
776 ViewLogic* This = static_cast<ViewLogic*>(data);
777 evas_object_focus_set(This->m_currentEwkView, EINA_TRUE);
779 // call loadFinish callback to wrt-client
780 if (!This->m_cbs->loadStart.empty()) {
781 This->m_cbs->loadStart(obj);
785 void ViewLogic::loadFinishedCallback(
790 LogDebug("loadFinishedCallback called");
792 ViewLogic* This = static_cast<ViewLogic*>(data);
795 const char* url = ewk_view_url_get(This->m_currentEwkView);
796 if (NULL == url || strlen(url) == 0) {
797 LogError("url is empty");
801 // check if this loading is for blocked url
802 if (This->m_blockedUri == url) {
803 if (ewk_view_back_possible(This->m_currentEwkView)) {
804 // go back to previous page
805 LogDebug("go to previous page");
806 ewk_view_back(This->m_currentEwkView);
809 LogDebug("remove current page");
810 ewk_view_stop(This->m_currentEwkView);
811 ecore_idler_add(windowCloseIdlerCallback, This);
813 This->m_blockedUri = std::string();
817 DPL::OptionalString jsOptionalString =
818 ViewModule::PasswordSupport::jsForAutoFillData(url);
819 if (jsOptionalString.IsNull()) {
820 LogError("Fail to get JS String");
822 std::string jsStr = DPL::ToUTF8String(*jsOptionalString).c_str();
824 if (EINA_FALSE == ewk_view_script_execute(
825 This->m_currentEwkView,
827 didRunJavaScriptCallback,
830 LogError("JS for auto fill data failed.");
834 // call loadFinish callback to wrt-client
835 if (!This->m_cbs->loadFinish.empty()) {
836 This->m_cbs->loadFinish(obj);
839 // set only encoded bundle
840 double scale = elm_config_scale_get();
841 PluginModuleSupport::setCustomProperties(
844 ApplicationDataSingleton::Instance().getEncodedBundle());
845 // check if 'appsevice' event is registed at the current frames.
846 // If so, dispatch the event to frames.
847 PluginModuleSupport::dispatchJavaScriptEvent(
849 WrtPlugins::W3C::ServiceCustomEvent,
852 // In this case, widget is reloaded in the background.
853 // After finished load, bundle should disconnent callback.
854 if (This->m_isBackgroundReload) {
855 ewk_view_suspend(This->m_currentEwkView);
856 This->m_isBackgroundReload = false;
860 void ViewLogic::titleChangedCallback(
865 LogDebug("titleChangedCallback called");
867 ViewLogic* This = static_cast<ViewLogic*>(data);
869 const char* title = static_cast<char*>(eventInfo);
871 if (0 == strlen(title)) {
872 LogDebug("title data is empty");
873 This->m_currentTitle = std::string();
876 LogDebug("Title = [" << title << "]");
877 bool ret = This->m_schemeSupport->HandleTizenScheme(
880 This->m_currentEwkView);
881 // if result is true, this is tizen scheme
882 // and then, title is reset to page's real title
884 std::string script = "document.title = \"";
885 script += This->m_currentTitle;
887 ewk_view_script_execute(obj, script.c_str(), didRunJavaScriptCallback, This);
889 This->m_currentTitle = std::string(title);
893 void ViewLogic::loadProgressCallback(
895 Evas_Object* /*obj*/,
898 double* progress = static_cast<double*>(eventInfo);
899 LogDebug("didChangeProgressCallback progress = " << *progress);
902 void ViewLogic::loadProgressFinishedCallback(
904 Evas_Object* /*obj*/,
907 LogDebug("didFinishProgressCallback");
909 ViewLogic const * const view = static_cast<ViewLogic const * const>(data);
910 if (!view->m_cbs->progressFinish.empty()) {
911 view->m_cbs->progressFinish();
915 void ViewLogic::processCrashedCallback(
917 Evas_Object* /*obj*/,
920 LogInfo("processCrashedCallback");
922 ViewLogic const * const view =
923 static_cast<ViewLogic const * const>(data);
924 if (!view->m_cbs->webCrash.empty()) {
925 view->m_cbs->webCrash();
927 // This flag will be prevented exit() call in the Webkit side
928 if (NULL != eventInfo) {
929 *(static_cast<Eina_Bool*>(eventInfo)) = EINA_TRUE;
933 void ViewLogic::createWindowCallback(
938 LogDebug("createWindowCallback");
940 ViewLogic* This = static_cast<ViewLogic*>(data);
942 // First, current webview should be handled by user callback
943 if (!This->m_cbs->bufferUnset.empty()) {
944 This->m_cbs->bufferUnset(obj);
947 // this can be set by executable for specific purpose
949 if (!This->m_cbs->windowCreateBefore.empty()) {
950 // 'obj' is parent webview object
951 This->m_cbs->windowCreateBefore(&canvas, obj);
954 canvas = evas_object_evas_get(This->m_window);
957 // create new ewkview
958 This->createEwkView(canvas);
959 Evas_Object* newEwkView = This->m_currentEwkView;
961 // initialize new ewkview
962 This->setStartPage();
963 This->ewkClientInit(newEwkView);
964 This->prepareEwkView(newEwkView);
966 // Specific jobs of child, parent webview are handled by each executable
967 if (!This->m_cbs->windowCreateAfter.empty()) {
968 // 'obj' is parent webview, 'newEwkView' is child webview
969 This->m_cbs->windowCreateAfter(obj, newEwkView);
972 // Lastly, new webview should be handled by user callback
973 if (!This->m_cbs->bufferSet.empty()) {
974 This->m_cbs->bufferSet(newEwkView);
976 *(static_cast<Evas_Object **>(eventInfo)) = newEwkView;
979 void ViewLogic::closeWindowCallback(
984 LogDebug("closeWindowCallback");
985 ViewLogic* This = static_cast<ViewLogic*>(data);
986 This->m_closedEwkView = obj;
987 ecore_idler_add(windowCloseIdlerCallback, This);
990 void ViewLogic::policyNavigationDecideCallback(
992 Evas_Object* /*obj*/,
995 LogDebug("policyNavigationDecideCallback called");
997 ViewLogic* This = static_cast<ViewLogic*>(data);
999 Ewk_Policy_Decision* policyDecision =
1000 static_cast<Ewk_Policy_Decision*>(eventInfo);
1002 if (This->m_schemeSupport->filterURIByScheme(policyDecision,
1006 This->m_currentEwkView))
1009 ewk_policy_decision_use(policyDecision);
1011 // check whether this is new empty window
1012 const char* activeUrl = ewk_view_url_get(This->m_currentEwkView);
1013 if (!activeUrl || 0 == strlen(activeUrl)) {
1015 * The view is empty and scheme has been handled externally. When
1016 * user gets back from the external application he'd see blank page
1017 * and won't be able to navigate back. This happens when window.open
1018 * is used to handle schemes like sms/mms/mailto (for example in
1019 * WAC web standards tests: WS-15XX).
1021 * To solve the problem, the empty view is removed from the stack
1022 * and the previous one is shown. This is not an elegant solution
1023 * but we don't have a better one.
1025 LogInfo("Scheme has been handled externally. Removing empty view.");
1026 if (ewk_view_back_possible(This->m_currentEwkView)) {
1027 // go back to previous WKPage
1028 ewk_view_back(This->m_currentEwkView);
1030 // stop current WKPage
1031 ewk_view_stop(This->m_currentEwkView);
1032 ecore_idler_add(windowCloseIdlerCallback, This);
1037 ewk_policy_decision_ignore(policyDecision);
1041 void ViewLogic::policyNewWindowDecideCallback(
1043 Evas_Object* /*obj*/,
1046 LogDebug("policyNewWindowDecideCallback called");
1048 ViewLogic* This = static_cast<ViewLogic*>(data);
1050 Ewk_Policy_Decision* policyDecision =
1051 static_cast<Ewk_Policy_Decision*>(eventInfo);
1053 if (This->m_schemeSupport->filterURIByScheme(policyDecision,
1057 This->m_currentEwkView))
1059 ewk_policy_decision_use(policyDecision);
1062 ewk_policy_decision_ignore(policyDecision);
1066 void ViewLogic::pageResponseDecideCallback(
1068 Evas_Object* /*obj*/,
1071 LogDebug("pageResponseDecideCallback called");
1073 ViewLogic* This = static_cast<ViewLogic*>(data);
1075 Ewk_Policy_Decision* policyDecision =
1076 static_cast<Ewk_Policy_Decision*>(eventInfo);
1077 Ewk_Policy_Decision_Type policyDecisionType =
1078 ewk_policy_decision_type_get(policyDecision);
1080 if (policyDecisionType == EWK_POLICY_DECISION_USE) {
1082 ewk_policy_decision_use(policyDecision);
1083 } else if (policyDecisionType == EWK_POLICY_DECISION_DOWNLOAD) {
1084 LogDebug("download");
1085 ewk_policy_decision_suspend(policyDecision);
1087 // get uri information
1088 const char* url = ewk_policy_decision_url_get(policyDecision);
1089 if (NULL == url || strlen(url) == 0) {
1090 LogDebug("url data is empty");
1091 ewk_policy_decision_use(policyDecision);
1094 LogDebug("url = [" << url << "]");
1096 // get content information
1097 const char* content =
1098 ewk_policy_decision_response_mime_get(policyDecision);
1099 LogDebug("content type = [" << content << "]");
1101 // get cookie information
1102 const char* cookie = ewk_policy_decision_cookie_get(policyDecision);
1103 LogDebug("cookie = [" << cookie << "]");
1105 LogDebug("Content not supported, will be opened in external app");
1106 This->m_appsSupport->downloadRequest(
1110 ewk_policy_decision_ignore(policyDecision);
1111 } else if (policyDecisionType == EWK_POLICY_DECISION_IGNORE) {
1113 ewk_policy_decision_ignore(policyDecision);
1115 LogDebug("Type isn't handled");
1116 ewk_policy_decision_ignore(policyDecision);
1120 void ViewLogic::contextmenuCustomizeCallback(
1122 Evas_Object* /*obj*/,
1125 LogDebug("contextmenuCustomizeCallback called");
1128 ViewLogic* This = static_cast<ViewLogic*>(const_cast<void*>(data));
1129 Ewk_Context_Menu* menu = static_cast<Ewk_Context_Menu*>(eventInfo);
1130 if ((This->m_model->Type.Get().appType == WrtDB::APP_TYPE_TIZENWEBAPP) &&
1131 (This->m_model->SettingList.Get().getContextMenu()
1132 == ContextMenu_Disable))
1134 LogDebug("ContextMenu Disable!!");
1135 for (unsigned int idx = 0; idx < ewk_context_menu_item_count(menu);) {
1136 Ewk_Context_Menu_Item* item = ewk_context_menu_nth_item_get(menu,
1139 ewk_context_menu_item_remove(menu, item);
1142 LogDebug("ContextMenu Enable!!");
1143 unsigned int menu_num = ewk_context_menu_item_count(menu);
1144 unsigned int idx = 0;
1146 Ewk_Context_Menu_Item* item = ewk_context_menu_nth_item_get(menu,
1152 Ewk_Context_Menu_Item_Tag tag = ewk_context_menu_item_tag_get(item);
1155 case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_IMAGE_IN_NEW_WINDOW:
1156 ewk_context_menu_item_remove(menu, item);
1159 case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_LINK_IN_NEW_WINDOW:
1160 ewk_context_menu_item_remove(menu, item);
1163 case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_FRAME_IN_NEW_WINDOW:
1164 ewk_context_menu_item_remove(menu, item);
1167 case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_MEDIA_IN_NEW_WINDOW:
1168 ewk_context_menu_item_remove(menu, item);
1171 case EWK_CONTEXT_MENU_ITEM_TAG_SEARCH_WEB:
1172 ewk_context_menu_item_remove(menu, item);
1179 } while (idx < menu_num);
1183 void ViewLogic::formSubmitCallback(
1185 Evas_Object* /*obj*/,
1188 LogDebug("formSubmitCallback called");
1190 Ewk_Form_Data* formData = static_cast<Ewk_Form_Data*>(eventInfo);
1192 const char* uri = ewk_form_data_url_get(formData);
1194 LogError("URL is empty");
1198 Eina_Hash* userData = ewk_form_data_values_get(formData);
1199 ViewModule::PasswordSupport::submitClicked(uri, userData);
1202 void ViewLogic::geolocationPermissionRequestCallback(
1204 Evas_Object* /*obj*/,
1208 ViewLogic* This = static_cast<ViewLogic*>(data);
1210 Ewk_Geolocation_Permission_Request* permissionRequest =
1211 static_cast<Ewk_Geolocation_Permission_Request*>(eventInfo);
1213 if (This->m_securityOriginSupport->isNeedPermissionCheck(
1214 SecurityOriginDB::FEATURE_GEOLOCATION)
1215 == WrtDB::SETTINGS_TYPE_OFF)
1217 ewk_geolocation_permission_request_set(permissionRequest, EINA_FALSE);
1220 ViewModule::GeolocationSupport::Webkit2::geolocationPermissionRequest(
1222 This->m_securityOriginSupport->getSecurityOriginDAO(),
1226 void ViewLogic::notificationShowCallback(
1228 Evas_Object* /*obj*/,
1231 LogDebug("notificationShowCallback called");
1233 ViewLogic* This = static_cast<ViewLogic*>(data);
1236 Ewk_Notification* noti = static_cast<Ewk_Notification*>(eventInfo);
1238 using namespace ViewModule::WebNotification;
1240 WebNotificationDataPtr notiData(
1241 new WebNotificationData(
1243 ewk_notification_id_get(noti)));
1245 DPL::OptionalString string =
1246 DPL::FromUTF8String(ewk_notification_icon_url_get(noti));
1247 if (!string.IsNull()) {
1248 notiData->m_iconURL = DPL::ToUTF8String(*string);
1250 string = DPL::FromUTF8String(ewk_notification_title_get(noti));
1251 if (!string.IsNull()) {
1252 notiData->m_title = DPL::ToUTF8String(*string);
1254 string = DPL::FromUTF8String(ewk_notification_body_get(noti));
1255 if (!string.IsNull()) {
1256 notiData->m_body = DPL::ToUTF8String(*string);
1259 LogInfo("notification id : " << notiData->m_id);
1260 LogInfo("notification iconURL : " << notiData->m_iconURL);
1261 LogInfo("notification title : " << notiData->m_title);
1262 LogInfo("notification body : " << notiData->m_body);
1264 showWebNotification(notiData);
1265 ewk_notification_showed(This->m_ewkContext, ewk_notification_id_get(noti));
1268 void ViewLogic::notificationCancelCallback(
1270 Evas_Object* /*obj*/,
1271 void* /*eventInfo*/)
1273 LogDebug("notificationCancelCallback called");
1276 void ViewLogic::notificationPermissionRequestCallback(
1278 Evas_Object* /*obj*/,
1281 LogDebug("notificationPermissionRequestCallback called");
1283 ViewLogic* This = static_cast<ViewLogic*>(data);
1284 if (This->m_securityOriginSupport->isNeedPermissionCheck(
1285 SecurityOriginDB::FEATURE_WEB_NOTIFICATION)
1286 == WrtDB::SETTINGS_TYPE_OFF)
1288 Ewk_Notification_Permission_Request* request =
1289 static_cast<Ewk_Notification_Permission_Request*>(eventInfo);
1290 ewk_notification_permission_request_set(
1297 ViewModule::WebNotification::webNotificationPermissionRequest(
1299 This->m_securityOriginSupport->getSecurityOriginDAO(),
1304 // EWK Orientation Callback
1305 Eina_Bool ViewLogic::orientationLockCallback(
1307 Eina_Bool /*needLock*/,
1311 LogDebug("orientationLockCallback called");
1313 ViewLogic* This = static_cast<ViewLogic*>(data);
1315 if (orientation & EWK_SCREEN_ORIENTATION_PORTRAIT_PRIMARY) {
1316 LogDebug("orientation is portrait-primary");
1317 elm_win_rotation_with_resize_set(This->m_window, 0);
1318 ewk_view_orientation_send(obj, 0);
1319 } else if (orientation & EWK_SCREEN_ORIENTATION_LANDSCAPE_PRIMARY) {
1320 LogDebug("orientation is landscape-primary");
1321 elm_win_rotation_with_resize_set(This->m_window, 270);
1322 ewk_view_orientation_send(obj, 90);
1323 } else if (orientation & EWK_SCREEN_ORIENTATION_PORTRAIT_SECONDARY) {
1324 LogDebug("orientation is portrait-secondary");
1325 elm_win_rotation_with_resize_set(This->m_window, 180);
1326 ewk_view_orientation_send(obj, 180);
1327 } else if (orientation & EWK_SCREEN_ORIENTATION_LANDSCAPE_SECONDARY) {
1328 LogDebug("orientation is landscape-secondary");
1329 elm_win_rotation_with_resize_set(This->m_window, 90);
1330 ewk_view_orientation_send(obj, -90);
1332 LogDebug("Wrong orientation is set");
1338 // Fullscreen API callbacks
1339 void ViewLogic::enterFullscreenCallback(
1341 Evas_Object* /*obj*/,
1342 void* /*eventInfo*/)
1344 LogInfo("enterFullscreenCallback called");
1346 ViewLogic* This = static_cast<ViewLogic*>(data);
1347 if (!This->m_cbs->toggleFullscreen.empty()) {
1348 This->m_cbs->toggleFullscreen(true);
1351 void ViewLogic::exitFullscreenCallback(
1353 Evas_Object* /*obj*/,
1354 void* /*eventInfo*/)
1356 LogInfo("exitFullscreenCallback called");
1358 ViewLogic* This = static_cast<ViewLogic*>(data);
1359 if (!This->m_cbs->toggleFullscreen.empty()) {
1360 This->m_cbs->toggleFullscreen(false);
1364 void ViewLogic::imeChangedCallback(
1366 Evas_Object* /*obj*/,
1372 ViewLogic* This = static_cast<ViewLogic*>(data);
1373 Eina_Rectangle *rect = static_cast<Eina_Rectangle *>(eventInfo);
1374 This->m_imeWidth = rect->w;
1375 This->m_imeHeight = rect->h;
1378 void ViewLogic::imeOpenedCallback(
1380 Evas_Object* /*obj*/,
1381 void* /*eventInfo*/)
1385 ViewLogic* This = static_cast<ViewLogic*>(data);
1387 using namespace WrtPlugins::W3C;
1388 SoftKeyboardChangeArgs args;
1389 args.state = IME_STATE_ON;
1390 args.width = This->m_imeWidth;
1391 args.height = This->m_imeHeight;
1392 This->fireJavascriptEvent(
1393 static_cast<int>(SoftKeyboardChangeCustomEvent),
1397 void ViewLogic::imeClosedCallback(
1399 Evas_Object* /*obj*/,
1400 void* /*eventInfo*/)
1404 ViewLogic* This = static_cast<ViewLogic*>(data);
1406 using namespace WrtPlugins::W3C;
1407 SoftKeyboardChangeArgs args;
1408 args.state = IME_STATE_OFF;
1410 This->fireJavascriptEvent(
1411 static_cast<int>(SoftKeyboardChangeCustomEvent),
1415 void ViewLogic::usermediaPermissionRequestCallback(
1417 Evas_Object* /*obj*/,
1420 LogDebug("usermediaPermissionRequestCallback called");
1422 ViewLogic* This = static_cast<ViewLogic*>(data);
1423 ViewModule::UsermediaSupport::usermediaPermissionRequest(This->m_window,
1428 CustomHandlerDB::CustomHandlerPtr getCustomHandlerFromData(void* data)
1431 Ewk_Custom_Handlers_Data* handler =
1432 static_cast<Ewk_Custom_Handlers_Data*>(data);
1433 CustomHandlerDB::CustomHandlerPtr customHandler(
1434 new CustomHandlerDB::CustomHandler());
1435 const char* base_url = ewk_custom_handlers_data_base_url_get(handler);
1437 LogDebug("base url: " << base_url);
1438 customHandler->base_url = DPL::FromASCIIString(string(base_url));
1440 const char* url = ewk_custom_handlers_data_url_get(handler);
1442 LogDebug("url: " << url);
1443 customHandler->url = DPL::FromASCIIString(string(url));
1445 const char* target = ewk_custom_handlers_data_target_get(handler);
1447 LogDebug("target: " << target);
1448 customHandler->target = DPL::FromASCIIString(string(target));
1450 const char* title = ewk_custom_handlers_data_title_get(handler);
1452 LogDebug("title: " << title);
1453 customHandler->title = DPL::FromASCIIString(string(title));
1455 return customHandler;
1458 void ViewLogic::attachToCustomHandlersDao()
1460 if (!m_attachedToCustomHandlerDao) {
1461 CustomHandlerDB::Interface::attachDatabaseRW();
1465 void ViewLogic::detachFromCustomHandlersDao()
1467 if (m_attachedToCustomHandlerDao) {
1468 CustomHandlerDB::Interface::detachDatabase();
1472 const int protocolWhiteListLenth = 15;
1473 char const * const protocolWhiteList[protocolWhiteListLenth] = {
1491 const int contentBlackListLenth = 14;
1492 char const * const contentBlackList[contentBlackListLenth] = {
1493 "application/x-www-form-urlencoded",
1494 "application/xhtml+xml",
1500 "multipart/x-mixed-replace",
1501 "text/cache-manifest",
1510 * Saves user's response from popup to custom handler. Saves Yes/No and remember
1513 * @param customHandler
1515 void saveUserResponse(Wrt::Popup::PopupResponse response,
1516 CustomHandlerDB::CustomHandlerPtr customHandler)
1519 case Wrt::Popup::YES_DO_REMEMBER:
1520 LogDebug("User allowed, remember");
1521 customHandler->user_decision =
1522 static_cast<CustomHandlerDB::HandlerState>
1523 (CustomHandlerDB::Agreed | CustomHandlerDB::DecisionSaved);
1525 case Wrt::Popup::YES_DONT_REMEMBER:
1526 LogDebug("User allowed, don't remember");
1527 customHandler->user_decision = CustomHandlerDB::Agreed;
1529 case Wrt::Popup::NO_DO_REMEMBER:
1530 LogDebug("User didn't allow, remember");
1531 customHandler->user_decision =
1532 static_cast<CustomHandlerDB::HandlerState>
1533 (CustomHandlerDB::Declined | CustomHandlerDB::DecisionSaved);
1535 case Wrt::Popup::NO_DONT_REMEMBER:
1536 LogDebug("User didn't allow, don't remember");
1537 customHandler->user_decision = CustomHandlerDB::Declined;
1542 //TODO registration, checking if registered and unregistration can be done in
1543 //common functions for both types of handlers. Only white and black lists
1544 //have to be separated
1545 //TODO attach database only one at the start (not in every callback?)
1546 void ViewLogic::protocolHandlerRegistrationCallback(void* data,
1547 Evas_Object* /*obj*/,
1552 CustomHandlerDB::CustomHandlerPtr customHandler =
1553 getCustomHandlerFromData(eventInfo);
1555 std::string scheme = DPL::ToUTF8String(customHandler->target);
1556 if (scheme.empty()) {
1557 LogError("No scheme provided");
1558 //TODO what about securityError?
1561 bool matched = false;
1562 //scheme on whiteList
1563 for (int i = 0; i < protocolWhiteListLenth; ++i) {
1564 if (0 == strcmp(protocolWhiteList[i], scheme.c_str())) {
1565 LogDebug("Match found, protocol can be handled");
1570 //starts with web+ and have at least 5 chars (lowercase ASCII)
1571 if (strncmp("web+", scheme.c_str(), 4) || scheme.length() < 5) {
1572 LogWarning("Scheme neither on whitelist nor starts with \"web+\"");
1573 //throw SecurityException
1579 if (c < 'a' || c > 'z') {
1580 LogWarning("Wrong char inside scheme. "
1581 << "Only lowercase ASCII letters accepted");
1582 //throw SecurityException
1589 ViewLogic* This = static_cast<ViewLogic*>(data);
1590 LogDebug("Creating handlers dao");
1591 This->attachToCustomHandlersDao();
1592 CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1593 CustomHandlerDB::CustomHandlerPtr handler =
1594 handlersDao.getProtocolHandler(customHandler->target,
1596 customHandler->base_url);
1597 if (handler && (handler->user_decision & CustomHandlerDB::DecisionSaved)) {
1598 LogDebug("Protocol already registered - nothing to do");
1600 LogDebug("Protocol handler not found");
1601 Wrt::Popup::PopupResponse response =
1602 GlobalSettings::PopupsTestModeEnabled() ? Wrt::Popup::
1604 Wrt::Popup::PopupInvoker().askYesNoCheckbox(
1605 PROTOCOL_HANDLER_ASK_TITLE,
1606 PROTOCOL_HANDLER_ASK_MSG,
1607 PROTOCOL_HANDLER_ASK_REMEMBER);
1608 saveUserResponse(response, customHandler);
1609 if (customHandler->user_decision == CustomHandlerDB::Declined) {
1612 handlersDao.registerProtocolHandler(*(customHandler.get()));
1613 if (customHandler->user_decision & CustomHandlerDB::Agreed) {
1614 //TODO remove old default handler somehow from appsvc
1615 LogDebug("Registering appservice entry");
1616 int ret = appsvc_set_defapp(APPSVC_OPERATION_VIEW,
1619 customHandler->target).c_str(),
1620 DPL::ToUTF8String(This->m_model->
1622 if (APPSVC_RET_OK != ret) {
1623 LogWarning("Appsvc entry failed: " << ret);
1626 LogDebug("Protocal saved");
1629 This->detachFromCustomHandlersDao();
1632 void ViewLogic::protocolHandlerIsRegisteredCallback(void* data,
1633 Evas_Object* /*obj*/,
1637 CustomHandlerDB::CustomHandlerPtr customHandler = getCustomHandlerFromData(
1639 ViewLogic* This = static_cast<ViewLogic*>(data);
1640 LogDebug("Creating handlers dao");
1641 This->attachToCustomHandlersDao();
1642 CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1643 CustomHandlerDB::CustomHandlerPtr handler =
1644 handlersDao.getProtocolHandler(customHandler->target,
1646 customHandler->base_url);
1648 if (handler->user_decision & CustomHandlerDB::Agreed) {
1649 ewk_custom_handlers_data_result_set(
1650 static_cast<Ewk_Custom_Handlers_Data*>(data),
1651 EWK_CUSTOM_HANDLERS_REGISTERED);
1653 ewk_custom_handlers_data_result_set(
1654 static_cast<Ewk_Custom_Handlers_Data*>(data),
1655 EWK_CUSTOM_HANDLERS_DECLINED);
1658 ewk_custom_handlers_data_result_set(
1659 static_cast<Ewk_Custom_Handlers_Data*>(data),
1660 EWK_CUSTOM_HANDLERS_NEW);
1662 This->detachFromCustomHandlersDao();
1665 void ViewLogic::protocolHandlerUnregistrationCallback(void* data,
1666 Evas_Object* /*obj*/,
1670 CustomHandlerDB::CustomHandlerPtr customHandler =
1671 getCustomHandlerFromData(eventInfo);
1672 ViewLogic* This = static_cast<ViewLogic*>(data);
1673 LogDebug("Creating handlers dao");
1674 This->attachToCustomHandlersDao();
1675 CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1676 CustomHandlerDB::CustomHandlerPtr handlerCheck =
1677 handlersDao.getProtocolHandler(customHandler->target,
1679 customHandler->base_url);
1681 if (handlerCheck->user_decision & CustomHandlerDB::Agreed) {
1682 appsvc_unset_defapp(DPL::ToUTF8String(This->m_model->TizenId).c_str());
1685 handlersDao.unregisterProtocolHandler(customHandler->target,
1687 customHandler->base_url);
1689 LogDebug("Nothing to unregister");
1692 This->detachFromCustomHandlersDao();
1695 void ViewLogic::contentHandlerRegistrationCallback(void* data,
1696 Evas_Object* /*obj*/,
1701 CustomHandlerDB::CustomHandlerPtr customHandler =
1702 getCustomHandlerFromData(eventInfo);
1704 std::string mimeType = DPL::ToUTF8String(customHandler->target);
1705 if (mimeType.empty()) {
1706 LogError("No mimeType provided.");
1709 for (int i = 0; i < contentBlackListLenth; ++i) {
1710 if (0 == strcmp(contentBlackList[i], mimeType.c_str())) {
1711 LogWarning("mimeType blacklisted");
1712 //throw SecurityException
1717 ViewLogic* This = static_cast<ViewLogic*>(data);
1718 LogDebug("Creating handlers dao");
1719 This->attachToCustomHandlersDao();
1720 CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1721 CustomHandlerDB::CustomHandlerPtr handler =
1722 handlersDao.getContentHandler(customHandler->target,
1724 customHandler->base_url);
1725 if (handler && (handler->user_decision & CustomHandlerDB::DecisionSaved)) {
1726 LogDebug("Protocol already registered - nothing to do");
1728 LogDebug("Protocol handler not found");
1729 Wrt::Popup::PopupResponse response =
1730 GlobalSettings::PopupsTestModeEnabled() ? Wrt::Popup::
1732 Wrt::Popup::PopupInvoker().askYesNoCheckbox(
1733 CONTENT_HANDLER_ASK_TITLE,
1734 CONTENT_HANDLER_ASK_MSG,
1735 CONTENT_HANDLER_AKS_REMEMBER);
1736 saveUserResponse(response, customHandler);
1737 if (customHandler->user_decision == CustomHandlerDB::Declined) {
1740 handlersDao.registerContentHandler(*(customHandler.get()));
1741 if (customHandler->user_decision & CustomHandlerDB::Agreed) {
1742 //TODO remove old default handler somehow from appsvc
1743 LogDebug("Registering appservice entry");
1744 int ret = appsvc_set_defapp(APPSVC_OPERATION_VIEW,
1746 customHandler->target).c_str(),
1748 DPL::ToUTF8String(This->m_model->
1750 if (APPSVC_RET_OK != ret) {
1751 LogWarning("Appsvc entry failed: " << ret);
1754 LogDebug("Content saved");
1756 This->detachFromCustomHandlersDao();
1759 void ViewLogic::contentHandlerIsRegisteredCallback(void* data,
1760 Evas_Object* /*obj*/,
1764 CustomHandlerDB::CustomHandlerPtr customHandler =
1765 getCustomHandlerFromData(eventInfo);
1766 ViewLogic* This = static_cast<ViewLogic*>(data);
1767 LogDebug("Creating handlers dao");
1769 This->attachToCustomHandlersDao();
1770 CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1771 CustomHandlerDB::CustomHandlerPtr handler =
1772 handlersDao.getContentHandler(customHandler->target,
1774 customHandler->base_url);
1776 if (handler->user_decision & CustomHandlerDB::Agreed) {
1777 ewk_custom_handlers_data_result_set(
1778 static_cast<Ewk_Custom_Handlers_Data*>(data),
1779 EWK_CUSTOM_HANDLERS_REGISTERED);
1781 ewk_custom_handlers_data_result_set(
1782 static_cast<Ewk_Custom_Handlers_Data*>(data),
1783 EWK_CUSTOM_HANDLERS_DECLINED);
1786 ewk_custom_handlers_data_result_set(
1787 static_cast<Ewk_Custom_Handlers_Data*>(data),
1788 EWK_CUSTOM_HANDLERS_NEW);
1790 This->detachFromCustomHandlersDao();
1793 void ViewLogic::contentHandlerUnregistrationCallback(void* data,
1794 Evas_Object* /*obj*/,
1798 CustomHandlerDB::CustomHandlerPtr customHandler =
1799 getCustomHandlerFromData(eventInfo);
1800 ViewLogic* This = static_cast<ViewLogic*>(data);
1801 LogDebug("Creating handlers dao");
1802 This->attachToCustomHandlersDao();
1803 CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1804 CustomHandlerDB::CustomHandlerPtr handlerCheck =
1805 handlersDao.getContentHandler(customHandler->target,
1807 customHandler->base_url);
1809 if (handlerCheck->user_decision & CustomHandlerDB::Agreed) {
1810 appsvc_unset_defapp(DPL::ToUTF8String(This->m_model->TizenId).c_str());
1813 handlersDao.unregisterContentHandler(customHandler->target,
1815 customHandler->base_url);
1817 LogDebug("Nothing to unregister");
1819 This->detachFromCustomHandlersDao();
1822 void ViewLogic::didRunJavaScriptCallback(
1823 Evas_Object* /*obj*/,
1827 LogInfo("didRunJavaScriptCallback called");
1828 LogInfo("result = " << result);
1831 Eina_Bool ViewLogic::windowCloseIdlerCallback(void* data)
1833 LogDebug("closeIdlerCallback");
1834 ViewLogic* This = static_cast<ViewLogic*>(data);
1835 This->windowClose();
1836 return ECORE_CALLBACK_CANCEL;
1839 void ViewLogic::certificateConfirmRequestCallback(
1841 Evas_Object* /*obj*/,
1844 LogDebug("certificateConfirmRequestCallback called");
1847 ViewLogic* This = static_cast<ViewLogic*>(data);
1849 ViewModule::CertificateConfirmSupport::certificatePermissionRequest(
1851 This->m_certificateSupport->getCertificateDAO(),
1855 void ViewLogic::authenticationChallengeRequestCallback(
1857 Evas_Object* /*obj*/,
1860 LogDebug("authenticationChallengeRequestCallback called");
1863 ViewLogic* This = static_cast<ViewLogic*>(data);
1864 const char* url = ewk_view_url_get(This->m_currentEwkView);
1865 if (!url || strlen(url) == 0) {
1866 url = This->m_currentUri.c_str();
1869 ViewModule::AuthenticationChallengeSupport::authenticationChallengeRequest(
1870 This->m_currentEwkView,
1875 std::string ViewLogic::requestUrlBlocked(const std::string& blockedUrl)
1879 if (m_model->Type.Get().appType == WrtDB::APP_TYPE_TIZENWEBAPP) {
1880 // block this page and open it in browser
1881 LogDebug("Request was blocked by WARP: " << blockedUrl);
1882 LogDebug("open browser : " << blockedUrl);
1883 bundle* bundleData = bundle_create();
1884 appsvc_set_operation(bundleData, APPSVC_OPERATION_VIEW);
1885 appsvc_set_uri(bundleData, blockedUrl.c_str());
1886 CONTROLLER_POST_EVENT(
1887 ApplicationLauncher,
1888 ApplicationLauncherEvents::LaunchApplicationByAppService(
1894 // set block url. This is used on load finished callback
1895 m_blockedUri = blockedUrl;
1897 // This is used in case of returning previous page
1898 return URICHANGE_PLUGIN_NO_CHANGE;
1901 std::string ViewLogic::requestUrlChanged(const std::string& changedUrl)
1903 using namespace ViewModule::SecuritySupport;
1905 LogInfo("changed url: " << changedUrl);
1907 // Check if this url with 'http' or 'https' is included in whitelist,
1908 // which has lists of accessible external documents and
1909 // used for ONLY Tizen app
1910 std::string matchedScheme;
1911 std::string matchedUri;
1912 pcrecpp::RE(PATTERN_URI_CHANGE).PartialMatch(changedUrl.c_str(),
1915 ViewModule::Scheme scheme(matchedScheme);
1916 if (scheme.GetType() == ViewModule::Scheme::HTTP ||
1917 scheme.GetType() == ViewModule::Scheme::HTTPS)
1919 if (m_model->Type.Get().appType == WrtDB::APP_TYPE_TIZENWEBAPP) {
1920 if (!checkWhitelist(changedUrl.c_str())) {
1921 LogInfo("This uri is not included in white document list");
1922 return URICHANGE_PLUGIN_STOP_ONLY;
1924 LogInfo("This url is included in WhiteList");
1926 // For WAC app, WRT should block access of device api
1927 // for external documents
1928 return URICHANGE_PLUGIN_STOP_ONLY;
1932 m_currentUri = changedUrl;
1933 return URICHANGE_PLUGIN_RESTART;
1936 void ViewLogic::windowClose()
1938 LogDebug("windowClose");
1939 Assert(m_closedEwkView && "no closed webview");
1941 if (1 >= m_ewkViewList.size()) {
1942 if (!m_cbs->webkitExit.empty()) {
1943 m_cbs->webkitExit();
1946 // call user callbacks
1947 if (!m_cbs->bufferUnset.empty()) {
1948 m_cbs->bufferUnset(m_currentEwkView);
1950 if (!m_cbs->windowClose.empty()) {
1951 m_cbs->windowClose(m_closedEwkView);
1953 removeEwkView(m_closedEwkView);
1955 // get latest ewkView
1956 m_currentEwkView = m_ewkViewList.back();
1957 const char* uri = ewk_view_url_get(m_currentEwkView);
1958 if (NULL == uri || 0 == strlen(uri)) {
1959 m_currentUri.clear();
1965 /* In case we support many pages in parallel
1966 * then view is not suspended*/
1967 //resumeEwkView(m_currentEwkView);
1968 setEwkViewVisible(m_currentEwkView);
1971 if (!m_cbs->bufferSet.empty()) {
1972 m_cbs->bufferSet(m_currentEwkView);