Remove filesystem usage popup
[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_geolocation_support_webkit2.h>
56 #include <view_logic_usermedia_support.h>
57 #include <view_logic_web_notification_support.h>
58 #include <view_logic_web_storage_support.h>
59 #include "bundles/plugin_module_support.h"
60 #include <popup-runner/PopupInvoker.h>
61
62 #include <EWebKit2.h>
63 #include <js_overlay_types.h>
64 #include <i_runnable_widget_object.h>
65 #include <profiling_util.h>
66 #include <wrt-commons/custom-handler-dao-ro/common_dao_types.h>
67 #include <wrt-commons/custom-handler-dao-ro/CustomHandlerDatabase.h>
68 #include <wrt-commons/custom-handler-dao-ro/custom_handler_dao_read_only.h>
69 #include <wrt-commons/custom-handler-dao-rw/custom_handler_dao.h>
70 #include <popup-runner/PopupInvoker.h>
71
72 #include <appsvc/appsvc.h>
73
74 namespace {
75 const char * const bundlePath = "/usr/lib/wrt-wk2-bundles/libwrt-wk2-bundle.so";
76 const char * const uriBlockedMessageName = "uri_blocked_msg";
77 const char * const uriChangedMessageName = "uri_changed_msg";
78 const char * const URICHANGE_PLUGIN_STOP_ONLY = "plugin_stop_only";
79 const char * const URICHANGE_PLUGIN_RESTART = "plugin_restart";
80 const char * const URICHANGE_PLUGIN_NO_CHANGE = "plugin_no_change";
81 const char * const URICHANGE_BLOCKED_URL = "null";
82 const char* PATTERN_URI_CHANGE = "^(([^:/\\?#]+)://[^\\?#]*)";
83 const int MAX_NUM_CONTEXT_MENU_ITEMS = 10;
84 // IME State value
85 const char * const IME_STATE_ON = "on";
86 const char * const IME_STATE_OFF = "off";
87
88 const char PROTOCOL_HANDLER_ASK_MSG[] = "Add protocol?";
89 const char PROTOCOL_HANDLER_ASK_TITLE[] = "Add protocol";
90 const char PROTOCOL_HANDLER_ASK_REMEMBER[] = "Remember dicision";
91 const char CONTENT_HANDLER_ASK_MSG[] = "Add content?";
92 const char CONTENT_HANDLER_ASK_TITLE[] = "Add content";
93 const char CONTENT_HANDLER_AKS_REMEMBER[] = "Remember dicision";
94 const char * const CERTIFICATE_CONFIRM_REQUEST_ASK_TITLE =
95     "Certification Info";
96 const char * const CERTIFICATE_CONFIRM_REQUEST_ASK_BODY =
97     "This site's security certificate is not trusted! Do you acess this site?";
98
99 const wchar_t* BACKGROUND_ENABLED = L"background_enabled";
100 } // anonymous namespace
101
102 std::map<const std::string,
103          const Evas_Smart_Cb> ViewLogic::m_ewkCallbacksMap = {
104     { "load,started", &ViewLogic::loadStartedCallback },
105     { "load,finished", &ViewLogic::loadFinishedCallback },
106     { "title,changed", &ViewLogic::titleChangedCallback },
107     { "load,progress", &ViewLogic::loadProgressCallback },
108     { "load,progress,finished", &ViewLogic::loadProgressFinishedCallback },
109     { "process,crashed", &ViewLogic::processCrashedCallback },
110     // WKPageUIClient
111     { "create,window", &ViewLogic::createWindowCallback },
112     { "close,window", &ViewLogic::closeWindowCallback },
113     // WKPagePolicyClient
114     { "policy,navigation,decide", &ViewLogic::policyNavigationDecideCallback },
115     { "policy,newwindow,decide", &ViewLogic::policyNewWindowDecideCallback },
116     { "policy,response,decide", &ViewLogic::pageResponseDecideCallback },
117     // WKPageContextMenuClient
118     { "contextmenu,customize", &ViewLogic::contextmenuCustomizeCallback },
119     // WKPageFormClient
120     { "form,submit", &ViewLogic::formSubmitCallback },
121     // EWK Geolocation Callback
122     { "request,geolocation,permission",
123       &ViewLogic::geolocationPermissionRequestCallback },
124     // EWK Notification Callback
125     { "notification,show", &ViewLogic::notificationShowCallback },
126     { "notification,cancel", &ViewLogic::notificationCancelCallback },
127     { "notification,permission,request",
128       &ViewLogic::notificationPermissionRequestCallback },
129
130     { "database,quota,exceeded",
131       &ViewLogic::databaseUsagePermissionRequestCallback },
132     { "fullscreen,enterfullscreen", &ViewLogic::enterFullscreenCallback },
133     { "fullscreen,exitfullscreen", &ViewLogic::exitFullscreenCallback },
134     // IME Callback
135     // when ime start to be showed on the webview,
136     // this callback will be called
137     { "inputmethod,changed", &ViewLogic::imeChangedCallback },
138     // this callback will be called
139     //  when ime finishes to be showed on the webview
140     // "event_info" arg of this callback is always NULL point
141     // if web content should know size of ime,
142     //  use "inputmethod,changed" instead of this.
143     //
144     { "editorclient,ime,opened", &ViewLogic::imeOpenedCallback },
145     // when ime finished to be hidden,
146     // this callback will be called
147     { "editorclient,ime,closed", &ViewLogic::imeClosedCallback },
148     // EWK Usermedia Callback
149     { "usermedia,permission,request",
150       &ViewLogic::usermediaPermissionRequestCallback },
151     // Custom handlers
152     { "protocolhandler,registration,requested",
153       &ViewLogic::protocolHandlerRegistrationCallback },
154     { "protocolhandler,isregistered",
155       &ViewLogic::protocolHandlerIsRegisteredCallback },
156     { "protocolhandler,unregistration,requested",
157       &ViewLogic::protocolHandlerUnregistrationCallback },
158     { "contenthandler,registration,requested",
159       &ViewLogic::contentHandlerRegistrationCallback },
160     { "contenthandler,isregistered",
161       &ViewLogic::contentHandlerIsRegisteredCallback },
162     { "contenthandler,unregistration,requested",
163       &ViewLogic::contentHandlerUnregistrationCallback },
164     { "request,certificate,confirm",
165       &ViewLogic::certificateConfirmRequestCallback }
166 };
167
168 ViewLogic::ViewLogic() :
169     m_ewkContext(0),
170     m_attachedToCustomHandlerDao(false),
171     m_currentEwkView(0),
172     m_closedEwkView(NULL),
173     m_window(NULL),
174     m_model(0),
175     m_cbs(new WRT::UserDelegates),
176     m_imeWidth(0),
177     m_imeHeight(0),
178     m_isBackgroundReload(false),
179     m_isBackgroundSupport(false),
180     m_appsSupport(new ViewModule::AppsSupport()),
181     m_vibrationSupport(new ViewModule::VibrationSupport())
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 = 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.empty()) {
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.empty()) {
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.empty()) {
391         while (!m_ewkViewList.empty()) {
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 = ViewModule::UriSupport::getUri(m_model, 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     // WRT should not fit web contents to device width automatically as default.
656     // Fitting to device width should be handled by web content using viewport meta tag.
657     ewk_settings_auto_fitting_set(settings, EINA_FALSE);
658
659     // disable zoom option when user click the input field
660     // this option is useful with the normal website
661     // for the make user friendly, disable auto zoom in the webapp
662     // The followings are not implemeted yet by webkit2
663     //      elm_webview_input_field_zoom_set(EINA_FALSE);
664
665     // set cookie database path
666     // The followings are not implemeted yet by webkit2
667     //      ewk_cookies_file_set(dao.getCookieDatabasePath().c_str()));
668
669     // set visibility to WebCore. This value will be used for html5.
670     // also, this value will be changed in the suspend, resume
671     // or create window, close window.
672     ewk_view_page_visibility_state_set(wkView,
673                                        EWK_PAGE_VISIBILITY_STATE_VISIBLE,
674                                        EINA_TRUE);
675 }
676
677 void ViewLogic::removeEwkView(Evas_Object *wkView)
678 {
679     LogInfo("removeEwkView called");
680     Assert(wkView);
681     Assert(0 != m_ewkViewList.size());
682
683     // unregister webview callbacks
684     ewkClientDeinit(wkView);
685
686     // suspend NPAPI plugin - Not implemented by Webkit2
687     //    ewk_view_pause_or_resume_plugins();
688     evas_object_del(wkView);
689     m_ewkViewList.remove(wkView);
690 }
691
692 void ViewLogic::resumeEwkView(Evas_Object *wkView)
693 {
694     LogInfo("resumeEwkView called");
695     Assert(wkView);
696
697     // register webview callback
698     ewkClientInit(wkView);
699
700     // resume webkit
701     resumeWebkit(wkView);
702
703     return;
704 }
705
706 void ViewLogic::suspendEwkView(Evas_Object *wkView)
707 {
708     LogInfo("suspendEwkView called");
709     Assert(wkView);
710
711     // suspend webkit
712     suspendWebkit(wkView);
713
714     // unregister webview callbacks
715     ewkClientDeinit(wkView);
716
717     return;
718 }
719
720 void ViewLogic::setEwkViewInvisible(Evas_Object *wkView)
721 {
722     LogInfo("setEwkViewInvisible called");
723     Assert(wkView);
724
725     ewk_view_page_visibility_state_set(wkView,
726                                        EWK_PAGE_VISIBILITY_STATE_HIDDEN,
727                                        EINA_FALSE);
728     ewk_view_visibility_set(wkView, EINA_FALSE);
729 }
730
731 void ViewLogic::setEwkViewVisible(Evas_Object *wkView)
732 {
733     LogInfo("setEwkViewVisible called");
734     Assert(wkView);
735
736     ewk_view_page_visibility_state_set(wkView,
737                                        EWK_PAGE_VISIBILITY_STATE_VISIBLE,
738                                        EINA_FALSE);
739     ewk_view_visibility_set(wkView, EINA_TRUE);
740 }
741
742 void ViewLogic::resumeWebkit(Evas_Object *wkView)
743 {
744     LogDebug("resumeWebkit");
745     Assert(wkView);
746
747     // resume NPAPI plugin
748     // The followings are not implemeted yet by webkit2
749     //      ewk_view_pause_or_resume_plugins(false);
750     //      ewk_view_pause_or_resume_video_audio(false);
751     //      ewk_view_javascript_resume();
752     //      ewk_view_enable_render();
753     //      ewk_view_reduce_plugins_frame_rate(false);
754     ewk_view_resume(wkView);
755
756     return;
757 }
758
759 void ViewLogic::suspendWebkit(Evas_Object *wkView)
760 {
761     LogDebug("suspendWebkit");
762     Assert(wkView);
763
764     // suspend the followings
765     // The followings are not implemeted yet by webkit2
766     //      ewk_view_pause_or_resume_plugins(true);
767     //      ewk_view_pause_or_resume_video_audio(true);
768     ewk_view_suspend(wkView);
769
770     return;
771 }
772
773 void ViewLogic::loadStartedCallback(
774     void* data,
775     Evas_Object* obj,
776     void* /*eventInfo*/)
777 {
778     LogDebug("loadStartedCallback called");
779     Assert(data);
780     ViewLogic* This = static_cast<ViewLogic*>(data);
781     evas_object_focus_set(This->m_currentEwkView, EINA_TRUE);
782
783     // call loadFinish callback to wrt-client
784     if (!This->m_cbs->loadStart.empty()) {
785         This->m_cbs->loadStart(obj);
786     }
787 }
788
789 void ViewLogic::loadFinishedCallback(
790     void* data,
791     Evas_Object* obj,
792     void* /*eventInfo*/)
793 {
794     LogDebug("loadFinishedCallback called");
795     Assert(data);
796     ViewLogic* This = static_cast<ViewLogic*>(data);
797
798     // Fill id/password
799     const char* url = ewk_view_url_get(This->m_currentEwkView);
800     if (NULL == url || strlen(url) == 0) {
801         LogError("url is empty");
802         return;
803     }
804
805     // check if this loading is for blocked url
806     if (This->m_blockedUri == url) {
807         if (ewk_view_back_possible(This->m_currentEwkView)) {
808             // go back to previous page
809             LogDebug("go to previous page");
810             ewk_view_back(This->m_currentEwkView);
811         } else {
812             // stop current page
813             LogDebug("remove current page");
814             ewk_view_stop(This->m_currentEwkView);
815             ecore_idler_add(windowCloseIdlerCallback, This);
816         }
817         This->m_blockedUri = std::string();
818         return;
819     }
820
821     DPL::OptionalString jsOptionalString =
822         ViewModule::PasswordSupport::jsForAutoFillData(url);
823     if (jsOptionalString.IsNull()) {
824         LogError("Fail to get JS String");
825     } else {
826         std::string jsStr = DPL::ToUTF8String(*jsOptionalString).c_str();
827
828         if (EINA_FALSE == ewk_view_script_execute(
829                 This->m_currentEwkView,
830                 jsStr.c_str(),
831                 didRunJavaScriptCallback,
832                 This))
833         {
834             LogError("JS for auto fill data failed.");
835         }
836     }
837
838     // call loadFinish callback to wrt-client
839     if (!This->m_cbs->loadFinish.empty()) {
840         This->m_cbs->loadFinish(obj);
841     }
842
843     // set only encoded bundle
844     double scale = elm_config_scale_get();
845     PluginModuleSupport::setCustomProperties(
846         This->m_ewkContext,
847         &scale,
848         ApplicationDataSingleton::Instance().getEncodedBundle());
849     // check if 'appsevice' event is registed at the current frames.
850     // If so, dispatch the event to frames.
851     PluginModuleSupport::dispatchJavaScriptEvent(
852         This->m_ewkContext,
853         WrtPlugins::W3C::ServiceCustomEvent,
854         NULL);
855
856     // In this case, widget is reloaded in the background.
857     // After finished load, bundle should disconnent callback.
858     if (This->m_isBackgroundReload) {
859         PluginModuleSupport::suspend(This->m_ewkContext);
860         ewk_view_suspend(This->m_currentEwkView);
861         This->m_isBackgroundReload = false;
862     }
863 }
864
865 void ViewLogic::titleChangedCallback(
866     void* data,
867     Evas_Object* /*obj*/,
868     void* eventInfo)
869 {
870     LogDebug("titleChangedCallback called");
871     Assert(data);
872     ViewLogic* This = static_cast<ViewLogic*>(data);
873     Assert(eventInfo);
874     const char* title = static_cast<char*>(eventInfo);
875
876     if (0 == strlen(title)) {
877         LogDebug("title data is empty");
878         return;
879     }
880     LogDebug("Title = [" << title << "]");
881     This->m_schemeSupport->HandleTizenScheme(title,
882                                              This->m_window,
883                                              This->m_currentEwkView);
884 }
885
886 void ViewLogic::loadProgressCallback(
887     void* /*data*/,
888     Evas_Object* /*obj*/,
889     void* eventInfo)
890 {
891     double* progress = static_cast<double*>(eventInfo);
892     LogDebug("didChangeProgressCallback progress = " << *progress);
893 }
894
895 void ViewLogic::loadProgressFinishedCallback(
896     void* data,
897     Evas_Object* /*obj*/,
898     void* /*eventInfo*/)
899 {
900     LogDebug("didFinishProgressCallback");
901     Assert(data);
902     ViewLogic const * const view = static_cast<ViewLogic const * const>(data);
903     if (!view->m_cbs->progressFinish.empty()) {
904         view->m_cbs->progressFinish();
905     }
906 }
907
908 void ViewLogic::processCrashedCallback(
909     void* data,
910     Evas_Object* /*obj*/,
911     void* eventInfo)
912 {
913     LogInfo("processCrashedCallback");
914     Assert(data);
915     ViewLogic const * const view =
916         static_cast<ViewLogic const * const>(data);
917     if (!view->m_cbs->webCrash.empty()) {
918         view->m_cbs->webCrash();
919     }
920     // This flag will be prevented exit() call in the Webkit side
921     if (NULL != eventInfo) {
922         *(static_cast<Eina_Bool*>(eventInfo)) = EINA_TRUE;
923     }
924 }
925
926 void ViewLogic::createWindowCallback(
927     void* data,
928     Evas_Object* obj,
929     void* eventInfo)
930 {
931     LogDebug("createWindowCallback");
932     Assert(data);
933     ViewLogic* This = static_cast<ViewLogic*>(data);
934
935     // First, current webview should be handled by user callback
936     if (!This->m_cbs->bufferUnset.empty()) {
937         This->m_cbs->bufferUnset(obj);
938     }
939
940     // this can be set by executable for specific purpose
941     Evas* canvas = NULL;
942     if (!This->m_cbs->windowCreateBefore.empty()) {
943         // 'obj' is parent webview object
944         This->m_cbs->windowCreateBefore(&canvas, obj);
945     }
946     if (!canvas) {
947         canvas = evas_object_evas_get(This->m_window);
948     }
949
950     // create new ewkview
951     This->createEwkView(canvas);
952     Evas_Object* newEwkView = This->m_currentEwkView;
953
954     // initialize new ewkview
955     This->setStartPage();
956     This->ewkClientInit(newEwkView);
957     This->prepareEwkView(newEwkView);
958
959     // Specific jobs of child, parent webview are handled by each executable
960     if (!This->m_cbs->windowCreateAfter.empty()) {
961         // 'obj' is parent webview, 'newEwkView' is child webview
962         This->m_cbs->windowCreateAfter(obj, newEwkView);
963     }
964
965     // Lastly, new webview should be handled by user callback
966     if (!This->m_cbs->bufferSet.empty()) {
967         This->m_cbs->bufferSet(newEwkView);
968     }
969     *(static_cast<Evas_Object **>(eventInfo)) = newEwkView;
970 }
971
972 void ViewLogic::closeWindowCallback(
973     void* data,
974     Evas_Object* obj,
975     void* /*eventInfo*/)
976 {
977     LogDebug("closeWindowCallback");
978     ViewLogic* This = static_cast<ViewLogic*>(data);
979     This->m_closedEwkView = obj;
980     ecore_idler_add(windowCloseIdlerCallback, This);
981 }
982
983 void ViewLogic::policyNavigationDecideCallback(
984     void* data,
985     Evas_Object* /*obj*/,
986     void* eventInfo)
987 {
988     LogDebug("policyNavigationDecideCallback called");
989     Assert(data);
990     ViewLogic* This = static_cast<ViewLogic*>(data);
991     Assert(eventInfo);
992     Ewk_Policy_Decision* policyDecision =
993         static_cast<Ewk_Policy_Decision*>(eventInfo);
994
995     if (This->m_schemeSupport->filterURIByScheme(policyDecision,
996                                                  false,
997                                                  This->m_model,
998                                                  This->m_window,
999                                                  This->m_currentEwkView))
1000     {
1001         LogDebug("use");
1002         ewk_policy_decision_use(policyDecision);
1003     } else {
1004         // check whether this is new empty window
1005         const char* activeUrl = ewk_view_url_get(This->m_currentEwkView);
1006         if (!activeUrl || 0 == strlen(activeUrl)) {
1007             /*
1008              * The view is empty and scheme has been handled externally. When
1009              * user gets back from the external application he'd see blank page
1010              * and won't be able to navigate back. This happens when window.open
1011              * is used to handle schemes like sms/mms/mailto (for example in
1012              * WAC web standards tests: WS-15XX).
1013              *
1014              * To solve the problem, the empty view is removed from the stack
1015              * and the previous one is shown. This is not an elegant solution
1016              * but we don't have a better one.
1017              */
1018             LogInfo("Scheme has been handled externally. Removing empty view.");
1019             if (ewk_view_back_possible(This->m_currentEwkView)) {
1020                 // go back to previous WKPage
1021                 ewk_view_back(This->m_currentEwkView);
1022             } else {
1023                 // stop current WKPage
1024                 ewk_view_stop(This->m_currentEwkView);
1025                 ecore_idler_add(windowCloseIdlerCallback, This);
1026             }
1027         }
1028
1029         LogDebug("ignore");
1030         ewk_policy_decision_ignore(policyDecision);
1031     }
1032 }
1033
1034 void ViewLogic::policyNewWindowDecideCallback(
1035     void* data,
1036     Evas_Object* /*obj*/,
1037     void* eventInfo)
1038 {
1039     LogDebug("policyNewWindowDecideCallback called");
1040     Assert(data);
1041     ViewLogic* This = static_cast<ViewLogic*>(data);
1042     Assert(eventInfo);
1043     Ewk_Policy_Decision* policyDecision =
1044         static_cast<Ewk_Policy_Decision*>(eventInfo);
1045
1046     if (This->m_schemeSupport->filterURIByScheme(policyDecision,
1047                                                  true,
1048                                                  This->m_model,
1049                                                  This->m_window,
1050                                                  This->m_currentEwkView))
1051     {
1052         ewk_policy_decision_use(policyDecision);
1053     } else {
1054         // scheme handled
1055         ewk_policy_decision_ignore(policyDecision);
1056     }
1057 }
1058
1059 void ViewLogic::pageResponseDecideCallback(
1060     void* data,
1061     Evas_Object* /*obj*/,
1062     void* eventInfo)
1063 {
1064     LogDebug("pageResponseDecideCallback called");
1065     Assert(data);
1066     ViewLogic* This = static_cast<ViewLogic*>(data);
1067     Assert(eventInfo);
1068     Ewk_Policy_Decision* policyDecision =
1069         static_cast<Ewk_Policy_Decision*>(eventInfo);
1070     Ewk_Policy_Decision_Type policyDecisionType =
1071         ewk_policy_decision_type_get(policyDecision);
1072
1073     if (policyDecisionType == EWK_POLICY_DECISION_USE) {
1074         LogDebug("use");
1075         ewk_policy_decision_use(policyDecision);
1076     } else if (policyDecisionType == EWK_POLICY_DECISION_DOWNLOAD) {
1077         LogDebug("download");
1078         ewk_policy_decision_suspend(policyDecision);
1079
1080         // get uri information
1081         const char* url = ewk_policy_decision_url_get(policyDecision);
1082         if (NULL == url || strlen(url) == 0) {
1083             LogDebug("url data is empty");
1084             ewk_policy_decision_use(policyDecision);
1085             return;
1086         }
1087         LogDebug("url = [" << url << "]");
1088
1089         // get content information
1090         const char* content =
1091             ewk_policy_decision_response_mime_get(policyDecision);
1092         LogDebug("content type = [" << content << "]");
1093
1094         // get cookie information
1095         const char* cookie = ewk_policy_decision_cookie_get(policyDecision);
1096         LogDebug("cookie = [" << cookie << "]");
1097
1098         LogDebug("Content not supported, will be opened in external app");
1099         This->m_appsSupport->downloadRequest(
1100             url,
1101             content,
1102             cookie);
1103         ewk_policy_decision_ignore(policyDecision);
1104     } else if (policyDecisionType == EWK_POLICY_DECISION_IGNORE) {
1105         LogDebug("ignore");
1106         ewk_policy_decision_ignore(policyDecision);
1107     } else {
1108         LogDebug("Type isn't handled");
1109         ewk_policy_decision_ignore(policyDecision);
1110     }
1111 }
1112
1113 void ViewLogic::contextmenuCustomizeCallback(
1114     void* data,
1115     Evas_Object* /*obj*/,
1116     void* eventInfo)
1117 {
1118     LogDebug("contextmenuCustomizeCallback called");
1119     Assert(data);
1120     Assert(eventInfo);
1121     ViewLogic* This = static_cast<ViewLogic*>(const_cast<void*>(data));
1122     Ewk_Context_Menu* menu = static_cast<Ewk_Context_Menu*>(eventInfo);
1123     if ((This->m_model->Type.Get().appType == WrtDB::APP_TYPE_TIZENWEBAPP) &&
1124         (This->m_model->SettingList.Get().getContextMenu()
1125          == ContextMenu_Disable))
1126     {
1127         LogDebug("ContextMenu Disable!!");
1128         for (unsigned int idx = 0; idx < ewk_context_menu_item_count(menu);) {
1129             Ewk_Context_Menu_Item* item = ewk_context_menu_nth_item_get(menu,
1130                                                                         idx);
1131             Assert(item);
1132             ewk_context_menu_item_remove(menu, item);
1133         }
1134     } else {
1135         LogDebug("ContextMenu Enable!!");
1136         unsigned int menu_num = ewk_context_menu_item_count(menu);
1137         unsigned int idx = 0;
1138         do {
1139             Ewk_Context_Menu_Item* item = ewk_context_menu_nth_item_get(menu,
1140                                                                         idx);
1141             if (!item) {
1142                 idx++;
1143                 continue;
1144             }
1145             Ewk_Context_Menu_Item_Tag tag = ewk_context_menu_item_tag_get(item);
1146
1147             switch (tag) {
1148             case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_IMAGE_IN_NEW_WINDOW:
1149                 ewk_context_menu_item_remove(menu, item);
1150                 continue;
1151
1152             case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_LINK_IN_NEW_WINDOW:
1153                 ewk_context_menu_item_remove(menu, item);
1154                 continue;
1155
1156             case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_FRAME_IN_NEW_WINDOW:
1157                 ewk_context_menu_item_remove(menu, item);
1158                 continue;
1159
1160             case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_MEDIA_IN_NEW_WINDOW:
1161                 ewk_context_menu_item_remove(menu, item);
1162                 continue;
1163
1164             case EWK_CONTEXT_MENU_ITEM_TAG_SEARCH_WEB:
1165                 ewk_context_menu_item_remove(menu, item);
1166                 continue;
1167
1168             default:
1169                 idx++;
1170                 break;
1171             }
1172         } while (idx < menu_num);
1173     }
1174 }
1175
1176 void ViewLogic::formSubmitCallback(
1177     void* /*data*/,
1178     Evas_Object* /*obj*/,
1179     void* eventInfo)
1180 {
1181     LogDebug("formSubmitCallback called");
1182     Assert(eventInfo);
1183     Ewk_Form_Data* formData = static_cast<Ewk_Form_Data*>(eventInfo);
1184
1185     const char* uri = ewk_form_data_url_get(formData);
1186     if (!uri) {
1187         LogError("URL is empty");
1188         return;
1189     }
1190
1191     Eina_Hash* userData = ewk_form_data_values_get(formData);
1192     ViewModule::PasswordSupport::submitClicked(uri, userData);
1193 }
1194
1195 void ViewLogic::geolocationPermissionRequestCallback(
1196     void* data,
1197     Evas_Object* /*obj*/,
1198     void* eventInfo)
1199 {
1200     Assert(data);
1201     ViewLogic* This = static_cast<ViewLogic*>(data);
1202     Assert(eventInfo);
1203     Ewk_Geolocation_Permission_Data* permissionRequest =
1204         static_cast<Ewk_Geolocation_Permission_Data*>(eventInfo);
1205
1206     if (This->m_securityOriginSupport->isNeedPermissionCheck(
1207             SecurityOriginDB::FEATURE_GEOLOCATION)
1208         == WrtDB::SETTINGS_TYPE_OFF)
1209     {
1210         ewk_geolocation_permission_request_allow_set(
1211             ewk_geolocation_permission_request_get(permissionRequest),
1212             EINA_FALSE);
1213         return;
1214     }
1215     ViewModule::GeolocationSupport::Webkit2::geolocationPermissionRequest(
1216         This->m_window,
1217         This->m_securityOriginSupport->getSecurityOriginDAO(),
1218         eventInfo);
1219 }
1220
1221 void ViewLogic::notificationShowCallback(
1222     void* data,
1223     Evas_Object* /*obj*/,
1224     void* eventInfo)
1225 {
1226     LogDebug("notificationShowCallback called");
1227     Assert(data);
1228     ViewLogic* This = static_cast<ViewLogic*>(data);
1229
1230     Assert(eventInfo);
1231     Ewk_Notification* noti = static_cast<Ewk_Notification*>(eventInfo);
1232
1233     using namespace ViewModule::WebNotification;
1234
1235     WebNotificationDataPtr notiData(
1236         new WebNotificationData(
1237             This->m_model,
1238             ewk_notification_id_get(noti)));
1239
1240     DPL::OptionalString string =
1241         DPL::FromUTF8String(ewk_notification_icon_url_get(noti));
1242     if (!string.IsNull()) {
1243         notiData->m_iconURL = DPL::ToUTF8String(*string);
1244     }
1245     string = DPL::FromUTF8String(ewk_notification_title_get(noti));
1246     if (!string.IsNull()) {
1247         notiData->m_title = DPL::ToUTF8String(*string);
1248     }
1249     string = DPL::FromUTF8String(ewk_notification_body_get(noti));
1250     if (!string.IsNull()) {
1251         notiData->m_body = DPL::ToUTF8String(*string);
1252     }
1253
1254     LogInfo("notification id : " << notiData->m_id);
1255     LogInfo("notification iconURL : " << notiData->m_iconURL);
1256     LogInfo("notification title : " << notiData->m_title);
1257     LogInfo("notification body : " << notiData->m_body);
1258
1259     showWebNotification(notiData);
1260     ewk_notification_showed(This->m_ewkContext, ewk_notification_id_get(noti));
1261 }
1262
1263 void ViewLogic::notificationCancelCallback(
1264     void* /*data*/,
1265     Evas_Object* /*obj*/,
1266     void* /*eventInfo*/)
1267 {
1268     LogDebug("notificationCancelCallback called");
1269 }
1270
1271 void ViewLogic::notificationPermissionRequestCallback(
1272     void* data,
1273     Evas_Object* /*obj*/,
1274     void* eventInfo)
1275 {
1276     LogDebug("notificationPermissionRequestCallback called");
1277     Assert(data);
1278     ViewLogic* This = static_cast<ViewLogic*>(data);
1279     if (This->m_securityOriginSupport->isNeedPermissionCheck(
1280             SecurityOriginDB::FEATURE_WEB_NOTIFICATION)
1281         == WrtDB::SETTINGS_TYPE_OFF)
1282     {
1283         Ewk_Notification_Permission_Request* request =
1284             static_cast<Ewk_Notification_Permission_Request*>(eventInfo);
1285         ewk_notification_permission_request_response(
1286             This->m_ewkContext,
1287             request,
1288             EINA_FALSE);
1289         return;
1290     }
1291
1292     Assert(eventInfo);
1293     ViewModule::WebNotification::webNotificationPermissionRequest(
1294         This->m_window,
1295         This->m_securityOriginSupport->getSecurityOriginDAO(),
1296         This->m_ewkContext,
1297         eventInfo);
1298     return;
1299 }
1300
1301 // EWK Orientation Callback
1302 Eina_Bool ViewLogic::orientationLockCallback(
1303     Evas_Object* obj,
1304     Eina_Bool /*needLock*/,
1305     int orientation,
1306     void* data)
1307 {
1308     LogDebug("orientationLockCallback called");
1309     Assert(data);
1310     ViewLogic* This = static_cast<ViewLogic*>(data);
1311
1312     if (orientation & EWK_SCREEN_ORIENTATION_PORTRAIT_PRIMARY) {
1313         LogDebug("orientation is portrait-primary");
1314         elm_win_rotation_with_resize_set(This->m_window, 0);
1315         ewk_view_orientation_send(obj, 0);
1316     } else if (orientation & EWK_SCREEN_ORIENTATION_LANDSCAPE_PRIMARY) {
1317         LogDebug("orientation is landscape-primary");
1318         elm_win_rotation_with_resize_set(This->m_window, 270);
1319         ewk_view_orientation_send(obj, 90);
1320     } else if (orientation & EWK_SCREEN_ORIENTATION_PORTRAIT_SECONDARY) {
1321         LogDebug("orientation is portrait-secondary");
1322         elm_win_rotation_with_resize_set(This->m_window, 180);
1323         ewk_view_orientation_send(obj, 180);
1324     } else if (orientation & EWK_SCREEN_ORIENTATION_LANDSCAPE_SECONDARY) {
1325         LogDebug("orientation is landscape-secondary");
1326         elm_win_rotation_with_resize_set(This->m_window, 90);
1327         ewk_view_orientation_send(obj, -90);
1328     } else {
1329         LogDebug("Wrong orientation is set");
1330         return EINA_FALSE;
1331     }
1332     return EINA_TRUE;
1333 }
1334
1335 // Fullscreen API callbacks
1336 void ViewLogic::enterFullscreenCallback(
1337     void* data,
1338     Evas_Object* /*obj*/,
1339     void* /*eventInfo*/)
1340 {
1341     LogInfo("enterFullscreenCallback called");
1342     Assert(data);
1343     ViewLogic* This = static_cast<ViewLogic*>(data);
1344     if (!This->m_cbs->toggleFullscreen.empty()) {
1345         This->m_cbs->toggleFullscreen(true);
1346     }
1347 }
1348 void ViewLogic::exitFullscreenCallback(
1349     void* data,
1350     Evas_Object* /*obj*/,
1351     void* /*eventInfo*/)
1352 {
1353     LogInfo("exitFullscreenCallback called");
1354     Assert(data);
1355     ViewLogic* This = static_cast<ViewLogic*>(data);
1356     if (!This->m_cbs->toggleFullscreen.empty()) {
1357         This->m_cbs->toggleFullscreen(false);
1358     }
1359 }
1360
1361 void ViewLogic::imeChangedCallback(
1362     void* data,
1363     Evas_Object* /*obj*/,
1364     void* eventInfo)
1365 {
1366     LogDebug("enter");
1367     Assert(data);
1368     Assert(eventInfo);
1369     ViewLogic* This = static_cast<ViewLogic*>(data);
1370     Eina_Rectangle *rect = static_cast<Eina_Rectangle *>(eventInfo);
1371     This->m_imeWidth = rect->w;
1372     This->m_imeHeight = rect->h;
1373 }
1374
1375 void ViewLogic::imeOpenedCallback(
1376     void* data,
1377     Evas_Object* /*obj*/,
1378     void* /*eventInfo*/)
1379 {
1380     LogDebug("enter");
1381     Assert(data);
1382     ViewLogic* This = static_cast<ViewLogic*>(data);
1383
1384     using namespace WrtPlugins::W3C;
1385     SoftKeyboardChangeArgs args;
1386     args.state = IME_STATE_ON;
1387     args.width = This->m_imeWidth;
1388     args.height = This->m_imeHeight;
1389     This->fireJavascriptEvent(
1390         static_cast<int>(SoftKeyboardChangeCustomEvent),
1391         &args);
1392 }
1393
1394 void ViewLogic::imeClosedCallback(
1395     void* data,
1396     Evas_Object* /*obj*/,
1397     void* /*eventInfo*/)
1398 {
1399     LogDebug("enter");
1400     Assert(data);
1401     ViewLogic* This = static_cast<ViewLogic*>(data);
1402
1403     using namespace WrtPlugins::W3C;
1404     SoftKeyboardChangeArgs args;
1405     args.state = IME_STATE_OFF;
1406
1407     This->fireJavascriptEvent(
1408         static_cast<int>(SoftKeyboardChangeCustomEvent),
1409         &args);
1410 }
1411
1412 void ViewLogic::usermediaPermissionRequestCallback(
1413     void* data,
1414     Evas_Object* /*obj*/,
1415     void* eventInfo)
1416 {
1417     LogDebug("usermediaPermissionRequestCallback called");
1418     Assert(data);
1419     ViewLogic* This = static_cast<ViewLogic*>(data);
1420     ViewModule::UsermediaSupport::usermediaPermissionRequest(This->m_window,
1421                                                              eventInfo);
1422 }
1423
1424 // helper method
1425 CustomHandlerDB::CustomHandlerPtr getCustomHandlerFromData(void* data)
1426 {
1427     Assert(data);
1428     Ewk_Custom_Handlers_Data* handler =
1429         static_cast<Ewk_Custom_Handlers_Data*>(data);
1430     CustomHandlerDB::CustomHandlerPtr customHandler(
1431         new CustomHandlerDB::CustomHandler());
1432     const char* base_url = ewk_custom_handlers_data_base_url_get(handler);
1433     if (base_url) {
1434         LogDebug("base url: " << base_url);
1435         customHandler->base_url = DPL::FromASCIIString(string(base_url));
1436     }
1437     const char* url = ewk_custom_handlers_data_url_get(handler);
1438     if (url) {
1439         LogDebug("url: " << url);
1440         customHandler->url = DPL::FromASCIIString(string(url));
1441     }
1442     const char* target = ewk_custom_handlers_data_target_get(handler);
1443     if (target) {
1444         LogDebug("target: " << target);
1445         customHandler->target = DPL::FromASCIIString(string(target));
1446     }
1447     const char* title = ewk_custom_handlers_data_title_get(handler);
1448     if (title) {
1449         LogDebug("title: " << title);
1450         customHandler->title = DPL::FromASCIIString(string(title));
1451     }
1452     return customHandler;
1453 }
1454
1455 void ViewLogic::attachToCustomHandlersDao()
1456 {
1457     if (!m_attachedToCustomHandlerDao) {
1458         CustomHandlerDB::Interface::attachDatabaseRW();
1459     }
1460 }
1461
1462 void ViewLogic::detachFromCustomHandlersDao()
1463 {
1464     if (m_attachedToCustomHandlerDao) {
1465         CustomHandlerDB::Interface::detachDatabase();
1466     }
1467 }
1468
1469 const int protocolWhiteListLenth = 15;
1470 char const * const protocolWhiteList[protocolWhiteListLenth] = {
1471     "irc",
1472     "geo",
1473     "mailto",
1474     "magnet",
1475     "mms",
1476     "news",
1477     "nntp",
1478     "sip",
1479     "sms",
1480     "smsto",
1481     "ssh",
1482     "tel",
1483     "urn",
1484     "webcal",
1485     "xmpp"
1486 };
1487
1488 const int contentBlackListLenth = 14;
1489 char const * const contentBlackList[contentBlackListLenth] = {
1490     "application/x-www-form-urlencoded",
1491     "application/xhtml+xml",
1492     "application/xml",
1493     "image/gif",
1494     "image/jpeg",
1495     "image/png",
1496     "image/svg+xml",
1497     "multipart/x-mixed-replace",
1498     "text/cache-manifest",
1499     "text/css",
1500     "text/html",
1501     "text/ping",
1502     "text/plain",
1503     "text/xml"
1504 };
1505
1506 /**
1507  * Saves user's response from popup to custom handler. Saves Yes/No and remember
1508  * state.
1509  * @param response
1510  * @param customHandler
1511  */
1512 void saveUserResponse(Wrt::Popup::PopupResponse response,
1513                       CustomHandlerDB::CustomHandlerPtr customHandler)
1514 {
1515     switch (response) {
1516     case Wrt::Popup::YES_DO_REMEMBER:
1517         LogDebug("User allowed, remember");
1518         customHandler->user_decision =
1519             static_cast<CustomHandlerDB::HandlerState>
1520             (CustomHandlerDB::Agreed | CustomHandlerDB::DecisionSaved);
1521         break;
1522     case Wrt::Popup::YES_DONT_REMEMBER:
1523         LogDebug("User allowed, don't remember");
1524         customHandler->user_decision = CustomHandlerDB::Agreed;
1525         break;
1526     case Wrt::Popup::NO_DO_REMEMBER:
1527         LogDebug("User didn't allow, remember");
1528         customHandler->user_decision =
1529             static_cast<CustomHandlerDB::HandlerState>
1530             (CustomHandlerDB::Declined | CustomHandlerDB::DecisionSaved);
1531         break;
1532     case Wrt::Popup::NO_DONT_REMEMBER:
1533         LogDebug("User didn't allow, don't remember");
1534         customHandler->user_decision = CustomHandlerDB::Declined;
1535         break;
1536     }
1537 }
1538
1539 //TODO registration, checking if registered and unregistration can be done in
1540 //common functions for both types of handlers. Only white and black lists
1541 //have to be separated
1542 //TODO attach database only one at the start (not in every callback?)
1543 void ViewLogic::protocolHandlerRegistrationCallback(void* data,
1544                                                     Evas_Object* /*obj*/,
1545                                                     void* eventInfo)
1546 {
1547     Assert(data);
1548     LogDebug("enter");
1549     CustomHandlerDB::CustomHandlerPtr customHandler =
1550         getCustomHandlerFromData(eventInfo);
1551
1552     std::string scheme = DPL::ToUTF8String(customHandler->target);
1553     if (scheme.empty()) {
1554         LogError("No scheme provided");
1555         //TODO what about securityError?
1556         return;
1557     }
1558     bool matched = false;
1559     //scheme on whiteList
1560     for (int i = 0; i < protocolWhiteListLenth; ++i) {
1561         if (0 == strcmp(protocolWhiteList[i], scheme.c_str())) {
1562             LogDebug("Match found, protocol can be handled");
1563             matched = true;
1564         }
1565     }
1566     if (!matched) {
1567         //starts with web+ and have at least 5 chars (lowercase ASCII)
1568         if (strncmp("web+", scheme.c_str(), 4) || scheme.length() < 5) {
1569             LogWarning("Scheme neither on whitelist nor starts with \"web+\"");
1570             //throw SecurityException
1571             return;
1572         }
1573         int l = 4;
1574         char c = scheme[l];
1575         while (c != '\0') {
1576             if (c < 'a' || c > 'z') {
1577                 LogWarning("Wrong char inside scheme. "
1578                            << "Only lowercase ASCII letters accepted");
1579                 //throw SecurityException
1580                 return;
1581             }
1582             c = scheme[++l];
1583         }
1584     }
1585
1586     ViewLogic* This = static_cast<ViewLogic*>(data);
1587     LogDebug("Creating handlers dao");
1588     This->attachToCustomHandlersDao();
1589     CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1590     CustomHandlerDB::CustomHandlerPtr handler =
1591         handlersDao.getProtocolHandler(customHandler->target,
1592                                        customHandler->url,
1593                                        customHandler->base_url);
1594     if (handler && (handler->user_decision & CustomHandlerDB::DecisionSaved)) {
1595         LogDebug("Protocol already registered - nothing to do");
1596     } else {
1597         LogDebug("Protocol handler not found");
1598         Wrt::Popup::PopupResponse response =
1599             GlobalSettings::PopupsTestModeEnabled() ? Wrt::Popup::
1600                 YES_DO_REMEMBER :
1601             Wrt::Popup::PopupInvoker().askYesNoCheckbox(
1602                 PROTOCOL_HANDLER_ASK_TITLE,
1603                 PROTOCOL_HANDLER_ASK_MSG,
1604                 PROTOCOL_HANDLER_ASK_REMEMBER);
1605         saveUserResponse(response, customHandler);
1606         if (customHandler->user_decision == CustomHandlerDB::Declined) {
1607             return;
1608         }
1609         handlersDao.registerProtocolHandler(*(customHandler.get()));
1610         if (customHandler->user_decision & CustomHandlerDB::Agreed) {
1611             //TODO remove old default handler somehow from appsvc
1612             LogDebug("Registering appservice entry");
1613             int ret = appsvc_set_defapp(APPSVC_OPERATION_VIEW,
1614                                         NULL,
1615                                         DPL::ToUTF8String(
1616                                             customHandler->target).c_str(),
1617                                         DPL::ToUTF8String(This->m_model->
1618                                                               TizenId).c_str());
1619             if (APPSVC_RET_OK != ret) {
1620                 LogWarning("Appsvc entry failed: " << ret);
1621             }
1622         }
1623         LogDebug("Protocal saved");
1624     }
1625
1626     This->detachFromCustomHandlersDao();
1627 }
1628
1629 void ViewLogic::protocolHandlerIsRegisteredCallback(void* data,
1630                                                     Evas_Object* /*obj*/,
1631                                                     void* eventInfo)
1632 {
1633     LogDebug("enter");
1634     CustomHandlerDB::CustomHandlerPtr customHandler = getCustomHandlerFromData(
1635             eventInfo);
1636     ViewLogic* This = static_cast<ViewLogic*>(data);
1637     LogDebug("Creating handlers dao");
1638     This->attachToCustomHandlersDao();
1639     CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1640     CustomHandlerDB::CustomHandlerPtr handler =
1641         handlersDao.getProtocolHandler(customHandler->target,
1642                                        customHandler->url,
1643                                        customHandler->base_url);
1644     if (handler) {
1645         if (handler->user_decision & CustomHandlerDB::Agreed) {
1646             ewk_custom_handlers_data_result_set(
1647                 static_cast<Ewk_Custom_Handlers_Data*>(data),
1648                 EWK_CUSTOM_HANDLERS_REGISTERED);
1649         } else {
1650             ewk_custom_handlers_data_result_set(
1651                 static_cast<Ewk_Custom_Handlers_Data*>(data),
1652                 EWK_CUSTOM_HANDLERS_DECLINED);
1653         }
1654     } else {
1655         ewk_custom_handlers_data_result_set(
1656             static_cast<Ewk_Custom_Handlers_Data*>(data),
1657             EWK_CUSTOM_HANDLERS_NEW);
1658     }
1659     This->detachFromCustomHandlersDao();
1660 }
1661
1662 void ViewLogic::protocolHandlerUnregistrationCallback(void* data,
1663                                                       Evas_Object* /*obj*/,
1664                                                       void* eventInfo)
1665 {
1666     LogDebug("enter");
1667     CustomHandlerDB::CustomHandlerPtr customHandler =
1668         getCustomHandlerFromData(eventInfo);
1669     ViewLogic* This = static_cast<ViewLogic*>(data);
1670     LogDebug("Creating handlers dao");
1671     This->attachToCustomHandlersDao();
1672     CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1673     CustomHandlerDB::CustomHandlerPtr handlerCheck =
1674         handlersDao.getProtocolHandler(customHandler->target,
1675                                        customHandler->url,
1676                                        customHandler->base_url);
1677     if (handlerCheck) {
1678         if (handlerCheck->user_decision & CustomHandlerDB::Agreed) {
1679             appsvc_unset_defapp(DPL::ToUTF8String(This->m_model->TizenId).c_str());
1680         }
1681
1682         handlersDao.unregisterProtocolHandler(customHandler->target,
1683                                               customHandler->url,
1684                                               customHandler->base_url);
1685     } else {
1686         LogDebug("Nothing to unregister");
1687     }
1688
1689     This->detachFromCustomHandlersDao();
1690 }
1691
1692 void ViewLogic::contentHandlerRegistrationCallback(void* data,
1693                                                    Evas_Object* /*obj*/,
1694                                                    void* eventInfo)
1695 {
1696     Assert(data);
1697     LogDebug("enter");
1698     CustomHandlerDB::CustomHandlerPtr customHandler =
1699         getCustomHandlerFromData(eventInfo);
1700
1701     std::string mimeType = DPL::ToUTF8String(customHandler->target);
1702     if (mimeType.empty()) {
1703         LogError("No mimeType provided.");
1704         return;
1705     }
1706     for (int i = 0; i < contentBlackListLenth; ++i) {
1707         if (0 == strcmp(contentBlackList[i], mimeType.c_str())) {
1708             LogWarning("mimeType blacklisted");
1709             //throw SecurityException
1710             return;
1711         }
1712     }
1713
1714     ViewLogic* This = static_cast<ViewLogic*>(data);
1715     LogDebug("Creating handlers dao");
1716     This->attachToCustomHandlersDao();
1717     CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1718     CustomHandlerDB::CustomHandlerPtr handler =
1719         handlersDao.getContentHandler(customHandler->target,
1720                                       customHandler->url,
1721                                       customHandler->base_url);
1722     if (handler && (handler->user_decision & CustomHandlerDB::DecisionSaved)) {
1723         LogDebug("Protocol already registered - nothing to do");
1724     } else {
1725         LogDebug("Protocol handler not found");
1726         Wrt::Popup::PopupResponse response =
1727             GlobalSettings::PopupsTestModeEnabled() ? Wrt::Popup::
1728                 YES_DO_REMEMBER :
1729             Wrt::Popup::PopupInvoker().askYesNoCheckbox(
1730                 CONTENT_HANDLER_ASK_TITLE,
1731                 CONTENT_HANDLER_ASK_MSG,
1732                 CONTENT_HANDLER_AKS_REMEMBER);
1733         saveUserResponse(response, customHandler);
1734         if (customHandler->user_decision == CustomHandlerDB::Declined) {
1735             return;
1736         }
1737         handlersDao.registerContentHandler(*(customHandler.get()));
1738         if (customHandler->user_decision & CustomHandlerDB::Agreed) {
1739             //TODO remove old default handler somehow from appsvc
1740             LogDebug("Registering appservice entry");
1741             int ret = appsvc_set_defapp(APPSVC_OPERATION_VIEW,
1742                                         DPL::ToUTF8String(
1743                                             customHandler->target).c_str(),
1744                                         NULL,
1745                                         DPL::ToUTF8String(This->m_model->
1746                                                               TizenId).c_str());
1747             if (APPSVC_RET_OK != ret) {
1748                 LogWarning("Appsvc entry failed: " << ret);
1749             }
1750         }
1751         LogDebug("Content saved");
1752     }
1753     This->detachFromCustomHandlersDao();
1754 }
1755
1756 void ViewLogic::contentHandlerIsRegisteredCallback(void* data,
1757                                                    Evas_Object* /*obj*/,
1758                                                    void* eventInfo)
1759 {
1760     LogDebug("enter");
1761     CustomHandlerDB::CustomHandlerPtr customHandler =
1762         getCustomHandlerFromData(eventInfo);
1763     ViewLogic* This = static_cast<ViewLogic*>(data);
1764     LogDebug("Creating handlers dao");
1765
1766     This->attachToCustomHandlersDao();
1767     CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1768     CustomHandlerDB::CustomHandlerPtr handler =
1769         handlersDao.getContentHandler(customHandler->target,
1770                                       customHandler->url,
1771                                       customHandler->base_url);
1772     if (handler) {
1773         if (handler->user_decision & CustomHandlerDB::Agreed) {
1774             ewk_custom_handlers_data_result_set(
1775                 static_cast<Ewk_Custom_Handlers_Data*>(data),
1776                 EWK_CUSTOM_HANDLERS_REGISTERED);
1777         } else {
1778             ewk_custom_handlers_data_result_set(
1779                 static_cast<Ewk_Custom_Handlers_Data*>(data),
1780                 EWK_CUSTOM_HANDLERS_DECLINED);
1781         }
1782     } else {
1783         ewk_custom_handlers_data_result_set(
1784             static_cast<Ewk_Custom_Handlers_Data*>(data),
1785             EWK_CUSTOM_HANDLERS_NEW);
1786     }
1787     This->detachFromCustomHandlersDao();
1788 }
1789
1790 void ViewLogic::contentHandlerUnregistrationCallback(void* data,
1791                                                      Evas_Object* /*obj*/,
1792                                                      void* eventInfo)
1793 {
1794     LogDebug("enter");
1795     CustomHandlerDB::CustomHandlerPtr customHandler =
1796         getCustomHandlerFromData(eventInfo);
1797     ViewLogic* This = static_cast<ViewLogic*>(data);
1798     LogDebug("Creating handlers dao");
1799     This->attachToCustomHandlersDao();
1800     CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1801     CustomHandlerDB::CustomHandlerPtr handlerCheck =
1802         handlersDao.getContentHandler(customHandler->target,
1803                                       customHandler->url,
1804                                       customHandler->base_url);
1805     if (handlerCheck) {
1806         if (handlerCheck->user_decision & CustomHandlerDB::Agreed) {
1807             appsvc_unset_defapp(DPL::ToUTF8String(This->m_model->TizenId).c_str());
1808         }
1809
1810         handlersDao.unregisterContentHandler(customHandler->target,
1811                                              customHandler->url,
1812                                              customHandler->base_url);
1813     } else {
1814         LogDebug("Nothing to unregister");
1815     }
1816     This->detachFromCustomHandlersDao();
1817 }
1818
1819 void ViewLogic::didRunJavaScriptCallback(
1820     Evas_Object* /*obj*/,
1821     const char* result,
1822     void* /*userData*/)
1823 {
1824     LogInfo("didRunJavaScriptCallback called");
1825     LogInfo("result = " << result);
1826 }
1827
1828 Eina_Bool ViewLogic::windowCloseIdlerCallback(void* data)
1829 {
1830     LogDebug("closeIdlerCallback");
1831     ViewLogic* This = static_cast<ViewLogic*>(data);
1832     This->windowClose();
1833     return ECORE_CALLBACK_CANCEL;
1834 }
1835
1836
1837 void ViewLogic::databaseUsagePermissionRequestCallback(
1838     void* data,
1839     Evas_Object* /*obj*/,
1840     void* eventInfo)
1841 {
1842     LogDebug("databaseUsagePermissionRequestCallback called");
1843     Assert(data);
1844     ViewLogic* This = static_cast<ViewLogic*>(data);
1845     Assert(eventInfo);
1846
1847     if (This->m_securityOriginSupport->isNeedPermissionCheck(
1848             SecurityOriginDB::FEATURE_WEB_DATABASE)
1849         == WrtDB::SETTINGS_TYPE_OFF)
1850     {
1851         // default value is deny
1852         return;
1853     }
1854     ViewModule::WebStorageSupport::webStorageCreatePermissionRequest(
1855         This->m_window,
1856         This->m_securityOriginSupport->getSecurityOriginDAO(),
1857         eventInfo);
1858     return;
1859 }
1860
1861 void ViewLogic::certificateConfirmRequestCallback(
1862     void* data,
1863     Evas_Object* /*obj*/,
1864     void* eventInfo)
1865 {
1866     LogDebug("certificateConfirmRequestCallback called");
1867
1868     Assert(data);
1869     ViewLogic* This = static_cast<ViewLogic*>(data);
1870     Assert(eventInfo);
1871     Ewk_Certificate_Policy_Decision* certificatePolicyDecision =
1872         static_cast<Ewk_Certificate_Policy_Decision*>(eventInfo);
1873
1874     bool status = This->askUserForCertificateConfirm();
1875     if (!status) {
1876         ewk_certificate_policy_decision_allowed_set(
1877             certificatePolicyDecision,
1878             EINA_FALSE);
1879     } else {
1880         ewk_certificate_policy_decision_allowed_set(
1881             certificatePolicyDecision,
1882             EINA_TRUE);
1883     }
1884 }
1885
1886 bool ViewLogic::askUserForCertificateConfirm()
1887 {
1888     return Wrt::Popup::PopupInvoker().askYesNo(
1889                CERTIFICATE_CONFIRM_REQUEST_ASK_TITLE,
1890                CERTIFICATE_CONFIRM_REQUEST_ASK_BODY);
1891 }
1892
1893 std::string ViewLogic::requestUrlBlocked(const std::string& blockedUrl)
1894 {
1895     LogInfo("enter");
1896
1897     if (m_model->Type.Get().appType == WrtDB::APP_TYPE_TIZENWEBAPP) {
1898         // block this page and open it in browser
1899         LogDebug("Request was blocked by WARP: " << blockedUrl);
1900         LogDebug("open browser : " << blockedUrl);
1901         bundle* bundleData = bundle_create();
1902         appsvc_set_operation(bundleData, APPSVC_OPERATION_VIEW);
1903         appsvc_set_uri(bundleData, blockedUrl.c_str());
1904         CONTROLLER_POST_EVENT(
1905             ApplicationLauncher,
1906             ApplicationLauncherEvents::LaunchApplicationByAppService(
1907                 bundleData,
1908                 NULL,
1909                 NULL));
1910     }
1911
1912     // set block url. This is used on load finished callback
1913     m_blockedUri = blockedUrl;
1914
1915     // This is used in case of returning previous page
1916     return URICHANGE_PLUGIN_NO_CHANGE;
1917 }
1918
1919 std::string ViewLogic::requestUrlChanged(const std::string& changedUrl)
1920 {
1921     using namespace ViewModule::SecuritySupport;
1922
1923     LogInfo("changed url: " << changedUrl);
1924
1925     // Check if this url with 'http' or 'https' is included in whitelist,
1926     // which has lists of accessible external documents and
1927     // used for ONLY Tizen app
1928     std::string matchedScheme;
1929     std::string matchedUri;
1930     pcrecpp::RE(PATTERN_URI_CHANGE).PartialMatch(changedUrl.c_str(),
1931                                                  &matchedUri,
1932                                                  &matchedScheme);
1933     ViewModule::Scheme scheme(matchedScheme);
1934     if (scheme.GetType() == ViewModule::Scheme::HTTP ||
1935         scheme.GetType() == ViewModule::Scheme::HTTPS)
1936     {
1937         if (m_model->Type.Get().appType == WrtDB::APP_TYPE_TIZENWEBAPP) {
1938             if (!checkWhitelist(changedUrl.c_str())) {
1939                 LogInfo("This uri is not included in white document list");
1940                 return URICHANGE_PLUGIN_STOP_ONLY;
1941             }
1942             LogInfo("This url is included in WhiteList");
1943         } else {
1944             // For WAC app, WRT should block access of device api
1945             // for external documents
1946             return URICHANGE_PLUGIN_STOP_ONLY;
1947         }
1948     }
1949
1950     m_currentUri = changedUrl;
1951     return URICHANGE_PLUGIN_RESTART;
1952 }
1953
1954 void ViewLogic::windowClose()
1955 {
1956     LogDebug("windowClose");
1957     Assert(m_closedEwkView && "no closed webview");
1958
1959     if (1 >= m_ewkViewList.size()) {
1960         if (!m_cbs->webkitExit.empty()) {
1961             m_cbs->webkitExit();
1962         }
1963     } else {
1964         // call user callbacks
1965         if (!m_cbs->bufferUnset.empty()) {
1966             m_cbs->bufferUnset(m_currentEwkView);
1967         }
1968         if (!m_cbs->windowClose.empty()) {
1969             m_cbs->windowClose(m_closedEwkView);
1970         }
1971         removeEwkView(m_closedEwkView);
1972
1973         // get latest ewkView
1974         m_currentEwkView = m_ewkViewList.back();
1975         const char* uri = ewk_view_url_get(m_currentEwkView);
1976         if (NULL == uri || 0 == strlen(uri)) {
1977             m_currentUri.clear();
1978         } else {
1979             m_currentUri = uri;
1980         }
1981
1982         // resume ewkView
1983         /* In case we support many pages in parallel
1984          * then view is not suspended*/
1985         //resumeEwkView(m_currentEwkView);
1986         setEwkViewVisible(m_currentEwkView);
1987
1988         // show ewkView
1989         if (!m_cbs->bufferSet.empty()) {
1990             m_cbs->bufferSet(m_currentEwkView);
1991         }
1992     }
1993 }
1994