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>
38 #include <common/application_data.h>
39 #include <common/application_launcher.h>
40 #include <common/scheme.h>
42 #include <common/view_logic_apps_support.h>
43 #include <common/view_logic_custom_header_support.h>
44 #include <common/view_logic_password_support.h>
45 #include <common/view_logic_security_support.h>
46 #include <common/view_logic_storage_support.h>
47 #include <common/view_logic_uri_support.h>
48 #include <common/view_logic_user_agent_support.h>
49 #include <common/view_logic_vibration_support.h>
50 #include <common/view_logic_web_notification_support.h>
51 #include <view_logic_scheme_support.h>
52 #include "view_logic_geolocation_support_webkit2.h"
53 #include "bundles/plugin_module_support.h"
56 #include <js_overlay_types.h>
57 #include <i_runnable_widget_object.h>
58 #include <PopupInvoker.h>
59 #include <profiling_util.h>
62 const char * const bundlePath = "/usr/lib/wrt-wk2-bundles/libwrt-wk2-bundle.so";
63 const char * const uriBlockedMessageName = "uri_block_msg";
64 const char * const uriChangedMessageName = "uri_changed_msg";
65 const char * const URICHANGE_PLUGIN_STOP_ONLY = "plugin_stop_only";
66 const char * const URICHANGE_PLUGIN_RESTART = "plugin_restart";
67 const char * const URICHANGE_PLUGIN_NO_CHANGE = "plugin_no_change";
68 const char * const URICHANGE_BLOCKED_URL = "null";
69 const char* PATTERN_URI_CHANGE = "^(([^:/\\?#]+)://[^\\?#]*)";
70 const int MAX_NUM_CONTEXT_MENU_ITEMS = 10;
73 const char * const EWK_LOAD_STARTED = "load,started";
74 const char * const EWK_LOAD_FINISHED = "load,finished";
75 const char * const EWK_TITLE_CHANGED = "title,changed";
76 const char * const EWK_LOAD_PROGRESS = "load,progress";
77 const char * const EWK_LOAD_PROGRESS_FINISHED = "load,progress,finished";
78 const char * const EWK_PROCESS_CRASHED = "process,crashed";
80 const char * const EWK_CREATE_WINDOW = "create,window";
81 const char * const EWK_CLOSE_WINDOW = "close,window";
83 const char * const EWK_POLICY_NAVIGATION_DECIDE = "policy,navigation,decide";
84 const char * const EWK_POLICY_NEWWINDOW_DECIDE = "policy,newwindow,decide";
85 const char * const EWK_POLICY_RESPONSE_DECIDE = "policy,response,decide";
86 // WKPageContextMenuClient
87 const char * const EWK_CONTEXTMENU_CUSTOMIZE = "contextmenu,customize";
89 const char * const EWK_FORM_SUBMIT = "form,submit";
90 // EWK Geolocation Callback
91 const char * const EWK_REQUEST_GEOLOCATION_PERMISSION =
92 "request,geolocation,permission";
93 // EWK Notification Callback
94 const char * const EWK_NOTIFICATION_SHOW = "notification,show";
95 const char * const EWK_NOTIFICATION_CANCEL = "notification,cancel";
96 const char * const EWK_NOTIFICATION_PERMISSION_REQUEST =
97 "notification,permission,request";
98 // EWK Vibration Callback
99 const char * const EWK_VIBRATION_VIBRATE = "vibration,vibrate";
100 const char * const EWK_VIBRATION_CANCEL = "vibration,cancel";
102 const char * const EWK_CONTEXT_EXCEEDED_QUOATA = "database,quota,exceeded";
103 const char * const EWK_CONTEXT_FILE_SYSTEM_PERMISSION = "filesystem,permission,request";
104 const char * const EWK_FULLSCREEN_ENTER = "fullscreen,enterfullscreen";
105 const char * const EWK_FULLSCREEN_EXIT = "fullscreen,exitfullscreen";
107 // DataBase Use Ask Title
108 const char * const DATABASE_USE_ASK_TITLE = "Increase Database Size?";
109 const char * const FILESYSTEM_USE_ASK_TITLE = "Use FileSystem?";
112 ViewLogic::ViewLogic():
117 m_cbs(new WRT::UserDelegates),
118 m_appsSupport(new ViewModule::AppsSupport()),
119 m_vibrationSupport(NULL)
123 ViewLogic::~ViewLogic ()
127 void ViewLogic::createWebView(Ewk_Context* context,
131 initializeEwkContext(context);
132 Assert(NULL != m_ewkContext);
138 void ViewLogic::destroyWebView()
141 finalizeEwkContext();
145 void ViewLogic::initialize()
147 LogDebug("Initializing");
148 ApplicationLauncherSingleton::Instance().Touch();
149 appcore_set_event_callback(
150 APPCORE_EVENT_LOW_MEMORY,
151 &appcoreLowMemoryCallback,
155 void ViewLogic::terminate()
157 LogDebug("terminating view logic");
161 LogError("Widget model not created");
166 void ViewLogic::prepareView(WidgetModel* m, const std::string &startUrl)
168 LogDebug("View prepare");
172 m_startUrl = ViewModule::UriSupport::getUri(m_model, startUrl);
173 Assert(NULL != m_ewkContext);
176 ADD_PROFILING_POINT("initializeSupport", "start");
178 ADD_PROFILING_POINT("initializeSupport", "stop");
180 ewkClientInit(m_currentEwkView);
181 ADD_PROFILING_POINT("prepareEwkView", "start");
182 prepareEwkView(m_currentEwkView);
183 ADD_PROFILING_POINT("prepareEwkView", "stop");
184 initializePluginLoading();
187 void ViewLogic::showWidget()
189 LogDebug("showing widget");
190 Assert(NULL != m_currentEwkView && "ewk_view not created at this point");
191 if (m_currentUri.empty()) {
192 LogError("Localized current URI doesn't exist");
196 LogInfo("m_currentUri: " << m_currentUri);
199 ewk_view_url_set(m_currentEwkView, m_currentUri.c_str());
201 if (!m_cbs->bufferSet.empty()) {
202 m_cbs->bufferSet(m_currentEwkView);
206 void ViewLogic::hideWidget()
208 LogDebug("hiding widget");
209 ViewModule::StorageSupport::deinitializeStorage(m_model);
210 m_appsSupport->deinitialize();
213 // m_vibrationSupport->deinitialize();
215 while (m_ewkViewList.size()) {
216 LogInfo("pop webview: " << m_ewkViewList.back());
217 removeEwkView(m_ewkViewList.back());
219 m_ewkViewList.clear();
222 void ViewLogic::suspendWidget()
224 LogInfo("Pausing widget");
227 if (!m_currentEwkView) {
228 LogWarning("Cannot suspend widget without view");
230 suspendWebkit(m_currentEwkView);
233 // call user callback
234 if (!m_cbs->suspend.empty()) {
235 m_cbs->suspend(true);
239 void ViewLogic::resumeWidget()
241 LogInfo("Resume widget");
244 if (m_currentEwkView) {
245 resumeWebkit(m_currentEwkView);
249 elm_win_activate(m_window);
251 evas_object_focus_set(m_currentEwkView, EINA_TRUE);
253 // call user callback
254 if (!m_cbs->resume.empty()) {
259 void ViewLogic::resetWidget()
261 LogInfo("Resetting Widget");
263 // check if already created webview exists
264 if (!m_ewkViewList.size()) {
265 // create new webview
268 ewkClientInit(m_currentEwkView);
269 prepareEwkView(m_currentEwkView);
271 // check if current url is service url for this tizen service
272 std::string requestedUri =
273 ViewModule::UriSupport::getUri(m_model, m_startUrl);
274 DPL::OptionalString servicedUri = ViewModule::UriSupport::localizeURI(
275 DPL::FromUTF8String(requestedUri.c_str()),
278 const char* currentUri = ewk_view_uri_get(m_currentEwkView);
279 if (!currentUri && 0 == strlen(currentUri)) {
280 LogError("Fail to get uri from ewk_view_uri_get");
283 if (DPL::ToUTF8String(*servicedUri) == currentUri) {
284 // set only encoded bundle
285 double scale = elm_config_scale_get();
286 PluginModuleSupport::setCustomProperties(
289 ApplicationDataSingleton::Instance().getEncodedBundle());
290 // dispatch 'appservice' js event
291 PluginModuleSupport::dispatchJavaScriptEvent(
293 WrtPlugins::W3C::ServiceCustomEvent,
295 ewk_view_reload(m_currentEwkView);
297 m_currentUri = DPL::ToUTF8String(*servicedUri);
298 // inform wrt information for plugin loading to web process
299 PluginModuleSupport::start(
301 m_model->Handle.Get(),
302 elm_config_scale_get(),
303 ApplicationDataSingleton::Instance().getEncodedBundle(),
305 m_model->SettingList.Get().isEncrypted());
307 ewk_view_url_set(m_currentEwkView, m_currentUri.c_str());
311 resumeWebkit(m_currentEwkView);
313 // call user callback
314 if (!m_cbs->reset.empty()) {
317 if (!m_cbs->bufferSet.empty()) {
318 m_cbs->bufferSet(m_currentEwkView);
322 void ViewLogic::backward()
324 if (ewk_view_back_possible(m_currentEwkView)) {
325 ewk_view_back(m_currentEwkView);
327 if (1 >= m_ewkViewList.size()) {
328 // If there is no previous page, widget move to backgroud.
329 LogInfo("Widget move to backgroud");
330 elm_win_lower(m_window);
332 // Back to previous webview
333 LogInfo("Widget move to previous webview");
334 ecore_idler_add(windowCloseIdlerCallback, this);
339 void ViewLogic::reload()
341 ewk_view_reload(m_currentEwkView);
344 void ViewLogic::forward()
346 if (ewk_view_forward_possible(m_currentEwkView)) {
347 ewk_view_forward(m_currentEwkView);
351 void ViewLogic::reloadStartPage()
353 LogInfo("Reload Start Page");
355 if (m_ewkViewList.size() == 0) {
356 // create new webview
358 ewkClientInit(m_currentEwkView);
360 // close opened windows
361 while (m_ewkViewList.size() > 1) {
362 if (!m_cbs->bufferUnset.empty()) {
363 m_cbs->bufferUnset(m_currentEwkView);
365 removeEwkView(m_currentEwkView);
366 m_currentEwkView = m_ewkViewList.back();
368 LogInfo("Close ewkViews done : m_ewkViewList.size() = "
369 << m_ewkViewList.size());
373 prepareEwkView(m_currentEwkView);
374 initializePluginLoading();
377 ewk_view_url_set(m_currentEwkView, m_currentUri.c_str());
380 if (!m_cbs->bufferSet.empty()) {
381 m_cbs->bufferSet(m_currentEwkView);
383 LogInfo("Reloading Start Page is done!");
386 Evas_Object* ViewLogic::getCurrentWebview()
388 LogInfo("get current webview");
389 return m_currentEwkView;
392 void ViewLogic::fireJavascriptEvent(int event, void* data)
394 PluginModuleSupport::dispatchJavaScriptEvent(
396 static_cast<WrtPlugins::W3C::CustomEventType>(event),
400 void ViewLogic::setUserCallbacks(const WRT::UserDelegatesPtr& cbs)
405 void ViewLogic::initializeEwkContext(Ewk_Context* newEwkContext)
407 LogInfo("initializeEwkContext called");
408 Assert(newEwkContext && "Ewk_Context provided can not be null");
409 // bundle callback setting
410 ewk_context_message_from_injected_bundle_callback_set(
412 contextMessageFromInjectedBundleCallback,
413 static_cast<void*>(this));
415 // proxy server setting
416 char *proxyAddress = vconf_get_str(VCONFKEY_NETWORK_PROXY);
417 if ((!proxyAddress) || (strlen(proxyAddress) == 0)
418 || (strstr(proxyAddress, "0.0.0.0")))
420 LogInfo("proxy address is empty");
421 ewk_context_proxy_uri_set(newEwkContext, NULL);
423 LogInfo("proxy address [" << proxyAddress << "]");
424 ewk_context_proxy_uri_set(newEwkContext, proxyAddress);
433 const char *theme = elm_theme_get(NULL);
436 LogInfo("theme is " << m_theme);
439 // Ewk download callback (WKContextDownloadClient)
440 ewk_context_did_start_download_callback_set(
442 didStartDownloadCallback,
445 // set to member value
446 m_ewkContext = newEwkContext;
449 void ViewLogic::finalizeEwkContext()
451 LogInfo("finalizeEwkContext called");
452 ewk_context_message_from_injected_bundle_callback_set(
456 // ewk_context_delete(m_ewkContext);
460 void ViewLogic::initializeSupport()
462 // set local stroage database path
463 WrtDB::WidgetDAOReadOnly dao(m_model->Handle.Get());
464 ewk_context_web_storage_path_set(m_ewkContext,
465 dao.getPrivateLocalStoragePath().c_str());
466 m_schemeSupport.reset(new SchemeSupport(m_model->Type.Get().appType));
467 ViewModule::StorageSupport::initializeStorage(m_model);
468 m_appsSupport->initialize(m_model);
471 // m_vibrationSupport->initialize();
473 ViewModule::GeolocationSupport::Webkit2::initialize(m_model->TizenId.Get());
474 ViewModule::GeolocationSupport::Webkit2::
475 adjustGeolocationModuleState(m_currentEwkView);
478 void ViewLogic::initializePluginLoading()
480 // inform wrt information for plugin loading to web process
481 PluginModuleSupport::start(
483 m_model->Handle.Get(),
484 elm_config_scale_get(),
485 ApplicationDataSingleton::Instance().getEncodedBundle(),
487 m_model->SettingList.Get().isEncrypted());
490 void ViewLogic::ewkClientInit(Evas_Object *wkView) {
491 Assert(NULL != wkView && "ewk_view not created at this point");
492 ViewModule::GeolocationSupport::Webkit2::
493 initialize(m_model->TizenId.Get());
495 // WKPageLoaderClient
496 evas_object_smart_callback_add(
501 evas_object_smart_callback_add(
504 loadFinishedCallback,
506 evas_object_smart_callback_add(
509 titleChangedCallback,
511 evas_object_smart_callback_add(
514 loadProgressCallback,
516 evas_object_smart_callback_add(
518 EWK_LOAD_PROGRESS_FINISHED,
519 loadProgressFinishedCallback,
521 evas_object_smart_callback_add(
524 processCrashedCallback,
528 evas_object_smart_callback_add(
531 createWindowCallback,
533 evas_object_smart_callback_add(
539 // WKPagePolicyClient
540 evas_object_smart_callback_add(
542 EWK_POLICY_NAVIGATION_DECIDE,
543 policyNavigationDecideCallback,
545 evas_object_smart_callback_add(
547 EWK_POLICY_NEWWINDOW_DECIDE,
548 policyNewWindowDecideCallback,
550 evas_object_smart_callback_add(
552 EWK_POLICY_RESPONSE_DECIDE,
553 pageResponseDecideCallback,
556 // WKPageContextMenuClient
557 evas_object_smart_callback_add(
559 EWK_CONTEXTMENU_CUSTOMIZE,
560 contextmenuCustomizeCallback,
564 evas_object_smart_callback_add(
570 // EWK Geolocation Callback
571 evas_object_smart_callback_add(
573 EWK_REQUEST_GEOLOCATION_PERMISSION,
574 geolocationPermissionRequestCallback,
577 // EWK Notification Callback
578 evas_object_smart_callback_add(
580 EWK_NOTIFICATION_SHOW,
581 notificationShowCallback,
583 evas_object_smart_callback_add(
585 EWK_NOTIFICATION_CANCEL,
586 notificationCancelCallback,
588 evas_object_smart_callback_add(
590 EWK_NOTIFICATION_PERMISSION_REQUEST,
591 notificationPermissionRequestCallback,
594 // EWK Vibration Callback
595 evas_object_smart_callback_add(
597 EWK_VIBRATION_VIBRATE,
598 vibrationVibrateCallback,
600 evas_object_smart_callback_add(
602 EWK_VIBRATION_CANCEL,
603 vibrationCancelCallback,
605 evas_object_smart_callback_add(
607 EWK_CONTEXT_EXCEEDED_QUOATA,
608 databaseUsagePermissionRequestCallback,
610 // The followings are provisional comment for preventing popup
611 //evas_object_smart_callback_add(
613 //EWK_CONTEXT_FILE_SYSTEM_PERMISSION,
614 //fileSystemPermissionRequestCallback,
617 // EWK Orientation Callback
618 ewk_view_orientation_lock_callback_set(
620 orientationLockCallback,
623 // Fullscreen API callbacks
624 evas_object_smart_callback_add(
626 EWK_FULLSCREEN_ENTER,
627 enterFullscreenCallback,
629 evas_object_smart_callback_add(
632 exitFullscreenCallback,
636 void ViewLogic::ewkClientDeinit(Evas_Object *wkView) {
637 LogDebug("ewkClientDeinit");
638 Assert(NULL != wkView && "ewk_view not created at this point");
640 // WKPageLoaderClient
641 evas_object_smart_callback_del(
644 loadStartedCallback);
645 evas_object_smart_callback_del(
648 loadFinishedCallback);
649 evas_object_smart_callback_del(
652 titleChangedCallback);
653 evas_object_smart_callback_del(
656 loadProgressCallback);
657 evas_object_smart_callback_del(
659 EWK_LOAD_PROGRESS_FINISHED,
660 loadProgressFinishedCallback);
661 evas_object_smart_callback_del(
664 loadProgressCallback);
667 evas_object_smart_callback_del(
670 createWindowCallback);
671 evas_object_smart_callback_del(
674 closeWindowCallback);
676 // WKPagePolicyClient
677 evas_object_smart_callback_del(
679 EWK_POLICY_NAVIGATION_DECIDE,
680 policyNavigationDecideCallback);
681 evas_object_smart_callback_del(
683 EWK_POLICY_NEWWINDOW_DECIDE,
684 policyNewWindowDecideCallback);
685 evas_object_smart_callback_del(
687 EWK_POLICY_RESPONSE_DECIDE,
688 pageResponseDecideCallback);
690 // WKPageContextMenuClient
691 evas_object_smart_callback_del(
693 EWK_CONTEXTMENU_CUSTOMIZE,
694 contextmenuCustomizeCallback);
697 evas_object_smart_callback_del(
702 // EWK Geolocation Callback
703 evas_object_smart_callback_del(
705 EWK_REQUEST_GEOLOCATION_PERMISSION,
706 geolocationPermissionRequestCallback);
708 // EWK Notification Callback
709 evas_object_smart_callback_del(
711 EWK_NOTIFICATION_SHOW,
712 notificationShowCallback);
713 evas_object_smart_callback_del(
715 EWK_NOTIFICATION_CANCEL,
716 notificationCancelCallback);
717 evas_object_smart_callback_del(
719 EWK_NOTIFICATION_PERMISSION_REQUEST,
720 notificationPermissionRequestCallback);
722 // EWK Vibration Callback
723 evas_object_smart_callback_del(
725 EWK_VIBRATION_VIBRATE,
726 vibrationVibrateCallback);
727 evas_object_smart_callback_del(
729 EWK_VIBRATION_CANCEL,
730 vibrationCancelCallback);
732 evas_object_smart_callback_del(
734 EWK_CONTEXT_EXCEEDED_QUOATA,
735 databaseUsagePermissionRequestCallback);
736 //The followings are provisional comment for preventing popup
737 //evas_object_smart_callback_del(
739 //EWK_CONTEXT_FILE_SYSTEM_PERMISSION,
740 //fileSystemPermissionRequestCallback);
742 // EWK Orientation Callback
743 ewk_view_orientation_lock_callback_set(
749 void ViewLogic::createEwkView()
751 LogDebug("createEwkVeiw");
752 ADD_PROFILING_POINT("ewk_view_add_with_context", "start");
753 Evas_Object* newEwkView = ewk_view_add_with_context(
754 evas_object_evas_get(m_window),
756 ADD_PROFILING_POINT("ewk_view_add_with_context", "stop");
759 LogError("WKView creation failed");
764 // even arguments pass the ewkContext, this API should be called
765 // after webkit Evas_Object is created
766 ewk_context_cookies_policy_set(m_ewkContext, EWK_COOKIE_JAR_ACCEPT_ALWAYS);
768 LogInfo("push webview: " << newEwkView);
769 m_ewkViewList.push_back(newEwkView);
770 m_currentEwkView = newEwkView;
773 void ViewLogic::setStartPage()
775 /* Start URI (as other uris) is now localized
776 * on WebProcess side */
777 m_currentUri = m_startUrl;
780 void ViewLogic::prepareEwkView(Evas_Object *wkView)
782 LogDebug("prepareEwkView called");
784 Ewk_Setting* setting = ewk_view_setting_get(wkView);
787 auto userAgentString =
788 ViewModule::UserAgentSupport::getUserAgentFromVconf();
789 if (!userAgentString.empty()) {
790 LogDebug("Setting custom user agent as: " << userAgentString);
791 ewk_view_user_agent_set(wkView, userAgentString.c_str());
794 // set custom header : language
795 using namespace ViewModule::CustomHeaderSupport;
796 std::string customHeaderString = getValueByField(ACCEPT_LANGUAGE);
797 if (!customHeaderString.empty()) {
798 LogDebug("custom field=[" << ACCEPT_LANGUAGE << "]");
799 LogDebug("custom value=[" << customHeaderString << "]");
800 ewk_view_custom_header_add(wkView,
801 ACCEPT_LANGUAGE.c_str(),
802 customHeaderString.c_str());
805 // webkit NPAPI plugins is always on in wrt
806 ewk_setting_enable_plugins_set(setting, EINA_TRUE);
808 // The followings are not implemeted yet by webkit2
809 // ewk_view_setting_accelerated_compositing_enable_set(EINA_TRUE);
810 // ewk_view_mode_set();
811 // ewk_view_setting_enable_specified_plugin_set(EINA_TRUE, FLASH_MIME_TYPE);
812 // ewk_view_setting_html5video_external_player_enable_set(EINA_FALSE);
813 // ewk_view_show_ime_on_autofocus_set(EINA_TRUE);
814 // elm_webview_show_magnifier_set(EINA_FALSE);
815 ewk_setting_enable_scripts_set(setting, EINA_TRUE);
816 ewk_setting_auto_load_images_set(setting, EINA_TRUE);
817 ewk_setting_auto_fitting_set(setting, EINA_FALSE);
819 // disable zoom option when user click the input field
820 // this option is useful with the normal website
821 // for the make user friendly, disable auto zoom in the webapp
822 // The followings are not implemeted yet by webkit2
823 // elm_webview_input_field_zoom_set(EINA_FALSE);
825 // set cookie database path
826 // The followings are not implemeted yet by webkit2
827 // ewk_cookies_file_set(dao.getCookieDatabasePath().c_str()));
829 // set visibility to WebCore. This value will be used for html5.
830 // also, this value will be changed in the suspend, resume
831 // or create window, close window.
832 ewk_view_page_visibility_state_set(wkView,
833 EWK_PAGE_VISIBILITY_STATE_VISIBLE,
837 void ViewLogic::removeEwkView(Evas_Object *wkView)
839 LogInfo("removeEwkView called");
841 Assert(0 != m_ewkViewList.size());
843 // unregister webview callbacks
844 ewkClientDeinit(wkView);
846 // suspend NPAPI plugin - Not implemented by Webkit2
847 // ewk_view_pause_or_resume_plugins();
848 evas_object_del(wkView);
849 m_ewkViewList.remove(wkView);
852 void ViewLogic::resumeEwkView(Evas_Object *wkView)
854 LogInfo("resumeEwkView called");
857 // register webview callback
858 ewkClientInit(wkView);
861 resumeWebkit(wkView);
866 void ViewLogic::suspendEwkView(Evas_Object *wkView)
868 LogInfo("suspendEwkView called");
872 suspendWebkit(wkView);
874 // unregister webview callbacks
875 ewkClientDeinit(wkView);
879 void ViewLogic::resumeWebkit(Evas_Object *wkView)
881 LogDebug("resumeWebkit");
884 // resume NPAPI plugin
885 // The followings are not implemeted yet by webkit2
886 // ewk_view_pause_or_resume_plugins(false);
887 // ewk_view_pause_or_resume_video_audio(false);
888 // ewk_view_javascript_resume();
889 // ewk_view_enable_render();
890 // ewk_view_reduce_plugins_frame_rate(false);
891 ewk_view_resume(wkView);
892 ewk_view_visibility_set(wkView, EINA_TRUE);
893 ewk_view_page_visibility_state_set(wkView,
894 EWK_PAGE_VISIBILITY_STATE_VISIBLE,
899 void ViewLogic::suspendWebkit(Evas_Object *wkView)
901 LogDebug("suspendWebkit");
904 // suspend the followings
905 // The followings are not implemeted yet by webkit2
906 // ewk_view_pause_or_resume_plugins(true);
907 // ewk_view_pause_or_resume_video_audio(true);
909 // send visibility event to webpage
910 ewk_view_page_visibility_state_set(wkView,
911 EWK_PAGE_VISIBILITY_STATE_HIDDEN,
913 ewk_view_suspend(wkView);
914 ewk_view_visibility_set(wkView, EINA_FALSE);
918 void ViewLogic::contextMessageFromInjectedBundleCallback(
924 LogDebug("contextMessageFromInjectedBundleCallback called");
926 ViewLogic* This = static_cast<ViewLogic*>(clientInfo);
927 // didRecieveMessageFromInjectedBundleCallback - returnData is null
928 // didReceiveSynchronousMessageCallback - returnData isn't null
929 // WKContextInjectedBundleClient bundleClient = {
930 // kWKContextInjectedBundleClientCurrentVersion,
931 // static_cast<void*>(this),
932 // &didRecieveMessageFromInjectedBundleCallback,
933 // &didReceiveSynchronousMessageCallback
935 if (NULL == returnData) {
936 This->didRecieveMessageFromInjectedBundle(name, body);
938 This->didReceiveSynchronousMessage(name, body, returnData);
942 void ViewLogic::didStartDownloadCallback(
943 const char* downloadUrl,
946 LogDebug("didStartDownloadCallback called");
948 ViewLogic* This = static_cast<ViewLogic*>(data);
950 LogDebug("download url = " << downloadUrl);
951 This->m_appsSupport->downloadRequest(
957 void ViewLogic::loadStartedCallback(
959 Evas_Object* /*obj*/,
962 LogDebug("loadStartedCallback called");
964 ViewLogic* This = static_cast<ViewLogic*>(data);
965 evas_object_focus_set(This->m_currentEwkView, EINA_TRUE);
968 void ViewLogic::loadFinishedCallback(
970 Evas_Object* /*obj*/,
973 LogDebug("loadFinishedCallback called");
975 ViewLogic* This = static_cast<ViewLogic*>(data);
978 const char* url = ewk_view_uri_get(This->m_currentEwkView);
979 if (NULL == url || strlen(url) == 0) {
980 LogError("url is empty");
982 DPL::OptionalString jsOptionalString =
983 ViewModule::PasswordSupport::jsForAutoFillData(url);
984 if (jsOptionalString.IsNull()) {
985 LogError("Fail to get JS String");
987 std::string jsStr = DPL::ToUTF8String(*jsOptionalString).c_str();
988 ewk_view_script_execute(
989 This->m_currentEwkView,
991 didRunJavaScriptCallback,
996 // call loadFinish callback to wrt-client
997 if (!This->m_cbs->loadFinish.empty()) {
998 This->m_cbs->loadFinish(true);
1001 // set only encoded bundle
1002 double scale = elm_config_scale_get();
1003 PluginModuleSupport::setCustomProperties(
1006 ApplicationDataSingleton::Instance().getEncodedBundle());
1007 // check if 'appsevice' event is registed at the current frames.
1008 // If so, dispatch the event to frames.
1009 PluginModuleSupport::dispatchJavaScriptEvent(
1011 WrtPlugins::W3C::ServiceCustomEvent,
1015 void ViewLogic::titleChangedCallback(
1017 Evas_Object* /*obj*/,
1020 LogDebug("titleChangedCallback called");
1022 ViewLogic* This = static_cast<ViewLogic*>(data);
1024 const char* title = static_cast<char*>(eventInfo);
1026 if (0 == strlen(title)) {
1027 LogDebug("title data is empty");
1030 LogDebug("Title = [" << title << "]");
1031 This->m_schemeSupport->HandleTizenScheme(title,
1033 This->m_currentEwkView);
1036 void ViewLogic::loadProgressCallback(
1038 Evas_Object* /*obj*/,
1041 double* progress = static_cast<double*>(eventInfo);
1042 LogDebug("didChangeProgressCallback progress = " << *progress);
1045 void ViewLogic::loadProgressFinishedCallback(
1047 Evas_Object* /*obj*/,
1048 void* /*eventInfo*/)
1050 LogDebug("didFinishProgressCallback");
1052 ViewLogic const * const view = static_cast<ViewLogic const * const>(data);
1053 if (!view->m_cbs->progressFinish.empty()) {
1054 view->m_cbs->progressFinish();
1058 void ViewLogic::processCrashedCallback(
1060 Evas_Object* /*obj*/,
1063 LogInfo("processCrashedCallback");
1065 ViewLogic const * const view =
1066 static_cast<ViewLogic const * const>(data);
1067 if (!view->m_cbs->webCrash.empty()) {
1068 view->m_cbs->webCrash();
1070 // This flag will be prevented exit() call in the Webkit side
1071 if (NULL != eventInfo) {
1072 *(static_cast<Eina_Bool*>(eventInfo)) = EINA_TRUE;
1076 void ViewLogic::createWindowCallback(
1081 LogDebug("createWindowCallback");
1083 ViewLogic* This = static_cast<ViewLogic*>(data);
1085 Evas_Object* currentEwkView = This->m_currentEwkView;
1087 // suspend current ewkview
1088 /* In case we support many pages in parallel
1089 then view should not be suspended*/
1090 //This->suspendEwkView(currentEwkView);
1092 if (!This->m_cbs->bufferUnset.empty()) {
1093 This->m_cbs->bufferUnset(currentEwkView);
1096 // create new ewkview
1097 This->createEwkView();
1099 Evas_Object* newEwkView = This->m_currentEwkView;
1101 // initialize new ewkview
1102 This->setStartPage();
1103 This->ewkClientInit(newEwkView);
1104 This->prepareEwkView(newEwkView);
1107 if (!This->m_cbs->bufferUnset.empty()) {
1108 This->m_cbs->bufferSet(newEwkView);
1110 *(static_cast<Evas_Object **>(eventInfo)) = newEwkView;
1113 void ViewLogic::closeWindowCallback(
1115 Evas_Object* /*obj*/,
1116 void* /*eventInfo*/)
1118 LogDebug("closeWindowCallback");
1119 ecore_idler_add(windowCloseIdlerCallback, data);
1122 void ViewLogic::policyNavigationDecideCallback(
1124 Evas_Object* /*obj*/,
1127 LogDebug("policyNavigationDecideCallback called");
1129 ViewLogic* This = static_cast<ViewLogic*>(data);
1131 Ewk_Policy_Decision* policyDecision =
1132 static_cast<Ewk_Policy_Decision*>(eventInfo);
1134 if (This->m_schemeSupport->filterURIByScheme(policyDecision,
1138 This->m_currentEwkView))
1141 ewk_policy_decision_use(policyDecision);
1143 // check whether this is new empty window
1144 const char* activeUrl = ewk_view_uri_get(This->m_currentEwkView);
1145 if(!activeUrl || 0 == strlen(activeUrl)) {
1147 * The view is empty and scheme has been handled externally. When
1148 * user gets back from the external application he'd see blank page
1149 * and won't be able to navigate back. This happens when window.open
1150 * is used to handle schemes like sms/mms/mailto (for example in
1151 * WAC web standards tests: WS-15XX).
1153 * To solve the problem, the empty view is removed from the stack
1154 * and the previous one is shown. This is not an elegant solution
1155 * but we don't have a better one.
1157 LogInfo("Scheme has been handled externally. Removing empty view.");
1158 if (ewk_view_back_possible(This->m_currentEwkView)) {
1159 // go back to previous WKPage
1160 ewk_view_back(This->m_currentEwkView);
1162 // stop current WKPage
1163 ewk_view_stop(This->m_currentEwkView);
1164 ecore_idler_add(windowCloseIdlerCallback, This);
1169 ewk_policy_decision_ignore(policyDecision);
1173 void ViewLogic::policyNewWindowDecideCallback(
1175 Evas_Object* /*obj*/,
1178 LogDebug("policyNewWindowDecideCallback called");
1180 ViewLogic* This = static_cast<ViewLogic*>(data);
1182 Ewk_Policy_Decision* policyDecision =
1183 static_cast<Ewk_Policy_Decision*>(eventInfo);
1185 if (This->m_schemeSupport->filterURIByScheme(policyDecision,
1189 This->m_currentEwkView))
1191 ewk_policy_decision_use(policyDecision);
1194 ewk_policy_decision_ignore(policyDecision);
1198 void ViewLogic::pageResponseDecideCallback(
1200 Evas_Object* /*obj*/,
1203 LogDebug("pageResponseDecideCallback called");
1205 ViewLogic* This = static_cast<ViewLogic*>(data);
1207 Ewk_Policy_Decision* policyDecision =
1208 static_cast<Ewk_Policy_Decision*>(eventInfo);
1209 Ewk_Policy_Decision_Type policyDecisionType =
1210 ewk_policy_decision_type_get(policyDecision);
1212 if (policyDecisionType == EWK_POLICY_DECISION_USE) {
1214 ewk_policy_decision_use(policyDecision);
1215 } else if (policyDecisionType == EWK_POLICY_DECISION_DOWNLOAD) {
1216 LogDebug("download");
1217 ewk_policy_decision_suspend(policyDecision);
1219 // get uri information
1220 const char* url = ewk_policy_decision_url_get(policyDecision);
1221 if (NULL == url || strlen(url) == 0) {
1222 LogDebug("url data is empty");
1223 ewk_policy_decision_use(policyDecision);
1226 LogDebug("url = [" << url << "]");
1228 // get content information
1229 const char* content =
1230 ewk_policy_decision_response_mime_get(policyDecision);
1231 LogDebug("content type = [" << content << "]");
1233 // get cookie information
1234 const char* cookie = ewk_policy_decision_cookie_get(policyDecision);
1235 LogDebug("cookie = [" << cookie << "]");
1237 LogDebug("Content not supported, will be opened in external app");
1238 This->m_appsSupport->downloadRequest(
1242 ewk_policy_decision_ignore(policyDecision);
1243 } else if (policyDecisionType == EWK_POLICY_DECISION_IGNORE) {
1245 ewk_policy_decision_ignore(policyDecision);
1247 LogDebug("Type isn't handled");
1248 ewk_policy_decision_ignore(policyDecision);
1252 void ViewLogic::contextmenuCustomizeCallback(
1254 Evas_Object* /*obj*/,
1257 LogDebug("contextmenuCustomizeCallback called");
1260 ViewLogic* This = static_cast<ViewLogic*>(const_cast<void*>(data));
1261 Ewk_Context_Menu* menu = static_cast<Ewk_Context_Menu*>(eventInfo);
1262 if ((This->m_model->Type.Get().appType == WrtDB::APP_TYPE_TIZENWEBAPP) &&
1263 (This->m_model->SettingList.Get().getContextMenu()
1264 == ContextMenu_Disable))
1266 LogDebug("ContextMenu Disable!!");
1267 for (unsigned int idx = 0; idx < ewk_context_menu_item_count(menu);) {
1268 Ewk_Context_Menu_Item* item = ewk_context_menu_nth_item_get(menu, idx);
1270 ewk_context_menu_item_remove(menu, item);
1273 LogDebug("ContextMenu Enable!!");
1274 for (unsigned int idx = 0; idx < ewk_context_menu_item_count(menu);) {
1275 Ewk_Context_Menu_Item* item = ewk_context_menu_nth_item_get(menu, idx);
1277 Ewk_Context_Menu_Item_Tag tag = ewk_context_menu_item_tag_get(item);
1280 case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_IMAGE_IN_NEW_WINDOW:
1281 ewk_context_menu_item_remove(menu, item);
1284 case EWK_CONTEXT_MENU_ITEM_TAG_SEARCH_WEB:
1285 ewk_context_menu_item_remove(menu, item);
1296 void ViewLogic::formSubmitCallback(
1298 Evas_Object* /*obj*/,
1301 LogDebug("formSubmitCallback called");
1303 Ewk_Form_Data* formData = static_cast<Ewk_Form_Data*>(eventInfo);
1305 const char* uri = ewk_form_data_url_get(formData);
1307 LogError("URL is empty");
1311 Eina_Hash* userData = ewk_form_data_values_get(formData);
1312 ViewModule::PasswordSupport::submitClicked(uri, userData);
1315 void ViewLogic::geolocationPermissionRequestCallback(
1317 Evas_Object* /*obj*/,
1320 LogDebug("geolocationPermissionRequestCallback called");
1322 ViewModule::GeolocationSupport::Webkit2::
1323 geolocationPermissionRequest(eventInfo);
1327 void ViewLogic::notificationShowCallback(
1329 Evas_Object* /*obj*/,
1332 LogDebug("notificationShowCallback called");
1334 ViewLogic* This = static_cast<ViewLogic*>(data);
1337 Ewk_Notification* noti = static_cast<Ewk_Notification*>(eventInfo);
1339 using namespace ViewModule::WebNotification;
1341 WebNotificationDataPtr notiData(
1342 new WebNotificationData(
1344 ewk_notification_id_get(noti)));
1346 DPL::OptionalString string =
1347 DPL::FromUTF8String(ewk_notification_icon_url_get(noti));
1348 if (!string.IsNull()) {
1349 notiData->m_iconURL = DPL::ToUTF8String(*string);
1351 string = DPL::FromUTF8String(ewk_notification_title_get(noti));
1352 if (!string.IsNull()) {
1353 notiData->m_title = DPL::ToUTF8String(*string);
1355 string = DPL::FromUTF8String(ewk_notification_body_get(noti));
1356 if (!string.IsNull()) {
1357 notiData->m_body = DPL::ToUTF8String(*string);
1360 LogInfo("notification id : " << notiData->m_id);
1361 LogInfo("notification iconURL : " << notiData->m_iconURL);
1362 LogInfo("notification title : " << notiData->m_title);
1363 LogInfo("notification body : " << notiData->m_body);
1365 showWebNotification(notiData);
1366 ewk_notification_showed(This->m_ewkContext, ewk_notification_id_get(noti));
1369 void ViewLogic::notificationCancelCallback(
1371 Evas_Object* /*obj*/,
1372 void* /*eventInfo*/)
1374 LogDebug("notificationCancelCallback called");
1377 void ViewLogic::notificationPermissionRequestCallback(
1379 Evas_Object* /*obj*/,
1382 LogDebug("notificationPermissionRequestCallback called");
1384 ViewLogic* This = static_cast<ViewLogic*>(data);
1387 Ewk_Notification_Permission_Request* request =
1388 static_cast<Ewk_Notification_Permission_Request*>(eventInfo);
1389 ewk_notification_permission_request_response(
1396 void ViewLogic::vibrationVibrateCallback(
1398 Evas_Object* /*obj*/,
1401 LogDebug("vibrationVibrateCallback called");
1403 ViewLogic* This = static_cast<ViewLogic*>(data);
1406 const long vibrationTime = *(static_cast<const long*>(eventInfo));
1409 // This->m_vibrationSupport->startVibration(vibrationTime);
1414 void ViewLogic::vibrationCancelCallback(
1416 Evas_Object* /*obj*/,
1417 void* /*eventInfo*/)
1419 LogDebug("vibrationCancelCallback called");
1421 ViewLogic* This = static_cast<ViewLogic*>(data);
1424 // This->m_vibrationSupport->stopVibration();
1429 // EWK Orientation Callback
1430 Eina_Bool ViewLogic::orientationLockCallback(
1432 Eina_Bool /*needLock*/,
1436 LogDebug("orientationLockCallback called");
1438 ViewLogic* This = static_cast<ViewLogic*>(data);
1440 if (orientation & EWK_SCREEN_ORIENTATION_PORTRAIT_PRIMARY) {
1441 LogDebug("orientation is portrait-primary");
1442 elm_win_rotation_with_resize_set(This->m_window, 0);
1443 ewk_view_orientation_send(obj, 0);
1444 } else if(orientation & EWK_SCREEN_ORIENTATION_LANDSCAPE_PRIMARY) {
1445 LogDebug("orientation is landscape-primary");
1446 elm_win_rotation_with_resize_set(This->m_window, 270);
1447 ewk_view_orientation_send(obj, 90);
1448 } else if(orientation & EWK_SCREEN_ORIENTATION_PORTRAIT_SECONDARY) {
1449 LogDebug("orientation is portrait-secondary");
1450 elm_win_rotation_with_resize_set(This->m_window, 180);
1451 ewk_view_orientation_send(obj, 180);
1452 } else if(orientation & EWK_SCREEN_ORIENTATION_LANDSCAPE_SECONDARY) {
1453 LogDebug("orientation is landscape-secondary");
1454 elm_win_rotation_with_resize_set(This->m_window, 90);
1455 ewk_view_orientation_send(obj, -90);
1457 LogDebug("Wrong orientation is set");
1464 // Fullscreen API callbacks
1465 void ViewLogic::enterFullscreenCallback(
1467 Evas_Object* /*obj*/,
1468 void* /*eventInfo*/)
1470 LogInfo("enterFullscreenCallback called");
1472 ViewLogic* This = static_cast<ViewLogic*>(data);
1473 if (!This->m_cbs->toggleFullscreen.empty()) {
1474 This->m_cbs->toggleFullscreen(true);
1477 void ViewLogic::exitFullscreenCallback(
1479 Evas_Object* /*obj*/,
1480 void* /*eventInfo*/)
1482 LogInfo("exitFullscreenCallback called");
1484 ViewLogic* This = static_cast<ViewLogic*>(data);
1485 if (!This->m_cbs->toggleFullscreen.empty()) {
1486 This->m_cbs->toggleFullscreen(false);
1490 void ViewLogic::didRunJavaScriptCallback(
1491 Evas_Object* /*obj*/,
1495 LogInfo("didRunJavaScriptCallback called");
1496 LogInfo("result = " << result);
1499 Eina_Bool ViewLogic::windowCloseIdlerCallback(void* data)
1501 LogDebug("closeIdlerCallback");
1502 ViewLogic* This = static_cast<ViewLogic*>(data);
1503 This->windowClose();
1504 return ECORE_CALLBACK_CANCEL;
1507 int ViewLogic::appcoreLowMemoryCallback(void *data)
1509 LogInfo("appcoreLowMemoryCallback");
1511 ViewLogic* This = static_cast<ViewLogic*>(data);
1513 if (NULL == This->m_ewkContext) {
1514 LogInfo("ewk isn't initialize at this moment");
1516 ewk_context_cache_clear(This->m_ewkContext);
1517 ewk_context_notify_low_memory(This->m_ewkContext);
1523 void ViewLogic::databaseUsagePermissionRequestCallback(
1525 Evas_Object* /*obj*/,
1528 LogDebug("databaseUsagePermissionRequestCallback called");
1530 ViewLogic* This = static_cast<ViewLogic*>(data);
1531 This->databaseUsagePermissionRequest(eventInfo);
1535 void ViewLogic::databaseUsagePermissionRequest(
1538 LogDebug("databaseUsagePermissionRequest called");
1540 Ewk_Context_Exceeded_Quota* exceededQuota =
1541 static_cast<Ewk_Context_Exceeded_Quota*>(eventInfo);
1543 bool state = askUserForDatabaseExceedPermission(
1546 if (true == state) {
1548 ewk_context_web_database_exceeded_quota_new_quota_set(
1550 ewk_context_web_database_exceeded_quota_expected_usage_get(
1552 + 10*(1024*1024)); //10MB
1559 bool ViewLogic::askUserForDatabaseExceedPermission(
1560 Ewk_Context_Exceeded_Quota* exceededQuota)
1562 LogDebug("askUserForDatabaseExceedPermission called");
1563 Ewk_Security_Origin* origin =
1564 ewk_context_web_database_exceeded_quota_security_origin_get(
1566 char databaseUseAskTitle[180];
1568 snprintf(databaseUseAskTitle, sizeof(databaseUseAskTitle),
1569 "Do you want to allow %s to use up to %dMB of storage?",
1570 ewk_security_origin_host_get(origin),
1571 static_cast<int>(ewk_context_web_database_exceeded_quota_expected_usage_get(
1572 exceededQuota) / (1024 * 1024)));
1574 return Wrt::PopupInvoker().askYesNo(
1575 DATABASE_USE_ASK_TITLE,
1576 databaseUseAskTitle);
1579 void ViewLogic::fileSystemPermissionRequestCallback(
1581 Evas_Object* /*obj*/,
1584 LogDebug("filesystemPermissionRequestCallback called");
1586 ViewLogic* This = static_cast<ViewLogic*>(data);
1587 This->fileSystemPermissionRequest(eventInfo);
1591 void ViewLogic::fileSystemPermissionRequest(
1594 LogDebug("filesystemPermissionRequest called");
1596 Ewk_Context_File_System_Permission* fileSystemPermission =
1597 static_cast<Ewk_Context_File_System_Permission*>(eventInfo);
1598 bool state = askUserForFileSystemPermission(
1599 fileSystemPermission);
1601 if (true == state) {
1603 ewk_context_file_system_permission_allow_set(
1604 fileSystemPermission, EINA_TRUE);
1611 bool ViewLogic::askUserForFileSystemPermission(
1612 Ewk_Context_File_System_Permission* fileSystemPermission)
1614 LogDebug("askUserForFileSystemPermission called");
1615 Ewk_Security_Origin* origin =
1616 ewk_context_file_system_permission_origin_get(
1617 fileSystemPermission);
1619 char fileSystemPermissionAskTitle[110];
1620 snprintf(fileSystemPermissionAskTitle,
1621 sizeof(fileSystemPermissionAskTitle),
1622 "Do you want to allow %s to use persistent filesystem?",
1623 ewk_security_origin_host_get(origin));
1625 return Wrt::PopupInvoker().askYesNo(
1626 FILESYSTEM_USE_ASK_TITLE,
1627 fileSystemPermissionAskTitle);
1630 void ViewLogic::didRecieveMessageFromInjectedBundle(
1632 const char* /*body*/)
1634 LogDebug("did recive message " << name);
1637 void ViewLogic::didReceiveSynchronousMessage(
1642 LogDebug("didReceiveSynchronousMessage called");
1647 LogDebug("body is empty");
1651 if (!strcmp(name, uriBlockedMessageName)) {
1652 LogDebug("received : " << uriBlockedMessageName);
1653 // Currently WebProcess informs obly about blocked
1654 // URI - URI localization and security chekcs are
1655 // done by WebProcess itself (see: wrt-wk2-bundle.cpp
1656 // and bundle_uri_handling.cpp)
1657 rememberBlockedURI(DPL::FromUTF8String(body));
1659 } else if (!strcmp(name, uriChangedMessageName)) {
1660 LogDebug("received : " << uriChangedMessageName);
1661 std::string ret = requestUriChanged(DPL::FromUTF8String(body));
1662 *returnData = strdup(ret.c_str());
1666 void ViewLogic::rememberBlockedURI(const DPL::String& inputURI)
1668 m_blockedUri = DPL::ToUTF8String(inputURI);
1669 LogInfo("set blocked uri to open browser later : " << m_blockedUri);
1673 std::string ViewLogic::requestUriChanged(const DPL::String& changedURL)
1675 using namespace ViewModule::SecuritySupport;
1677 std::string url = DPL::ToUTF8String(changedURL);
1678 LogInfo("URL = [" << url << "]");
1681 // If url is same to URICHANGE_BLOCKED_URL,
1682 // this url has been already blocked by willsend.
1683 // So current page should be moved to previous page
1684 if (url == URICHANGE_BLOCKED_URL)
1686 if (m_model->Type.Get().appType == WrtDB::APP_TYPE_TIZENWEBAPP)
1688 // block this page and open it in browser
1689 LogDebug("Request was blocked by WARP: " << url.c_str());
1690 if (!m_blockedUri.empty()) {
1691 LogDebug("open browser : " << m_blockedUri);
1692 bundle* bundleData = bundle_create();
1693 appsvc_set_operation(bundleData, APPSVC_OPERATION_VIEW);
1694 appsvc_set_uri(bundleData, m_blockedUri.c_str());
1695 CONTROLLER_POST_EVENT(
1696 ApplicationLauncher,
1697 ApplicationLauncherEvents::LaunchApplicationByAppService(
1701 m_blockedUri = std::string();
1704 if (ewk_view_back_possible(m_currentEwkView)) {
1705 // go back to previous page
1706 ewk_view_back(m_currentEwkView);
1708 // stop current page
1709 ewk_view_stop(m_currentEwkView);
1710 ecore_idler_add(windowCloseIdlerCallback, this);
1713 // This is used in case of returning previous page
1715 return URICHANGE_PLUGIN_NO_CHANGE;
1720 // Check if this url with 'http' or 'https' is included in whitelist,
1721 // which has lists of accessible external documents and
1722 // used for ONLY Tizen app
1723 std::string matchedScheme;
1724 std::string matchedUri;
1725 pcrecpp::RE(PATTERN_URI_CHANGE).PartialMatch(url.c_str(),
1728 ViewModule::Scheme scheme(matchedScheme);
1729 if (scheme.GetType() == ViewModule::Scheme::HTTP ||
1730 scheme.GetType() == ViewModule::Scheme::HTTPS)
1732 if (m_model->Type.Get().appType == WrtDB::APP_TYPE_TIZENWEBAPP) {
1733 if (!checkWhitelist(url.c_str())) {
1734 LogInfo("This uri is not included in white document list");
1735 return URICHANGE_PLUGIN_STOP_ONLY;
1737 LogInfo("This url is included in WhiteList");
1739 // For WAC app, WRT should block access of device api
1740 // for external documents
1741 return URICHANGE_PLUGIN_STOP_ONLY;
1745 // register javascript object for plugins to be used
1746 LogInfo("Register Plugin Objects");
1747 return URICHANGE_PLUGIN_RESTART;
1750 void ViewLogic::windowClose()
1752 LogDebug("windowClose");
1754 if (1 >= m_ewkViewList.size()) {
1755 if (!m_cbs->windowClose.empty()) {
1756 m_cbs->windowClose();
1759 // hide current ewkView
1761 if (!m_cbs->bufferUnset.empty()) {
1762 m_cbs->bufferUnset(m_currentEwkView);
1764 removeEwkView(m_currentEwkView);
1766 // get latest ewkView
1767 m_currentEwkView = m_ewkViewList.back();
1768 const char* uri = ewk_view_uri_get(m_currentEwkView);
1769 if (NULL == uri || 0 == strlen(uri)) {
1770 m_currentUri.clear();
1776 /* In case we support many pages in parallel
1777 then view is not suspended*/
1778 //resumeEwkView(m_currentEwkView);
1781 if (!m_cbs->bufferSet.empty()) {
1782 m_cbs->bufferSet(m_currentEwkView);