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(
862 Evas_Object* /*obj*/,
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");
875 LogDebug("Title = [" << title << "]");
876 This->m_schemeSupport->HandleTizenScheme(title,
878 This->m_currentEwkView);
881 void ViewLogic::loadProgressCallback(
883 Evas_Object* /*obj*/,
886 double* progress = static_cast<double*>(eventInfo);
887 LogDebug("didChangeProgressCallback progress = " << *progress);
890 void ViewLogic::loadProgressFinishedCallback(
892 Evas_Object* /*obj*/,
895 LogDebug("didFinishProgressCallback");
897 ViewLogic const * const view = static_cast<ViewLogic const * const>(data);
898 if (!view->m_cbs->progressFinish.empty()) {
899 view->m_cbs->progressFinish();
903 void ViewLogic::processCrashedCallback(
905 Evas_Object* /*obj*/,
908 LogInfo("processCrashedCallback");
910 ViewLogic const * const view =
911 static_cast<ViewLogic const * const>(data);
912 if (!view->m_cbs->webCrash.empty()) {
913 view->m_cbs->webCrash();
915 // This flag will be prevented exit() call in the Webkit side
916 if (NULL != eventInfo) {
917 *(static_cast<Eina_Bool*>(eventInfo)) = EINA_TRUE;
921 void ViewLogic::createWindowCallback(
926 LogDebug("createWindowCallback");
928 ViewLogic* This = static_cast<ViewLogic*>(data);
930 // First, current webview should be handled by user callback
931 if (!This->m_cbs->bufferUnset.empty()) {
932 This->m_cbs->bufferUnset(obj);
935 // this can be set by executable for specific purpose
937 if (!This->m_cbs->windowCreateBefore.empty()) {
938 // 'obj' is parent webview object
939 This->m_cbs->windowCreateBefore(&canvas, obj);
942 canvas = evas_object_evas_get(This->m_window);
945 // create new ewkview
946 This->createEwkView(canvas);
947 Evas_Object* newEwkView = This->m_currentEwkView;
949 // initialize new ewkview
950 This->setStartPage();
951 This->ewkClientInit(newEwkView);
952 This->prepareEwkView(newEwkView);
954 // Specific jobs of child, parent webview are handled by each executable
955 if (!This->m_cbs->windowCreateAfter.empty()) {
956 // 'obj' is parent webview, 'newEwkView' is child webview
957 This->m_cbs->windowCreateAfter(obj, newEwkView);
960 // Lastly, new webview should be handled by user callback
961 if (!This->m_cbs->bufferSet.empty()) {
962 This->m_cbs->bufferSet(newEwkView);
964 *(static_cast<Evas_Object **>(eventInfo)) = newEwkView;
967 void ViewLogic::closeWindowCallback(
972 LogDebug("closeWindowCallback");
973 ViewLogic* This = static_cast<ViewLogic*>(data);
974 This->m_closedEwkView = obj;
975 ecore_idler_add(windowCloseIdlerCallback, This);
978 void ViewLogic::policyNavigationDecideCallback(
980 Evas_Object* /*obj*/,
983 LogDebug("policyNavigationDecideCallback called");
985 ViewLogic* This = static_cast<ViewLogic*>(data);
987 Ewk_Policy_Decision* policyDecision =
988 static_cast<Ewk_Policy_Decision*>(eventInfo);
990 if (This->m_schemeSupport->filterURIByScheme(policyDecision,
994 This->m_currentEwkView))
997 ewk_policy_decision_use(policyDecision);
999 // check whether this is new empty window
1000 const char* activeUrl = ewk_view_url_get(This->m_currentEwkView);
1001 if (!activeUrl || 0 == strlen(activeUrl)) {
1003 * The view is empty and scheme has been handled externally. When
1004 * user gets back from the external application he'd see blank page
1005 * and won't be able to navigate back. This happens when window.open
1006 * is used to handle schemes like sms/mms/mailto (for example in
1007 * WAC web standards tests: WS-15XX).
1009 * To solve the problem, the empty view is removed from the stack
1010 * and the previous one is shown. This is not an elegant solution
1011 * but we don't have a better one.
1013 LogInfo("Scheme has been handled externally. Removing empty view.");
1014 if (ewk_view_back_possible(This->m_currentEwkView)) {
1015 // go back to previous WKPage
1016 ewk_view_back(This->m_currentEwkView);
1018 // stop current WKPage
1019 ewk_view_stop(This->m_currentEwkView);
1020 ecore_idler_add(windowCloseIdlerCallback, This);
1025 ewk_policy_decision_ignore(policyDecision);
1029 void ViewLogic::policyNewWindowDecideCallback(
1031 Evas_Object* /*obj*/,
1034 LogDebug("policyNewWindowDecideCallback called");
1036 ViewLogic* This = static_cast<ViewLogic*>(data);
1038 Ewk_Policy_Decision* policyDecision =
1039 static_cast<Ewk_Policy_Decision*>(eventInfo);
1041 if (This->m_schemeSupport->filterURIByScheme(policyDecision,
1045 This->m_currentEwkView))
1047 ewk_policy_decision_use(policyDecision);
1050 ewk_policy_decision_ignore(policyDecision);
1054 void ViewLogic::pageResponseDecideCallback(
1056 Evas_Object* /*obj*/,
1059 LogDebug("pageResponseDecideCallback called");
1061 ViewLogic* This = static_cast<ViewLogic*>(data);
1063 Ewk_Policy_Decision* policyDecision =
1064 static_cast<Ewk_Policy_Decision*>(eventInfo);
1065 Ewk_Policy_Decision_Type policyDecisionType =
1066 ewk_policy_decision_type_get(policyDecision);
1068 if (policyDecisionType == EWK_POLICY_DECISION_USE) {
1070 ewk_policy_decision_use(policyDecision);
1071 } else if (policyDecisionType == EWK_POLICY_DECISION_DOWNLOAD) {
1072 LogDebug("download");
1073 ewk_policy_decision_suspend(policyDecision);
1075 // get uri information
1076 const char* url = ewk_policy_decision_url_get(policyDecision);
1077 if (NULL == url || strlen(url) == 0) {
1078 LogDebug("url data is empty");
1079 ewk_policy_decision_use(policyDecision);
1082 LogDebug("url = [" << url << "]");
1084 // get content information
1085 const char* content =
1086 ewk_policy_decision_response_mime_get(policyDecision);
1087 LogDebug("content type = [" << content << "]");
1089 // get cookie information
1090 const char* cookie = ewk_policy_decision_cookie_get(policyDecision);
1091 LogDebug("cookie = [" << cookie << "]");
1093 LogDebug("Content not supported, will be opened in external app");
1094 This->m_appsSupport->downloadRequest(
1098 ewk_policy_decision_ignore(policyDecision);
1099 } else if (policyDecisionType == EWK_POLICY_DECISION_IGNORE) {
1101 ewk_policy_decision_ignore(policyDecision);
1103 LogDebug("Type isn't handled");
1104 ewk_policy_decision_ignore(policyDecision);
1108 void ViewLogic::contextmenuCustomizeCallback(
1110 Evas_Object* /*obj*/,
1113 LogDebug("contextmenuCustomizeCallback called");
1116 ViewLogic* This = static_cast<ViewLogic*>(const_cast<void*>(data));
1117 Ewk_Context_Menu* menu = static_cast<Ewk_Context_Menu*>(eventInfo);
1118 if ((This->m_model->Type.Get().appType == WrtDB::APP_TYPE_TIZENWEBAPP) &&
1119 (This->m_model->SettingList.Get().getContextMenu()
1120 == ContextMenu_Disable))
1122 LogDebug("ContextMenu Disable!!");
1123 for (unsigned int idx = 0; idx < ewk_context_menu_item_count(menu);) {
1124 Ewk_Context_Menu_Item* item = ewk_context_menu_nth_item_get(menu,
1127 ewk_context_menu_item_remove(menu, item);
1130 LogDebug("ContextMenu Enable!!");
1131 unsigned int menu_num = ewk_context_menu_item_count(menu);
1132 unsigned int idx = 0;
1134 Ewk_Context_Menu_Item* item = ewk_context_menu_nth_item_get(menu,
1140 Ewk_Context_Menu_Item_Tag tag = ewk_context_menu_item_tag_get(item);
1143 case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_IMAGE_IN_NEW_WINDOW:
1144 ewk_context_menu_item_remove(menu, item);
1147 case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_LINK_IN_NEW_WINDOW:
1148 ewk_context_menu_item_remove(menu, item);
1151 case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_FRAME_IN_NEW_WINDOW:
1152 ewk_context_menu_item_remove(menu, item);
1155 case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_MEDIA_IN_NEW_WINDOW:
1156 ewk_context_menu_item_remove(menu, item);
1159 case EWK_CONTEXT_MENU_ITEM_TAG_SEARCH_WEB:
1160 ewk_context_menu_item_remove(menu, item);
1167 } while (idx < menu_num);
1171 void ViewLogic::formSubmitCallback(
1173 Evas_Object* /*obj*/,
1176 LogDebug("formSubmitCallback called");
1178 Ewk_Form_Data* formData = static_cast<Ewk_Form_Data*>(eventInfo);
1180 const char* uri = ewk_form_data_url_get(formData);
1182 LogError("URL is empty");
1186 Eina_Hash* userData = ewk_form_data_values_get(formData);
1187 ViewModule::PasswordSupport::submitClicked(uri, userData);
1190 void ViewLogic::geolocationPermissionRequestCallback(
1192 Evas_Object* /*obj*/,
1196 ViewLogic* This = static_cast<ViewLogic*>(data);
1198 Ewk_Geolocation_Permission_Request* permissionRequest =
1199 static_cast<Ewk_Geolocation_Permission_Request*>(eventInfo);
1201 if (This->m_securityOriginSupport->isNeedPermissionCheck(
1202 SecurityOriginDB::FEATURE_GEOLOCATION)
1203 == WrtDB::SETTINGS_TYPE_OFF)
1205 ewk_geolocation_permission_request_set(permissionRequest, EINA_FALSE);
1208 ViewModule::GeolocationSupport::Webkit2::geolocationPermissionRequest(
1210 This->m_securityOriginSupport->getSecurityOriginDAO(),
1214 void ViewLogic::notificationShowCallback(
1216 Evas_Object* /*obj*/,
1219 LogDebug("notificationShowCallback called");
1221 ViewLogic* This = static_cast<ViewLogic*>(data);
1224 Ewk_Notification* noti = static_cast<Ewk_Notification*>(eventInfo);
1226 using namespace ViewModule::WebNotification;
1228 WebNotificationDataPtr notiData(
1229 new WebNotificationData(
1231 ewk_notification_id_get(noti)));
1233 DPL::OptionalString string =
1234 DPL::FromUTF8String(ewk_notification_icon_url_get(noti));
1235 if (!string.IsNull()) {
1236 notiData->m_iconURL = DPL::ToUTF8String(*string);
1238 string = DPL::FromUTF8String(ewk_notification_title_get(noti));
1239 if (!string.IsNull()) {
1240 notiData->m_title = DPL::ToUTF8String(*string);
1242 string = DPL::FromUTF8String(ewk_notification_body_get(noti));
1243 if (!string.IsNull()) {
1244 notiData->m_body = DPL::ToUTF8String(*string);
1247 LogInfo("notification id : " << notiData->m_id);
1248 LogInfo("notification iconURL : " << notiData->m_iconURL);
1249 LogInfo("notification title : " << notiData->m_title);
1250 LogInfo("notification body : " << notiData->m_body);
1252 showWebNotification(notiData);
1253 ewk_notification_showed(This->m_ewkContext, ewk_notification_id_get(noti));
1256 void ViewLogic::notificationCancelCallback(
1258 Evas_Object* /*obj*/,
1259 void* /*eventInfo*/)
1261 LogDebug("notificationCancelCallback called");
1264 void ViewLogic::notificationPermissionRequestCallback(
1266 Evas_Object* /*obj*/,
1269 LogDebug("notificationPermissionRequestCallback called");
1271 ViewLogic* This = static_cast<ViewLogic*>(data);
1272 if (This->m_securityOriginSupport->isNeedPermissionCheck(
1273 SecurityOriginDB::FEATURE_WEB_NOTIFICATION)
1274 == WrtDB::SETTINGS_TYPE_OFF)
1276 Ewk_Notification_Permission_Request* request =
1277 static_cast<Ewk_Notification_Permission_Request*>(eventInfo);
1278 ewk_notification_permission_request_set(
1285 ViewModule::WebNotification::webNotificationPermissionRequest(
1287 This->m_securityOriginSupport->getSecurityOriginDAO(),
1292 // EWK Orientation Callback
1293 Eina_Bool ViewLogic::orientationLockCallback(
1295 Eina_Bool /*needLock*/,
1299 LogDebug("orientationLockCallback called");
1301 ViewLogic* This = static_cast<ViewLogic*>(data);
1303 if (orientation & EWK_SCREEN_ORIENTATION_PORTRAIT_PRIMARY) {
1304 LogDebug("orientation is portrait-primary");
1305 elm_win_rotation_with_resize_set(This->m_window, 0);
1306 ewk_view_orientation_send(obj, 0);
1307 } else if (orientation & EWK_SCREEN_ORIENTATION_LANDSCAPE_PRIMARY) {
1308 LogDebug("orientation is landscape-primary");
1309 elm_win_rotation_with_resize_set(This->m_window, 270);
1310 ewk_view_orientation_send(obj, 90);
1311 } else if (orientation & EWK_SCREEN_ORIENTATION_PORTRAIT_SECONDARY) {
1312 LogDebug("orientation is portrait-secondary");
1313 elm_win_rotation_with_resize_set(This->m_window, 180);
1314 ewk_view_orientation_send(obj, 180);
1315 } else if (orientation & EWK_SCREEN_ORIENTATION_LANDSCAPE_SECONDARY) {
1316 LogDebug("orientation is landscape-secondary");
1317 elm_win_rotation_with_resize_set(This->m_window, 90);
1318 ewk_view_orientation_send(obj, -90);
1320 LogDebug("Wrong orientation is set");
1326 // Fullscreen API callbacks
1327 void ViewLogic::enterFullscreenCallback(
1329 Evas_Object* /*obj*/,
1330 void* /*eventInfo*/)
1332 LogInfo("enterFullscreenCallback called");
1334 ViewLogic* This = static_cast<ViewLogic*>(data);
1335 if (!This->m_cbs->toggleFullscreen.empty()) {
1336 This->m_cbs->toggleFullscreen(true);
1339 void ViewLogic::exitFullscreenCallback(
1341 Evas_Object* /*obj*/,
1342 void* /*eventInfo*/)
1344 LogInfo("exitFullscreenCallback called");
1346 ViewLogic* This = static_cast<ViewLogic*>(data);
1347 if (!This->m_cbs->toggleFullscreen.empty()) {
1348 This->m_cbs->toggleFullscreen(false);
1352 void ViewLogic::imeChangedCallback(
1354 Evas_Object* /*obj*/,
1360 ViewLogic* This = static_cast<ViewLogic*>(data);
1361 Eina_Rectangle *rect = static_cast<Eina_Rectangle *>(eventInfo);
1362 This->m_imeWidth = rect->w;
1363 This->m_imeHeight = rect->h;
1366 void ViewLogic::imeOpenedCallback(
1368 Evas_Object* /*obj*/,
1369 void* /*eventInfo*/)
1373 ViewLogic* This = static_cast<ViewLogic*>(data);
1375 using namespace WrtPlugins::W3C;
1376 SoftKeyboardChangeArgs args;
1377 args.state = IME_STATE_ON;
1378 args.width = This->m_imeWidth;
1379 args.height = This->m_imeHeight;
1380 This->fireJavascriptEvent(
1381 static_cast<int>(SoftKeyboardChangeCustomEvent),
1385 void ViewLogic::imeClosedCallback(
1387 Evas_Object* /*obj*/,
1388 void* /*eventInfo*/)
1392 ViewLogic* This = static_cast<ViewLogic*>(data);
1394 using namespace WrtPlugins::W3C;
1395 SoftKeyboardChangeArgs args;
1396 args.state = IME_STATE_OFF;
1398 This->fireJavascriptEvent(
1399 static_cast<int>(SoftKeyboardChangeCustomEvent),
1403 void ViewLogic::usermediaPermissionRequestCallback(
1405 Evas_Object* /*obj*/,
1408 LogDebug("usermediaPermissionRequestCallback called");
1410 ViewLogic* This = static_cast<ViewLogic*>(data);
1411 ViewModule::UsermediaSupport::usermediaPermissionRequest(This->m_window,
1416 CustomHandlerDB::CustomHandlerPtr getCustomHandlerFromData(void* data)
1419 Ewk_Custom_Handlers_Data* handler =
1420 static_cast<Ewk_Custom_Handlers_Data*>(data);
1421 CustomHandlerDB::CustomHandlerPtr customHandler(
1422 new CustomHandlerDB::CustomHandler());
1423 const char* base_url = ewk_custom_handlers_data_base_url_get(handler);
1425 LogDebug("base url: " << base_url);
1426 customHandler->base_url = DPL::FromASCIIString(string(base_url));
1428 const char* url = ewk_custom_handlers_data_url_get(handler);
1430 LogDebug("url: " << url);
1431 customHandler->url = DPL::FromASCIIString(string(url));
1433 const char* target = ewk_custom_handlers_data_target_get(handler);
1435 LogDebug("target: " << target);
1436 customHandler->target = DPL::FromASCIIString(string(target));
1438 const char* title = ewk_custom_handlers_data_title_get(handler);
1440 LogDebug("title: " << title);
1441 customHandler->title = DPL::FromASCIIString(string(title));
1443 return customHandler;
1446 void ViewLogic::attachToCustomHandlersDao()
1448 if (!m_attachedToCustomHandlerDao) {
1449 CustomHandlerDB::Interface::attachDatabaseRW();
1453 void ViewLogic::detachFromCustomHandlersDao()
1455 if (m_attachedToCustomHandlerDao) {
1456 CustomHandlerDB::Interface::detachDatabase();
1460 const int protocolWhiteListLenth = 15;
1461 char const * const protocolWhiteList[protocolWhiteListLenth] = {
1479 const int contentBlackListLenth = 14;
1480 char const * const contentBlackList[contentBlackListLenth] = {
1481 "application/x-www-form-urlencoded",
1482 "application/xhtml+xml",
1488 "multipart/x-mixed-replace",
1489 "text/cache-manifest",
1498 * Saves user's response from popup to custom handler. Saves Yes/No and remember
1501 * @param customHandler
1503 void saveUserResponse(Wrt::Popup::PopupResponse response,
1504 CustomHandlerDB::CustomHandlerPtr customHandler)
1507 case Wrt::Popup::YES_DO_REMEMBER:
1508 LogDebug("User allowed, remember");
1509 customHandler->user_decision =
1510 static_cast<CustomHandlerDB::HandlerState>
1511 (CustomHandlerDB::Agreed | CustomHandlerDB::DecisionSaved);
1513 case Wrt::Popup::YES_DONT_REMEMBER:
1514 LogDebug("User allowed, don't remember");
1515 customHandler->user_decision = CustomHandlerDB::Agreed;
1517 case Wrt::Popup::NO_DO_REMEMBER:
1518 LogDebug("User didn't allow, remember");
1519 customHandler->user_decision =
1520 static_cast<CustomHandlerDB::HandlerState>
1521 (CustomHandlerDB::Declined | CustomHandlerDB::DecisionSaved);
1523 case Wrt::Popup::NO_DONT_REMEMBER:
1524 LogDebug("User didn't allow, don't remember");
1525 customHandler->user_decision = CustomHandlerDB::Declined;
1530 //TODO registration, checking if registered and unregistration can be done in
1531 //common functions for both types of handlers. Only white and black lists
1532 //have to be separated
1533 //TODO attach database only one at the start (not in every callback?)
1534 void ViewLogic::protocolHandlerRegistrationCallback(void* data,
1535 Evas_Object* /*obj*/,
1540 CustomHandlerDB::CustomHandlerPtr customHandler =
1541 getCustomHandlerFromData(eventInfo);
1543 std::string scheme = DPL::ToUTF8String(customHandler->target);
1544 if (scheme.empty()) {
1545 LogError("No scheme provided");
1546 //TODO what about securityError?
1549 bool matched = false;
1550 //scheme on whiteList
1551 for (int i = 0; i < protocolWhiteListLenth; ++i) {
1552 if (0 == strcmp(protocolWhiteList[i], scheme.c_str())) {
1553 LogDebug("Match found, protocol can be handled");
1558 //starts with web+ and have at least 5 chars (lowercase ASCII)
1559 if (strncmp("web+", scheme.c_str(), 4) || scheme.length() < 5) {
1560 LogWarning("Scheme neither on whitelist nor starts with \"web+\"");
1561 //throw SecurityException
1567 if (c < 'a' || c > 'z') {
1568 LogWarning("Wrong char inside scheme. "
1569 << "Only lowercase ASCII letters accepted");
1570 //throw SecurityException
1577 ViewLogic* This = static_cast<ViewLogic*>(data);
1578 LogDebug("Creating handlers dao");
1579 This->attachToCustomHandlersDao();
1580 CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1581 CustomHandlerDB::CustomHandlerPtr handler =
1582 handlersDao.getProtocolHandler(customHandler->target,
1584 customHandler->base_url);
1585 if (handler && (handler->user_decision & CustomHandlerDB::DecisionSaved)) {
1586 LogDebug("Protocol already registered - nothing to do");
1588 LogDebug("Protocol handler not found");
1589 Wrt::Popup::PopupResponse response =
1590 GlobalSettings::PopupsTestModeEnabled() ? Wrt::Popup::
1592 Wrt::Popup::PopupInvoker().askYesNoCheckbox(
1593 PROTOCOL_HANDLER_ASK_TITLE,
1594 PROTOCOL_HANDLER_ASK_MSG,
1595 PROTOCOL_HANDLER_ASK_REMEMBER);
1596 saveUserResponse(response, customHandler);
1597 if (customHandler->user_decision == CustomHandlerDB::Declined) {
1600 handlersDao.registerProtocolHandler(*(customHandler.get()));
1601 if (customHandler->user_decision & CustomHandlerDB::Agreed) {
1602 //TODO remove old default handler somehow from appsvc
1603 LogDebug("Registering appservice entry");
1604 int ret = appsvc_set_defapp(APPSVC_OPERATION_VIEW,
1607 customHandler->target).c_str(),
1608 DPL::ToUTF8String(This->m_model->
1610 if (APPSVC_RET_OK != ret) {
1611 LogWarning("Appsvc entry failed: " << ret);
1614 LogDebug("Protocal saved");
1617 This->detachFromCustomHandlersDao();
1620 void ViewLogic::protocolHandlerIsRegisteredCallback(void* data,
1621 Evas_Object* /*obj*/,
1625 CustomHandlerDB::CustomHandlerPtr customHandler = getCustomHandlerFromData(
1627 ViewLogic* This = static_cast<ViewLogic*>(data);
1628 LogDebug("Creating handlers dao");
1629 This->attachToCustomHandlersDao();
1630 CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1631 CustomHandlerDB::CustomHandlerPtr handler =
1632 handlersDao.getProtocolHandler(customHandler->target,
1634 customHandler->base_url);
1636 if (handler->user_decision & CustomHandlerDB::Agreed) {
1637 ewk_custom_handlers_data_result_set(
1638 static_cast<Ewk_Custom_Handlers_Data*>(data),
1639 EWK_CUSTOM_HANDLERS_REGISTERED);
1641 ewk_custom_handlers_data_result_set(
1642 static_cast<Ewk_Custom_Handlers_Data*>(data),
1643 EWK_CUSTOM_HANDLERS_DECLINED);
1646 ewk_custom_handlers_data_result_set(
1647 static_cast<Ewk_Custom_Handlers_Data*>(data),
1648 EWK_CUSTOM_HANDLERS_NEW);
1650 This->detachFromCustomHandlersDao();
1653 void ViewLogic::protocolHandlerUnregistrationCallback(void* data,
1654 Evas_Object* /*obj*/,
1658 CustomHandlerDB::CustomHandlerPtr customHandler =
1659 getCustomHandlerFromData(eventInfo);
1660 ViewLogic* This = static_cast<ViewLogic*>(data);
1661 LogDebug("Creating handlers dao");
1662 This->attachToCustomHandlersDao();
1663 CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1664 CustomHandlerDB::CustomHandlerPtr handlerCheck =
1665 handlersDao.getProtocolHandler(customHandler->target,
1667 customHandler->base_url);
1669 if (handlerCheck->user_decision & CustomHandlerDB::Agreed) {
1670 appsvc_unset_defapp(DPL::ToUTF8String(This->m_model->TizenId).c_str());
1673 handlersDao.unregisterProtocolHandler(customHandler->target,
1675 customHandler->base_url);
1677 LogDebug("Nothing to unregister");
1680 This->detachFromCustomHandlersDao();
1683 void ViewLogic::contentHandlerRegistrationCallback(void* data,
1684 Evas_Object* /*obj*/,
1689 CustomHandlerDB::CustomHandlerPtr customHandler =
1690 getCustomHandlerFromData(eventInfo);
1692 std::string mimeType = DPL::ToUTF8String(customHandler->target);
1693 if (mimeType.empty()) {
1694 LogError("No mimeType provided.");
1697 for (int i = 0; i < contentBlackListLenth; ++i) {
1698 if (0 == strcmp(contentBlackList[i], mimeType.c_str())) {
1699 LogWarning("mimeType blacklisted");
1700 //throw SecurityException
1705 ViewLogic* This = static_cast<ViewLogic*>(data);
1706 LogDebug("Creating handlers dao");
1707 This->attachToCustomHandlersDao();
1708 CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1709 CustomHandlerDB::CustomHandlerPtr handler =
1710 handlersDao.getContentHandler(customHandler->target,
1712 customHandler->base_url);
1713 if (handler && (handler->user_decision & CustomHandlerDB::DecisionSaved)) {
1714 LogDebug("Protocol already registered - nothing to do");
1716 LogDebug("Protocol handler not found");
1717 Wrt::Popup::PopupResponse response =
1718 GlobalSettings::PopupsTestModeEnabled() ? Wrt::Popup::
1720 Wrt::Popup::PopupInvoker().askYesNoCheckbox(
1721 CONTENT_HANDLER_ASK_TITLE,
1722 CONTENT_HANDLER_ASK_MSG,
1723 CONTENT_HANDLER_AKS_REMEMBER);
1724 saveUserResponse(response, customHandler);
1725 if (customHandler->user_decision == CustomHandlerDB::Declined) {
1728 handlersDao.registerContentHandler(*(customHandler.get()));
1729 if (customHandler->user_decision & CustomHandlerDB::Agreed) {
1730 //TODO remove old default handler somehow from appsvc
1731 LogDebug("Registering appservice entry");
1732 int ret = appsvc_set_defapp(APPSVC_OPERATION_VIEW,
1734 customHandler->target).c_str(),
1736 DPL::ToUTF8String(This->m_model->
1738 if (APPSVC_RET_OK != ret) {
1739 LogWarning("Appsvc entry failed: " << ret);
1742 LogDebug("Content saved");
1744 This->detachFromCustomHandlersDao();
1747 void ViewLogic::contentHandlerIsRegisteredCallback(void* data,
1748 Evas_Object* /*obj*/,
1752 CustomHandlerDB::CustomHandlerPtr customHandler =
1753 getCustomHandlerFromData(eventInfo);
1754 ViewLogic* This = static_cast<ViewLogic*>(data);
1755 LogDebug("Creating handlers dao");
1757 This->attachToCustomHandlersDao();
1758 CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1759 CustomHandlerDB::CustomHandlerPtr handler =
1760 handlersDao.getContentHandler(customHandler->target,
1762 customHandler->base_url);
1764 if (handler->user_decision & CustomHandlerDB::Agreed) {
1765 ewk_custom_handlers_data_result_set(
1766 static_cast<Ewk_Custom_Handlers_Data*>(data),
1767 EWK_CUSTOM_HANDLERS_REGISTERED);
1769 ewk_custom_handlers_data_result_set(
1770 static_cast<Ewk_Custom_Handlers_Data*>(data),
1771 EWK_CUSTOM_HANDLERS_DECLINED);
1774 ewk_custom_handlers_data_result_set(
1775 static_cast<Ewk_Custom_Handlers_Data*>(data),
1776 EWK_CUSTOM_HANDLERS_NEW);
1778 This->detachFromCustomHandlersDao();
1781 void ViewLogic::contentHandlerUnregistrationCallback(void* data,
1782 Evas_Object* /*obj*/,
1786 CustomHandlerDB::CustomHandlerPtr customHandler =
1787 getCustomHandlerFromData(eventInfo);
1788 ViewLogic* This = static_cast<ViewLogic*>(data);
1789 LogDebug("Creating handlers dao");
1790 This->attachToCustomHandlersDao();
1791 CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1792 CustomHandlerDB::CustomHandlerPtr handlerCheck =
1793 handlersDao.getContentHandler(customHandler->target,
1795 customHandler->base_url);
1797 if (handlerCheck->user_decision & CustomHandlerDB::Agreed) {
1798 appsvc_unset_defapp(DPL::ToUTF8String(This->m_model->TizenId).c_str());
1801 handlersDao.unregisterContentHandler(customHandler->target,
1803 customHandler->base_url);
1805 LogDebug("Nothing to unregister");
1807 This->detachFromCustomHandlersDao();
1810 void ViewLogic::didRunJavaScriptCallback(
1811 Evas_Object* /*obj*/,
1815 LogInfo("didRunJavaScriptCallback called");
1816 LogInfo("result = " << result);
1819 Eina_Bool ViewLogic::windowCloseIdlerCallback(void* data)
1821 LogDebug("closeIdlerCallback");
1822 ViewLogic* This = static_cast<ViewLogic*>(data);
1823 This->windowClose();
1824 return ECORE_CALLBACK_CANCEL;
1827 void ViewLogic::certificateConfirmRequestCallback(
1829 Evas_Object* /*obj*/,
1832 LogDebug("certificateConfirmRequestCallback called");
1835 ViewLogic* This = static_cast<ViewLogic*>(data);
1837 ViewModule::CertificateConfirmSupport::certificatePermissionRequest(
1839 This->m_certificateSupport->getCertificateDAO(),
1843 void ViewLogic::authenticationChallengeRequestCallback(
1845 Evas_Object* /*obj*/,
1848 LogDebug("authenticationChallengeRequestCallback called");
1851 ViewLogic* This = static_cast<ViewLogic*>(data);
1852 const char* url = ewk_view_url_get(This->m_currentEwkView);
1853 if (!url || strlen(url) == 0) {
1854 url = This->m_currentUri.c_str();
1857 ViewModule::AuthenticationChallengeSupport::authenticationChallengeRequest(
1858 This->m_currentEwkView,
1863 std::string ViewLogic::requestUrlBlocked(const std::string& blockedUrl)
1867 if (m_model->Type.Get().appType == WrtDB::APP_TYPE_TIZENWEBAPP) {
1868 // block this page and open it in browser
1869 LogDebug("Request was blocked by WARP: " << blockedUrl);
1870 LogDebug("open browser : " << blockedUrl);
1871 bundle* bundleData = bundle_create();
1872 appsvc_set_operation(bundleData, APPSVC_OPERATION_VIEW);
1873 appsvc_set_uri(bundleData, blockedUrl.c_str());
1874 CONTROLLER_POST_EVENT(
1875 ApplicationLauncher,
1876 ApplicationLauncherEvents::LaunchApplicationByAppService(
1882 // set block url. This is used on load finished callback
1883 m_blockedUri = blockedUrl;
1885 // This is used in case of returning previous page
1886 return URICHANGE_PLUGIN_NO_CHANGE;
1889 std::string ViewLogic::requestUrlChanged(const std::string& changedUrl)
1891 using namespace ViewModule::SecuritySupport;
1893 LogInfo("changed url: " << changedUrl);
1895 // Check if this url with 'http' or 'https' is included in whitelist,
1896 // which has lists of accessible external documents and
1897 // used for ONLY Tizen app
1898 std::string matchedScheme;
1899 std::string matchedUri;
1900 pcrecpp::RE(PATTERN_URI_CHANGE).PartialMatch(changedUrl.c_str(),
1903 ViewModule::Scheme scheme(matchedScheme);
1904 if (scheme.GetType() == ViewModule::Scheme::HTTP ||
1905 scheme.GetType() == ViewModule::Scheme::HTTPS)
1907 if (m_model->Type.Get().appType == WrtDB::APP_TYPE_TIZENWEBAPP) {
1908 if (!checkWhitelist(changedUrl.c_str())) {
1909 LogInfo("This uri is not included in white document list");
1910 return URICHANGE_PLUGIN_STOP_ONLY;
1912 LogInfo("This url is included in WhiteList");
1914 // For WAC app, WRT should block access of device api
1915 // for external documents
1916 return URICHANGE_PLUGIN_STOP_ONLY;
1920 m_currentUri = changedUrl;
1921 return URICHANGE_PLUGIN_RESTART;
1924 void ViewLogic::windowClose()
1926 LogDebug("windowClose");
1927 Assert(m_closedEwkView && "no closed webview");
1929 if (1 >= m_ewkViewList.size()) {
1930 if (!m_cbs->webkitExit.empty()) {
1931 m_cbs->webkitExit();
1934 // call user callbacks
1935 if (!m_cbs->bufferUnset.empty()) {
1936 m_cbs->bufferUnset(m_currentEwkView);
1938 if (!m_cbs->windowClose.empty()) {
1939 m_cbs->windowClose(m_closedEwkView);
1941 removeEwkView(m_closedEwkView);
1943 // get latest ewkView
1944 m_currentEwkView = m_ewkViewList.back();
1945 const char* uri = ewk_view_url_get(m_currentEwkView);
1946 if (NULL == uri || 0 == strlen(uri)) {
1947 m_currentUri.clear();
1953 /* In case we support many pages in parallel
1954 * then view is not suspended*/
1955 //resumeEwkView(m_currentEwkView);
1956 setEwkViewVisible(m_currentEwkView);
1959 if (!m_cbs->bufferSet.empty()) {
1960 m_cbs->bufferSet(m_currentEwkView);