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>
33 #include <appcore-common.h>
36 #include <widget_model.h>
37 #include <dpl/wrt-dao-ro/widget_dao_read_only.h>
38 #include <dpl/wrt-dao-ro/vconf_config.h>
39 #include <dpl/utils/wrt_global_settings.h>
41 #include <common/application_data.h>
42 #include <common/application_launcher.h>
43 #include <common/scheme.h>
45 #include <common/view_logic_apps_support.h>
46 #include <common/view_logic_custom_header_support.h>
47 #include <common/view_logic_password_support.h>
48 #include <common/view_logic_security_support.h>
49 #include <common/view_logic_security_origin_support.h>
50 #include <common/view_logic_storage_support.h>
51 #include <common/view_logic_uri_support.h>
52 #include <common/view_logic_user_agent_support.h>
53 #include <common/view_logic_vibration_support.h>
54 #include <view_logic_scheme_support.h>
55 #include <view_logic_filesystem_support.h>
56 #include <view_logic_geolocation_support_webkit2.h>
57 #include <view_logic_usermedia_support.h>
58 #include <view_logic_web_notification_support.h>
59 #include <view_logic_web_storage_support.h>
60 #include "bundles/plugin_module_support.h"
61 #include <popup-runner/PopupInvoker.h>
64 #include <js_overlay_types.h>
65 #include <i_runnable_widget_object.h>
66 #include <profiling_util.h>
67 #include <wrt-commons/custom-handler-dao-ro/common_dao_types.h>
68 #include <wrt-commons/custom-handler-dao-ro/CustomHandlerDatabase.h>
69 #include <wrt-commons/custom-handler-dao-ro/custom_handler_dao_read_only.h>
70 #include <wrt-commons/custom-handler-dao-rw/custom_handler_dao.h>
71 #include <popup-runner/PopupInvoker.h>
73 #include <appsvc/appsvc.h>
76 const char * const bundlePath = "/usr/lib/wrt-wk2-bundles/libwrt-wk2-bundle.so";
77 const char * const uriBlockedMessageName = "uri_block_msg";
78 const char * const uriChangedMessageName = "uri_changed_msg";
79 const char * const URICHANGE_PLUGIN_STOP_ONLY = "plugin_stop_only";
80 const char * const URICHANGE_PLUGIN_RESTART = "plugin_restart";
81 const char * const URICHANGE_PLUGIN_NO_CHANGE = "plugin_no_change";
82 const char * const URICHANGE_BLOCKED_URL = "null";
83 const char* PATTERN_URI_CHANGE = "^(([^:/\\?#]+)://[^\\?#]*)";
84 const int MAX_NUM_CONTEXT_MENU_ITEMS = 10;
86 const char * const IME_STATE_ON = "on";
87 const char * const IME_STATE_OFF = "off";
89 const char PROTOCOL_HANDLER_ASK_MSG[] = "Add protocol?";
90 const char PROTOCOL_HANDLER_ASK_TITLE[] = "Add protocol";
91 const char PROTOCOL_HANDLER_ASK_REMEMBER[] = "Remember dicision";
92 const char CONTENT_HANDLER_ASK_MSG[] = "Add content?";
93 const char CONTENT_HANDLER_ASK_TITLE[] = "Add content";
94 const char CONTENT_HANDLER_AKS_REMEMBER[] = "Remember dicision";
95 const char * const CERTIFICATE_CONFIRM_REQUEST_ASK_TITLE =
97 const char * const CERTIFICATE_CONFIRM_REQUEST_ASK_BODY =
98 "This site's security certificate is not trusted! Do you acess this site?";
99 } // anonymous namespace
101 std::map<const std::string, const Evas_Smart_Cb> ViewLogic::m_ewkCallbacksMap =
103 {"load,started", &ViewLogic::loadStartedCallback},
104 {"load,finished", &ViewLogic::loadFinishedCallback},
105 {"title,changed", &ViewLogic::titleChangedCallback},
106 {"load,progress", &ViewLogic::loadProgressCallback},
107 {"load,progress,finished", &ViewLogic::loadProgressFinishedCallback},
108 {"process,crashed", &ViewLogic::processCrashedCallback},
110 {"create,window", &ViewLogic::createWindowCallback},
111 {"close,window", &ViewLogic::closeWindowCallback},
112 // WKPagePolicyClient
113 {"policy,navigation,decide", &ViewLogic::policyNavigationDecideCallback},
114 {"policy,newwindow,decide", &ViewLogic::policyNewWindowDecideCallback},
115 {"policy,response,decide", &ViewLogic::pageResponseDecideCallback},
116 // WKPageContextMenuClient
117 {"contextmenu,customize", &ViewLogic::contextmenuCustomizeCallback},
119 {"form,submit", &ViewLogic::formSubmitCallback},
120 // EWK Geolocation Callback
121 {"request,geolocation,permission", &ViewLogic::geolocationPermissionRequestCallback},
122 // EWK Notification Callback
123 {"notification,show", &ViewLogic::notificationShowCallback},
124 {"notification,cancel", &ViewLogic::notificationCancelCallback},
125 {"notification,permission,request", &ViewLogic::notificationPermissionRequestCallback},
127 {"database,quota,exceeded", &ViewLogic::databaseUsagePermissionRequestCallback},
128 {"filesystem,permission,request", &ViewLogic::fileSystemPermissionRequestCallback},
129 {"fullscreen,enterfullscreen", &ViewLogic::enterFullscreenCallback},
130 {"fullscreen,exitfullscreen", &ViewLogic::exitFullscreenCallback},
132 // when ime start to be showed on the webview,
133 // this callback will be called
134 {"inputmethod,changed", &ViewLogic::imeChangedCallback},
135 // this callback will be called
136 // when ime finishes to be showed on the webview
137 // "event_info" arg of this callback is always NULL point
138 // if web content should know size of ime,
139 // use "inputmethod,changed" instead of this.
141 {"editorclient,ime,opened", &ViewLogic::imeOpenedCallback},
142 // when ime finished to be hidden,
143 // this callback will be called
144 {"editorclient,ime,closed", &ViewLogic::imeClosedCallback},
145 // EWK Usermedia Callback
146 {"usermedia,permission,request", &ViewLogic::usermediaPermissionRequestCallback},
148 {"protocolhandler,registration,requested", &ViewLogic::protocolHandlerRegistrationCallback},
149 {"protocolhandler,isregistered", &ViewLogic::protocolHandlerIsRegisteredCallback},
150 {"protocolhandler,unregistration,requested", &ViewLogic::protocolHandlerUnregistrationCallback},
151 {"contenthandler,registration,requested", &ViewLogic::contentHandlerRegistrationCallback},
152 {"contenthandler,isregistered", &ViewLogic::contentHandlerIsRegisteredCallback},
153 {"contenthandler,unregistration,requested", &ViewLogic::contentHandlerUnregistrationCallback},
154 {"request,certificate,confirm", &ViewLogic::certificateConfirmRequestCallback}
157 ViewLogic::ViewLogic():
162 m_cbs(new WRT::UserDelegates),
163 m_isBackgroundReload(false),
164 m_appsSupport(new ViewModule::AppsSupport()),
165 m_vibrationSupport(new ViewModule::VibrationSupport()),
166 m_attachedToCustomHandlerDao(false)
170 ViewLogic::~ViewLogic ()
172 detachFromCustomHandlersDao();
175 bool ViewLogic::createWebView(Ewk_Context* context,
179 initializeEwkContext(context);
180 Assert(NULL != m_ewkContext);
183 if(!createEwkView(evas_object_evas_get(m_window)))
190 void ViewLogic::destroyWebView()
193 finalizeEwkContext();
197 void ViewLogic::initialize()
199 LogDebug("Initializing");
200 ApplicationLauncherSingleton::Instance().Touch();
201 appcore_set_event_callback(
202 APPCORE_EVENT_LOW_MEMORY,
203 &appcoreLowMemoryCallback,
207 void ViewLogic::terminate()
209 LogDebug("terminating view logic");
213 LogError("Widget model not created");
218 void ViewLogic::prepareView(WidgetModel* m, const std::string &startUrl)
220 LogDebug("View prepare");
224 m_startUrl = ViewModule::UriSupport::getUri(m_model, startUrl);
225 Assert(NULL != m_ewkContext);
228 ADD_PROFILING_POINT("initializeSupport", "start");
230 ADD_PROFILING_POINT("initializeSupport", "stop");
232 ewkClientInit(m_currentEwkView);
233 ADD_PROFILING_POINT("prepareEwkView", "start");
234 prepareEwkView(m_currentEwkView);
235 ADD_PROFILING_POINT("prepareEwkView", "stop");
236 initializePluginLoading();
239 void ViewLogic::showWidget()
241 LogDebug("showing widget");
242 Assert(NULL != m_currentEwkView && "ewk_view not created at this point");
243 if (m_currentUri.empty()) {
244 LogError("Localized current URI doesn't exist");
248 LogInfo("m_currentUri: " << m_currentUri);
251 ewk_view_url_set(m_currentEwkView, m_currentUri.c_str());
253 if (!m_cbs->bufferSet.empty()) {
254 m_cbs->bufferSet(m_currentEwkView);
258 void ViewLogic::hideWidget()
260 LogDebug("hiding widget");
261 ViewModule::StorageSupport::deinitializeStorage(m_model);
262 m_appsSupport->deinitialize();
264 m_vibrationSupport->deinitialize();
266 while (m_ewkViewList.size()) {
267 LogInfo("pop webview: " << m_ewkViewList.back());
268 removeEwkView(m_ewkViewList.back());
270 m_ewkViewList.clear();
273 void ViewLogic::changeViewVisibility(bool isVisible)
275 Evas_Object* wkView = m_currentEwkView;
280 ewk_view_page_visibility_state_set(wkView,
281 EWK_PAGE_VISIBILITY_STATE_VISIBLE,
283 ewk_view_visibility_set(wkView, EINA_TRUE);
285 ewk_view_page_visibility_state_set(wkView,
286 EWK_PAGE_VISIBILITY_STATE_HIDDEN,
288 ewk_view_visibility_set(wkView, EINA_FALSE);
292 void ViewLogic::suspendWidget()
294 LogInfo("Pausing widget");
297 LogDebug("Request bundle to suspend");
298 PluginModuleSupport::suspend(m_ewkContext);
300 if (!m_currentEwkView) {
301 LogWarning("Cannot suspend widget without view");
303 suspendWebkit(m_currentEwkView);
306 evas_object_focus_set(m_currentEwkView, EINA_FALSE);
308 // call user callback
309 if (!m_cbs->suspend.empty()) {
310 m_cbs->suspend(true);
314 void ViewLogic::resumeWidget()
316 LogInfo("Resume widget");
319 LogDebug("Request bundle to resume");
320 PluginModuleSupport::resume(m_ewkContext);
322 if (m_currentEwkView) {
323 resumeWebkit(m_currentEwkView);
326 /* window system team recomend removing this win_raise code. */
329 elm_win_raise(m_window);
332 evas_object_focus_set(m_currentEwkView, EINA_TRUE);
334 // call user callback
335 if (!m_cbs->resume.empty()) {
340 void ViewLogic::resetWidget()
342 LogInfo("Resetting Widget");
344 // destory all webview
345 while (m_ewkViewList.size()) {
346 LogInfo("pop webview: " << m_ewkViewList.back());
347 removeEwkView(m_ewkViewList.back());
349 m_ewkViewList.clear();
351 // create new webview
352 createEwkView(evas_object_evas_get(m_window));
354 ewkClientInit(m_currentEwkView);
355 prepareEwkView(m_currentEwkView);
357 // check if current url is service url for this tizen service
358 std::string requestedUri =
359 ViewModule::UriSupport::getUri(m_model, m_startUrl);
360 DPL::OptionalString servicedUri = ViewModule::UriSupport::localizeURI(
361 DPL::FromUTF8String(requestedUri.c_str()),
365 PluginModuleSupport::resume(m_ewkContext);
366 m_currentUri = DPL::ToUTF8String(*servicedUri);
367 ewk_view_url_set(m_currentEwkView, m_currentUri.c_str());
368 elm_win_activate(m_window);
369 evas_object_focus_set(m_currentEwkView, EINA_TRUE);
371 // call user callback
372 if (!m_cbs->reset.empty()) {
375 if (!m_cbs->bufferSet.empty()) {
376 m_cbs->bufferSet(m_currentEwkView);
380 void ViewLogic::backward()
382 if (ewk_view_back_possible(m_currentEwkView)) {
383 ewk_view_back(m_currentEwkView);
385 if (1 >= m_ewkViewList.size()) {
386 // If there is no previous page, widget move to backgroud.
387 LogInfo("Widget move to backgroud");
388 elm_win_lower(m_window);
390 // Back to previous webview
391 LogInfo("Widget move to previous webview");
392 ecore_idler_add(windowCloseIdlerCallback, this);
397 void ViewLogic::reloadStartPage()
399 LogInfo("Reload Start Page");
400 // prevent fail to load plugin bundle side
401 m_isBackgroundReload = true;
402 PluginModuleSupport::resume(m_ewkContext);
404 if (m_ewkViewList.size() != 0) {
405 while (m_ewkViewList.size() > 0) {
406 if (!m_cbs->bufferUnset.empty()) {
407 m_cbs->bufferUnset(m_currentEwkView);
409 removeEwkView(m_currentEwkView);
413 // create new webview
414 createEwkView(evas_object_evas_get(m_window));
415 ewkClientInit(m_currentEwkView);
418 prepareEwkView(m_currentEwkView);
419 initializePluginLoading();
422 ewk_view_url_set(m_currentEwkView, m_currentUri.c_str());
425 if (!m_cbs->bufferSet.empty()) {
426 m_cbs->bufferSet(m_currentEwkView);
428 LogInfo("Reloading Start Page is done!");
431 Evas_Object* ViewLogic::getCurrentWebview()
433 LogInfo("get current webview");
434 return m_currentEwkView;
437 void ViewLogic::fireJavascriptEvent(int event, void* data)
439 PluginModuleSupport::dispatchJavaScriptEvent(
441 static_cast<WrtPlugins::W3C::CustomEventType>(event),
445 void ViewLogic::setUserCallbacks(const WRT::UserDelegatesPtr& cbs)
450 void ViewLogic::initializeEwkContext(Ewk_Context* newEwkContext)
452 LogInfo("initializeEwkContext called");
453 Assert(newEwkContext && "Ewk_Context provided can not be null");
454 // bundle callback setting
455 ewk_context_message_from_injected_bundle_callback_set(
457 contextMessageFromInjectedBundleCallback,
458 static_cast<void*>(this));
460 // proxy server setting
461 char *proxyAddress = vconf_get_str(VCONFKEY_NETWORK_PROXY);
462 if ((!proxyAddress) || (strlen(proxyAddress) == 0)
463 || (strstr(proxyAddress, "0.0.0.0")))
465 LogInfo("proxy address is empty");
466 ewk_context_proxy_uri_set(newEwkContext, NULL);
468 LogInfo("proxy address [" << proxyAddress << "]");
469 ewk_context_proxy_uri_set(newEwkContext, proxyAddress);
478 const char *theme = elm_theme_get(NULL);
481 LogInfo("theme is " << m_theme);
484 // Ewk download callback (WKContextDownloadClient)
485 ewk_context_did_start_download_callback_set(
487 didStartDownloadCallback,
490 ewk_context_vibration_client_callbacks_set(
492 vibrationVibrateCallback,
493 vibrationCancelCallback,
496 ewk_context_certificate_file_set(m_ewkContext,
497 "/opt/usr/share/certs/ca-certificate.crt");
499 // set to member value
500 m_ewkContext = newEwkContext;
503 void ViewLogic::finalizeEwkContext()
505 LogInfo("finalizeEwkContext called");
506 ewk_context_message_from_injected_bundle_callback_set(
510 ewk_context_did_start_download_callback_set(
514 ewk_context_vibration_client_callbacks_set(
519 // ewk_context_delete(m_ewkContext);
523 void ViewLogic::initializeSupport()
525 // set local stroage database path
526 WrtDB::WidgetDAOReadOnly dao(m_model->TizenId);
527 ewk_context_web_storage_path_set(m_ewkContext,
528 dao.getPrivateLocalStoragePath().c_str());
529 // memory saving mode
532 WrtDB::VconfConfig::GetVconfKeyMemorySavingMode(
533 m_model->TizenId).c_str(),
535 ewk_context_memory_saving_mode_set(
537 static_cast<WrtDB::SettingsType>(result) ==
538 WrtDB::SETTINGS_TYPE_ON ? EINA_TRUE : EINA_FALSE);
539 m_schemeSupport.reset(new SchemeSupport(m_model->Type.Get().appType));
540 ViewModule::StorageSupport::initializeStorage(m_model);
541 m_appsSupport->initialize(m_model);
542 m_securityOriginSupport.reset(new ViewModule::SecurityOriginSupport(m_model));
544 m_vibrationSupport->initialize();
547 void ViewLogic::initializePluginLoading()
549 // inform wrt information for plugin loading to web process
550 PluginModuleSupport::start(
553 elm_config_scale_get(),
554 ApplicationDataSingleton::Instance().getEncodedBundle(),
556 m_model->SettingList.Get().isEncrypted());
559 void ViewLogic::ewkClientInit(Evas_Object *wkView) {
560 Assert(NULL != wkView && "ewk_view not created at this point");
562 FOREACH(it, m_ewkCallbacksMap) {
563 evas_object_smart_callback_add(
571 void ViewLogic::ewkClientDeinit(Evas_Object *wkView) {
572 LogDebug("ewkClientDeinit");
573 Assert(NULL != wkView && "ewk_view not created at this point");
575 FOREACH(it, m_ewkCallbacksMap) {
576 evas_object_smart_callback_del(
583 bool ViewLogic::createEwkView(Evas* canvas)
585 LogDebug("createEwkVeiw");
587 ADD_PROFILING_POINT("ewk_view_add_with_context", "start");
588 Evas_Object* newEwkView = ewk_view_add_with_context(
591 ADD_PROFILING_POINT("ewk_view_add_with_context", "stop");
594 LogError("View creation failed");
595 Wrt::Popup::PopupInvoker().showInfo(
596 "Info", "View creation failed","close");
601 // even arguments pass the ewkContext, this API should be called
602 // after webkit Evas_Object is created
603 Ewk_Cookie_Manager *ewkCookieManager;
605 ewk_context_cookie_manager_get(m_ewkContext);
606 ewk_cookie_manager_accept_policy_set(ewkCookieManager,
607 EWK_COOKIE_ACCEPT_POLICY_ALWAYS);
609 LogInfo("push webview: " << newEwkView);
610 m_ewkViewList.push_back(newEwkView);
611 m_currentEwkView = newEwkView;
615 void ViewLogic::setStartPage()
617 /* Start URI (as other uris) is now localized
618 * on WebProcess side */
619 m_currentUri = m_startUrl;
622 void ViewLogic::prepareEwkView(Evas_Object *wkView)
624 LogDebug("prepareEwkView called");
626 Ewk_Settings* settings = ewk_view_settings_get(wkView);
629 std::string customUserAgent = m_model->SettingList.Get().getUserAgent();
630 if (customUserAgent.empty()) {
631 auto userAgentString =
632 ViewModule::UserAgentSupport::getUserAgentFromVconf();
633 if (!userAgentString.empty()) {
634 LogDebug("Setting user agent as: " << userAgentString);
635 ewk_view_user_agent_set(wkView, userAgentString.c_str());
638 LogDebug("Setting custom user agent as: " << customUserAgent);
639 ewk_view_user_agent_set(wkView, customUserAgent.c_str());
642 // set custom header : language
643 using namespace ViewModule::CustomHeaderSupport;
644 std::string customHeaderString = getValueByField(ACCEPT_LANGUAGE);
645 if (!customHeaderString.empty()) {
646 LogDebug("custom field=[" << ACCEPT_LANGUAGE << "]");
647 LogDebug("custom value=[" << customHeaderString << "]");
648 ewk_view_custom_header_add(wkView,
649 ACCEPT_LANGUAGE.c_str(),
650 customHeaderString.c_str());
653 // webkit NPAPI plugins is always on in wrt
654 ewk_settings_plugins_enabled_set(settings, EINA_TRUE);
656 // The followings are not implemeted yet by webkit2
657 // ewk_view_setting_accelerated_compositing_enable_set(EINA_TRUE);
658 // ewk_view_mode_set();
659 // ewk_view_setting_enable_specified_plugin_set(EINA_TRUE, FLASH_MIME_TYPE);
660 // ewk_view_setting_html5video_external_player_enable_set(EINA_FALSE);
661 // ewk_view_show_ime_on_autofocus_set(EINA_TRUE);
662 // elm_webview_show_magnifier_set(EINA_FALSE);
663 ewk_settings_javascript_enabled_set(settings, EINA_TRUE);
664 ewk_settings_loads_images_automatically_set(settings, EINA_TRUE);
665 ewk_settings_auto_fitting_set(settings, EINA_TRUE);
667 // disable zoom option when user click the input field
668 // this option is useful with the normal website
669 // for the make user friendly, disable auto zoom in the webapp
670 // The followings are not implemeted yet by webkit2
671 // elm_webview_input_field_zoom_set(EINA_FALSE);
673 // set cookie database path
674 // The followings are not implemeted yet by webkit2
675 // ewk_cookies_file_set(dao.getCookieDatabasePath().c_str()));
677 // set visibility to WebCore. This value will be used for html5.
678 // also, this value will be changed in the suspend, resume
679 // or create window, close window.
680 ewk_view_page_visibility_state_set(wkView,
681 EWK_PAGE_VISIBILITY_STATE_VISIBLE,
685 void ViewLogic::removeEwkView(Evas_Object *wkView)
687 LogInfo("removeEwkView called");
689 Assert(0 != m_ewkViewList.size());
691 // unregister webview callbacks
692 ewkClientDeinit(wkView);
694 // suspend NPAPI plugin - Not implemented by Webkit2
695 // ewk_view_pause_or_resume_plugins();
696 evas_object_del(wkView);
697 m_ewkViewList.remove(wkView);
700 void ViewLogic::resumeEwkView(Evas_Object *wkView)
702 LogInfo("resumeEwkView called");
705 // register webview callback
706 ewkClientInit(wkView);
709 resumeWebkit(wkView);
714 void ViewLogic::suspendEwkView(Evas_Object *wkView)
716 LogInfo("suspendEwkView called");
720 suspendWebkit(wkView);
722 // unregister webview callbacks
723 ewkClientDeinit(wkView);
728 void ViewLogic::resumeWebkit(Evas_Object *wkView)
730 LogDebug("resumeWebkit");
733 // resume NPAPI plugin
734 // The followings are not implemeted yet by webkit2
735 // ewk_view_pause_or_resume_plugins(false);
736 // ewk_view_pause_or_resume_video_audio(false);
737 // ewk_view_javascript_resume();
738 // ewk_view_enable_render();
739 // ewk_view_reduce_plugins_frame_rate(false);
740 ewk_view_resume(wkView);
741 ewk_view_visibility_set(wkView, EINA_TRUE);
742 ewk_view_page_visibility_state_set(wkView,
743 EWK_PAGE_VISIBILITY_STATE_VISIBLE,
748 void ViewLogic::suspendWebkit(Evas_Object *wkView)
750 LogDebug("suspendWebkit");
753 // suspend the followings
754 // The followings are not implemeted yet by webkit2
755 // ewk_view_pause_or_resume_plugins(true);
756 // ewk_view_pause_or_resume_video_audio(true);
757 ewk_view_suspend(wkView);
762 void ViewLogic::contextMessageFromInjectedBundleCallback(
768 LogDebug("contextMessageFromInjectedBundleCallback called");
770 ViewLogic* This = static_cast<ViewLogic*>(clientInfo);
771 // didRecieveMessageFromInjectedBundleCallback - returnData is null
772 // didReceiveSynchronousMessageCallback - returnData isn't null
773 // WKContextInjectedBundleClient bundleClient = {
774 // kWKContextInjectedBundleClientCurrentVersion,
775 // static_cast<void*>(this),
776 // &didRecieveMessageFromInjectedBundleCallback,
777 // &didReceiveSynchronousMessageCallback
779 if (NULL == returnData) {
780 This->didRecieveMessageFromInjectedBundle(name, body);
782 This->didReceiveSynchronousMessage(name, body, returnData);
786 void ViewLogic::didStartDownloadCallback(
787 const char* downloadUrl,
790 LogDebug("didStartDownloadCallback called");
792 ViewLogic* This = static_cast<ViewLogic*>(data);
794 LogDebug("download url = " << downloadUrl);
795 This->m_appsSupport->downloadRequest(
801 void ViewLogic::loadStartedCallback(
806 LogDebug("loadStartedCallback called");
808 ViewLogic* This = static_cast<ViewLogic*>(data);
809 evas_object_focus_set(This->m_currentEwkView, EINA_TRUE);
811 // call loadFinish callback to wrt-client
812 if (!This->m_cbs->loadStart.empty()) {
813 This->m_cbs->loadStart(obj);
818 void ViewLogic::loadFinishedCallback(
823 LogDebug("loadFinishedCallback called");
825 ViewLogic* This = static_cast<ViewLogic*>(data);
828 const char* url = ewk_view_url_get(This->m_currentEwkView);
829 if (NULL == url || strlen(url) == 0) {
830 LogError("url is empty");
832 DPL::OptionalString jsOptionalString =
833 ViewModule::PasswordSupport::jsForAutoFillData(url);
834 if (jsOptionalString.IsNull()) {
835 LogError("Fail to get JS String");
837 std::string jsStr = DPL::ToUTF8String(*jsOptionalString).c_str();
839 if(EINA_FALSE == ewk_view_script_execute(
840 This->m_currentEwkView,
842 didRunJavaScriptCallback,
845 LogError("JS for auto fill data failed.");
850 // call loadFinish callback to wrt-client
851 if (!This->m_cbs->loadFinish.empty()) {
852 This->m_cbs->loadFinish(obj);
855 // set only encoded bundle
856 double scale = elm_config_scale_get();
857 PluginModuleSupport::setCustomProperties(
860 ApplicationDataSingleton::Instance().getEncodedBundle());
861 // check if 'appsevice' event is registed at the current frames.
862 // If so, dispatch the event to frames.
863 PluginModuleSupport::dispatchJavaScriptEvent(
865 WrtPlugins::W3C::ServiceCustomEvent,
868 // In this case, widget is reloaded in the background.
869 // After finished load, bundle should disconnent callback.
870 if (This->m_isBackgroundReload) {
871 PluginModuleSupport::suspend(This->m_ewkContext);
872 ewk_view_suspend(This->m_currentEwkView);
873 This->m_isBackgroundReload = false;
877 void ViewLogic::titleChangedCallback(
879 Evas_Object* /*obj*/,
882 LogDebug("titleChangedCallback called");
884 ViewLogic* This = static_cast<ViewLogic*>(data);
886 const char* title = static_cast<char*>(eventInfo);
888 if (0 == strlen(title)) {
889 LogDebug("title data is empty");
892 LogDebug("Title = [" << title << "]");
893 This->m_schemeSupport->HandleTizenScheme(title,
895 This->m_currentEwkView);
898 void ViewLogic::loadProgressCallback(
900 Evas_Object* /*obj*/,
903 double* progress = static_cast<double*>(eventInfo);
904 LogDebug("didChangeProgressCallback progress = " << *progress);
907 void ViewLogic::loadProgressFinishedCallback(
909 Evas_Object* /*obj*/,
912 LogDebug("didFinishProgressCallback");
914 ViewLogic const * const view = static_cast<ViewLogic const * const>(data);
915 if (!view->m_cbs->progressFinish.empty()) {
916 view->m_cbs->progressFinish();
920 void ViewLogic::processCrashedCallback(
922 Evas_Object* /*obj*/,
925 LogInfo("processCrashedCallback");
927 ViewLogic const * const view =
928 static_cast<ViewLogic const * const>(data);
929 if (!view->m_cbs->webCrash.empty()) {
930 view->m_cbs->webCrash();
932 // This flag will be prevented exit() call in the Webkit side
933 if (NULL != eventInfo) {
934 *(static_cast<Eina_Bool*>(eventInfo)) = EINA_TRUE;
938 void ViewLogic::createWindowCallback(
943 LogDebug("createWindowCallback");
945 ViewLogic* This = static_cast<ViewLogic*>(data);
947 // First, current webview should be handled by user callback
948 if (!This->m_cbs->bufferUnset.empty()) {
949 This->m_cbs->bufferUnset(obj);
952 // this can be set by executable for specific purpose
954 if (!This->m_cbs->windowCreateBefore.empty()) {
955 // 'obj' is parent webview object
956 This->m_cbs->windowCreateBefore(&canvas, obj);
959 canvas = evas_object_evas_get(This->m_window);
962 // create new ewkview
963 This->createEwkView(canvas);
964 Evas_Object* newEwkView = This->m_currentEwkView;
966 // initialize new ewkview
967 This->setStartPage();
968 This->ewkClientInit(newEwkView);
969 This->prepareEwkView(newEwkView);
971 // Specific jobs of child, parent webview are handled by each executable
972 if (!This->m_cbs->windowCreateAfter.empty()) {
973 // 'obj' is parent webview, 'newEwkView' is child webview
974 This->m_cbs->windowCreateAfter(obj, newEwkView);
977 // Lastly, new webview should be handled by user callback
978 if (!This->m_cbs->bufferSet.empty()) {
979 This->m_cbs->bufferSet(newEwkView);
981 *(static_cast<Evas_Object **>(eventInfo)) = newEwkView;
984 void ViewLogic::closeWindowCallback(
989 LogDebug("closeWindowCallback");
990 ViewLogic* This = static_cast<ViewLogic*>(data);
991 This->m_closedEwkView = obj;
992 ecore_idler_add(windowCloseIdlerCallback, This);
995 void ViewLogic::policyNavigationDecideCallback(
997 Evas_Object* /*obj*/,
1000 LogDebug("policyNavigationDecideCallback called");
1002 ViewLogic* This = static_cast<ViewLogic*>(data);
1004 Ewk_Policy_Decision* policyDecision =
1005 static_cast<Ewk_Policy_Decision*>(eventInfo);
1007 if (This->m_schemeSupport->filterURIByScheme(policyDecision,
1011 This->m_currentEwkView))
1014 ewk_policy_decision_use(policyDecision);
1016 // check whether this is new empty window
1017 const char* activeUrl = ewk_view_url_get(This->m_currentEwkView);
1018 if(!activeUrl || 0 == strlen(activeUrl)) {
1020 * The view is empty and scheme has been handled externally. When
1021 * user gets back from the external application he'd see blank page
1022 * and won't be able to navigate back. This happens when window.open
1023 * is used to handle schemes like sms/mms/mailto (for example in
1024 * WAC web standards tests: WS-15XX).
1026 * To solve the problem, the empty view is removed from the stack
1027 * and the previous one is shown. This is not an elegant solution
1028 * but we don't have a better one.
1030 LogInfo("Scheme has been handled externally. Removing empty view.");
1031 if (ewk_view_back_possible(This->m_currentEwkView)) {
1032 // go back to previous WKPage
1033 ewk_view_back(This->m_currentEwkView);
1035 // stop current WKPage
1036 ewk_view_stop(This->m_currentEwkView);
1037 ecore_idler_add(windowCloseIdlerCallback, This);
1042 ewk_policy_decision_ignore(policyDecision);
1046 void ViewLogic::policyNewWindowDecideCallback(
1048 Evas_Object* /*obj*/,
1051 LogDebug("policyNewWindowDecideCallback called");
1053 ViewLogic* This = static_cast<ViewLogic*>(data);
1055 Ewk_Policy_Decision* policyDecision =
1056 static_cast<Ewk_Policy_Decision*>(eventInfo);
1058 if (This->m_schemeSupport->filterURIByScheme(policyDecision,
1062 This->m_currentEwkView))
1064 ewk_policy_decision_use(policyDecision);
1067 ewk_policy_decision_ignore(policyDecision);
1071 void ViewLogic::pageResponseDecideCallback(
1073 Evas_Object* /*obj*/,
1076 LogDebug("pageResponseDecideCallback called");
1078 ViewLogic* This = static_cast<ViewLogic*>(data);
1080 Ewk_Policy_Decision* policyDecision =
1081 static_cast<Ewk_Policy_Decision*>(eventInfo);
1082 Ewk_Policy_Decision_Type policyDecisionType =
1083 ewk_policy_decision_type_get(policyDecision);
1085 if (policyDecisionType == EWK_POLICY_DECISION_USE) {
1087 ewk_policy_decision_use(policyDecision);
1088 } else if (policyDecisionType == EWK_POLICY_DECISION_DOWNLOAD) {
1089 LogDebug("download");
1090 ewk_policy_decision_suspend(policyDecision);
1092 // get uri information
1093 const char* url = ewk_policy_decision_url_get(policyDecision);
1094 if (NULL == url || strlen(url) == 0) {
1095 LogDebug("url data is empty");
1096 ewk_policy_decision_use(policyDecision);
1099 LogDebug("url = [" << url << "]");
1101 // get content information
1102 const char* content =
1103 ewk_policy_decision_response_mime_get(policyDecision);
1104 LogDebug("content type = [" << content << "]");
1106 // get cookie information
1107 const char* cookie = ewk_policy_decision_cookie_get(policyDecision);
1108 LogDebug("cookie = [" << cookie << "]");
1110 LogDebug("Content not supported, will be opened in external app");
1111 This->m_appsSupport->downloadRequest(
1115 ewk_policy_decision_ignore(policyDecision);
1116 } else if (policyDecisionType == EWK_POLICY_DECISION_IGNORE) {
1118 ewk_policy_decision_ignore(policyDecision);
1120 LogDebug("Type isn't handled");
1121 ewk_policy_decision_ignore(policyDecision);
1125 void ViewLogic::contextmenuCustomizeCallback(
1127 Evas_Object* /*obj*/,
1130 LogDebug("contextmenuCustomizeCallback called");
1133 ViewLogic* This = static_cast<ViewLogic*>(const_cast<void*>(data));
1134 Ewk_Context_Menu* menu = static_cast<Ewk_Context_Menu*>(eventInfo);
1135 if ((This->m_model->Type.Get().appType == WrtDB::APP_TYPE_TIZENWEBAPP) &&
1136 (This->m_model->SettingList.Get().getContextMenu()
1137 == ContextMenu_Disable))
1139 LogDebug("ContextMenu Disable!!");
1140 for (unsigned int idx = 0; idx < ewk_context_menu_item_count(menu);) {
1141 Ewk_Context_Menu_Item* item = ewk_context_menu_nth_item_get(menu, idx);
1143 ewk_context_menu_item_remove(menu, item);
1146 LogDebug("ContextMenu Enable!!");
1147 for (unsigned int idx = 0; idx < ewk_context_menu_item_count(menu);) {
1148 Ewk_Context_Menu_Item* item = ewk_context_menu_nth_item_get(menu, idx);
1150 Ewk_Context_Menu_Item_Tag tag = ewk_context_menu_item_tag_get(item);
1153 case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_IMAGE_IN_NEW_WINDOW:
1154 ewk_context_menu_item_remove(menu, item);
1157 case EWK_CONTEXT_MENU_ITEM_TAG_SEARCH_WEB:
1158 ewk_context_menu_item_remove(menu, item);
1169 void ViewLogic::formSubmitCallback(
1171 Evas_Object* /*obj*/,
1174 LogDebug("formSubmitCallback called");
1176 Ewk_Form_Data* formData = static_cast<Ewk_Form_Data*>(eventInfo);
1178 const char* uri = ewk_form_data_url_get(formData);
1180 LogError("URL is empty");
1184 Eina_Hash* userData = ewk_form_data_values_get(formData);
1185 ViewModule::PasswordSupport::submitClicked(uri, userData);
1188 void ViewLogic::geolocationPermissionRequestCallback(
1190 Evas_Object* /*obj*/,
1194 ViewLogic* This = static_cast<ViewLogic*>(data);
1196 Ewk_Geolocation_Permission_Data* permissionRequest =
1197 static_cast<Ewk_Geolocation_Permission_Data*>(eventInfo);
1199 if (This->m_securityOriginSupport->isNeedPermissionCheck(
1200 SecurityOriginDB::FEATURE_GEOLOCATION)
1201 == WrtDB::SETTINGS_TYPE_OFF)
1203 ewk_geolocation_permission_request_allow_set(
1204 ewk_geolocation_permission_request_get(permissionRequest),
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_response(
1286 ViewModule::WebNotification::webNotificationPermissionRequest(
1288 This->m_securityOriginSupport->getSecurityOriginDAO(),
1294 void ViewLogic::vibrationVibrateCallback(uint64_t time, void* data)
1296 LogDebug("vibrationVibrateCallback called");
1298 ViewLogic* This = static_cast<ViewLogic*>(data);
1299 This->m_vibrationSupport->startVibration(static_cast<long>(time));
1303 void ViewLogic::vibrationCancelCallback(void* data)
1305 LogDebug("vibrationCancelCallback called");
1307 ViewLogic* This = static_cast<ViewLogic*>(data);
1309 This->m_vibrationSupport->stopVibration();
1314 // EWK Orientation Callback
1315 Eina_Bool ViewLogic::orientationLockCallback(
1317 Eina_Bool /*needLock*/,
1321 LogDebug("orientationLockCallback called");
1323 ViewLogic* This = static_cast<ViewLogic*>(data);
1325 if (orientation & EWK_SCREEN_ORIENTATION_PORTRAIT_PRIMARY) {
1326 LogDebug("orientation is portrait-primary");
1327 elm_win_rotation_with_resize_set(This->m_window, 0);
1328 ewk_view_orientation_send(obj, 0);
1329 } else if(orientation & EWK_SCREEN_ORIENTATION_LANDSCAPE_PRIMARY) {
1330 LogDebug("orientation is landscape-primary");
1331 elm_win_rotation_with_resize_set(This->m_window, 270);
1332 ewk_view_orientation_send(obj, 90);
1333 } else if(orientation & EWK_SCREEN_ORIENTATION_PORTRAIT_SECONDARY) {
1334 LogDebug("orientation is portrait-secondary");
1335 elm_win_rotation_with_resize_set(This->m_window, 180);
1336 ewk_view_orientation_send(obj, 180);
1337 } else if(orientation & EWK_SCREEN_ORIENTATION_LANDSCAPE_SECONDARY) {
1338 LogDebug("orientation is landscape-secondary");
1339 elm_win_rotation_with_resize_set(This->m_window, 90);
1340 ewk_view_orientation_send(obj, -90);
1342 LogDebug("Wrong orientation is set");
1349 // Fullscreen API callbacks
1350 void ViewLogic::enterFullscreenCallback(
1352 Evas_Object* /*obj*/,
1353 void* /*eventInfo*/)
1355 LogInfo("enterFullscreenCallback called");
1357 ViewLogic* This = static_cast<ViewLogic*>(data);
1358 if (!This->m_cbs->toggleFullscreen.empty()) {
1359 This->m_cbs->toggleFullscreen(true);
1362 void ViewLogic::exitFullscreenCallback(
1364 Evas_Object* /*obj*/,
1365 void* /*eventInfo*/)
1367 LogInfo("exitFullscreenCallback called");
1369 ViewLogic* This = static_cast<ViewLogic*>(data);
1370 if (!This->m_cbs->toggleFullscreen.empty()) {
1371 This->m_cbs->toggleFullscreen(false);
1375 void ViewLogic::imeChangedCallback(
1377 Evas_Object* /*obj*/,
1383 ViewLogic* This = static_cast<ViewLogic*>(data);
1384 Eina_Rectangle *rect = static_cast<Eina_Rectangle *>(eventInfo);
1385 This->m_imeWidth = rect->w;
1386 This->m_imeHeight = rect->h;
1389 void ViewLogic::imeOpenedCallback(
1391 Evas_Object* /*obj*/,
1392 void* /*eventInfo*/)
1396 ViewLogic* This = static_cast<ViewLogic*>(data);
1398 using namespace WrtPlugins::W3C;
1399 SoftKeyboardChangeArgs args;
1400 args.state = IME_STATE_ON;
1401 args.width = This->m_imeWidth;
1402 args.height = This->m_imeHeight;
1403 This->fireJavascriptEvent(
1404 static_cast<int>(SoftKeyboardChangeCustomEvent),
1408 void ViewLogic::imeClosedCallback(
1410 Evas_Object* /*obj*/,
1411 void* /*eventInfo*/)
1415 ViewLogic* This = static_cast<ViewLogic*>(data);
1417 using namespace WrtPlugins::W3C;
1418 SoftKeyboardChangeArgs args;
1419 args.state = IME_STATE_OFF;
1421 This->fireJavascriptEvent(
1422 static_cast<int>(SoftKeyboardChangeCustomEvent),
1426 void ViewLogic::usermediaPermissionRequestCallback(
1428 Evas_Object* /*obj*/,
1431 LogDebug("usermediaPermissionRequestCallback called");
1433 ViewLogic* This = static_cast<ViewLogic*>(data);
1434 ViewModule::UsermediaSupport::usermediaPermissionRequest(This->m_window,
1440 CustomHandlerDB::CustomHandlerPtr getCustomHandlerFromData(void* data)
1443 Ewk_Custom_Handlers_Data* handler =
1444 static_cast<Ewk_Custom_Handlers_Data*>(data);
1445 CustomHandlerDB::CustomHandlerPtr customHandler(new CustomHandlerDB::CustomHandler());
1446 const char* base_url = ewk_custom_handlers_data_base_url_get(handler);
1448 LogDebug("base url: " << base_url);
1449 customHandler->base_url = DPL::FromASCIIString(string(base_url));
1451 const char* url = ewk_custom_handlers_data_url_get(handler);
1453 LogDebug("url: " << url);
1454 customHandler->url = DPL::FromASCIIString(string(url));
1456 const char* target = ewk_custom_handlers_data_target_get(handler);
1458 LogDebug("target: " << target);
1459 customHandler->target = DPL::FromASCIIString(string(target));
1461 const char* title = ewk_custom_handlers_data_title_get(handler);
1463 LogDebug("title: " << title);
1464 customHandler->title = DPL::FromASCIIString(string(title));
1466 return customHandler;
1469 void ViewLogic::attachToCustomHandlersDao()
1471 if (!m_attachedToCustomHandlerDao) {
1472 CustomHandlerDB::Interface::attachDatabaseRW();
1476 void ViewLogic::detachFromCustomHandlersDao()
1478 if (m_attachedToCustomHandlerDao) {
1479 CustomHandlerDB::Interface::detachDatabase();
1483 const int protocolWhiteListLenth = 15;
1484 char const * const protocolWhiteList[protocolWhiteListLenth] = {
1502 const int contentBlackListLenth = 14;
1503 char const * const contentBlackList[contentBlackListLenth] = {
1504 "application/x-www-form-urlencoded",
1505 "application/xhtml+xml",
1511 "multipart/x-mixed-replace",
1512 "text/cache-manifest",
1521 * Saves user's response from popup to custom handler. Saves Yes/No and remember
1524 * @param customHandler
1526 void saveUserResponse(Wrt::Popup::PopupResponse response,
1527 CustomHandlerDB::CustomHandlerPtr customHandler)
1530 case Wrt::Popup::YES_DO_REMEMBER:
1531 LogDebug("User allowed, remember");
1532 customHandler->user_decision = static_cast<CustomHandlerDB::HandlerState>
1533 (CustomHandlerDB::Agreed | CustomHandlerDB::DecisionSaved);
1535 case Wrt::Popup::YES_DONT_REMEMBER:
1536 LogDebug("User allowed, don't remember");
1537 customHandler->user_decision = CustomHandlerDB::Agreed;
1539 case Wrt::Popup::NO_DO_REMEMBER:
1540 LogDebug("User didn't allow, remember");
1541 customHandler->user_decision = static_cast<CustomHandlerDB::HandlerState>
1542 (CustomHandlerDB::Declined | CustomHandlerDB::DecisionSaved);
1544 case Wrt::Popup::NO_DONT_REMEMBER:
1545 LogDebug("User didn't allow, don't remember");
1546 customHandler->user_decision = CustomHandlerDB::Declined;
1551 //TODO registration, checking if registered and unregistration can be done in
1552 //common functions for both types of handlers. Only white and black lists
1553 //have to be separated
1554 //TODO attach database only one at the start (not in every callback?)
1555 void ViewLogic::protocolHandlerRegistrationCallback(void* data,
1561 CustomHandlerDB::CustomHandlerPtr customHandler =
1562 getCustomHandlerFromData(eventInfo);
1564 std::string scheme = DPL::ToUTF8String(customHandler->target);
1565 if (scheme.empty()) {
1566 LogError("No scheme provided");
1567 //TODO what about securityError?
1570 bool matched = false;
1571 //scheme on whiteList
1572 for (int i = 0; i < protocolWhiteListLenth; ++i) {
1573 if (0 == strcmp(protocolWhiteList[i], scheme.c_str()))
1575 LogDebug("Match found, protocol can be handled");
1580 //starts with web+ and have at least 5 chars (lowercase ASCII)
1581 if (strncmp("web+", scheme.c_str(), 4) || scheme.length() < 5) {
1582 LogWarning("Scheme neither on whitelist nor starts with \"web+\"");
1583 //throw SecurityException
1590 if (c < 'a' || c > 'z') {
1591 LogWarning("Wrong char inside scheme. "
1592 << "Only lowercase ASCII letters accepted");
1593 //throw SecurityException
1600 ViewLogic* This = static_cast<ViewLogic*>(data);
1601 LogDebug("Creating handlers dao");
1602 This->attachToCustomHandlersDao();
1603 CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1604 CustomHandlerDB::CustomHandlerPtr handler =
1605 handlersDao.getProtocolHandler(customHandler->target,
1607 customHandler->base_url);
1608 if (handler && (handler->user_decision & CustomHandlerDB::DecisionSaved)) {
1609 LogDebug("Protocol already registered - nothing to do");
1611 LogDebug("Protocol handler not found");
1612 Wrt::Popup::PopupResponse response =
1613 GlobalSettings::PopupsTestModeEnabled() ? Wrt::Popup::YES_DO_REMEMBER :
1614 Wrt::Popup::PopupInvoker().askYesNoCheckbox(
1615 PROTOCOL_HANDLER_ASK_TITLE,
1616 PROTOCOL_HANDLER_ASK_MSG,
1617 PROTOCOL_HANDLER_ASK_REMEMBER);
1618 saveUserResponse(response, customHandler);
1619 if (customHandler->user_decision == CustomHandlerDB::Declined)
1621 handlersDao.registerProtocolHandler(*(customHandler.get()));
1622 if (customHandler->user_decision & CustomHandlerDB::Agreed) {
1623 //TODO remove old default handler somehow from appsvc
1624 LogDebug("Registering appservice entry");
1625 int ret = appsvc_set_defapp(APPSVC_OPERATION_VIEW,
1627 DPL::ToUTF8String(customHandler->target).c_str(),
1628 DPL::ToUTF8String(This->m_model->TizenId).c_str());
1629 if (APPSVC_RET_OK != ret)
1631 LogWarning("Appsvc entry failed: " << ret);
1634 LogDebug("Protocal saved");
1637 This->detachFromCustomHandlersDao();
1640 void ViewLogic::protocolHandlerIsRegisteredCallback(void* data,
1645 CustomHandlerDB::CustomHandlerPtr customHandler = getCustomHandlerFromData(eventInfo);
1646 ViewLogic* This = static_cast<ViewLogic*>(data);
1647 LogDebug("Creating handlers dao");
1648 This->attachToCustomHandlersDao();
1649 CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1650 CustomHandlerDB::CustomHandlerPtr handler =
1651 handlersDao.getProtocolHandler(customHandler->target,
1653 customHandler->base_url);
1655 if (handler->user_decision & CustomHandlerDB::Agreed)
1656 ewk_custom_handlers_data_result_set(
1657 static_cast<Ewk_Custom_Handlers_Data*>(data),
1658 EWK_CUSTOM_HANDLERS_REGISTERED);
1660 ewk_custom_handlers_data_result_set(
1661 static_cast<Ewk_Custom_Handlers_Data*>(data),
1662 EWK_CUSTOM_HANDLERS_DECLINED);
1664 ewk_custom_handlers_data_result_set(
1665 static_cast<Ewk_Custom_Handlers_Data*>(data),
1666 EWK_CUSTOM_HANDLERS_NEW);
1667 This->detachFromCustomHandlersDao();
1670 void ViewLogic::protocolHandlerUnregistrationCallback(void* data,
1675 CustomHandlerDB::CustomHandlerPtr customHandler =
1676 getCustomHandlerFromData(eventInfo);
1677 ViewLogic* This = static_cast<ViewLogic*>(data);
1678 LogDebug("Creating handlers dao");
1679 This->attachToCustomHandlersDao();
1680 CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1681 CustomHandlerDB::CustomHandlerPtr handlerCheck =
1682 handlersDao.getProtocolHandler(customHandler->target,
1684 customHandler->base_url);
1686 if (handlerCheck->user_decision & CustomHandlerDB::Agreed)
1687 appsvc_unset_defapp(DPL::ToUTF8String(This->m_model->TizenId).c_str());
1689 handlersDao.unregisterProtocolHandler(customHandler->target,
1691 customHandler->base_url);
1693 LogDebug("Nothing to unregister");
1695 This->detachFromCustomHandlersDao();
1698 void ViewLogic::contentHandlerRegistrationCallback(void* data,
1704 CustomHandlerDB::CustomHandlerPtr customHandler =
1705 getCustomHandlerFromData(eventInfo);
1707 std::string mimeType = DPL::ToUTF8String(customHandler->target);
1708 if (mimeType.empty()) {
1709 LogError("No mimeType provided.");
1712 for (int i = 0; i < contentBlackListLenth; ++i)
1714 if (0 == strcmp(contentBlackList[i], mimeType.c_str()))
1716 LogWarning("mimeType blacklisted");
1717 //throw SecurityException
1722 ViewLogic* This = static_cast<ViewLogic*>(data);
1723 LogDebug("Creating handlers dao");
1724 This->attachToCustomHandlersDao();
1725 CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1726 CustomHandlerDB::CustomHandlerPtr handler =
1727 handlersDao.getContentHandler(customHandler->target,
1729 customHandler->base_url);
1730 if (handler && (handler->user_decision & CustomHandlerDB::DecisionSaved)) {
1731 LogDebug("Protocol already registered - nothing to do");
1733 LogDebug("Protocol handler not found");
1734 Wrt::Popup::PopupResponse response =
1735 GlobalSettings::PopupsTestModeEnabled() ? Wrt::Popup::YES_DO_REMEMBER :
1736 Wrt::Popup::PopupInvoker().askYesNoCheckbox(
1737 CONTENT_HANDLER_ASK_TITLE,
1738 CONTENT_HANDLER_ASK_MSG,
1739 CONTENT_HANDLER_AKS_REMEMBER);
1740 saveUserResponse(response, customHandler);
1741 if (customHandler->user_decision == CustomHandlerDB::Declined)
1743 handlersDao.registerContentHandler(*(customHandler.get()));
1744 if (customHandler->user_decision & CustomHandlerDB::Agreed) {
1745 //TODO remove old default handler somehow from appsvc
1746 LogDebug("Registering appservice entry");
1747 int ret = appsvc_set_defapp(APPSVC_OPERATION_VIEW,
1748 DPL::ToUTF8String(customHandler->target).c_str(),
1750 DPL::ToUTF8String(This->m_model->TizenId).c_str());
1751 if (APPSVC_RET_OK != ret)
1753 LogWarning("Appsvc entry failed: " << ret);
1756 LogDebug("Content saved");
1758 This->detachFromCustomHandlersDao();
1761 void ViewLogic::contentHandlerIsRegisteredCallback(void* data,
1766 CustomHandlerDB::CustomHandlerPtr customHandler =
1767 getCustomHandlerFromData(eventInfo);
1768 ViewLogic* This = static_cast<ViewLogic*>(data);
1769 LogDebug("Creating handlers dao");
1771 This->attachToCustomHandlersDao();
1772 CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1773 CustomHandlerDB::CustomHandlerPtr handler =
1774 handlersDao.getContentHandler(customHandler->target,
1776 customHandler->base_url);
1778 if (handler->user_decision & CustomHandlerDB::Agreed)
1779 ewk_custom_handlers_data_result_set(
1780 static_cast<Ewk_Custom_Handlers_Data*>(data),
1781 EWK_CUSTOM_HANDLERS_REGISTERED);
1783 ewk_custom_handlers_data_result_set(
1784 static_cast<Ewk_Custom_Handlers_Data*>(data),
1785 EWK_CUSTOM_HANDLERS_DECLINED);
1787 ewk_custom_handlers_data_result_set(
1788 static_cast<Ewk_Custom_Handlers_Data*>(data),
1789 EWK_CUSTOM_HANDLERS_NEW);
1790 This->detachFromCustomHandlersDao();
1793 void ViewLogic::contentHandlerUnregistrationCallback(void* data,
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());
1812 handlersDao.unregisterContentHandler(customHandler->target,
1814 customHandler->base_url);
1816 LogDebug("Nothing to unregister");
1817 This->detachFromCustomHandlersDao();
1820 void ViewLogic::didRunJavaScriptCallback(
1821 Evas_Object* /*obj*/,
1825 LogInfo("didRunJavaScriptCallback called");
1826 LogInfo("result = " << result);
1829 Eina_Bool ViewLogic::windowCloseIdlerCallback(void* data)
1831 LogDebug("closeIdlerCallback");
1832 ViewLogic* This = static_cast<ViewLogic*>(data);
1833 This->windowClose();
1834 return ECORE_CALLBACK_CANCEL;
1837 int ViewLogic::appcoreLowMemoryCallback(void *data)
1839 LogInfo("appcoreLowMemoryCallback");
1841 ViewLogic* This = static_cast<ViewLogic*>(data);
1843 if (NULL == This->m_ewkContext) {
1844 LogInfo("ewk isn't initialize at this moment");
1846 // Crash may occur on specific situation
1847 // So use the followings after they become stable
1848 //ewk_context_cache_clear(This->m_ewkContext);
1849 //ewk_context_notify_low_memory(This->m_ewkContext);
1855 void ViewLogic::databaseUsagePermissionRequestCallback(
1857 Evas_Object* /*obj*/,
1860 LogDebug("databaseUsagePermissionRequestCallback called");
1862 ViewLogic* This = static_cast<ViewLogic*>(data);
1865 if (This->m_securityOriginSupport->isNeedPermissionCheck(
1866 SecurityOriginDB::FEATURE_WEB_DATABASE)
1867 == WrtDB::SETTINGS_TYPE_OFF)
1869 // default value is deny
1872 ViewModule::WebStorageSupport::webStorageCreatePermissionRequest(
1874 This->m_securityOriginSupport->getSecurityOriginDAO(),
1879 void ViewLogic::fileSystemPermissionRequestCallback(
1881 Evas_Object* /*obj*/,
1884 LogDebug("fileSystemPermissionRequestCallback called");
1886 ViewLogic* This = static_cast<ViewLogic*>(data);
1888 if (This->m_securityOriginSupport->isNeedPermissionCheck(
1889 SecurityOriginDB::FEATURE_FILE_SYSTEM_ACCESS)
1890 == WrtDB::SETTINGS_TYPE_OFF)
1892 Ewk_Context_File_System_Permission* fileSystemPermission =
1893 static_cast<Ewk_Context_File_System_Permission*>(eventInfo);
1894 ewk_context_file_system_permission_allow_set(fileSystemPermission,
1900 ViewModule::FileSystemSupport::fileSystemPermissionRequest(
1902 This->m_securityOriginSupport->getSecurityOriginDAO(),
1906 void ViewLogic::certificateConfirmRequestCallback(
1908 Evas_Object* /*obj*/,
1911 LogDebug("certificateConfirmRequestCallback called");
1914 ViewLogic* This = static_cast<ViewLogic*>(data);
1916 Ewk_Certificate_Policy_Decision* certificatePolicyDecision =
1917 static_cast<Ewk_Certificate_Policy_Decision*>(eventInfo);
1919 bool status = This->askUserForCertificateConfirm();
1921 ewk_certificate_policy_decision_allowed_set(
1922 certificatePolicyDecision,
1926 ewk_certificate_policy_decision_allowed_set(
1927 certificatePolicyDecision,
1932 bool ViewLogic::askUserForCertificateConfirm()
1934 return Wrt::Popup::PopupInvoker().askYesNo(
1935 CERTIFICATE_CONFIRM_REQUEST_ASK_TITLE,
1936 CERTIFICATE_CONFIRM_REQUEST_ASK_BODY);
1939 void ViewLogic::didRecieveMessageFromInjectedBundle(
1941 const char* /*body*/)
1943 LogDebug("did recive message " << name);
1946 void ViewLogic::didReceiveSynchronousMessage(
1951 LogDebug("didReceiveSynchronousMessage called");
1956 LogDebug("body is empty");
1960 if (!strcmp(name, uriBlockedMessageName)) {
1961 LogDebug("received : " << uriBlockedMessageName);
1962 // Currently WebProcess informs obly about blocked
1963 // URI - URI localization and security chekcs are
1964 // done by WebProcess itself (see: wrt-wk2-bundle.cpp
1965 // and bundle_uri_handling.cpp)
1966 rememberBlockedURI(DPL::FromUTF8String(body));
1968 } else if (!strcmp(name, uriChangedMessageName)) {
1969 LogDebug("received : " << uriChangedMessageName);
1970 std::string ret = requestUriChanged(DPL::FromUTF8String(body));
1971 *returnData = strdup(ret.c_str());
1975 void ViewLogic::rememberBlockedURI(const DPL::String& inputURI)
1977 m_blockedUri = DPL::ToUTF8String(inputURI);
1978 LogInfo("set blocked uri to open browser later : " << m_blockedUri);
1982 std::string ViewLogic::requestUriChanged(const DPL::String& changedURL)
1984 using namespace ViewModule::SecuritySupport;
1986 std::string url = DPL::ToUTF8String(changedURL);
1987 LogInfo("URL = [" << url << "]");
1990 // If url is same to URICHANGE_BLOCKED_URL,
1991 // this url has been already blocked by willsend.
1992 // So current page should be moved to previous page
1993 if (url == URICHANGE_BLOCKED_URL)
1995 if (m_model->Type.Get().appType == WrtDB::APP_TYPE_TIZENWEBAPP)
1997 // block this page and open it in browser
1998 LogDebug("Request was blocked by WARP: " << url.c_str());
1999 if (!m_blockedUri.empty()) {
2000 LogDebug("open browser : " << m_blockedUri);
2001 bundle* bundleData = bundle_create();
2002 appsvc_set_operation(bundleData, APPSVC_OPERATION_VIEW);
2003 appsvc_set_uri(bundleData, m_blockedUri.c_str());
2004 CONTROLLER_POST_EVENT(
2005 ApplicationLauncher,
2006 ApplicationLauncherEvents::LaunchApplicationByAppService(
2010 m_blockedUri = std::string();
2013 if (ewk_view_back_possible(m_currentEwkView)) {
2014 // go back to previous page
2015 ewk_view_back(m_currentEwkView);
2017 // stop current page
2018 ewk_view_stop(m_currentEwkView);
2019 ecore_idler_add(windowCloseIdlerCallback, this);
2022 // This is used in case of returning previous page
2024 return URICHANGE_PLUGIN_NO_CHANGE;
2029 // Check if this url with 'http' or 'https' is included in whitelist,
2030 // which has lists of accessible external documents and
2031 // used for ONLY Tizen app
2032 std::string matchedScheme;
2033 std::string matchedUri;
2034 pcrecpp::RE(PATTERN_URI_CHANGE).PartialMatch(url.c_str(),
2037 ViewModule::Scheme scheme(matchedScheme);
2038 if (scheme.GetType() == ViewModule::Scheme::HTTP ||
2039 scheme.GetType() == ViewModule::Scheme::HTTPS)
2041 if (m_model->Type.Get().appType == WrtDB::APP_TYPE_TIZENWEBAPP) {
2042 if (!checkWhitelist(url.c_str())) {
2043 LogInfo("This uri is not included in white document list");
2044 return URICHANGE_PLUGIN_STOP_ONLY;
2046 LogInfo("This url is included in WhiteList");
2048 // For WAC app, WRT should block access of device api
2049 // for external documents
2050 return URICHANGE_PLUGIN_STOP_ONLY;
2054 // register javascript object for plugins to be used
2055 LogInfo("Register Plugin Objects");
2056 return URICHANGE_PLUGIN_RESTART;
2059 void ViewLogic::windowClose()
2061 LogDebug("windowClose");
2062 Assert(m_closedEwkView && "no closed webview");
2064 if (1 >= m_ewkViewList.size()) {
2065 if (!m_cbs->webkitExit.empty()) {
2066 m_cbs->webkitExit();
2069 // call user callbacks
2070 if (!m_cbs->bufferUnset.empty()) {
2071 m_cbs->bufferUnset(m_currentEwkView);
2073 if (!m_cbs->windowClose.empty()) {
2074 m_cbs->windowClose(m_closedEwkView);
2076 removeEwkView(m_closedEwkView);
2078 // get latest ewkView
2079 m_currentEwkView = m_ewkViewList.back();
2080 const char* uri = ewk_view_url_get(m_currentEwkView);
2081 if (NULL == uri || 0 == strlen(uri)) {
2082 m_currentUri.clear();
2088 /* In case we support many pages in parallel
2089 then view is not suspended*/
2090 //resumeEwkView(m_currentEwkView);
2093 if (!m_cbs->bufferSet.empty()) {
2094 m_cbs->bufferSet(m_currentEwkView);