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>
32 #include <appcore-common.h>
35 #include <widget_model.h>
36 #include <dpl/wrt-dao-ro/widget_dao_read_only.h>
37 #include <wrt-commons/custom-handler-dao-ro/CustomHandlerDatabase.h>
38 #include <wrt-commons/custom-handler-dao-rw/custom_handler_dao.h>
40 #include <common/application_data.h>
41 #include <common/application_launcher.h>
42 #include <common/scheme.h>
44 #include <common/view_logic_apps_support.h>
45 #include <common/view_logic_custom_header_support.h>
46 #include <common/view_logic_password_support.h>
47 #include <common/view_logic_security_support.h>
48 #include <common/view_logic_security_origin_support.h>
49 #include <common/view_logic_storage_support.h>
50 #include <common/view_logic_uri_support.h>
51 #include <common/view_logic_user_agent_support.h>
52 #include <common/view_logic_vibration_support.h>
53 #include <common/view_logic_web_notification_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_web_storage_support.h>
58 #include "bundles/plugin_module_support.h"
59 #include <popup-runner/PopupInvoker.h>
62 #include <js_overlay_types.h>
63 #include <i_runnable_widget_object.h>
64 #include <profiling_util.h>
67 const char * const bundlePath = "/usr/lib/wrt-wk2-bundles/libwrt-wk2-bundle.so";
68 const char * const uriBlockedMessageName = "uri_block_msg";
69 const char * const uriChangedMessageName = "uri_changed_msg";
70 const char * const URICHANGE_PLUGIN_STOP_ONLY = "plugin_stop_only";
71 const char * const URICHANGE_PLUGIN_RESTART = "plugin_restart";
72 const char * const URICHANGE_PLUGIN_NO_CHANGE = "plugin_no_change";
73 const char * const URICHANGE_BLOCKED_URL = "null";
74 const char* PATTERN_URI_CHANGE = "^(([^:/\\?#]+)://[^\\?#]*)";
75 const int MAX_NUM_CONTEXT_MENU_ITEMS = 10;
77 const char * const IME_STATE_ON = "on";
78 const char * const IME_STATE_OFF = "off";
81 const char * const EWK_LOAD_STARTED = "load,started";
82 const char * const EWK_LOAD_FINISHED = "load,finished";
83 const char * const EWK_TITLE_CHANGED = "title,changed";
84 const char * const EWK_LOAD_PROGRESS = "load,progress";
85 const char * const EWK_LOAD_PROGRESS_FINISHED = "load,progress,finished";
86 const char * const EWK_PROCESS_CRASHED = "process,crashed";
88 const char * const EWK_CREATE_WINDOW = "create,window";
89 const char * const EWK_CLOSE_WINDOW = "close,window";
91 const char * const EWK_POLICY_NAVIGATION_DECIDE = "policy,navigation,decide";
92 const char * const EWK_POLICY_NEWWINDOW_DECIDE = "policy,newwindow,decide";
93 const char * const EWK_POLICY_RESPONSE_DECIDE = "policy,response,decide";
94 // WKPageContextMenuClient
95 const char * const EWK_CONTEXTMENU_CUSTOMIZE = "contextmenu,customize";
97 const char * const EWK_FORM_SUBMIT = "form,submit";
98 // EWK Geolocation Callback
99 const char * const EWK_REQUEST_GEOLOCATION_PERMISSION =
100 "request,geolocation,permission";
101 // EWK Notification Callback
102 const char * const EWK_NOTIFICATION_SHOW = "notification,show";
103 const char * const EWK_NOTIFICATION_CANCEL = "notification,cancel";
104 const char * const EWK_NOTIFICATION_PERMISSION_REQUEST =
105 "notification,permission,request";
106 // EWK Vibration Callback
107 const char * const EWK_VIBRATION_VIBRATE = "vibration,vibrate";
108 const char * const EWK_VIBRATION_CANCEL = "vibration,cancel";
110 const char * const EWK_CONTEXT_EXCEEDED_QUOATA = "database,quota,exceeded";
111 const char * const EWK_FILESYSTEM_PERMISSION_REQUEST = "filesystem,permission,request";
112 const char * const EWK_FULLSCREEN_ENTER = "fullscreen,enterfullscreen";
113 const char * const EWK_FULLSCREEN_EXIT = "fullscreen,exitfullscreen";
116 const char * const EWK_INPUTMETHOD_CHANGED = "inputmethod,changed";
117 const char * const EWK_EDITORCLIENT_IME_CLOSED = "editorclient,ime,closed";
120 const char * const EWK_PROTOCOLHANDLER_REGISTRATION = "protocolhandler,registration,requested";
121 const char * const EWK_PROTOCOLHANDLER_ISREGISTERED = "protocolhandler,isregistered";
122 const char * const EWK_PROTOCOLHANDLER_UNREGISTRATION = "protocolhandler,unregistration,requested";
123 const char * const EWK_CONTENTHANDLER_REGISTRATION = "contenthandler,registration,requested";
124 const char * const EWK_CONTENTHANDLER_ISREGISTERED = "contenthandler,isregistered";
125 const char * const EWK_CONTENTHANDLER_UNREGISTRATION = "contenthandler,unregistration,requested";
127 const char PROTOCOL_HANDLER_ASK_MSG[] = "Add protocol?";
128 const char PROTOCOL_HANDLER_ASK_TITLE[] = "Add protocol";
129 const char CONTENT_HANDLER_ASK_MSG[] = "Add content?";
130 const char CONTENT_HANDLER_ASK_TITLE[] = "Add content";
133 ViewLogic::ViewLogic():
138 m_cbs(new WRT::UserDelegates),
139 m_appsSupport(new ViewModule::AppsSupport()),
140 m_vibrationSupport(NULL),
141 m_attachedToCustomHandlerDao(false)
145 ViewLogic::~ViewLogic ()
147 detachFromCustomHandlersDao();
150 void ViewLogic::createWebView(Ewk_Context* context,
154 initializeEwkContext(context);
155 Assert(NULL != m_ewkContext);
158 createEwkView(evas_object_evas_get(m_window));
161 void ViewLogic::destroyWebView()
164 finalizeEwkContext();
168 void ViewLogic::initialize()
170 LogDebug("Initializing");
171 ApplicationLauncherSingleton::Instance().Touch();
172 appcore_set_event_callback(
173 APPCORE_EVENT_LOW_MEMORY,
174 &appcoreLowMemoryCallback,
178 void ViewLogic::terminate()
180 LogDebug("terminating view logic");
184 LogError("Widget model not created");
189 void ViewLogic::prepareView(WidgetModel* m, const std::string &startUrl)
191 LogDebug("View prepare");
195 m_startUrl = ViewModule::UriSupport::getUri(m_model, startUrl);
196 Assert(NULL != m_ewkContext);
199 ADD_PROFILING_POINT("initializeSupport", "start");
201 ADD_PROFILING_POINT("initializeSupport", "stop");
203 ewkClientInit(m_currentEwkView);
204 ADD_PROFILING_POINT("prepareEwkView", "start");
205 prepareEwkView(m_currentEwkView);
206 ADD_PROFILING_POINT("prepareEwkView", "stop");
207 initializePluginLoading();
210 void ViewLogic::showWidget()
212 LogDebug("showing widget");
213 Assert(NULL != m_currentEwkView && "ewk_view not created at this point");
214 if (m_currentUri.empty()) {
215 LogError("Localized current URI doesn't exist");
219 LogInfo("m_currentUri: " << m_currentUri);
222 ewk_view_url_set(m_currentEwkView, m_currentUri.c_str());
224 if (!m_cbs->bufferSet.empty()) {
225 m_cbs->bufferSet(m_currentEwkView);
229 void ViewLogic::hideWidget()
231 LogDebug("hiding widget");
232 ViewModule::StorageSupport::deinitializeStorage(m_model);
233 m_appsSupport->deinitialize();
236 // m_vibrationSupport->deinitialize();
238 while (m_ewkViewList.size()) {
239 LogInfo("pop webview: " << m_ewkViewList.back());
240 removeEwkView(m_ewkViewList.back());
242 m_ewkViewList.clear();
245 void ViewLogic::suspendWidget()
247 LogInfo("Pausing widget");
250 LogDebug("Request bundle to suspend");
251 PluginModuleSupport::suspend(m_ewkContext);
253 if (!m_currentEwkView) {
254 LogWarning("Cannot suspend widget without view");
256 suspendWebkit(m_currentEwkView);
259 evas_object_focus_set(m_currentEwkView, EINA_FALSE);
261 // call user callback
262 if (!m_cbs->suspend.empty()) {
263 m_cbs->suspend(true);
267 void ViewLogic::resumeWidget()
269 LogInfo("Resume widget");
272 LogDebug("Request bundle to resume");
273 PluginModuleSupport::resume(m_ewkContext);
275 if (m_currentEwkView) {
276 resumeWebkit(m_currentEwkView);
280 elm_win_raise(m_window);
282 evas_object_focus_set(m_currentEwkView, EINA_TRUE);
284 // call user callback
285 if (!m_cbs->resume.empty()) {
290 void ViewLogic::resetWidget()
292 LogInfo("Resetting Widget");
294 // check if already created webview exists
295 if (!m_ewkViewList.size()) {
296 // create new webview
297 createEwkView(evas_object_evas_get(m_window));
299 ewkClientInit(m_currentEwkView);
300 prepareEwkView(m_currentEwkView);
302 // check if current url is service url for this tizen service
303 std::string requestedUri =
304 ViewModule::UriSupport::getUri(m_model, m_startUrl);
305 DPL::OptionalString servicedUri = ViewModule::UriSupport::localizeURI(
306 DPL::FromUTF8String(requestedUri.c_str()),
309 const char* currentUri = ewk_view_uri_get(m_currentEwkView);
310 if (!currentUri && 0 == strlen(currentUri)) {
311 LogError("Fail to get uri from ewk_view_uri_get");
316 PluginModuleSupport::resume(m_ewkContext);
317 resumeWebkit(m_currentEwkView);
318 if (DPL::ToUTF8String(*servicedUri) == currentUri) {
319 LogInfo("current page is raised");
320 // set only encoded bundle
321 double scale = elm_config_scale_get();
322 PluginModuleSupport::setCustomProperties(
325 ApplicationDataSingleton::Instance().getEncodedBundle());
326 PluginModuleSupport::dispatchJavaScriptEvent(
328 WrtPlugins::W3C::ServiceCustomEvent,
331 LogInfo("service page is loaded");
332 m_currentUri = DPL::ToUTF8String(*servicedUri);
333 ewk_view_url_set(m_currentEwkView, m_currentUri.c_str());
335 elm_win_raise(m_window);
336 evas_object_focus_set(m_currentEwkView, EINA_TRUE);
339 // call user callback
340 if (!m_cbs->reset.empty()) {
343 if (!m_cbs->bufferSet.empty()) {
344 m_cbs->bufferSet(m_currentEwkView);
348 void ViewLogic::backward()
350 if (ewk_view_back_possible(m_currentEwkView)) {
351 ewk_view_back(m_currentEwkView);
353 if (1 >= m_ewkViewList.size()) {
354 // If there is no previous page, widget move to backgroud.
355 LogInfo("Widget move to backgroud");
356 elm_win_lower(m_window);
358 // Back to previous webview
359 LogInfo("Widget move to previous webview");
360 ecore_idler_add(windowCloseIdlerCallback, this);
365 void ViewLogic::reload()
367 ewk_view_reload(m_currentEwkView);
370 void ViewLogic::forward()
372 if (ewk_view_forward_possible(m_currentEwkView)) {
373 ewk_view_forward(m_currentEwkView);
377 void ViewLogic::reloadStartPage()
379 LogInfo("Reload Start Page");
381 if (m_ewkViewList.size() == 0) {
382 // create new webview
383 createEwkView(evas_object_evas_get(m_window));
384 ewkClientInit(m_currentEwkView);
386 // close opened windows
387 while (m_ewkViewList.size() > 1) {
388 if (!m_cbs->bufferUnset.empty()) {
389 m_cbs->bufferUnset(m_currentEwkView);
391 removeEwkView(m_currentEwkView);
392 m_currentEwkView = m_ewkViewList.back();
394 LogInfo("Close ewkViews done : m_ewkViewList.size() = "
395 << m_ewkViewList.size());
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::initializeEwkContext(Ewk_Context* newEwkContext)
433 LogInfo("initializeEwkContext called");
434 Assert(newEwkContext && "Ewk_Context provided can not be null");
435 // bundle callback setting
436 ewk_context_message_from_injected_bundle_callback_set(
438 contextMessageFromInjectedBundleCallback,
439 static_cast<void*>(this));
441 // proxy server setting
442 char *proxyAddress = vconf_get_str(VCONFKEY_NETWORK_PROXY);
443 if ((!proxyAddress) || (strlen(proxyAddress) == 0)
444 || (strstr(proxyAddress, "0.0.0.0")))
446 LogInfo("proxy address is empty");
447 ewk_context_proxy_uri_set(newEwkContext, NULL);
449 LogInfo("proxy address [" << proxyAddress << "]");
450 ewk_context_proxy_uri_set(newEwkContext, proxyAddress);
459 const char *theme = elm_theme_get(NULL);
462 LogInfo("theme is " << m_theme);
465 // Ewk download callback (WKContextDownloadClient)
466 ewk_context_did_start_download_callback_set(
468 didStartDownloadCallback,
471 // set to member value
472 m_ewkContext = newEwkContext;
475 void ViewLogic::finalizeEwkContext()
477 LogInfo("finalizeEwkContext called");
478 ewk_context_message_from_injected_bundle_callback_set(
482 // ewk_context_delete(m_ewkContext);
486 void ViewLogic::initializeSupport()
488 // set local stroage database path
489 WrtDB::WidgetDAOReadOnly dao(m_model->TizenId);
490 ewk_context_web_storage_path_set(m_ewkContext,
491 dao.getPrivateLocalStoragePath().c_str());
492 m_schemeSupport.reset(new SchemeSupport(m_model->Type.Get().appType));
493 ViewModule::StorageSupport::initializeStorage(m_model);
494 m_appsSupport->initialize(m_model);
495 m_securityOriginSupport.reset(new ViewModule::SecurityOriginSupport(m_model));
498 // m_vibrationSupport->initialize();
501 void ViewLogic::initializePluginLoading()
503 // inform wrt information for plugin loading to web process
504 PluginModuleSupport::start(
507 elm_config_scale_get(),
508 ApplicationDataSingleton::Instance().getEncodedBundle(),
510 m_model->SettingList.Get().isEncrypted());
513 void ViewLogic::ewkClientInit(Evas_Object *wkView) {
514 Assert(NULL != wkView && "ewk_view not created at this point");
515 // WKPageLoaderClient
516 evas_object_smart_callback_add(
521 evas_object_smart_callback_add(
524 loadFinishedCallback,
526 evas_object_smart_callback_add(
529 titleChangedCallback,
531 evas_object_smart_callback_add(
534 loadProgressCallback,
536 evas_object_smart_callback_add(
538 EWK_LOAD_PROGRESS_FINISHED,
539 loadProgressFinishedCallback,
541 evas_object_smart_callback_add(
544 processCrashedCallback,
548 evas_object_smart_callback_add(
551 createWindowCallback,
553 evas_object_smart_callback_add(
559 // WKPagePolicyClient
560 evas_object_smart_callback_add(
562 EWK_POLICY_NAVIGATION_DECIDE,
563 policyNavigationDecideCallback,
565 evas_object_smart_callback_add(
567 EWK_POLICY_NEWWINDOW_DECIDE,
568 policyNewWindowDecideCallback,
570 evas_object_smart_callback_add(
572 EWK_POLICY_RESPONSE_DECIDE,
573 pageResponseDecideCallback,
576 // WKPageContextMenuClient
577 evas_object_smart_callback_add(
579 EWK_CONTEXTMENU_CUSTOMIZE,
580 contextmenuCustomizeCallback,
584 evas_object_smart_callback_add(
590 // EWK Geolocation Callback
591 evas_object_smart_callback_add(
593 EWK_REQUEST_GEOLOCATION_PERMISSION,
594 geolocationPermissionRequestCallback,
597 // EWK Notification Callback
598 evas_object_smart_callback_add(
600 EWK_NOTIFICATION_SHOW,
601 notificationShowCallback,
603 evas_object_smart_callback_add(
605 EWK_NOTIFICATION_CANCEL,
606 notificationCancelCallback,
608 evas_object_smart_callback_add(
610 EWK_NOTIFICATION_PERMISSION_REQUEST,
611 notificationPermissionRequestCallback,
614 // EWK Vibration Callback
615 evas_object_smart_callback_add(
617 EWK_VIBRATION_VIBRATE,
618 vibrationVibrateCallback,
620 evas_object_smart_callback_add(
622 EWK_VIBRATION_CANCEL,
623 vibrationCancelCallback,
625 evas_object_smart_callback_add(
627 EWK_CONTEXT_EXCEEDED_QUOATA,
628 databaseUsagePermissionRequestCallback,
630 evas_object_smart_callback_add(
632 EWK_FILESYSTEM_PERMISSION_REQUEST,
633 fileSystemPermissionRequestCallback,
636 // EWK Orientation Callback
637 ewk_view_orientation_lock_callback_set(
639 orientationLockCallback,
642 // Fullscreen API callbacks
643 evas_object_smart_callback_add(
645 EWK_FULLSCREEN_ENTER,
646 enterFullscreenCallback,
648 evas_object_smart_callback_add(
651 exitFullscreenCallback,
655 // when ime start to be showed on the webview,
656 // this callback will be called
657 evas_object_smart_callback_add(
659 EWK_INPUTMETHOD_CHANGED,
663 // this callback will be called
664 // when ime finishes to be showed on the webview
665 // "event_info" arg of this callback is always NULL point
666 // if web content should know size of ime,
667 // use "inputmethod,changed" instead of this.
669 //evas_object_smart_callback_add(
671 // "editorclient,ime,opened",
672 // imeSomethingCallback,
675 // when ime finished to be hidden,
676 // this callback will be called
677 evas_object_smart_callback_add(
679 EWK_EDITORCLIENT_IME_CLOSED,
683 // custom content/scheme handlers
684 evas_object_smart_callback_add(
686 EWK_PROTOCOLHANDLER_REGISTRATION,
687 protocolHandlerRegistrationCallback,
689 evas_object_smart_callback_add(
691 EWK_PROTOCOLHANDLER_ISREGISTERED,
692 protocolHandlerIsRegisteredCallback,
694 evas_object_smart_callback_add(
696 EWK_PROTOCOLHANDLER_UNREGISTRATION,
697 protocolHandlerUnregistrationCallback,
700 evas_object_smart_callback_add(
702 EWK_CONTENTHANDLER_REGISTRATION,
703 contentHandlerRegistrationCallback,
705 evas_object_smart_callback_add(
707 EWK_CONTENTHANDLER_ISREGISTERED,
708 contentHandlerIsRegisteredCallback,
710 evas_object_smart_callback_add(
712 EWK_CONTENTHANDLER_UNREGISTRATION,
713 contentHandlerUnregistrationCallback,
717 void ViewLogic::ewkClientDeinit(Evas_Object *wkView) {
718 LogDebug("ewkClientDeinit");
719 Assert(NULL != wkView && "ewk_view not created at this point");
721 // WKPageLoaderClient
722 evas_object_smart_callback_del(
725 loadStartedCallback);
726 evas_object_smart_callback_del(
729 loadFinishedCallback);
730 evas_object_smart_callback_del(
733 titleChangedCallback);
734 evas_object_smart_callback_del(
737 loadProgressCallback);
738 evas_object_smart_callback_del(
740 EWK_LOAD_PROGRESS_FINISHED,
741 loadProgressFinishedCallback);
742 evas_object_smart_callback_del(
745 loadProgressCallback);
748 evas_object_smart_callback_del(
751 createWindowCallback);
752 evas_object_smart_callback_del(
755 closeWindowCallback);
757 // WKPagePolicyClient
758 evas_object_smart_callback_del(
760 EWK_POLICY_NAVIGATION_DECIDE,
761 policyNavigationDecideCallback);
762 evas_object_smart_callback_del(
764 EWK_POLICY_NEWWINDOW_DECIDE,
765 policyNewWindowDecideCallback);
766 evas_object_smart_callback_del(
768 EWK_POLICY_RESPONSE_DECIDE,
769 pageResponseDecideCallback);
771 // WKPageContextMenuClient
772 evas_object_smart_callback_del(
774 EWK_CONTEXTMENU_CUSTOMIZE,
775 contextmenuCustomizeCallback);
778 evas_object_smart_callback_del(
783 // EWK Geolocation Callback
784 evas_object_smart_callback_del(
786 EWK_REQUEST_GEOLOCATION_PERMISSION,
787 geolocationPermissionRequestCallback);
789 // EWK Notification Callback
790 evas_object_smart_callback_del(
792 EWK_NOTIFICATION_SHOW,
793 notificationShowCallback);
794 evas_object_smart_callback_del(
796 EWK_NOTIFICATION_CANCEL,
797 notificationCancelCallback);
798 evas_object_smart_callback_del(
800 EWK_NOTIFICATION_PERMISSION_REQUEST,
801 notificationPermissionRequestCallback);
803 // EWK Vibration Callback
804 evas_object_smart_callback_del(
806 EWK_VIBRATION_VIBRATE,
807 vibrationVibrateCallback);
808 evas_object_smart_callback_del(
810 EWK_VIBRATION_CANCEL,
811 vibrationCancelCallback);
813 evas_object_smart_callback_del(
815 EWK_CONTEXT_EXCEEDED_QUOATA,
816 databaseUsagePermissionRequestCallback);
817 evas_object_smart_callback_del(
819 EWK_FILESYSTEM_PERMISSION_REQUEST,
820 fileSystemPermissionRequestCallback);
822 // EWK Orientation Callback
823 ewk_view_orientation_lock_callback_set(
828 // ime show/hide callback
829 evas_object_smart_callback_del(
831 EWK_INPUTMETHOD_CHANGED,
833 evas_object_smart_callback_del(
835 EWK_EDITORCLIENT_IME_CLOSED,
838 // custom content/scheme handlers
839 evas_object_smart_callback_del(
841 EWK_PROTOCOLHANDLER_REGISTRATION,
842 protocolHandlerRegistrationCallback);
843 evas_object_smart_callback_del(
845 EWK_PROTOCOLHANDLER_ISREGISTERED,
846 protocolHandlerIsRegisteredCallback);
847 evas_object_smart_callback_del(
849 EWK_PROTOCOLHANDLER_UNREGISTRATION,
850 protocolHandlerUnregistrationCallback);
852 evas_object_smart_callback_del(
854 EWK_CONTENTHANDLER_REGISTRATION,
855 contentHandlerRegistrationCallback);
856 evas_object_smart_callback_del(
858 EWK_CONTENTHANDLER_ISREGISTERED,
859 contentHandlerIsRegisteredCallback);
860 evas_object_smart_callback_del(
862 EWK_CONTENTHANDLER_UNREGISTRATION,
863 contentHandlerUnregistrationCallback);
866 void ViewLogic::createEwkView(Evas* canvas)
868 LogDebug("createEwkVeiw");
870 ADD_PROFILING_POINT("ewk_view_add_with_context", "start");
871 Evas_Object* newEwkView = ewk_view_add_with_context(
874 ADD_PROFILING_POINT("ewk_view_add_with_context", "stop");
877 LogError("WKView creation failed");
882 // even arguments pass the ewkContext, this API should be called
883 // after webkit Evas_Object is created
884 ewk_context_cookies_policy_set(m_ewkContext, EWK_COOKIE_JAR_ACCEPT_ALWAYS);
886 LogInfo("push webview: " << newEwkView);
887 m_ewkViewList.push_back(newEwkView);
888 m_currentEwkView = newEwkView;
891 void ViewLogic::setStartPage()
893 /* Start URI (as other uris) is now localized
894 * on WebProcess side */
895 m_currentUri = m_startUrl;
898 void ViewLogic::prepareEwkView(Evas_Object *wkView)
900 LogDebug("prepareEwkView called");
902 Ewk_Settings* settings = ewk_view_settings_get(wkView);
905 auto userAgentString =
906 ViewModule::UserAgentSupport::getUserAgentFromVconf();
907 if (!userAgentString.empty()) {
908 LogDebug("Setting custom user agent as: " << userAgentString);
909 ewk_view_user_agent_set(wkView, userAgentString.c_str());
912 // set custom header : language
913 using namespace ViewModule::CustomHeaderSupport;
914 std::string customHeaderString = getValueByField(ACCEPT_LANGUAGE);
915 if (!customHeaderString.empty()) {
916 LogDebug("custom field=[" << ACCEPT_LANGUAGE << "]");
917 LogDebug("custom value=[" << customHeaderString << "]");
918 ewk_view_custom_header_add(wkView,
919 ACCEPT_LANGUAGE.c_str(),
920 customHeaderString.c_str());
923 // webkit NPAPI plugins is always on in wrt
924 ewk_settings_plugins_enabled_set(settings, EINA_TRUE);
926 // The followings are not implemeted yet by webkit2
927 // ewk_view_setting_accelerated_compositing_enable_set(EINA_TRUE);
928 // ewk_view_mode_set();
929 // ewk_view_setting_enable_specified_plugin_set(EINA_TRUE, FLASH_MIME_TYPE);
930 // ewk_view_setting_html5video_external_player_enable_set(EINA_FALSE);
931 // ewk_view_show_ime_on_autofocus_set(EINA_TRUE);
932 // elm_webview_show_magnifier_set(EINA_FALSE);
933 ewk_settings_javascript_enabled_set(settings, EINA_TRUE);
934 ewk_settings_loads_images_automatically_set(settings, EINA_TRUE);
935 ewk_settings_auto_fitting_set(settings, EINA_TRUE);
937 // disable zoom option when user click the input field
938 // this option is useful with the normal website
939 // for the make user friendly, disable auto zoom in the webapp
940 // The followings are not implemeted yet by webkit2
941 // elm_webview_input_field_zoom_set(EINA_FALSE);
943 // set cookie database path
944 // The followings are not implemeted yet by webkit2
945 // ewk_cookies_file_set(dao.getCookieDatabasePath().c_str()));
947 // set visibility to WebCore. This value will be used for html5.
948 // also, this value will be changed in the suspend, resume
949 // or create window, close window.
950 ewk_view_page_visibility_state_set(wkView,
951 EWK_PAGE_VISIBILITY_STATE_VISIBLE,
955 void ViewLogic::removeEwkView(Evas_Object *wkView)
957 LogInfo("removeEwkView called");
959 Assert(0 != m_ewkViewList.size());
961 // unregister webview callbacks
962 ewkClientDeinit(wkView);
964 // suspend NPAPI plugin - Not implemented by Webkit2
965 // ewk_view_pause_or_resume_plugins();
966 evas_object_del(wkView);
967 m_ewkViewList.remove(wkView);
970 void ViewLogic::resumeEwkView(Evas_Object *wkView)
972 LogInfo("resumeEwkView called");
975 // register webview callback
976 ewkClientInit(wkView);
979 resumeWebkit(wkView);
984 void ViewLogic::suspendEwkView(Evas_Object *wkView)
986 LogInfo("suspendEwkView called");
990 suspendWebkit(wkView);
992 // unregister webview callbacks
993 ewkClientDeinit(wkView);
998 void ViewLogic::resumeWebkit(Evas_Object *wkView)
1000 LogDebug("resumeWebkit");
1003 // resume NPAPI plugin
1004 // The followings are not implemeted yet by webkit2
1005 // ewk_view_pause_or_resume_plugins(false);
1006 // ewk_view_pause_or_resume_video_audio(false);
1007 // ewk_view_javascript_resume();
1008 // ewk_view_enable_render();
1009 // ewk_view_reduce_plugins_frame_rate(false);
1010 ewk_view_resume(wkView);
1011 ewk_view_visibility_set(wkView, EINA_TRUE);
1012 ewk_view_page_visibility_state_set(wkView,
1013 EWK_PAGE_VISIBILITY_STATE_VISIBLE,
1018 void ViewLogic::suspendWebkit(Evas_Object *wkView)
1020 LogDebug("suspendWebkit");
1023 // suspend the followings
1024 // The followings are not implemeted yet by webkit2
1025 // ewk_view_pause_or_resume_plugins(true);
1026 // ewk_view_pause_or_resume_video_audio(true);
1028 // send visibility event to webpage
1029 ewk_view_page_visibility_state_set(wkView,
1030 EWK_PAGE_VISIBILITY_STATE_HIDDEN,
1032 ewk_view_suspend(wkView);
1033 ewk_view_visibility_set(wkView, EINA_FALSE);
1037 void ViewLogic::contextMessageFromInjectedBundleCallback(
1043 LogDebug("contextMessageFromInjectedBundleCallback called");
1045 ViewLogic* This = static_cast<ViewLogic*>(clientInfo);
1046 // didRecieveMessageFromInjectedBundleCallback - returnData is null
1047 // didReceiveSynchronousMessageCallback - returnData isn't null
1048 // WKContextInjectedBundleClient bundleClient = {
1049 // kWKContextInjectedBundleClientCurrentVersion,
1050 // static_cast<void*>(this),
1051 // &didRecieveMessageFromInjectedBundleCallback,
1052 // &didReceiveSynchronousMessageCallback
1054 if (NULL == returnData) {
1055 This->didRecieveMessageFromInjectedBundle(name, body);
1057 This->didReceiveSynchronousMessage(name, body, returnData);
1061 void ViewLogic::didStartDownloadCallback(
1062 const char* downloadUrl,
1065 LogDebug("didStartDownloadCallback called");
1067 ViewLogic* This = static_cast<ViewLogic*>(data);
1068 Assert(downloadUrl);
1069 LogDebug("download url = " << downloadUrl);
1070 This->m_appsSupport->downloadRequest(
1076 void ViewLogic::loadStartedCallback(
1079 void* /*eventInfo*/)
1081 LogDebug("loadStartedCallback called");
1083 ViewLogic* This = static_cast<ViewLogic*>(data);
1084 evas_object_focus_set(This->m_currentEwkView, EINA_TRUE);
1086 // call loadFinish callback to wrt-client
1087 if (!This->m_cbs->loadStart.empty()) {
1088 This->m_cbs->loadStart(obj);
1093 void ViewLogic::loadFinishedCallback(
1096 void* /*eventInfo*/)
1098 LogDebug("loadFinishedCallback called");
1100 ViewLogic* This = static_cast<ViewLogic*>(data);
1103 const char* url = ewk_view_uri_get(This->m_currentEwkView);
1104 if (NULL == url || strlen(url) == 0) {
1105 LogError("url is empty");
1107 DPL::OptionalString jsOptionalString =
1108 ViewModule::PasswordSupport::jsForAutoFillData(url);
1109 if (jsOptionalString.IsNull()) {
1110 LogError("Fail to get JS String");
1112 std::string jsStr = DPL::ToUTF8String(*jsOptionalString).c_str();
1114 if(EINA_FALSE == ewk_view_script_execute(
1115 This->m_currentEwkView,
1117 didRunJavaScriptCallback,
1120 LogError("JS for auto fill data failed.");
1125 // call loadFinish callback to wrt-client
1126 if (!This->m_cbs->loadFinish.empty()) {
1127 This->m_cbs->loadFinish(obj);
1130 // set only encoded bundle
1131 double scale = elm_config_scale_get();
1132 PluginModuleSupport::setCustomProperties(
1135 ApplicationDataSingleton::Instance().getEncodedBundle());
1136 // check if 'appsevice' event is registed at the current frames.
1137 // If so, dispatch the event to frames.
1138 PluginModuleSupport::dispatchJavaScriptEvent(
1140 WrtPlugins::W3C::ServiceCustomEvent,
1144 void ViewLogic::titleChangedCallback(
1146 Evas_Object* /*obj*/,
1149 LogDebug("titleChangedCallback called");
1151 ViewLogic* This = static_cast<ViewLogic*>(data);
1153 const char* title = static_cast<char*>(eventInfo);
1155 if (0 == strlen(title)) {
1156 LogDebug("title data is empty");
1159 LogDebug("Title = [" << title << "]");
1160 This->m_schemeSupport->HandleTizenScheme(title,
1162 This->m_currentEwkView);
1165 void ViewLogic::loadProgressCallback(
1167 Evas_Object* /*obj*/,
1170 double* progress = static_cast<double*>(eventInfo);
1171 LogDebug("didChangeProgressCallback progress = " << *progress);
1174 void ViewLogic::loadProgressFinishedCallback(
1176 Evas_Object* /*obj*/,
1177 void* /*eventInfo*/)
1179 LogDebug("didFinishProgressCallback");
1181 ViewLogic const * const view = static_cast<ViewLogic const * const>(data);
1182 if (!view->m_cbs->progressFinish.empty()) {
1183 view->m_cbs->progressFinish();
1187 void ViewLogic::processCrashedCallback(
1189 Evas_Object* /*obj*/,
1192 LogInfo("processCrashedCallback");
1194 ViewLogic const * const view =
1195 static_cast<ViewLogic const * const>(data);
1196 if (!view->m_cbs->webCrash.empty()) {
1197 view->m_cbs->webCrash();
1199 // This flag will be prevented exit() call in the Webkit side
1200 if (NULL != eventInfo) {
1201 *(static_cast<Eina_Bool*>(eventInfo)) = EINA_TRUE;
1205 void ViewLogic::createWindowCallback(
1210 LogDebug("createWindowCallback");
1212 ViewLogic* This = static_cast<ViewLogic*>(data);
1214 // First, current webview should be handled by user callback
1215 if (!This->m_cbs->bufferUnset.empty()) {
1216 This->m_cbs->bufferUnset(obj);
1219 // this can be set by executable for specific purpose
1220 Evas* canvas = NULL;
1221 if (!This->m_cbs->windowCreateBefore.empty()) {
1222 // 'obj' is parent webview object
1223 This->m_cbs->windowCreateBefore(&canvas, obj);
1226 canvas = evas_object_evas_get(This->m_window);
1229 // create new ewkview
1230 This->createEwkView(canvas);
1231 Evas_Object* newEwkView = This->m_currentEwkView;
1233 // initialize new ewkview
1234 This->setStartPage();
1235 This->ewkClientInit(newEwkView);
1236 This->prepareEwkView(newEwkView);
1238 // Specific jobs of child, parent webview are handled by each executable
1239 if (!This->m_cbs->windowCreateAfter.empty()) {
1240 // 'obj' is parent webview, 'newEwkView' is child webview
1241 This->m_cbs->windowCreateAfter(obj, newEwkView);
1244 // Lastly, new webview should be handled by user callback
1245 if (!This->m_cbs->bufferSet.empty()) {
1246 This->m_cbs->bufferSet(newEwkView);
1248 *(static_cast<Evas_Object **>(eventInfo)) = newEwkView;
1251 void ViewLogic::closeWindowCallback(
1254 void* /*eventInfo*/)
1256 LogDebug("closeWindowCallback");
1257 ViewLogic* This = static_cast<ViewLogic*>(data);
1258 This->m_closedEwkView = obj;
1259 ecore_idler_add(windowCloseIdlerCallback, This);
1262 void ViewLogic::policyNavigationDecideCallback(
1264 Evas_Object* /*obj*/,
1267 LogDebug("policyNavigationDecideCallback called");
1269 ViewLogic* This = static_cast<ViewLogic*>(data);
1271 Ewk_Policy_Decision* policyDecision =
1272 static_cast<Ewk_Policy_Decision*>(eventInfo);
1274 if (This->m_schemeSupport->filterURIByScheme(policyDecision,
1278 This->m_currentEwkView))
1281 ewk_policy_decision_use(policyDecision);
1283 // check whether this is new empty window
1284 const char* activeUrl = ewk_view_uri_get(This->m_currentEwkView);
1285 if(!activeUrl || 0 == strlen(activeUrl)) {
1287 * The view is empty and scheme has been handled externally. When
1288 * user gets back from the external application he'd see blank page
1289 * and won't be able to navigate back. This happens when window.open
1290 * is used to handle schemes like sms/mms/mailto (for example in
1291 * WAC web standards tests: WS-15XX).
1293 * To solve the problem, the empty view is removed from the stack
1294 * and the previous one is shown. This is not an elegant solution
1295 * but we don't have a better one.
1297 LogInfo("Scheme has been handled externally. Removing empty view.");
1298 if (ewk_view_back_possible(This->m_currentEwkView)) {
1299 // go back to previous WKPage
1300 ewk_view_back(This->m_currentEwkView);
1302 // stop current WKPage
1303 ewk_view_stop(This->m_currentEwkView);
1304 ecore_idler_add(windowCloseIdlerCallback, This);
1309 ewk_policy_decision_ignore(policyDecision);
1313 void ViewLogic::policyNewWindowDecideCallback(
1315 Evas_Object* /*obj*/,
1318 LogDebug("policyNewWindowDecideCallback called");
1320 ViewLogic* This = static_cast<ViewLogic*>(data);
1322 Ewk_Policy_Decision* policyDecision =
1323 static_cast<Ewk_Policy_Decision*>(eventInfo);
1325 if (This->m_schemeSupport->filterURIByScheme(policyDecision,
1329 This->m_currentEwkView))
1331 ewk_policy_decision_use(policyDecision);
1334 ewk_policy_decision_ignore(policyDecision);
1338 void ViewLogic::pageResponseDecideCallback(
1340 Evas_Object* /*obj*/,
1343 LogDebug("pageResponseDecideCallback called");
1345 ViewLogic* This = static_cast<ViewLogic*>(data);
1347 Ewk_Policy_Decision* policyDecision =
1348 static_cast<Ewk_Policy_Decision*>(eventInfo);
1349 Ewk_Policy_Decision_Type policyDecisionType =
1350 ewk_policy_decision_type_get(policyDecision);
1352 if (policyDecisionType == EWK_POLICY_DECISION_USE) {
1354 ewk_policy_decision_use(policyDecision);
1355 } else if (policyDecisionType == EWK_POLICY_DECISION_DOWNLOAD) {
1356 LogDebug("download");
1357 ewk_policy_decision_suspend(policyDecision);
1359 // get uri information
1360 const char* url = ewk_policy_decision_url_get(policyDecision);
1361 if (NULL == url || strlen(url) == 0) {
1362 LogDebug("url data is empty");
1363 ewk_policy_decision_use(policyDecision);
1366 LogDebug("url = [" << url << "]");
1368 // get content information
1369 const char* content =
1370 ewk_policy_decision_response_mime_get(policyDecision);
1371 LogDebug("content type = [" << content << "]");
1373 // get cookie information
1374 const char* cookie = ewk_policy_decision_cookie_get(policyDecision);
1375 LogDebug("cookie = [" << cookie << "]");
1377 LogDebug("Content not supported, will be opened in external app");
1378 This->m_appsSupport->downloadRequest(
1382 ewk_policy_decision_ignore(policyDecision);
1383 } else if (policyDecisionType == EWK_POLICY_DECISION_IGNORE) {
1385 ewk_policy_decision_ignore(policyDecision);
1387 LogDebug("Type isn't handled");
1388 ewk_policy_decision_ignore(policyDecision);
1392 void ViewLogic::contextmenuCustomizeCallback(
1394 Evas_Object* /*obj*/,
1397 LogDebug("contextmenuCustomizeCallback called");
1400 ViewLogic* This = static_cast<ViewLogic*>(const_cast<void*>(data));
1401 Ewk_Context_Menu* menu = static_cast<Ewk_Context_Menu*>(eventInfo);
1402 if ((This->m_model->Type.Get().appType == WrtDB::APP_TYPE_TIZENWEBAPP) &&
1403 (This->m_model->SettingList.Get().getContextMenu()
1404 == ContextMenu_Disable))
1406 LogDebug("ContextMenu Disable!!");
1407 for (unsigned int idx = 0; idx < ewk_context_menu_item_count(menu);) {
1408 Ewk_Context_Menu_Item* item = ewk_context_menu_nth_item_get(menu, idx);
1410 ewk_context_menu_item_remove(menu, item);
1413 LogDebug("ContextMenu Enable!!");
1414 for (unsigned int idx = 0; idx < ewk_context_menu_item_count(menu);) {
1415 Ewk_Context_Menu_Item* item = ewk_context_menu_nth_item_get(menu, idx);
1417 Ewk_Context_Menu_Item_Tag tag = ewk_context_menu_item_tag_get(item);
1420 case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_IMAGE_IN_NEW_WINDOW:
1421 ewk_context_menu_item_remove(menu, item);
1424 case EWK_CONTEXT_MENU_ITEM_TAG_SEARCH_WEB:
1425 ewk_context_menu_item_remove(menu, item);
1436 void ViewLogic::formSubmitCallback(
1438 Evas_Object* /*obj*/,
1441 LogDebug("formSubmitCallback called");
1443 Ewk_Form_Data* formData = static_cast<Ewk_Form_Data*>(eventInfo);
1445 const char* uri = ewk_form_data_url_get(formData);
1447 LogError("URL is empty");
1451 Eina_Hash* userData = ewk_form_data_values_get(formData);
1452 ViewModule::PasswordSupport::submitClicked(uri, userData);
1455 void ViewLogic::geolocationPermissionRequestCallback(
1457 Evas_Object* /*obj*/,
1461 ViewLogic* This = static_cast<ViewLogic*>(data);
1463 ViewModule::GeolocationSupport::Webkit2::geolocationPermissionRequest(
1465 This->m_securityOriginSupport->getSecurityOriginDAO(),
1469 void ViewLogic::notificationShowCallback(
1471 Evas_Object* /*obj*/,
1474 LogDebug("notificationShowCallback called");
1476 ViewLogic* This = static_cast<ViewLogic*>(data);
1479 Ewk_Notification* noti = static_cast<Ewk_Notification*>(eventInfo);
1481 using namespace ViewModule::WebNotification;
1483 WebNotificationDataPtr notiData(
1484 new WebNotificationData(
1486 ewk_notification_id_get(noti)));
1488 DPL::OptionalString string =
1489 DPL::FromUTF8String(ewk_notification_icon_url_get(noti));
1490 if (!string.IsNull()) {
1491 notiData->m_iconURL = DPL::ToUTF8String(*string);
1493 string = DPL::FromUTF8String(ewk_notification_title_get(noti));
1494 if (!string.IsNull()) {
1495 notiData->m_title = DPL::ToUTF8String(*string);
1497 string = DPL::FromUTF8String(ewk_notification_body_get(noti));
1498 if (!string.IsNull()) {
1499 notiData->m_body = DPL::ToUTF8String(*string);
1502 LogInfo("notification id : " << notiData->m_id);
1503 LogInfo("notification iconURL : " << notiData->m_iconURL);
1504 LogInfo("notification title : " << notiData->m_title);
1505 LogInfo("notification body : " << notiData->m_body);
1507 showWebNotification(notiData);
1508 ewk_notification_showed(This->m_ewkContext, ewk_notification_id_get(noti));
1511 void ViewLogic::notificationCancelCallback(
1513 Evas_Object* /*obj*/,
1514 void* /*eventInfo*/)
1516 LogDebug("notificationCancelCallback called");
1519 void ViewLogic::notificationPermissionRequestCallback(
1521 Evas_Object* /*obj*/,
1524 LogDebug("notificationPermissionRequestCallback called");
1526 ViewLogic* This = static_cast<ViewLogic*>(data);
1529 Ewk_Notification_Permission_Request* request =
1530 static_cast<Ewk_Notification_Permission_Request*>(eventInfo);
1531 ewk_notification_permission_request_response(
1538 void ViewLogic::vibrationVibrateCallback(
1540 Evas_Object* /*obj*/,
1543 LogDebug("vibrationVibrateCallback called");
1545 ViewLogic* This = static_cast<ViewLogic*>(data);
1548 const long vibrationTime = *(static_cast<const long*>(eventInfo));
1551 // This->m_vibrationSupport->startVibration(vibrationTime);
1556 void ViewLogic::vibrationCancelCallback(
1558 Evas_Object* /*obj*/,
1559 void* /*eventInfo*/)
1561 LogDebug("vibrationCancelCallback called");
1563 ViewLogic* This = static_cast<ViewLogic*>(data);
1566 // This->m_vibrationSupport->stopVibration();
1571 // EWK Orientation Callback
1572 Eina_Bool ViewLogic::orientationLockCallback(
1574 Eina_Bool /*needLock*/,
1578 LogDebug("orientationLockCallback called");
1580 ViewLogic* This = static_cast<ViewLogic*>(data);
1582 if (orientation & EWK_SCREEN_ORIENTATION_PORTRAIT_PRIMARY) {
1583 LogDebug("orientation is portrait-primary");
1584 elm_win_rotation_with_resize_set(This->m_window, 0);
1585 ewk_view_orientation_send(obj, 0);
1586 } else if(orientation & EWK_SCREEN_ORIENTATION_LANDSCAPE_PRIMARY) {
1587 LogDebug("orientation is landscape-primary");
1588 elm_win_rotation_with_resize_set(This->m_window, 270);
1589 ewk_view_orientation_send(obj, 90);
1590 } else if(orientation & EWK_SCREEN_ORIENTATION_PORTRAIT_SECONDARY) {
1591 LogDebug("orientation is portrait-secondary");
1592 elm_win_rotation_with_resize_set(This->m_window, 180);
1593 ewk_view_orientation_send(obj, 180);
1594 } else if(orientation & EWK_SCREEN_ORIENTATION_LANDSCAPE_SECONDARY) {
1595 LogDebug("orientation is landscape-secondary");
1596 elm_win_rotation_with_resize_set(This->m_window, 90);
1597 ewk_view_orientation_send(obj, -90);
1599 LogDebug("Wrong orientation is set");
1606 // Fullscreen API callbacks
1607 void ViewLogic::enterFullscreenCallback(
1609 Evas_Object* /*obj*/,
1610 void* /*eventInfo*/)
1612 LogInfo("enterFullscreenCallback called");
1614 ViewLogic* This = static_cast<ViewLogic*>(data);
1615 if (!This->m_cbs->toggleFullscreen.empty()) {
1616 This->m_cbs->toggleFullscreen(true);
1619 void ViewLogic::exitFullscreenCallback(
1621 Evas_Object* /*obj*/,
1622 void* /*eventInfo*/)
1624 LogInfo("exitFullscreenCallback called");
1626 ViewLogic* This = static_cast<ViewLogic*>(data);
1627 if (!This->m_cbs->toggleFullscreen.empty()) {
1628 This->m_cbs->toggleFullscreen(false);
1632 void ViewLogic::imeOpenCallback(
1634 Evas_Object* /*obj*/,
1640 ViewLogic* This = static_cast<ViewLogic*>(data);
1641 Eina_Rectangle *rect = static_cast<Eina_Rectangle *>(eventInfo);
1643 using namespace WrtPlugins::W3C;
1644 SoftKeyboardChangeArgs args;
1645 args.state = IME_STATE_ON;
1646 args.width = rect->w;
1647 args.height = rect->h;
1648 This->fireJavascriptEvent(
1649 static_cast<int>(SoftKeyboardChangeCustomEvent),
1653 void ViewLogic::imeCloseCallback(
1655 Evas_Object* /*obj*/,
1656 void* /*eventInfo*/)
1660 ViewLogic* This = static_cast<ViewLogic*>(data);
1662 using namespace WrtPlugins::W3C;
1663 SoftKeyboardChangeArgs args;
1664 args.state = IME_STATE_OFF;
1666 This->fireJavascriptEvent(
1667 static_cast<int>(SoftKeyboardChangeCustomEvent),
1672 CustomHandlerDB::CustomHandlerPtr getCustomHandlerFromData(void* data)
1675 Ewk_Custom_Handlers_Data* handler =
1676 static_cast<Ewk_Custom_Handlers_Data*>(data);
1677 CustomHandlerDB::CustomHandlerPtr customHandler(new CustomHandlerDB::CustomHandler());
1678 const char* base_url = ewk_custom_handlers_data_base_url_get(handler);
1680 LogDebug("base url: " << base_url);
1681 customHandler->base_url = DPL::FromASCIIString(string(base_url));
1683 const char* url = ewk_custom_handlers_data_url_get(handler);
1685 LogDebug("url: " << url);
1686 customHandler->url = DPL::FromASCIIString(string(url));
1688 const char* target = ewk_custom_handlers_data_target_get(handler);
1690 LogDebug("target: " << target);
1691 customHandler->target = DPL::FromASCIIString(string(target));
1693 const char* title = ewk_custom_handlers_data_title_get(handler);
1695 LogDebug("title: " << title);
1696 customHandler->title = DPL::FromASCIIString(string(title));
1698 return customHandler;
1701 void ViewLogic::attachToCustomHandlersDao()
1703 if (!m_attachedToCustomHandlerDao) {
1704 CustomHandlerDB::Interface::attachDatabaseRW();
1708 void ViewLogic::detachFromCustomHandlersDao()
1710 if (m_attachedToCustomHandlerDao) {
1711 CustomHandlerDB::Interface::detachDatabase();
1715 void ViewLogic::protocolHandlerRegistrationCallback(void* data,
1721 CustomHandlerDB::CustomHandlerPtr customHandler =
1722 getCustomHandlerFromData(eventInfo);
1723 //TODO: whitelist/blacklist
1724 ViewLogic* This = static_cast<ViewLogic*>(data);
1725 LogDebug("Creating handlers dao");
1726 This->attachToCustomHandlersDao();
1727 CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1728 CustomHandlerDB::CustomHandlerPtr handler =
1729 handlersDao.getProtocolHandler(customHandler->target, customHandler->url);
1731 LogDebug("Protocol already registered - nothing to do");
1733 LogDebug("Protocol handler not found");
1734 if (Wrt::Popup::PopupInvoker().askYesNo(PROTOCOL_HANDLER_ASK_TITLE, PROTOCOL_HANDLER_ASK_MSG)) {
1735 LogDebug("User allowed");
1736 customHandler->user_allowed = true;
1738 LogDebug("User didn't allow");
1739 customHandler->user_allowed = false;
1741 handlersDao.registerProtocolHandler(*(customHandler.get()));
1742 LogDebug("Protocal saved");
1746 void ViewLogic::protocolHandlerIsRegisteredCallback(void* data,
1751 getCustomHandlerFromData(eventInfo);
1752 // TODO to be continued...
1755 void ViewLogic::protocolHandlerUnregistrationCallback(void* data,
1760 getCustomHandlerFromData(eventInfo);
1761 // TODO to be continued...
1764 void ViewLogic::contentHandlerRegistrationCallback(void* data,
1770 CustomHandlerDB::CustomHandlerPtr customHandler =
1771 getCustomHandlerFromData(eventInfo);
1772 //TODO: whitelist/blacklist
1773 ViewLogic* This = static_cast<ViewLogic*>(data);
1774 LogDebug("Creating handlers dao");
1775 This->attachToCustomHandlersDao();
1776 CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1777 CustomHandlerDB::CustomHandlerPtr handler =
1778 handlersDao.getContentHandler(customHandler->target, customHandler->url);
1780 LogDebug("Content already registered - nothing to do");
1782 LogDebug("Content handler not found");
1783 if (Wrt::Popup::PopupInvoker().askYesNo(CONTENT_HANDLER_ASK_TITLE, CONTENT_HANDLER_ASK_MSG)) {
1784 LogDebug("User allowed");
1785 customHandler->user_allowed = true;
1787 LogDebug("User didn't allow");
1788 customHandler->user_allowed = false;
1790 handlersDao.registerContentHandler(*(customHandler.get()));
1791 LogDebug("Content saved");
1795 void ViewLogic::contentHandlerIsRegisteredCallback(void* data,
1800 getCustomHandlerFromData(eventInfo);
1801 // TODO to be continued...
1804 void ViewLogic::contentHandlerUnregistrationCallback(void* data,
1809 getCustomHandlerFromData(eventInfo);
1810 // TODO to be continued...
1813 void ViewLogic::didRunJavaScriptCallback(
1814 Evas_Object* /*obj*/,
1818 LogInfo("didRunJavaScriptCallback called");
1819 LogInfo("result = " << result);
1822 Eina_Bool ViewLogic::windowCloseIdlerCallback(void* data)
1824 LogDebug("closeIdlerCallback");
1825 ViewLogic* This = static_cast<ViewLogic*>(data);
1826 This->windowClose();
1827 return ECORE_CALLBACK_CANCEL;
1830 int ViewLogic::appcoreLowMemoryCallback(void *data)
1832 LogInfo("appcoreLowMemoryCallback");
1834 ViewLogic* This = static_cast<ViewLogic*>(data);
1836 if (NULL == This->m_ewkContext) {
1837 LogInfo("ewk isn't initialize at this moment");
1839 ewk_context_cache_clear(This->m_ewkContext);
1840 ewk_context_notify_low_memory(This->m_ewkContext);
1846 void ViewLogic::databaseUsagePermissionRequestCallback(
1848 Evas_Object* /*obj*/,
1851 LogDebug("databaseUsagePermissionRequestCallback called");
1853 ViewLogic* This = static_cast<ViewLogic*>(data);
1856 ViewModule::WebStorageSupport::webStorageCreatePermissionRequest(
1858 This->m_securityOriginSupport->getSecurityOriginDAO(),
1863 void ViewLogic::fileSystemPermissionRequestCallback(
1865 Evas_Object* /*obj*/,
1868 LogDebug("fileSystemPermissionRequestCallback called");
1870 ViewLogic* This = static_cast<ViewLogic*>(data);
1872 ViewModule::FileSystemSupport::fileSystemPermissionRequest(
1874 This->m_securityOriginSupport->getSecurityOriginDAO(),
1878 void ViewLogic::didRecieveMessageFromInjectedBundle(
1880 const char* /*body*/)
1882 LogDebug("did recive message " << name);
1885 void ViewLogic::didReceiveSynchronousMessage(
1890 LogDebug("didReceiveSynchronousMessage called");
1895 LogDebug("body is empty");
1899 if (!strcmp(name, uriBlockedMessageName)) {
1900 LogDebug("received : " << uriBlockedMessageName);
1901 // Currently WebProcess informs obly about blocked
1902 // URI - URI localization and security chekcs are
1903 // done by WebProcess itself (see: wrt-wk2-bundle.cpp
1904 // and bundle_uri_handling.cpp)
1905 rememberBlockedURI(DPL::FromUTF8String(body));
1907 } else if (!strcmp(name, uriChangedMessageName)) {
1908 LogDebug("received : " << uriChangedMessageName);
1909 std::string ret = requestUriChanged(DPL::FromUTF8String(body));
1910 *returnData = strdup(ret.c_str());
1914 void ViewLogic::rememberBlockedURI(const DPL::String& inputURI)
1916 m_blockedUri = DPL::ToUTF8String(inputURI);
1917 LogInfo("set blocked uri to open browser later : " << m_blockedUri);
1921 std::string ViewLogic::requestUriChanged(const DPL::String& changedURL)
1923 using namespace ViewModule::SecuritySupport;
1925 std::string url = DPL::ToUTF8String(changedURL);
1926 LogInfo("URL = [" << url << "]");
1929 // If url is same to URICHANGE_BLOCKED_URL,
1930 // this url has been already blocked by willsend.
1931 // So current page should be moved to previous page
1932 if (url == URICHANGE_BLOCKED_URL)
1934 if (m_model->Type.Get().appType == WrtDB::APP_TYPE_TIZENWEBAPP)
1936 // block this page and open it in browser
1937 LogDebug("Request was blocked by WARP: " << url.c_str());
1938 if (!m_blockedUri.empty()) {
1939 LogDebug("open browser : " << m_blockedUri);
1940 bundle* bundleData = bundle_create();
1941 appsvc_set_operation(bundleData, APPSVC_OPERATION_VIEW);
1942 appsvc_set_uri(bundleData, m_blockedUri.c_str());
1943 CONTROLLER_POST_EVENT(
1944 ApplicationLauncher,
1945 ApplicationLauncherEvents::LaunchApplicationByAppService(
1949 m_blockedUri = std::string();
1952 if (ewk_view_back_possible(m_currentEwkView)) {
1953 // go back to previous page
1954 ewk_view_back(m_currentEwkView);
1956 // stop current page
1957 ewk_view_stop(m_currentEwkView);
1958 ecore_idler_add(windowCloseIdlerCallback, this);
1961 // This is used in case of returning previous page
1963 return URICHANGE_PLUGIN_NO_CHANGE;
1968 // Check if this url with 'http' or 'https' is included in whitelist,
1969 // which has lists of accessible external documents and
1970 // used for ONLY Tizen app
1971 std::string matchedScheme;
1972 std::string matchedUri;
1973 pcrecpp::RE(PATTERN_URI_CHANGE).PartialMatch(url.c_str(),
1976 ViewModule::Scheme scheme(matchedScheme);
1977 if (scheme.GetType() == ViewModule::Scheme::HTTP ||
1978 scheme.GetType() == ViewModule::Scheme::HTTPS)
1980 if (m_model->Type.Get().appType == WrtDB::APP_TYPE_TIZENWEBAPP) {
1981 if (!checkWhitelist(url.c_str())) {
1982 LogInfo("This uri is not included in white document list");
1983 return URICHANGE_PLUGIN_STOP_ONLY;
1985 LogInfo("This url is included in WhiteList");
1987 // For WAC app, WRT should block access of device api
1988 // for external documents
1989 return URICHANGE_PLUGIN_STOP_ONLY;
1993 // register javascript object for plugins to be used
1994 LogInfo("Register Plugin Objects");
1995 return URICHANGE_PLUGIN_RESTART;
1998 void ViewLogic::windowClose()
2000 LogDebug("windowClose");
2001 Assert(m_closedEwkView && "no closed webview");
2003 if (1 >= m_ewkViewList.size()) {
2004 if (!m_cbs->webkitExit.empty()) {
2005 m_cbs->webkitExit();
2008 // call user callbacks
2009 if (!m_cbs->bufferUnset.empty()) {
2010 m_cbs->bufferUnset(m_currentEwkView);
2012 if (!m_cbs->windowClose.empty()) {
2013 m_cbs->windowClose(m_closedEwkView);
2015 removeEwkView(m_closedEwkView);
2017 // get latest ewkView
2018 m_currentEwkView = m_ewkViewList.back();
2019 const char* uri = ewk_view_uri_get(m_currentEwkView);
2020 if (NULL == uri || 0 == strlen(uri)) {
2021 m_currentUri.clear();
2027 /* In case we support many pages in parallel
2028 then view is not suspended*/
2029 //resumeEwkView(m_currentEwkView);
2032 if (!m_cbs->bufferSet.empty()) {
2033 m_cbs->bufferSet(m_currentEwkView);