Fix the problem of browser launch when webapp can't access remote url by WARP
[platform/framework/web/wrt.git] / src / view / webkit / view_logic.cpp
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
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
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 /**
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
22  */
23 #include "view_logic.h"
24
25 #include <cstring>
26 #include <string>
27 #include <dpl/assert.h>
28 #include <dpl/log/log.h>
29 #include <dpl/optional.h>
30 #include <dpl/string.h>
31 #include <dpl/foreach.h>
32
33 #include <pcrecpp.h>
34 #include <vconf.h>
35 #include <sysman.h>
36 #include <widget_model.h>
37 #include <dpl/wrt-dao-ro/widget_dao_read_only.h>
38 #include <dpl/wrt-dao-ro/vconf_config.h>
39 #include <dpl/utils/wrt_global_settings.h>
40
41 #include <common/application_data.h>
42 #include <common/application_launcher.h>
43 #include <common/scheme.h>
44
45 #include <common/view_logic_apps_support.h>
46 #include <common/view_logic_custom_header_support.h>
47 #include <common/view_logic_password_support.h>
48 #include <common/view_logic_security_support.h>
49 #include <common/view_logic_security_origin_support.h>
50 #include <common/view_logic_storage_support.h>
51 #include <common/view_logic_uri_support.h>
52 #include <common/view_logic_user_agent_support.h>
53 #include <common/view_logic_vibration_support.h>
54 #include <view_logic_scheme_support.h>
55 #include <view_logic_filesystem_support.h>
56 #include <view_logic_geolocation_support_webkit2.h>
57 #include <view_logic_usermedia_support.h>
58 #include <view_logic_web_notification_support.h>
59 #include <view_logic_web_storage_support.h>
60 #include "bundles/plugin_module_support.h"
61 #include <popup-runner/PopupInvoker.h>
62
63 #include <EWebKit2.h>
64 #include <js_overlay_types.h>
65 #include <i_runnable_widget_object.h>
66 #include <profiling_util.h>
67 #include <wrt-commons/custom-handler-dao-ro/common_dao_types.h>
68 #include <wrt-commons/custom-handler-dao-ro/CustomHandlerDatabase.h>
69 #include <wrt-commons/custom-handler-dao-ro/custom_handler_dao_read_only.h>
70 #include <wrt-commons/custom-handler-dao-rw/custom_handler_dao.h>
71 #include <popup-runner/PopupInvoker.h>
72
73 #include <appsvc/appsvc.h>
74
75 namespace {
76 const char * const bundlePath = "/usr/lib/wrt-wk2-bundles/libwrt-wk2-bundle.so";
77 const char * const uriBlockedMessageName = "uri_blocked_msg";
78 const char * const uriChangedMessageName = "uri_changed_msg";
79 const char * const URICHANGE_PLUGIN_STOP_ONLY = "plugin_stop_only";
80 const char * const URICHANGE_PLUGIN_RESTART = "plugin_restart";
81 const char * const URICHANGE_PLUGIN_NO_CHANGE = "plugin_no_change";
82 const char * const URICHANGE_BLOCKED_URL = "null";
83 const char* PATTERN_URI_CHANGE = "^(([^:/\\?#]+)://[^\\?#]*)";
84 const int MAX_NUM_CONTEXT_MENU_ITEMS = 10;
85 // IME State value
86 const char * const IME_STATE_ON = "on";
87 const char * const IME_STATE_OFF = "off";
88
89 const char PROTOCOL_HANDLER_ASK_MSG[] = "Add protocol?";
90 const char PROTOCOL_HANDLER_ASK_TITLE[] = "Add protocol";
91 const char PROTOCOL_HANDLER_ASK_REMEMBER[] = "Remember dicision";
92 const char CONTENT_HANDLER_ASK_MSG[] = "Add content?";
93 const char CONTENT_HANDLER_ASK_TITLE[] = "Add content";
94 const char CONTENT_HANDLER_AKS_REMEMBER[] = "Remember dicision";
95 const char * const CERTIFICATE_CONFIRM_REQUEST_ASK_TITLE =
96     "Certification Info";
97 const char * const CERTIFICATE_CONFIRM_REQUEST_ASK_BODY =
98     "This site's security certificate is not trusted! Do you acess this site?";
99
100 const wchar_t* BACKGROUND_ENABLED = L"background_enabled";
101 } // anonymous namespace
102
103 std::map<const std::string,
104          const Evas_Smart_Cb> ViewLogic::m_ewkCallbacksMap = {
105     { "load,started", &ViewLogic::loadStartedCallback },
106     { "load,finished", &ViewLogic::loadFinishedCallback },
107     { "title,changed", &ViewLogic::titleChangedCallback },
108     { "load,progress", &ViewLogic::loadProgressCallback },
109     { "load,progress,finished", &ViewLogic::loadProgressFinishedCallback },
110     { "process,crashed", &ViewLogic::processCrashedCallback },
111     // WKPageUIClient
112     { "create,window", &ViewLogic::createWindowCallback },
113     { "close,window", &ViewLogic::closeWindowCallback },
114     // WKPagePolicyClient
115     { "policy,navigation,decide", &ViewLogic::policyNavigationDecideCallback },
116     { "policy,newwindow,decide", &ViewLogic::policyNewWindowDecideCallback },
117     { "policy,response,decide", &ViewLogic::pageResponseDecideCallback },
118     // WKPageContextMenuClient
119     { "contextmenu,customize", &ViewLogic::contextmenuCustomizeCallback },
120     // WKPageFormClient
121     { "form,submit", &ViewLogic::formSubmitCallback },
122     // EWK Geolocation Callback
123     { "request,geolocation,permission",
124       &ViewLogic::geolocationPermissionRequestCallback },
125     // EWK Notification Callback
126     { "notification,show", &ViewLogic::notificationShowCallback },
127     { "notification,cancel", &ViewLogic::notificationCancelCallback },
128     { "notification,permission,request",
129       &ViewLogic::notificationPermissionRequestCallback },
130
131     { "database,quota,exceeded",
132       &ViewLogic::databaseUsagePermissionRequestCallback },
133     { "filesystem,permission,request",
134       &ViewLogic::fileSystemPermissionRequestCallback },
135     { "fullscreen,enterfullscreen", &ViewLogic::enterFullscreenCallback },
136     { "fullscreen,exitfullscreen", &ViewLogic::exitFullscreenCallback },
137     // IME Callback
138     // when ime start to be showed on the webview,
139     // this callback will be called
140     { "inputmethod,changed", &ViewLogic::imeChangedCallback },
141     // this callback will be called
142     //  when ime finishes to be showed on the webview
143     // "event_info" arg of this callback is always NULL point
144     // if web content should know size of ime,
145     //  use "inputmethod,changed" instead of this.
146     //
147     { "editorclient,ime,opened", &ViewLogic::imeOpenedCallback },
148     // when ime finished to be hidden,
149     // this callback will be called
150     { "editorclient,ime,closed", &ViewLogic::imeClosedCallback },
151     // EWK Usermedia Callback
152     { "usermedia,permission,request",
153       &ViewLogic::usermediaPermissionRequestCallback },
154     // Custom handlers
155     { "protocolhandler,registration,requested",
156       &ViewLogic::protocolHandlerRegistrationCallback },
157     { "protocolhandler,isregistered",
158       &ViewLogic::protocolHandlerIsRegisteredCallback },
159     { "protocolhandler,unregistration,requested",
160       &ViewLogic::protocolHandlerUnregistrationCallback },
161     { "contenthandler,registration,requested",
162       &ViewLogic::contentHandlerRegistrationCallback },
163     { "contenthandler,isregistered",
164       &ViewLogic::contentHandlerIsRegisteredCallback },
165     { "contenthandler,unregistration,requested",
166       &ViewLogic::contentHandlerUnregistrationCallback },
167     { "request,certificate,confirm",
168       &ViewLogic::certificateConfirmRequestCallback }
169 };
170
171 ViewLogic::ViewLogic() :
172     m_ewkContext(0),
173     m_currentEwkView(0),
174     m_window(NULL),
175     m_model(0),
176     m_cbs(new WRT::UserDelegates),
177     m_isBackgroundReload(false),
178     m_isBackgroundSupport(false),
179     m_appsSupport(new ViewModule::AppsSupport()),
180     m_vibrationSupport(new ViewModule::VibrationSupport()),
181     m_attachedToCustomHandlerDao(false)
182 {
183     ApplicationLauncherSingleton::Instance().Touch();
184 }
185
186 ViewLogic::~ViewLogic()
187 {
188     detachFromCustomHandlersDao();
189 }
190
191 bool ViewLogic::createWebView(Ewk_Context* context,
192                               Evas_Object* window)
193 {
194     LogDebug("enter");
195     if (!context || !window) {
196         return false;
197     }
198
199     // theme setting
200     const char *theme = elm_theme_get(NULL);
201     if (theme) {
202         m_theme = theme;
203         LogInfo("theme is " << m_theme);
204     }
205
206     // set members
207     m_ewkContext = context;
208     m_window = window;
209
210     Evas* canvas = evas_object_evas_get(m_window);
211     return createEwkView(canvas);
212 }
213
214 void ViewLogic::prepareView(WidgetModel* m, const std::string &startUrl)
215 {
216     LogDebug("View prepare");
217
218     Assert(m);
219     m_model = m;
220     m_startUrl = ViewModule::UriSupport::getUri(m_model, startUrl);
221     Assert(NULL != m_ewkContext);
222     Assert(m_window);
223
224     ADD_PROFILING_POINT("initializeSupport", "start");
225     initializeSupport();
226     ADD_PROFILING_POINT("initializeSupport", "stop");
227     setStartPage();
228     ewkClientInit(m_currentEwkView);
229     ADD_PROFILING_POINT("prepareEwkView", "start");
230     prepareEwkView(m_currentEwkView);
231     ADD_PROFILING_POINT("prepareEwkView", "stop");
232     initializePluginLoading();
233 }
234
235 void ViewLogic::showWidget()
236 {
237     LogDebug("showing widget");
238     Assert(NULL != m_currentEwkView && "ewk_view not created at this point");
239     if (m_currentUri.empty()) {
240         LogError("Localized current URI doesn't exist");
241         return;
242     }
243
244     LogInfo("m_currentUri: " << m_currentUri);
245
246     // load page
247     ewk_view_url_set(m_currentEwkView, m_currentUri.c_str());
248
249     if (!m_cbs->bufferSet.empty()) {
250         m_cbs->bufferSet(m_currentEwkView);
251     }
252 }
253
254 void ViewLogic::hideWidget()
255 {
256     LogDebug("hiding widget");
257     ViewModule::StorageSupport::deinitializeStorage(m_model);
258     m_appsSupport->deinitialize();
259
260     m_vibrationSupport->deinitialize();
261
262     while (m_ewkViewList.size()) {
263         LogInfo("pop webview: " << m_ewkViewList.back());
264         removeEwkView(m_ewkViewList.back());
265     }
266     m_ewkViewList.clear();
267 }
268
269 void ViewLogic::suspendWidget()
270 {
271     LogInfo("Pausing widget");
272     Assert(m_model);
273
274     LogDebug("Request bundle to suspend");
275     PluginModuleSupport::suspend(m_ewkContext);
276
277     if (!m_currentEwkView) {
278         LogWarning("Cannot suspend widget without view");
279     } else {
280         setEwkViewInvisible(m_currentEwkView);
281         if (!m_isBackgroundSupport) {
282             suspendWebkit(m_currentEwkView);
283         }
284     }
285
286     evas_object_focus_set(m_currentEwkView, EINA_FALSE);
287
288     // call user callback
289     if (!m_cbs->suspend.empty()) {
290         m_cbs->suspend(true);
291     }
292 }
293
294 void ViewLogic::resumeWidget()
295 {
296     LogInfo("Resume widget");
297     Assert(m_model);
298
299     LogDebug("Request bundle to resume");
300     PluginModuleSupport::resume(m_ewkContext);
301
302     if (m_currentEwkView) {
303         setEwkViewVisible(m_currentEwkView);
304         if (!m_isBackgroundSupport) {
305             resumeWebkit(m_currentEwkView);
306         }
307     }
308
309     /* window system team recomend removing this win_raise code. */
310     /*
311      * if (m_window) {
312      *  elm_win_raise(m_window);
313      * }
314      */
315     evas_object_focus_set(m_currentEwkView, EINA_TRUE);
316
317     // call user callback
318     if (!m_cbs->resume.empty()) {
319         m_cbs->resume(true);
320     }
321 }
322
323 void ViewLogic::resetWidget()
324 {
325     LogInfo("Resetting Widget");
326
327     // destory all webview
328     while (m_ewkViewList.size()) {
329         LogInfo("pop webview: " << m_ewkViewList.back());
330         removeEwkView(m_ewkViewList.back());
331     }
332     m_ewkViewList.clear();
333
334     // create new webview
335     createEwkView(evas_object_evas_get(m_window));
336     setStartPage();
337     ewkClientInit(m_currentEwkView);
338     prepareEwkView(m_currentEwkView);
339
340     // check if current url is service url for this tizen service
341     std::string requestedUri =
342         ViewModule::UriSupport::getUri(m_model, m_startUrl);
343     DPL::OptionalString servicedUri = ViewModule::UriSupport::localizeURI(
344             DPL::FromUTF8String(requestedUri.c_str()),
345             m_model);
346
347     initializePluginLoading();
348
349     // webview activated
350     PluginModuleSupport::resume(m_ewkContext);
351     m_currentUri = DPL::ToUTF8String(*servicedUri);
352     ewk_view_url_set(m_currentEwkView, m_currentUri.c_str());
353     elm_win_activate(m_window);
354     evas_object_focus_set(m_currentEwkView, EINA_TRUE);
355
356     // call user callback
357     if (!m_cbs->reset.empty()) {
358         m_cbs->reset(true);
359     }
360     if (!m_cbs->bufferSet.empty()) {
361         m_cbs->bufferSet(m_currentEwkView);
362     }
363 }
364
365 void ViewLogic::backward()
366 {
367     if (ewk_view_back_possible(m_currentEwkView)) {
368         ewk_view_back(m_currentEwkView);
369     } else {
370         if (1 >= m_ewkViewList.size()) {
371             // If there is no previous page, widget move to backgroud.
372             LogInfo("Widget move to backgroud");
373             elm_win_lower(m_window);
374         } else {
375             // Back to previous webview
376             LogInfo("Widget move to previous webview");
377             m_closedEwkView = m_currentEwkView;
378             ecore_idler_add(windowCloseIdlerCallback, this);
379         }
380     }
381 }
382
383 void ViewLogic::reloadStartPage()
384 {
385     LogInfo("Reload Start Page");
386     // prevent fail to load plugin bundle side
387     m_isBackgroundReload = true;
388     PluginModuleSupport::resume(m_ewkContext);
389
390     if (m_ewkViewList.size() != 0) {
391         while (m_ewkViewList.size() > 0) {
392             if (!m_cbs->bufferUnset.empty()) {
393                 m_cbs->bufferUnset(m_currentEwkView);
394             }
395             removeEwkView(m_currentEwkView);
396         }
397     }
398
399     // create new webview
400     createEwkView(evas_object_evas_get(m_window));
401     ewkClientInit(m_currentEwkView);
402
403     setStartPage();
404     prepareEwkView(m_currentEwkView);
405     initializePluginLoading();
406
407     // load page
408     ewk_view_url_set(m_currentEwkView, m_currentUri.c_str());
409
410     // show ewkView
411     if (!m_cbs->bufferSet.empty()) {
412         m_cbs->bufferSet(m_currentEwkView);
413     }
414     LogInfo("Reloading Start Page is done!");
415 }
416
417 Evas_Object* ViewLogic::getCurrentWebview()
418 {
419     LogInfo("get current webview");
420     return m_currentEwkView;
421 }
422
423 void ViewLogic::fireJavascriptEvent(int event, void* data)
424 {
425     PluginModuleSupport::dispatchJavaScriptEvent(
426         m_ewkContext,
427         static_cast<WrtPlugins::W3C::CustomEventType>(event),
428         data);
429 }
430
431 void ViewLogic::setUserCallbacks(const WRT::UserDelegatesPtr& cbs)
432 {
433     m_cbs = cbs;
434 }
435
436 void ViewLogic::checkSyncMessageFromBundle(
437         const char* name,
438         const char* body,
439         char** returnData)
440 {
441     LogDebug("didReceiveSynchronousMessage called");
442     Assert(name);
443     Assert(returnData);
444
445     if (!body) {
446         LogDebug("body is empty");
447         *returnData = NULL;
448         return;
449     }
450
451     LogDebug("received : " << name);
452     std::string result;
453     if (!strcmp(name, uriBlockedMessageName)) {
454         // Currently WebProcess informs obly about blocked
455         // URI - URI localization and security chekcs are
456         // done by WebProcess itself (see: wrt-wk2-bundle.cpp
457         // and bundle_uri_handling.cpp)
458         result = requestUrlBlocked(std::string(body));
459     } else if (!strcmp(name, uriChangedMessageName)) {
460         result = requestUrlChanged(std::string(body));
461     }
462
463     *returnData = strdup(result.c_str());
464 }
465
466 void ViewLogic::downloadData(const char* url)
467 {
468     LogInfo("enter");
469     if (!url) {
470         return;
471     }
472
473     m_appsSupport->downloadRequest(url, NULL, NULL);
474 }
475
476 void ViewLogic::activateVibration(bool on, uint64_t time)
477 {
478     LogInfo("enter");
479     if (on) {
480         m_vibrationSupport->startVibration(static_cast<long>(time));
481     } else {
482         m_vibrationSupport->stopVibration();
483     }
484 }
485
486 void ViewLogic::initializeSupport()
487 {
488     // background support
489     if (m_model->SettingList.Get().getBackgroundSupport()
490         == BackgroundSupport_Enable)
491     {
492         LogDebug("Background support enabled, set process active");
493         pid_t pid = getpid();
494         sysman_inform_active(pid);
495         m_isBackgroundSupport = true;
496     }
497 #ifndef DEPRECATED_SETTING_STRING
498     else {
499         WrtDB::WidgetDAOReadOnly dao(m_model->TizenId);
500         WrtDB::PropertyDAOReadOnly::WidgetPropertyValue bgEnableValue =
501             dao.getPropertyValue(DPL::String(BACKGROUND_ENABLED));
502
503         if (!bgEnableValue.IsNull() && !bgEnableValue->compare(L"true")) {
504             //skip suspendWidget
505             LogDebug("Background support enabled, set process active");
506             pid_t pid = getpid();
507             sysman_inform_active(pid);
508             m_isBackgroundSupport = true;
509         }
510     }
511 #endif
512
513     m_schemeSupport.reset(new SchemeSupport(m_model->Type.Get().appType));
514     ViewModule::StorageSupport::initializeStorage(m_model);
515     m_appsSupport->initialize(m_model);
516     m_securityOriginSupport.reset(new ViewModule::SecurityOriginSupport(m_model));
517
518     m_vibrationSupport->initialize();
519 }
520
521 void ViewLogic::initializePluginLoading()
522 {
523     // inform wrt information for plugin loading to web process
524     PluginModuleSupport::start(
525         m_ewkContext,
526         m_model->TizenId,
527         elm_config_scale_get(),
528         ApplicationDataSingleton::Instance().getEncodedBundle(),
529         m_theme.c_str(),
530         m_model->SettingList.Get().isEncrypted());
531 }
532
533 void ViewLogic::ewkClientInit(Evas_Object *wkView)
534 {
535     Assert(NULL != wkView && "ewk_view not created at this point");
536
537     FOREACH(it, m_ewkCallbacksMap) {
538         evas_object_smart_callback_add(
539             wkView,
540             it->first.c_str(),
541             it->second,
542             this);
543     }
544     // EWK Orientation Callback
545     ewk_view_orientation_lock_callback_set(
546         wkView,
547         orientationLockCallback,
548         this);
549 }
550
551 void ViewLogic::ewkClientDeinit(Evas_Object *wkView)
552 {
553     LogDebug("ewkClientDeinit");
554     Assert(NULL != wkView && "ewk_view not created at this point");
555
556     FOREACH(it, m_ewkCallbacksMap) {
557         evas_object_smart_callback_del(
558             wkView,
559             it->first.c_str(),
560             it->second);
561     }
562     ewk_view_orientation_lock_callback_set(
563         wkView,
564         NULL,
565         NULL);
566 }
567
568 bool ViewLogic::createEwkView(Evas* canvas)
569 {
570     LogDebug("createEwkVeiw");
571     Assert(canvas);
572     ADD_PROFILING_POINT("ewk_view_add_with_context", "start");
573     Evas_Object* newEwkView = ewk_view_add_with_context(
574             canvas,
575             m_ewkContext);
576     ADD_PROFILING_POINT("ewk_view_add_with_context", "stop");
577
578     if (!newEwkView) {
579         LogError("View creation failed");
580         Wrt::Popup::PopupInvoker().showInfo(
581             "Info", "View creation failed", "close");
582         return false;
583     }
584
585     // set cookie policy
586     // even arguments pass the ewkContext, this API should be called
587     // after webkit Evas_Object is created
588     Ewk_Cookie_Manager *ewkCookieManager;
589     ewkCookieManager =
590         ewk_context_cookie_manager_get(m_ewkContext);
591     ewk_cookie_manager_accept_policy_set(ewkCookieManager,
592                                          EWK_COOKIE_ACCEPT_POLICY_ALWAYS);
593
594     if (m_currentEwkView) {
595         setEwkViewInvisible(m_currentEwkView);
596     }
597
598     LogInfo("push webview: " << newEwkView);
599     m_ewkViewList.push_back(newEwkView);
600     m_currentEwkView = newEwkView;
601     return true;
602 }
603
604 void ViewLogic::setStartPage()
605 {
606     /* Start URI (as other uris) is now localized
607      * on WebProcess side */
608     m_currentUri = m_startUrl;
609 }
610
611 void ViewLogic::prepareEwkView(Evas_Object *wkView)
612 {
613     LogDebug("prepareEwkView called");
614     Assert(wkView);
615     Ewk_Settings* settings = ewk_view_settings_get(wkView);
616
617     // set user agent
618     std::string customUserAgent = m_model->SettingList.Get().getUserAgent();
619     if (customUserAgent.empty()) {
620         auto userAgentString =
621             ViewModule::UserAgentSupport::getUserAgentFromVconf();
622         if (!userAgentString.empty()) {
623             LogDebug("Setting user agent as: " << userAgentString);
624             ewk_view_user_agent_set(wkView, userAgentString.c_str());
625         }
626     } else {
627         LogDebug("Setting  custom user agent as: " << customUserAgent);
628         ewk_view_user_agent_set(wkView, customUserAgent.c_str());
629     }
630
631     // set custom header : language
632     using namespace ViewModule::CustomHeaderSupport;
633     std::string customHeaderString = getValueByField(ACCEPT_LANGUAGE);
634     if (!customHeaderString.empty()) {
635         LogDebug("custom field=[" << ACCEPT_LANGUAGE << "]");
636         LogDebug("custom value=[" << customHeaderString << "]");
637         ewk_view_custom_header_add(wkView,
638                                    ACCEPT_LANGUAGE.c_str(),
639                                    customHeaderString.c_str());
640     }
641
642     // webkit NPAPI plugins is always on in wrt
643     ewk_settings_plugins_enabled_set(settings, EINA_TRUE);
644
645     // The followings are not implemeted yet by webkit2
646     //      ewk_view_setting_accelerated_compositing_enable_set(EINA_TRUE);
647     //      ewk_view_mode_set();
648     //      ewk_view_setting_enable_specified_plugin_set(EINA_TRUE,
649     // FLASH_MIME_TYPE);
650     //      ewk_view_setting_html5video_external_player_enable_set(EINA_FALSE);
651     //      ewk_view_show_ime_on_autofocus_set(EINA_TRUE);
652     //      elm_webview_show_magnifier_set(EINA_FALSE);
653     ewk_settings_javascript_enabled_set(settings, EINA_TRUE);
654     ewk_settings_loads_images_automatically_set(settings, EINA_TRUE);
655     ewk_settings_auto_fitting_set(settings, EINA_TRUE);
656
657     // disable zoom option when user click the input field
658     // this option is useful with the normal website
659     // for the make user friendly, disable auto zoom in the webapp
660     // The followings are not implemeted yet by webkit2
661     //      elm_webview_input_field_zoom_set(EINA_FALSE);
662
663     // set cookie database path
664     // The followings are not implemeted yet by webkit2
665     //      ewk_cookies_file_set(dao.getCookieDatabasePath().c_str()));
666
667     // set visibility to WebCore. This value will be used for html5.
668     // also, this value will be changed in the suspend, resume
669     // or create window, close window.
670     ewk_view_page_visibility_state_set(wkView,
671                                        EWK_PAGE_VISIBILITY_STATE_VISIBLE,
672                                        EINA_TRUE);
673 }
674
675 void ViewLogic::removeEwkView(Evas_Object *wkView)
676 {
677     LogInfo("removeEwkView called");
678     Assert(wkView);
679     Assert(0 != m_ewkViewList.size());
680
681     // unregister webview callbacks
682     ewkClientDeinit(wkView);
683
684     // suspend NPAPI plugin - Not implemented by Webkit2
685     //    ewk_view_pause_or_resume_plugins();
686     evas_object_del(wkView);
687     m_ewkViewList.remove(wkView);
688 }
689
690 void ViewLogic::resumeEwkView(Evas_Object *wkView)
691 {
692     LogInfo("resumeEwkView called");
693     Assert(wkView);
694
695     // register webview callback
696     ewkClientInit(wkView);
697
698     // resume webkit
699     resumeWebkit(wkView);
700
701     return;
702 }
703
704 void ViewLogic::suspendEwkView(Evas_Object *wkView)
705 {
706     LogInfo("suspendEwkView called");
707     Assert(wkView);
708
709     // suspend webkit
710     suspendWebkit(wkView);
711
712     // unregister webview callbacks
713     ewkClientDeinit(wkView);
714
715     return;
716 }
717
718 void ViewLogic::setEwkViewInvisible(Evas_Object *wkView)
719 {
720     LogInfo("setEwkViewInvisible called");
721     Assert(wkView);
722
723     ewk_view_page_visibility_state_set(wkView,
724                                        EWK_PAGE_VISIBILITY_STATE_HIDDEN,
725                                        EINA_FALSE);
726     ewk_view_visibility_set(wkView, EINA_FALSE);
727 }
728
729 void ViewLogic::setEwkViewVisible(Evas_Object *wkView)
730 {
731     LogInfo("setEwkViewVisible called");
732     Assert(wkView);
733
734     ewk_view_page_visibility_state_set(wkView,
735                                        EWK_PAGE_VISIBILITY_STATE_VISIBLE,
736                                        EINA_FALSE);
737     ewk_view_visibility_set(wkView, EINA_TRUE);
738 }
739
740 void ViewLogic::resumeWebkit(Evas_Object *wkView)
741 {
742     LogDebug("resumeWebkit");
743     Assert(wkView);
744
745     // resume NPAPI plugin
746     // The followings are not implemeted yet by webkit2
747     //      ewk_view_pause_or_resume_plugins(false);
748     //      ewk_view_pause_or_resume_video_audio(false);
749     //      ewk_view_javascript_resume();
750     //      ewk_view_enable_render();
751     //      ewk_view_reduce_plugins_frame_rate(false);
752     ewk_view_resume(wkView);
753
754     return;
755 }
756
757 void ViewLogic::suspendWebkit(Evas_Object *wkView)
758 {
759     LogDebug("suspendWebkit");
760     Assert(wkView);
761
762     // suspend the followings
763     // The followings are not implemeted yet by webkit2
764     //      ewk_view_pause_or_resume_plugins(true);
765     //      ewk_view_pause_or_resume_video_audio(true);
766     ewk_view_suspend(wkView);
767
768     return;
769 }
770
771 void ViewLogic::loadStartedCallback(
772     void* data,
773     Evas_Object* obj,
774     void* /*eventInfo*/)
775 {
776     LogDebug("loadStartedCallback called");
777     Assert(data);
778     ViewLogic* This = static_cast<ViewLogic*>(data);
779     evas_object_focus_set(This->m_currentEwkView, EINA_TRUE);
780
781     // call loadFinish callback to wrt-client
782     if (!This->m_cbs->loadStart.empty()) {
783         This->m_cbs->loadStart(obj);
784     }
785 }
786
787 void ViewLogic::loadFinishedCallback(
788     void* data,
789     Evas_Object* obj,
790     void* /*eventInfo*/)
791 {
792     LogDebug("loadFinishedCallback called");
793     Assert(data);
794     ViewLogic* This = static_cast<ViewLogic*>(data);
795
796     // Fill id/password
797     const char* url = ewk_view_url_get(This->m_currentEwkView);
798     if (NULL == url || strlen(url) == 0) {
799         LogError("url is empty");
800         return;
801     }
802
803     // check if this loading is for blocked url
804     if (This->m_blockedUri == url) {
805         if (ewk_view_back_possible(This->m_currentEwkView)) {
806             // go back to previous page
807             LogDebug("go to previous page");
808             ewk_view_back(This->m_currentEwkView);
809         } else {
810             // stop current page
811             LogDebug("remove current page");
812             ewk_view_stop(This->m_currentEwkView);
813             ecore_idler_add(windowCloseIdlerCallback, This);
814         }
815         This->m_blockedUri = std::string();
816         return;
817     }
818
819     DPL::OptionalString jsOptionalString =
820         ViewModule::PasswordSupport::jsForAutoFillData(url);
821     if (jsOptionalString.IsNull()) {
822         LogError("Fail to get JS String");
823     } else {
824         std::string jsStr = DPL::ToUTF8String(*jsOptionalString).c_str();
825
826         if (EINA_FALSE == ewk_view_script_execute(
827                 This->m_currentEwkView,
828                 jsStr.c_str(),
829                 didRunJavaScriptCallback,
830                 This))
831         {
832             LogError("JS for auto fill data failed.");
833         }
834     }
835
836     // call loadFinish callback to wrt-client
837     if (!This->m_cbs->loadFinish.empty()) {
838         This->m_cbs->loadFinish(obj);
839     }
840
841     // set only encoded bundle
842     double scale = elm_config_scale_get();
843     PluginModuleSupport::setCustomProperties(
844         This->m_ewkContext,
845         &scale,
846         ApplicationDataSingleton::Instance().getEncodedBundle());
847     // check if 'appsevice' event is registed at the current frames.
848     // If so, dispatch the event to frames.
849     PluginModuleSupport::dispatchJavaScriptEvent(
850         This->m_ewkContext,
851         WrtPlugins::W3C::ServiceCustomEvent,
852         NULL);
853
854     // In this case, widget is reloaded in the background.
855     // After finished load, bundle should disconnent callback.
856     if (This->m_isBackgroundReload) {
857         PluginModuleSupport::suspend(This->m_ewkContext);
858         ewk_view_suspend(This->m_currentEwkView);
859         This->m_isBackgroundReload = false;
860     }
861 }
862
863 void ViewLogic::titleChangedCallback(
864     void* data,
865     Evas_Object* /*obj*/,
866     void* eventInfo)
867 {
868     LogDebug("titleChangedCallback called");
869     Assert(data);
870     ViewLogic* This = static_cast<ViewLogic*>(data);
871     Assert(eventInfo);
872     const char* title = static_cast<char*>(eventInfo);
873
874     if (0 == strlen(title)) {
875         LogDebug("title data is empty");
876         return;
877     }
878     LogDebug("Title = [" << title << "]");
879     This->m_schemeSupport->HandleTizenScheme(title,
880                                              This->m_window,
881                                              This->m_currentEwkView);
882 }
883
884 void ViewLogic::loadProgressCallback(
885     void* /*data*/,
886     Evas_Object* /*obj*/,
887     void* eventInfo)
888 {
889     double* progress = static_cast<double*>(eventInfo);
890     LogDebug("didChangeProgressCallback progress = " << *progress);
891 }
892
893 void ViewLogic::loadProgressFinishedCallback(
894     void* data,
895     Evas_Object* /*obj*/,
896     void* /*eventInfo*/)
897 {
898     LogDebug("didFinishProgressCallback");
899     Assert(data);
900     ViewLogic const * const view = static_cast<ViewLogic const * const>(data);
901     if (!view->m_cbs->progressFinish.empty()) {
902         view->m_cbs->progressFinish();
903     }
904 }
905
906 void ViewLogic::processCrashedCallback(
907     void* data,
908     Evas_Object* /*obj*/,
909     void* eventInfo)
910 {
911     LogInfo("processCrashedCallback");
912     Assert(data);
913     ViewLogic const * const view =
914         static_cast<ViewLogic const * const>(data);
915     if (!view->m_cbs->webCrash.empty()) {
916         view->m_cbs->webCrash();
917     }
918     // This flag will be prevented exit() call in the Webkit side
919     if (NULL != eventInfo) {
920         *(static_cast<Eina_Bool*>(eventInfo)) = EINA_TRUE;
921     }
922 }
923
924 void ViewLogic::createWindowCallback(
925     void* data,
926     Evas_Object* obj,
927     void* eventInfo)
928 {
929     LogDebug("createWindowCallback");
930     Assert(data);
931     ViewLogic* This = static_cast<ViewLogic*>(data);
932
933     // First, current webview should be handled by user callback
934     if (!This->m_cbs->bufferUnset.empty()) {
935         This->m_cbs->bufferUnset(obj);
936     }
937
938     // this can be set by executable for specific purpose
939     Evas* canvas = NULL;
940     if (!This->m_cbs->windowCreateBefore.empty()) {
941         // 'obj' is parent webview object
942         This->m_cbs->windowCreateBefore(&canvas, obj);
943     }
944     if (!canvas) {
945         canvas = evas_object_evas_get(This->m_window);
946     }
947
948     // create new ewkview
949     This->createEwkView(canvas);
950     Evas_Object* newEwkView = This->m_currentEwkView;
951
952     // initialize new ewkview
953     This->setStartPage();
954     This->ewkClientInit(newEwkView);
955     This->prepareEwkView(newEwkView);
956
957     // Specific jobs of child, parent webview are handled by each executable
958     if (!This->m_cbs->windowCreateAfter.empty()) {
959         // 'obj' is parent webview, 'newEwkView' is child webview
960         This->m_cbs->windowCreateAfter(obj, newEwkView);
961     }
962
963     // Lastly, new webview should be handled by user callback
964     if (!This->m_cbs->bufferSet.empty()) {
965         This->m_cbs->bufferSet(newEwkView);
966     }
967     *(static_cast<Evas_Object **>(eventInfo)) = newEwkView;
968 }
969
970 void ViewLogic::closeWindowCallback(
971     void* data,
972     Evas_Object* obj,
973     void* /*eventInfo*/)
974 {
975     LogDebug("closeWindowCallback");
976     ViewLogic* This = static_cast<ViewLogic*>(data);
977     This->m_closedEwkView = obj;
978     ecore_idler_add(windowCloseIdlerCallback, This);
979 }
980
981 void ViewLogic::policyNavigationDecideCallback(
982     void* data,
983     Evas_Object* /*obj*/,
984     void* eventInfo)
985 {
986     LogDebug("policyNavigationDecideCallback called");
987     Assert(data);
988     ViewLogic* This = static_cast<ViewLogic*>(data);
989     Assert(eventInfo);
990     Ewk_Policy_Decision* policyDecision =
991         static_cast<Ewk_Policy_Decision*>(eventInfo);
992
993     if (This->m_schemeSupport->filterURIByScheme(policyDecision,
994                                                  false,
995                                                  This->m_model,
996                                                  This->m_window,
997                                                  This->m_currentEwkView))
998     {
999         LogDebug("use");
1000         ewk_policy_decision_use(policyDecision);
1001     } else {
1002         // check whether this is new empty window
1003         const char* activeUrl = ewk_view_url_get(This->m_currentEwkView);
1004         if (!activeUrl || 0 == strlen(activeUrl)) {
1005             /*
1006              * The view is empty and scheme has been handled externally. When
1007              * user gets back from the external application he'd see blank page
1008              * and won't be able to navigate back. This happens when window.open
1009              * is used to handle schemes like sms/mms/mailto (for example in
1010              * WAC web standards tests: WS-15XX).
1011              *
1012              * To solve the problem, the empty view is removed from the stack
1013              * and the previous one is shown. This is not an elegant solution
1014              * but we don't have a better one.
1015              */
1016             LogInfo("Scheme has been handled externally. Removing empty view.");
1017             if (ewk_view_back_possible(This->m_currentEwkView)) {
1018                 // go back to previous WKPage
1019                 ewk_view_back(This->m_currentEwkView);
1020             } else {
1021                 // stop current WKPage
1022                 ewk_view_stop(This->m_currentEwkView);
1023                 ecore_idler_add(windowCloseIdlerCallback, This);
1024             }
1025         }
1026
1027         LogDebug("ignore");
1028         ewk_policy_decision_ignore(policyDecision);
1029     }
1030 }
1031
1032 void ViewLogic::policyNewWindowDecideCallback(
1033     void* data,
1034     Evas_Object* /*obj*/,
1035     void* eventInfo)
1036 {
1037     LogDebug("policyNewWindowDecideCallback called");
1038     Assert(data);
1039     ViewLogic* This = static_cast<ViewLogic*>(data);
1040     Assert(eventInfo);
1041     Ewk_Policy_Decision* policyDecision =
1042         static_cast<Ewk_Policy_Decision*>(eventInfo);
1043
1044     if (This->m_schemeSupport->filterURIByScheme(policyDecision,
1045                                                  true,
1046                                                  This->m_model,
1047                                                  This->m_window,
1048                                                  This->m_currentEwkView))
1049     {
1050         ewk_policy_decision_use(policyDecision);
1051     } else {
1052         // scheme handled
1053         ewk_policy_decision_ignore(policyDecision);
1054     }
1055 }
1056
1057 void ViewLogic::pageResponseDecideCallback(
1058     void* data,
1059     Evas_Object* /*obj*/,
1060     void* eventInfo)
1061 {
1062     LogDebug("pageResponseDecideCallback called");
1063     Assert(data);
1064     ViewLogic* This = static_cast<ViewLogic*>(data);
1065     Assert(eventInfo);
1066     Ewk_Policy_Decision* policyDecision =
1067         static_cast<Ewk_Policy_Decision*>(eventInfo);
1068     Ewk_Policy_Decision_Type policyDecisionType =
1069         ewk_policy_decision_type_get(policyDecision);
1070
1071     if (policyDecisionType == EWK_POLICY_DECISION_USE) {
1072         LogDebug("use");
1073         ewk_policy_decision_use(policyDecision);
1074     } else if (policyDecisionType == EWK_POLICY_DECISION_DOWNLOAD) {
1075         LogDebug("download");
1076         ewk_policy_decision_suspend(policyDecision);
1077
1078         // get uri information
1079         const char* url = ewk_policy_decision_url_get(policyDecision);
1080         if (NULL == url || strlen(url) == 0) {
1081             LogDebug("url data is empty");
1082             ewk_policy_decision_use(policyDecision);
1083             return;
1084         }
1085         LogDebug("url = [" << url << "]");
1086
1087         // get content information
1088         const char* content =
1089             ewk_policy_decision_response_mime_get(policyDecision);
1090         LogDebug("content type = [" << content << "]");
1091
1092         // get cookie information
1093         const char* cookie = ewk_policy_decision_cookie_get(policyDecision);
1094         LogDebug("cookie = [" << cookie << "]");
1095
1096         LogDebug("Content not supported, will be opened in external app");
1097         This->m_appsSupport->downloadRequest(
1098             url,
1099             content,
1100             cookie);
1101         ewk_policy_decision_ignore(policyDecision);
1102     } else if (policyDecisionType == EWK_POLICY_DECISION_IGNORE) {
1103         LogDebug("ignore");
1104         ewk_policy_decision_ignore(policyDecision);
1105     } else {
1106         LogDebug("Type isn't handled");
1107         ewk_policy_decision_ignore(policyDecision);
1108     }
1109 }
1110
1111 void ViewLogic::contextmenuCustomizeCallback(
1112     void* data,
1113     Evas_Object* /*obj*/,
1114     void* eventInfo)
1115 {
1116     LogDebug("contextmenuCustomizeCallback called");
1117     Assert(data);
1118     Assert(eventInfo);
1119     ViewLogic* This = static_cast<ViewLogic*>(const_cast<void*>(data));
1120     Ewk_Context_Menu* menu = static_cast<Ewk_Context_Menu*>(eventInfo);
1121     if ((This->m_model->Type.Get().appType == WrtDB::APP_TYPE_TIZENWEBAPP) &&
1122         (This->m_model->SettingList.Get().getContextMenu()
1123          == ContextMenu_Disable))
1124     {
1125         LogDebug("ContextMenu Disable!!");
1126         for (unsigned int idx = 0; idx < ewk_context_menu_item_count(menu);) {
1127             Ewk_Context_Menu_Item* item = ewk_context_menu_nth_item_get(menu,
1128                                                                         idx);
1129             Assert(item);
1130             ewk_context_menu_item_remove(menu, item);
1131         }
1132     } else {
1133         LogDebug("ContextMenu Enable!!");
1134         unsigned int menu_num = ewk_context_menu_item_count(menu);
1135         unsigned int idx = 0;
1136         do {
1137             Ewk_Context_Menu_Item* item = ewk_context_menu_nth_item_get(menu,
1138                                                                         idx);
1139             if (!item) {
1140                 idx++;
1141                 continue;
1142             }
1143             Ewk_Context_Menu_Item_Tag tag = ewk_context_menu_item_tag_get(item);
1144
1145             switch (tag) {
1146             case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_IMAGE_IN_NEW_WINDOW:
1147                 ewk_context_menu_item_remove(menu, item);
1148                 continue;
1149
1150             case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_LINK_IN_NEW_WINDOW:
1151                 ewk_context_menu_item_remove(menu, item);
1152                 continue;
1153
1154             case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_FRAME_IN_NEW_WINDOW:
1155                 ewk_context_menu_item_remove(menu, item);
1156                 continue;
1157
1158             case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_MEDIA_IN_NEW_WINDOW:
1159                 ewk_context_menu_item_remove(menu, item);
1160                 continue;
1161
1162             case EWK_CONTEXT_MENU_ITEM_TAG_SEARCH_WEB:
1163                 ewk_context_menu_item_remove(menu, item);
1164                 continue;
1165
1166             default:
1167                 idx++;
1168                 break;
1169             }
1170         } while (idx < menu_num);
1171     }
1172 }
1173
1174 void ViewLogic::formSubmitCallback(
1175     void* /*data*/,
1176     Evas_Object* /*obj*/,
1177     void* eventInfo)
1178 {
1179     LogDebug("formSubmitCallback called");
1180     Assert(eventInfo);
1181     Ewk_Form_Data* formData = static_cast<Ewk_Form_Data*>(eventInfo);
1182
1183     const char* uri = ewk_form_data_url_get(formData);
1184     if (!uri) {
1185         LogError("URL is empty");
1186         return;
1187     }
1188
1189     Eina_Hash* userData = ewk_form_data_values_get(formData);
1190     ViewModule::PasswordSupport::submitClicked(uri, userData);
1191 }
1192
1193 void ViewLogic::geolocationPermissionRequestCallback(
1194     void* data,
1195     Evas_Object* /*obj*/,
1196     void* eventInfo)
1197 {
1198     Assert(data);
1199     ViewLogic* This = static_cast<ViewLogic*>(data);
1200     Assert(eventInfo);
1201     Ewk_Geolocation_Permission_Data* permissionRequest =
1202         static_cast<Ewk_Geolocation_Permission_Data*>(eventInfo);
1203
1204     if (This->m_securityOriginSupport->isNeedPermissionCheck(
1205             SecurityOriginDB::FEATURE_GEOLOCATION)
1206         == WrtDB::SETTINGS_TYPE_OFF)
1207     {
1208         ewk_geolocation_permission_request_allow_set(
1209             ewk_geolocation_permission_request_get(permissionRequest),
1210             EINA_FALSE);
1211         return;
1212     }
1213     ViewModule::GeolocationSupport::Webkit2::geolocationPermissionRequest(
1214         This->m_window,
1215         This->m_securityOriginSupport->getSecurityOriginDAO(),
1216         eventInfo);
1217 }
1218
1219 void ViewLogic::notificationShowCallback(
1220     void* data,
1221     Evas_Object* /*obj*/,
1222     void* eventInfo)
1223 {
1224     LogDebug("notificationShowCallback called");
1225     Assert(data);
1226     ViewLogic* This = static_cast<ViewLogic*>(data);
1227
1228     Assert(eventInfo);
1229     Ewk_Notification* noti = static_cast<Ewk_Notification*>(eventInfo);
1230
1231     using namespace ViewModule::WebNotification;
1232
1233     WebNotificationDataPtr notiData(
1234         new WebNotificationData(
1235             This->m_model,
1236             ewk_notification_id_get(noti)));
1237
1238     DPL::OptionalString string =
1239         DPL::FromUTF8String(ewk_notification_icon_url_get(noti));
1240     if (!string.IsNull()) {
1241         notiData->m_iconURL = DPL::ToUTF8String(*string);
1242     }
1243     string = DPL::FromUTF8String(ewk_notification_title_get(noti));
1244     if (!string.IsNull()) {
1245         notiData->m_title = DPL::ToUTF8String(*string);
1246     }
1247     string = DPL::FromUTF8String(ewk_notification_body_get(noti));
1248     if (!string.IsNull()) {
1249         notiData->m_body = DPL::ToUTF8String(*string);
1250     }
1251
1252     LogInfo("notification id : " << notiData->m_id);
1253     LogInfo("notification iconURL : " << notiData->m_iconURL);
1254     LogInfo("notification title : " << notiData->m_title);
1255     LogInfo("notification body : " << notiData->m_body);
1256
1257     showWebNotification(notiData);
1258     ewk_notification_showed(This->m_ewkContext, ewk_notification_id_get(noti));
1259 }
1260
1261 void ViewLogic::notificationCancelCallback(
1262     void* /*data*/,
1263     Evas_Object* /*obj*/,
1264     void* /*eventInfo*/)
1265 {
1266     LogDebug("notificationCancelCallback called");
1267 }
1268
1269 void ViewLogic::notificationPermissionRequestCallback(
1270     void* data,
1271     Evas_Object* /*obj*/,
1272     void* eventInfo)
1273 {
1274     LogDebug("notificationPermissionRequestCallback called");
1275     Assert(data);
1276     ViewLogic* This = static_cast<ViewLogic*>(data);
1277     if (This->m_securityOriginSupport->isNeedPermissionCheck(
1278             SecurityOriginDB::FEATURE_WEB_NOTIFICATION)
1279         == WrtDB::SETTINGS_TYPE_OFF)
1280     {
1281         Ewk_Notification_Permission_Request* request =
1282             static_cast<Ewk_Notification_Permission_Request*>(eventInfo);
1283         ewk_notification_permission_request_response(
1284             This->m_ewkContext,
1285             request,
1286             EINA_FALSE);
1287         return;
1288     }
1289
1290     Assert(eventInfo);
1291     ViewModule::WebNotification::webNotificationPermissionRequest(
1292         This->m_window,
1293         This->m_securityOriginSupport->getSecurityOriginDAO(),
1294         This->m_ewkContext,
1295         eventInfo);
1296     return;
1297 }
1298
1299 // EWK Orientation Callback
1300 Eina_Bool ViewLogic::orientationLockCallback(
1301     Evas_Object* obj,
1302     Eina_Bool /*needLock*/,
1303     int orientation,
1304     void* data)
1305 {
1306     LogDebug("orientationLockCallback called");
1307     Assert(data);
1308     ViewLogic* This = static_cast<ViewLogic*>(data);
1309
1310     if (orientation & EWK_SCREEN_ORIENTATION_PORTRAIT_PRIMARY) {
1311         LogDebug("orientation is portrait-primary");
1312         elm_win_rotation_with_resize_set(This->m_window, 0);
1313         ewk_view_orientation_send(obj, 0);
1314     } else if (orientation & EWK_SCREEN_ORIENTATION_LANDSCAPE_PRIMARY) {
1315         LogDebug("orientation is landscape-primary");
1316         elm_win_rotation_with_resize_set(This->m_window, 270);
1317         ewk_view_orientation_send(obj, 90);
1318     } else if (orientation & EWK_SCREEN_ORIENTATION_PORTRAIT_SECONDARY) {
1319         LogDebug("orientation is portrait-secondary");
1320         elm_win_rotation_with_resize_set(This->m_window, 180);
1321         ewk_view_orientation_send(obj, 180);
1322     } else if (orientation & EWK_SCREEN_ORIENTATION_LANDSCAPE_SECONDARY) {
1323         LogDebug("orientation is landscape-secondary");
1324         elm_win_rotation_with_resize_set(This->m_window, 90);
1325         ewk_view_orientation_send(obj, -90);
1326     } else {
1327         LogDebug("Wrong orientation is set");
1328         return EINA_FALSE;
1329     }
1330     return EINA_TRUE;
1331 }
1332
1333 // Fullscreen API callbacks
1334 void ViewLogic::enterFullscreenCallback(
1335     void* data,
1336     Evas_Object* /*obj*/,
1337     void* /*eventInfo*/)
1338 {
1339     LogInfo("enterFullscreenCallback called");
1340     Assert(data);
1341     ViewLogic* This = static_cast<ViewLogic*>(data);
1342     if (!This->m_cbs->toggleFullscreen.empty()) {
1343         This->m_cbs->toggleFullscreen(true);
1344     }
1345 }
1346 void ViewLogic::exitFullscreenCallback(
1347     void* data,
1348     Evas_Object* /*obj*/,
1349     void* /*eventInfo*/)
1350 {
1351     LogInfo("exitFullscreenCallback called");
1352     Assert(data);
1353     ViewLogic* This = static_cast<ViewLogic*>(data);
1354     if (!This->m_cbs->toggleFullscreen.empty()) {
1355         This->m_cbs->toggleFullscreen(false);
1356     }
1357 }
1358
1359 void ViewLogic::imeChangedCallback(
1360     void* data,
1361     Evas_Object* /*obj*/,
1362     void* eventInfo)
1363 {
1364     LogDebug("enter");
1365     Assert(data);
1366     Assert(eventInfo);
1367     ViewLogic* This = static_cast<ViewLogic*>(data);
1368     Eina_Rectangle *rect = static_cast<Eina_Rectangle *>(eventInfo);
1369     This->m_imeWidth = rect->w;
1370     This->m_imeHeight = rect->h;
1371 }
1372
1373 void ViewLogic::imeOpenedCallback(
1374     void* data,
1375     Evas_Object* /*obj*/,
1376     void* /*eventInfo*/)
1377 {
1378     LogDebug("enter");
1379     Assert(data);
1380     ViewLogic* This = static_cast<ViewLogic*>(data);
1381
1382     using namespace WrtPlugins::W3C;
1383     SoftKeyboardChangeArgs args;
1384     args.state = IME_STATE_ON;
1385     args.width = This->m_imeWidth;
1386     args.height = This->m_imeHeight;
1387     This->fireJavascriptEvent(
1388         static_cast<int>(SoftKeyboardChangeCustomEvent),
1389         &args);
1390 }
1391
1392 void ViewLogic::imeClosedCallback(
1393     void* data,
1394     Evas_Object* /*obj*/,
1395     void* /*eventInfo*/)
1396 {
1397     LogDebug("enter");
1398     Assert(data);
1399     ViewLogic* This = static_cast<ViewLogic*>(data);
1400
1401     using namespace WrtPlugins::W3C;
1402     SoftKeyboardChangeArgs args;
1403     args.state = IME_STATE_OFF;
1404
1405     This->fireJavascriptEvent(
1406         static_cast<int>(SoftKeyboardChangeCustomEvent),
1407         &args);
1408 }
1409
1410 void ViewLogic::usermediaPermissionRequestCallback(
1411     void* data,
1412     Evas_Object* /*obj*/,
1413     void* eventInfo)
1414 {
1415     LogDebug("usermediaPermissionRequestCallback called");
1416     Assert(data);
1417     ViewLogic* This = static_cast<ViewLogic*>(data);
1418     ViewModule::UsermediaSupport::usermediaPermissionRequest(This->m_window,
1419                                                              eventInfo);
1420 }
1421
1422 // helper method
1423 CustomHandlerDB::CustomHandlerPtr getCustomHandlerFromData(void* data)
1424 {
1425     Assert(data);
1426     Ewk_Custom_Handlers_Data* handler =
1427         static_cast<Ewk_Custom_Handlers_Data*>(data);
1428     CustomHandlerDB::CustomHandlerPtr customHandler(
1429         new CustomHandlerDB::CustomHandler());
1430     const char* base_url = ewk_custom_handlers_data_base_url_get(handler);
1431     if (base_url) {
1432         LogDebug("base url: " << base_url);
1433         customHandler->base_url = DPL::FromASCIIString(string(base_url));
1434     }
1435     const char* url = ewk_custom_handlers_data_url_get(handler);
1436     if (url) {
1437         LogDebug("url: " << url);
1438         customHandler->url = DPL::FromASCIIString(string(url));
1439     }
1440     const char* target = ewk_custom_handlers_data_target_get(handler);
1441     if (target) {
1442         LogDebug("target: " << target);
1443         customHandler->target = DPL::FromASCIIString(string(target));
1444     }
1445     const char* title = ewk_custom_handlers_data_title_get(handler);
1446     if (title) {
1447         LogDebug("title: " << title);
1448         customHandler->title = DPL::FromASCIIString(string(title));
1449     }
1450     return customHandler;
1451 }
1452
1453 void ViewLogic::attachToCustomHandlersDao()
1454 {
1455     if (!m_attachedToCustomHandlerDao) {
1456         CustomHandlerDB::Interface::attachDatabaseRW();
1457     }
1458 }
1459
1460 void ViewLogic::detachFromCustomHandlersDao()
1461 {
1462     if (m_attachedToCustomHandlerDao) {
1463         CustomHandlerDB::Interface::detachDatabase();
1464     }
1465 }
1466
1467 const int protocolWhiteListLenth = 15;
1468 char const * const protocolWhiteList[protocolWhiteListLenth] = {
1469     "irc",
1470     "geo",
1471     "mailto",
1472     "magnet",
1473     "mms",
1474     "news",
1475     "nntp",
1476     "sip",
1477     "sms",
1478     "smsto",
1479     "ssh",
1480     "tel",
1481     "urn",
1482     "webcal",
1483     "xmpp"
1484 };
1485
1486 const int contentBlackListLenth = 14;
1487 char const * const contentBlackList[contentBlackListLenth] = {
1488     "application/x-www-form-urlencoded",
1489     "application/xhtml+xml",
1490     "application/xml",
1491     "image/gif",
1492     "image/jpeg",
1493     "image/png",
1494     "image/svg+xml",
1495     "multipart/x-mixed-replace",
1496     "text/cache-manifest",
1497     "text/css",
1498     "text/html",
1499     "text/ping",
1500     "text/plain",
1501     "text/xml"
1502 };
1503
1504 /**
1505  * Saves user's response from popup to custom handler. Saves Yes/No and remember
1506  * state.
1507  * @param response
1508  * @param customHandler
1509  */
1510 void saveUserResponse(Wrt::Popup::PopupResponse response,
1511                       CustomHandlerDB::CustomHandlerPtr customHandler)
1512 {
1513     switch (response) {
1514     case Wrt::Popup::YES_DO_REMEMBER:
1515         LogDebug("User allowed, remember");
1516         customHandler->user_decision =
1517             static_cast<CustomHandlerDB::HandlerState>
1518             (CustomHandlerDB::Agreed | CustomHandlerDB::DecisionSaved);
1519         break;
1520     case Wrt::Popup::YES_DONT_REMEMBER:
1521         LogDebug("User allowed, don't remember");
1522         customHandler->user_decision = CustomHandlerDB::Agreed;
1523         break;
1524     case Wrt::Popup::NO_DO_REMEMBER:
1525         LogDebug("User didn't allow, remember");
1526         customHandler->user_decision =
1527             static_cast<CustomHandlerDB::HandlerState>
1528             (CustomHandlerDB::Declined | CustomHandlerDB::DecisionSaved);
1529         break;
1530     case Wrt::Popup::NO_DONT_REMEMBER:
1531         LogDebug("User didn't allow, don't remember");
1532         customHandler->user_decision = CustomHandlerDB::Declined;
1533         break;
1534     }
1535 }
1536
1537 //TODO registration, checking if registered and unregistration can be done in
1538 //common functions for both types of handlers. Only white and black lists
1539 //have to be separated
1540 //TODO attach database only one at the start (not in every callback?)
1541 void ViewLogic::protocolHandlerRegistrationCallback(void* data,
1542                                                     Evas_Object* /*obj*/,
1543                                                     void* eventInfo)
1544 {
1545     Assert(data);
1546     LogDebug("enter");
1547     CustomHandlerDB::CustomHandlerPtr customHandler =
1548         getCustomHandlerFromData(eventInfo);
1549
1550     std::string scheme = DPL::ToUTF8String(customHandler->target);
1551     if (scheme.empty()) {
1552         LogError("No scheme provided");
1553         //TODO what about securityError?
1554         return;
1555     }
1556     bool matched = false;
1557     //scheme on whiteList
1558     for (int i = 0; i < protocolWhiteListLenth; ++i) {
1559         if (0 == strcmp(protocolWhiteList[i], scheme.c_str())) {
1560             LogDebug("Match found, protocol can be handled");
1561             matched = true;
1562         }
1563     }
1564     if (!matched) {
1565         //starts with web+ and have at least 5 chars (lowercase ASCII)
1566         if (strncmp("web+", scheme.c_str(), 4) || scheme.length() < 5) {
1567             LogWarning("Scheme neither on whitelist nor starts with \"web+\"");
1568             //throw SecurityException
1569             return;
1570         }
1571         int l = 4;
1572         char c = scheme[l];
1573         while (c != '\0') {
1574             if (c < 'a' || c > 'z') {
1575                 LogWarning("Wrong char inside scheme. "
1576                            << "Only lowercase ASCII letters accepted");
1577                 //throw SecurityException
1578                 return;
1579             }
1580             c = scheme[++l];
1581         }
1582     }
1583
1584     ViewLogic* This = static_cast<ViewLogic*>(data);
1585     LogDebug("Creating handlers dao");
1586     This->attachToCustomHandlersDao();
1587     CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1588     CustomHandlerDB::CustomHandlerPtr handler =
1589         handlersDao.getProtocolHandler(customHandler->target,
1590                                        customHandler->url,
1591                                        customHandler->base_url);
1592     if (handler && (handler->user_decision & CustomHandlerDB::DecisionSaved)) {
1593         LogDebug("Protocol already registered - nothing to do");
1594     } else {
1595         LogDebug("Protocol handler not found");
1596         Wrt::Popup::PopupResponse response =
1597             GlobalSettings::PopupsTestModeEnabled() ? Wrt::Popup::
1598                 YES_DO_REMEMBER :
1599             Wrt::Popup::PopupInvoker().askYesNoCheckbox(
1600                 PROTOCOL_HANDLER_ASK_TITLE,
1601                 PROTOCOL_HANDLER_ASK_MSG,
1602                 PROTOCOL_HANDLER_ASK_REMEMBER);
1603         saveUserResponse(response, customHandler);
1604         if (customHandler->user_decision == CustomHandlerDB::Declined) {
1605             return;
1606         }
1607         handlersDao.registerProtocolHandler(*(customHandler.get()));
1608         if (customHandler->user_decision & CustomHandlerDB::Agreed) {
1609             //TODO remove old default handler somehow from appsvc
1610             LogDebug("Registering appservice entry");
1611             int ret = appsvc_set_defapp(APPSVC_OPERATION_VIEW,
1612                                         NULL,
1613                                         DPL::ToUTF8String(
1614                                             customHandler->target).c_str(),
1615                                         DPL::ToUTF8String(This->m_model->
1616                                                               TizenId).c_str());
1617             if (APPSVC_RET_OK != ret) {
1618                 LogWarning("Appsvc entry failed: " << ret);
1619             }
1620         }
1621         LogDebug("Protocal saved");
1622     }
1623
1624     This->detachFromCustomHandlersDao();
1625 }
1626
1627 void ViewLogic::protocolHandlerIsRegisteredCallback(void* data,
1628                                                     Evas_Object* /*obj*/,
1629                                                     void* eventInfo)
1630 {
1631     LogDebug("enter");
1632     CustomHandlerDB::CustomHandlerPtr customHandler = getCustomHandlerFromData(
1633             eventInfo);
1634     ViewLogic* This = static_cast<ViewLogic*>(data);
1635     LogDebug("Creating handlers dao");
1636     This->attachToCustomHandlersDao();
1637     CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1638     CustomHandlerDB::CustomHandlerPtr handler =
1639         handlersDao.getProtocolHandler(customHandler->target,
1640                                        customHandler->url,
1641                                        customHandler->base_url);
1642     if (handler) {
1643         if (handler->user_decision & CustomHandlerDB::Agreed) {
1644             ewk_custom_handlers_data_result_set(
1645                 static_cast<Ewk_Custom_Handlers_Data*>(data),
1646                 EWK_CUSTOM_HANDLERS_REGISTERED);
1647         } else {
1648             ewk_custom_handlers_data_result_set(
1649                 static_cast<Ewk_Custom_Handlers_Data*>(data),
1650                 EWK_CUSTOM_HANDLERS_DECLINED);
1651         }
1652     } else {
1653         ewk_custom_handlers_data_result_set(
1654             static_cast<Ewk_Custom_Handlers_Data*>(data),
1655             EWK_CUSTOM_HANDLERS_NEW);
1656     }
1657     This->detachFromCustomHandlersDao();
1658 }
1659
1660 void ViewLogic::protocolHandlerUnregistrationCallback(void* data,
1661                                                       Evas_Object* /*obj*/,
1662                                                       void* eventInfo)
1663 {
1664     LogDebug("enter");
1665     CustomHandlerDB::CustomHandlerPtr customHandler =
1666         getCustomHandlerFromData(eventInfo);
1667     ViewLogic* This = static_cast<ViewLogic*>(data);
1668     LogDebug("Creating handlers dao");
1669     This->attachToCustomHandlersDao();
1670     CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1671     CustomHandlerDB::CustomHandlerPtr handlerCheck =
1672         handlersDao.getProtocolHandler(customHandler->target,
1673                                        customHandler->url,
1674                                        customHandler->base_url);
1675     if (handlerCheck) {
1676         if (handlerCheck->user_decision & CustomHandlerDB::Agreed) {
1677             appsvc_unset_defapp(DPL::ToUTF8String(This->m_model->TizenId).c_str());
1678         }
1679
1680         handlersDao.unregisterProtocolHandler(customHandler->target,
1681                                               customHandler->url,
1682                                               customHandler->base_url);
1683     } else {
1684         LogDebug("Nothing to unregister");
1685     }
1686
1687     This->detachFromCustomHandlersDao();
1688 }
1689
1690 void ViewLogic::contentHandlerRegistrationCallback(void* data,
1691                                                    Evas_Object* /*obj*/,
1692                                                    void* eventInfo)
1693 {
1694     Assert(data);
1695     LogDebug("enter");
1696     CustomHandlerDB::CustomHandlerPtr customHandler =
1697         getCustomHandlerFromData(eventInfo);
1698
1699     std::string mimeType = DPL::ToUTF8String(customHandler->target);
1700     if (mimeType.empty()) {
1701         LogError("No mimeType provided.");
1702         return;
1703     }
1704     for (int i = 0; i < contentBlackListLenth; ++i) {
1705         if (0 == strcmp(contentBlackList[i], mimeType.c_str())) {
1706             LogWarning("mimeType blacklisted");
1707             //throw SecurityException
1708             return;
1709         }
1710     }
1711
1712     ViewLogic* This = static_cast<ViewLogic*>(data);
1713     LogDebug("Creating handlers dao");
1714     This->attachToCustomHandlersDao();
1715     CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1716     CustomHandlerDB::CustomHandlerPtr handler =
1717         handlersDao.getContentHandler(customHandler->target,
1718                                       customHandler->url,
1719                                       customHandler->base_url);
1720     if (handler && (handler->user_decision & CustomHandlerDB::DecisionSaved)) {
1721         LogDebug("Protocol already registered - nothing to do");
1722     } else {
1723         LogDebug("Protocol handler not found");
1724         Wrt::Popup::PopupResponse response =
1725             GlobalSettings::PopupsTestModeEnabled() ? Wrt::Popup::
1726                 YES_DO_REMEMBER :
1727             Wrt::Popup::PopupInvoker().askYesNoCheckbox(
1728                 CONTENT_HANDLER_ASK_TITLE,
1729                 CONTENT_HANDLER_ASK_MSG,
1730                 CONTENT_HANDLER_AKS_REMEMBER);
1731         saveUserResponse(response, customHandler);
1732         if (customHandler->user_decision == CustomHandlerDB::Declined) {
1733             return;
1734         }
1735         handlersDao.registerContentHandler(*(customHandler.get()));
1736         if (customHandler->user_decision & CustomHandlerDB::Agreed) {
1737             //TODO remove old default handler somehow from appsvc
1738             LogDebug("Registering appservice entry");
1739             int ret = appsvc_set_defapp(APPSVC_OPERATION_VIEW,
1740                                         DPL::ToUTF8String(
1741                                             customHandler->target).c_str(),
1742                                         NULL,
1743                                         DPL::ToUTF8String(This->m_model->
1744                                                               TizenId).c_str());
1745             if (APPSVC_RET_OK != ret) {
1746                 LogWarning("Appsvc entry failed: " << ret);
1747             }
1748         }
1749         LogDebug("Content saved");
1750     }
1751     This->detachFromCustomHandlersDao();
1752 }
1753
1754 void ViewLogic::contentHandlerIsRegisteredCallback(void* data,
1755                                                    Evas_Object* /*obj*/,
1756                                                    void* eventInfo)
1757 {
1758     LogDebug("enter");
1759     CustomHandlerDB::CustomHandlerPtr customHandler =
1760         getCustomHandlerFromData(eventInfo);
1761     ViewLogic* This = static_cast<ViewLogic*>(data);
1762     LogDebug("Creating handlers dao");
1763
1764     This->attachToCustomHandlersDao();
1765     CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1766     CustomHandlerDB::CustomHandlerPtr handler =
1767         handlersDao.getContentHandler(customHandler->target,
1768                                       customHandler->url,
1769                                       customHandler->base_url);
1770     if (handler) {
1771         if (handler->user_decision & CustomHandlerDB::Agreed) {
1772             ewk_custom_handlers_data_result_set(
1773                 static_cast<Ewk_Custom_Handlers_Data*>(data),
1774                 EWK_CUSTOM_HANDLERS_REGISTERED);
1775         } else {
1776             ewk_custom_handlers_data_result_set(
1777                 static_cast<Ewk_Custom_Handlers_Data*>(data),
1778                 EWK_CUSTOM_HANDLERS_DECLINED);
1779         }
1780     } else {
1781         ewk_custom_handlers_data_result_set(
1782             static_cast<Ewk_Custom_Handlers_Data*>(data),
1783             EWK_CUSTOM_HANDLERS_NEW);
1784     }
1785     This->detachFromCustomHandlersDao();
1786 }
1787
1788 void ViewLogic::contentHandlerUnregistrationCallback(void* data,
1789                                                      Evas_Object* /*obj*/,
1790                                                      void* eventInfo)
1791 {
1792     LogDebug("enter");
1793     CustomHandlerDB::CustomHandlerPtr customHandler =
1794         getCustomHandlerFromData(eventInfo);
1795     ViewLogic* This = static_cast<ViewLogic*>(data);
1796     LogDebug("Creating handlers dao");
1797     This->attachToCustomHandlersDao();
1798     CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1799     CustomHandlerDB::CustomHandlerPtr handlerCheck =
1800         handlersDao.getContentHandler(customHandler->target,
1801                                       customHandler->url,
1802                                       customHandler->base_url);
1803     if (handlerCheck) {
1804         if (handlerCheck->user_decision & CustomHandlerDB::Agreed) {
1805             appsvc_unset_defapp(DPL::ToUTF8String(This->m_model->TizenId).c_str());
1806         }
1807
1808         handlersDao.unregisterContentHandler(customHandler->target,
1809                                              customHandler->url,
1810                                              customHandler->base_url);
1811     } else {
1812         LogDebug("Nothing to unregister");
1813     }
1814     This->detachFromCustomHandlersDao();
1815 }
1816
1817 void ViewLogic::didRunJavaScriptCallback(
1818     Evas_Object* /*obj*/,
1819     const char* result,
1820     void* /*userData*/)
1821 {
1822     LogInfo("didRunJavaScriptCallback called");
1823     LogInfo("result = " << result);
1824 }
1825
1826 Eina_Bool ViewLogic::windowCloseIdlerCallback(void* data)
1827 {
1828     LogDebug("closeIdlerCallback");
1829     ViewLogic* This = static_cast<ViewLogic*>(data);
1830     This->windowClose();
1831     return ECORE_CALLBACK_CANCEL;
1832 }
1833
1834
1835 void ViewLogic::databaseUsagePermissionRequestCallback(
1836     void* data,
1837     Evas_Object* /*obj*/,
1838     void* eventInfo)
1839 {
1840     LogDebug("databaseUsagePermissionRequestCallback called");
1841     Assert(data);
1842     ViewLogic* This = static_cast<ViewLogic*>(data);
1843     Assert(eventInfo);
1844
1845     if (This->m_securityOriginSupport->isNeedPermissionCheck(
1846             SecurityOriginDB::FEATURE_WEB_DATABASE)
1847         == WrtDB::SETTINGS_TYPE_OFF)
1848     {
1849         // default value is deny
1850         return;
1851     }
1852     ViewModule::WebStorageSupport::webStorageCreatePermissionRequest(
1853         This->m_window,
1854         This->m_securityOriginSupport->getSecurityOriginDAO(),
1855         eventInfo);
1856     return;
1857 }
1858
1859 void ViewLogic::fileSystemPermissionRequestCallback(
1860     void* data,
1861     Evas_Object* /*obj*/,
1862     void* eventInfo)
1863 {
1864     LogDebug("fileSystemPermissionRequestCallback called");
1865     Assert(data);
1866     ViewLogic* This = static_cast<ViewLogic*>(data);
1867
1868     if (This->m_securityOriginSupport->isNeedPermissionCheck(
1869             SecurityOriginDB::FEATURE_FILE_SYSTEM_ACCESS)
1870         == WrtDB::SETTINGS_TYPE_OFF)
1871     {
1872         Ewk_Context_File_System_Permission* fileSystemPermission =
1873             static_cast<Ewk_Context_File_System_Permission*>(eventInfo);
1874         ewk_context_file_system_permission_allow_set(fileSystemPermission,
1875                                                      EINA_FALSE);
1876         return;
1877     }
1878
1879     Assert(eventInfo);
1880     ViewModule::FileSystemSupport::fileSystemPermissionRequest(
1881         This->m_window,
1882         This->m_securityOriginSupport->getSecurityOriginDAO(),
1883         eventInfo);
1884 }
1885
1886 void ViewLogic::certificateConfirmRequestCallback(
1887     void* data,
1888     Evas_Object* /*obj*/,
1889     void* eventInfo)
1890 {
1891     LogDebug("certificateConfirmRequestCallback called");
1892
1893     Assert(data);
1894     ViewLogic* This = static_cast<ViewLogic*>(data);
1895     Assert(eventInfo);
1896     Ewk_Certificate_Policy_Decision* certificatePolicyDecision =
1897         static_cast<Ewk_Certificate_Policy_Decision*>(eventInfo);
1898
1899     bool status = This->askUserForCertificateConfirm();
1900     if (!status) {
1901         ewk_certificate_policy_decision_allowed_set(
1902             certificatePolicyDecision,
1903             EINA_FALSE);
1904     } else {
1905         ewk_certificate_policy_decision_allowed_set(
1906             certificatePolicyDecision,
1907             EINA_TRUE);
1908     }
1909 }
1910
1911 bool ViewLogic::askUserForCertificateConfirm()
1912 {
1913     return Wrt::Popup::PopupInvoker().askYesNo(
1914                CERTIFICATE_CONFIRM_REQUEST_ASK_TITLE,
1915                CERTIFICATE_CONFIRM_REQUEST_ASK_BODY);
1916 }
1917
1918 std::string ViewLogic::requestUrlBlocked(const std::string& blockedUrl)
1919 {
1920     LogInfo("enter");
1921
1922     if (m_model->Type.Get().appType == WrtDB::APP_TYPE_TIZENWEBAPP) {
1923         // block this page and open it in browser
1924         LogDebug("Request was blocked by WARP: " << blockedUrl);
1925         LogDebug("open browser : " << blockedUrl);
1926         bundle* bundleData = bundle_create();
1927         appsvc_set_operation(bundleData, APPSVC_OPERATION_VIEW);
1928         appsvc_set_uri(bundleData, blockedUrl.c_str());
1929         CONTROLLER_POST_EVENT(
1930             ApplicationLauncher,
1931             ApplicationLauncherEvents::LaunchApplicationByAppService(
1932                 bundleData,
1933                 NULL,
1934                 NULL));
1935     }
1936
1937     // set block url. This is used on load finished callback
1938     m_blockedUri = blockedUrl;
1939
1940     // This is used in case of returning previous page
1941     return URICHANGE_PLUGIN_NO_CHANGE;
1942 }
1943
1944 std::string ViewLogic::requestUrlChanged(const std::string& changedUrl)
1945 {
1946     using namespace ViewModule::SecuritySupport;
1947
1948     LogInfo("changed url: " << changedUrl);
1949
1950     // Check if this url with 'http' or 'https' is included in whitelist,
1951     // which has lists of accessible external documents and
1952     // used for ONLY Tizen app
1953     std::string matchedScheme;
1954     std::string matchedUri;
1955     pcrecpp::RE(PATTERN_URI_CHANGE).PartialMatch(changedUrl.c_str(),
1956                                                  &matchedUri,
1957                                                  &matchedScheme);
1958     ViewModule::Scheme scheme(matchedScheme);
1959     if (scheme.GetType() == ViewModule::Scheme::HTTP ||
1960         scheme.GetType() == ViewModule::Scheme::HTTPS)
1961     {
1962         if (m_model->Type.Get().appType == WrtDB::APP_TYPE_TIZENWEBAPP) {
1963             if (!checkWhitelist(changedUrl.c_str())) {
1964                 LogInfo("This uri is not included in white document list");
1965                 return URICHANGE_PLUGIN_STOP_ONLY;
1966             }
1967             LogInfo("This url is included in WhiteList");
1968         } else {
1969             // For WAC app, WRT should block access of device api
1970             // for external documents
1971             return URICHANGE_PLUGIN_STOP_ONLY;
1972         }
1973     }
1974
1975     m_currentUri = changedUrl;
1976     return URICHANGE_PLUGIN_RESTART;
1977 }
1978
1979 void ViewLogic::windowClose()
1980 {
1981     LogDebug("windowClose");
1982     Assert(m_closedEwkView && "no closed webview");
1983
1984     if (1 >= m_ewkViewList.size()) {
1985         if (!m_cbs->webkitExit.empty()) {
1986             m_cbs->webkitExit();
1987         }
1988     } else {
1989         // call user callbacks
1990         if (!m_cbs->bufferUnset.empty()) {
1991             m_cbs->bufferUnset(m_currentEwkView);
1992         }
1993         if (!m_cbs->windowClose.empty()) {
1994             m_cbs->windowClose(m_closedEwkView);
1995         }
1996         removeEwkView(m_closedEwkView);
1997
1998         // get latest ewkView
1999         m_currentEwkView = m_ewkViewList.back();
2000         const char* uri = ewk_view_url_get(m_currentEwkView);
2001         if (NULL == uri || 0 == strlen(uri)) {
2002             m_currentUri.clear();
2003         } else {
2004             m_currentUri = uri;
2005         }
2006
2007         // resume ewkView
2008         /* In case we support many pages in parallel
2009          * then view is not suspended*/
2010         //resumeEwkView(m_currentEwkView);
2011         setEwkViewVisible(m_currentEwkView);
2012
2013         // show ewkView
2014         if (!m_cbs->bufferSet.empty()) {
2015             m_cbs->bufferSet(m_currentEwkView);
2016         }
2017     }
2018 }
2019