Support multiple webkit context on wrt-core
[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_block_msg";
78 const char * const uriChangedMessageName = "uri_changed_msg";
79 const char * const URICHANGE_PLUGIN_STOP_ONLY = "plugin_stop_only";
80 const char * const URICHANGE_PLUGIN_RESTART = "plugin_restart";
81 const char * const URICHANGE_PLUGIN_NO_CHANGE = "plugin_no_change";
82 const char * const URICHANGE_BLOCKED_URL = "null";
83 const char* PATTERN_URI_CHANGE = "^(([^:/\\?#]+)://[^\\?#]*)";
84 const int MAX_NUM_CONTEXT_MENU_ITEMS = 10;
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     if (!strcmp(name, uriBlockedMessageName)) {
451         LogDebug("received : " << uriBlockedMessageName);
452         // Currently WebProcess informs obly about blocked
453         // URI - URI localization and security chekcs are
454         // done by WebProcess itself (see: wrt-wk2-bundle.cpp
455         // and bundle_uri_handling.cpp)
456         rememberBlockedURI(DPL::FromUTF8String(body));
457         *returnData = NULL;
458     } else if (!strcmp(name, uriChangedMessageName)) {
459         LogDebug("received : " << uriChangedMessageName);
460         std::string ret = requestUriChanged(DPL::FromUTF8String(body));
461         *returnData = strdup(ret.c_str());
462     }
463 }
464
465 void ViewLogic::downloadData(const char* url)
466 {
467     LogInfo("enter");
468     if (!url) {
469         return;
470     }
471
472     m_appsSupport->downloadRequest(url, NULL, NULL);
473 }
474
475 void ViewLogic::activateVibration(bool on, uint64_t time)
476 {
477     LogInfo("enter");
478     if (on) {
479         m_vibrationSupport->startVibration(static_cast<long>(time));
480     } else {
481         m_vibrationSupport->stopVibration();
482     }
483 }
484
485 void ViewLogic::initializeSupport()
486 {
487     // background support
488     if (m_model->SettingList.Get().getBackgroundSupport()
489         == BackgroundSupport_Enable)
490     {
491         LogDebug("Background support enabled, set process active");
492         pid_t pid = getpid();
493         sysman_inform_active(pid);
494         m_isBackgroundSupport = true;
495     }
496 #ifndef DEPRECATED_SETTING_STRING
497     else {
498         WrtDB::WidgetDAOReadOnly dao(m_model->TizenId);
499         WrtDB::PropertyDAOReadOnly::WidgetPropertyValue bgEnableValue =
500             dao.getPropertyValue(DPL::String(BACKGROUND_ENABLED));
501
502         if (!bgEnableValue.IsNull() && !bgEnableValue->compare(L"true")) {
503             //skip suspendWidget
504             LogDebug("Background support enabled, set process active");
505             pid_t pid = getpid();
506             sysman_inform_active(pid);
507             m_isBackgroundSupport = true;
508         }
509     }
510 #endif
511
512     m_schemeSupport.reset(new SchemeSupport(m_model->Type.Get().appType));
513     ViewModule::StorageSupport::initializeStorage(m_model);
514     m_appsSupport->initialize(m_model);
515     m_securityOriginSupport.reset(new ViewModule::SecurityOriginSupport(m_model));
516
517     m_vibrationSupport->initialize();
518 }
519
520 void ViewLogic::initializePluginLoading()
521 {
522     // inform wrt information for plugin loading to web process
523     PluginModuleSupport::start(
524         m_ewkContext,
525         m_model->TizenId,
526         elm_config_scale_get(),
527         ApplicationDataSingleton::Instance().getEncodedBundle(),
528         m_theme.c_str(),
529         m_model->SettingList.Get().isEncrypted());
530 }
531
532 void ViewLogic::ewkClientInit(Evas_Object *wkView)
533 {
534     Assert(NULL != wkView && "ewk_view not created at this point");
535
536     FOREACH(it, m_ewkCallbacksMap) {
537         evas_object_smart_callback_add(
538             wkView,
539             it->first.c_str(),
540             it->second,
541             this);
542     }
543     // EWK Orientation Callback
544     ewk_view_orientation_lock_callback_set(
545         wkView,
546         orientationLockCallback,
547         this);
548 }
549
550 void ViewLogic::ewkClientDeinit(Evas_Object *wkView)
551 {
552     LogDebug("ewkClientDeinit");
553     Assert(NULL != wkView && "ewk_view not created at this point");
554
555     FOREACH(it, m_ewkCallbacksMap) {
556         evas_object_smart_callback_del(
557             wkView,
558             it->first.c_str(),
559             it->second);
560     }
561     ewk_view_orientation_lock_callback_set(
562         wkView,
563         NULL,
564         NULL);
565 }
566
567 bool ViewLogic::createEwkView(Evas* canvas)
568 {
569     LogDebug("createEwkVeiw");
570     Assert(canvas);
571     ADD_PROFILING_POINT("ewk_view_add_with_context", "start");
572     Evas_Object* newEwkView = ewk_view_add_with_context(
573             canvas,
574             m_ewkContext);
575     ADD_PROFILING_POINT("ewk_view_add_with_context", "stop");
576
577     if (!newEwkView) {
578         LogError("View creation failed");
579         Wrt::Popup::PopupInvoker().showInfo(
580             "Info", "View creation failed", "close");
581         return false;
582     }
583
584     // set cookie policy
585     // even arguments pass the ewkContext, this API should be called
586     // after webkit Evas_Object is created
587     Ewk_Cookie_Manager *ewkCookieManager;
588     ewkCookieManager =
589         ewk_context_cookie_manager_get(m_ewkContext);
590     ewk_cookie_manager_accept_policy_set(ewkCookieManager,
591                                          EWK_COOKIE_ACCEPT_POLICY_ALWAYS);
592
593     if (m_currentEwkView) {
594         setEwkViewInvisible(m_currentEwkView);
595     }
596
597     LogInfo("push webview: " << newEwkView);
598     m_ewkViewList.push_back(newEwkView);
599     m_currentEwkView = newEwkView;
600     return true;
601 }
602
603 void ViewLogic::setStartPage()
604 {
605     /* Start URI (as other uris) is now localized
606      * on WebProcess side */
607     m_currentUri = m_startUrl;
608 }
609
610 void ViewLogic::prepareEwkView(Evas_Object *wkView)
611 {
612     LogDebug("prepareEwkView called");
613     Assert(wkView);
614     Ewk_Settings* settings = ewk_view_settings_get(wkView);
615
616     // set user agent
617     std::string customUserAgent = m_model->SettingList.Get().getUserAgent();
618     if (customUserAgent.empty()) {
619         auto userAgentString =
620             ViewModule::UserAgentSupport::getUserAgentFromVconf();
621         if (!userAgentString.empty()) {
622             LogDebug("Setting user agent as: " << userAgentString);
623             ewk_view_user_agent_set(wkView, userAgentString.c_str());
624         }
625     } else {
626         LogDebug("Setting  custom user agent as: " << customUserAgent);
627         ewk_view_user_agent_set(wkView, customUserAgent.c_str());
628     }
629
630     // set custom header : language
631     using namespace ViewModule::CustomHeaderSupport;
632     std::string customHeaderString = getValueByField(ACCEPT_LANGUAGE);
633     if (!customHeaderString.empty()) {
634         LogDebug("custom field=[" << ACCEPT_LANGUAGE << "]");
635         LogDebug("custom value=[" << customHeaderString << "]");
636         ewk_view_custom_header_add(wkView,
637                                    ACCEPT_LANGUAGE.c_str(),
638                                    customHeaderString.c_str());
639     }
640
641     // webkit NPAPI plugins is always on in wrt
642     ewk_settings_plugins_enabled_set(settings, EINA_TRUE);
643
644     // The followings are not implemeted yet by webkit2
645     //      ewk_view_setting_accelerated_compositing_enable_set(EINA_TRUE);
646     //      ewk_view_mode_set();
647     //      ewk_view_setting_enable_specified_plugin_set(EINA_TRUE,
648     // FLASH_MIME_TYPE);
649     //      ewk_view_setting_html5video_external_player_enable_set(EINA_FALSE);
650     //      ewk_view_show_ime_on_autofocus_set(EINA_TRUE);
651     //      elm_webview_show_magnifier_set(EINA_FALSE);
652     ewk_settings_javascript_enabled_set(settings, EINA_TRUE);
653     ewk_settings_loads_images_automatically_set(settings, EINA_TRUE);
654     ewk_settings_auto_fitting_set(settings, EINA_TRUE);
655
656     // disable zoom option when user click the input field
657     // this option is useful with the normal website
658     // for the make user friendly, disable auto zoom in the webapp
659     // The followings are not implemeted yet by webkit2
660     //      elm_webview_input_field_zoom_set(EINA_FALSE);
661
662     // set cookie database path
663     // The followings are not implemeted yet by webkit2
664     //      ewk_cookies_file_set(dao.getCookieDatabasePath().c_str()));
665
666     // set visibility to WebCore. This value will be used for html5.
667     // also, this value will be changed in the suspend, resume
668     // or create window, close window.
669     ewk_view_page_visibility_state_set(wkView,
670                                        EWK_PAGE_VISIBILITY_STATE_VISIBLE,
671                                        EINA_TRUE);
672 }
673
674 void ViewLogic::removeEwkView(Evas_Object *wkView)
675 {
676     LogInfo("removeEwkView called");
677     Assert(wkView);
678     Assert(0 != m_ewkViewList.size());
679
680     // unregister webview callbacks
681     ewkClientDeinit(wkView);
682
683     // suspend NPAPI plugin - Not implemented by Webkit2
684     //    ewk_view_pause_or_resume_plugins();
685     evas_object_del(wkView);
686     m_ewkViewList.remove(wkView);
687 }
688
689 void ViewLogic::resumeEwkView(Evas_Object *wkView)
690 {
691     LogInfo("resumeEwkView called");
692     Assert(wkView);
693
694     // register webview callback
695     ewkClientInit(wkView);
696
697     // resume webkit
698     resumeWebkit(wkView);
699
700     return;
701 }
702
703 void ViewLogic::suspendEwkView(Evas_Object *wkView)
704 {
705     LogInfo("suspendEwkView called");
706     Assert(wkView);
707
708     // suspend webkit
709     suspendWebkit(wkView);
710
711     // unregister webview callbacks
712     ewkClientDeinit(wkView);
713
714     return;
715 }
716
717 void ViewLogic::setEwkViewInvisible(Evas_Object *wkView)
718 {
719     LogInfo("setEwkViewInvisible called");
720     Assert(wkView);
721
722     ewk_view_page_visibility_state_set(wkView,
723                                        EWK_PAGE_VISIBILITY_STATE_HIDDEN,
724                                        EINA_FALSE);
725     ewk_view_visibility_set(wkView, EINA_FALSE);
726 }
727
728 void ViewLogic::setEwkViewVisible(Evas_Object *wkView)
729 {
730     LogInfo("setEwkViewVisible called");
731     Assert(wkView);
732
733     ewk_view_page_visibility_state_set(wkView,
734                                        EWK_PAGE_VISIBILITY_STATE_VISIBLE,
735                                        EINA_FALSE);
736     ewk_view_visibility_set(wkView, EINA_TRUE);
737 }
738
739 void ViewLogic::resumeWebkit(Evas_Object *wkView)
740 {
741     LogDebug("resumeWebkit");
742     Assert(wkView);
743
744     // resume NPAPI plugin
745     // The followings are not implemeted yet by webkit2
746     //      ewk_view_pause_or_resume_plugins(false);
747     //      ewk_view_pause_or_resume_video_audio(false);
748     //      ewk_view_javascript_resume();
749     //      ewk_view_enable_render();
750     //      ewk_view_reduce_plugins_frame_rate(false);
751     ewk_view_resume(wkView);
752
753     return;
754 }
755
756 void ViewLogic::suspendWebkit(Evas_Object *wkView)
757 {
758     LogDebug("suspendWebkit");
759     Assert(wkView);
760
761     // suspend the followings
762     // The followings are not implemeted yet by webkit2
763     //      ewk_view_pause_or_resume_plugins(true);
764     //      ewk_view_pause_or_resume_video_audio(true);
765     ewk_view_suspend(wkView);
766
767     return;
768 }
769
770 void ViewLogic::loadStartedCallback(
771     void* data,
772     Evas_Object* obj,
773     void* /*eventInfo*/)
774 {
775     LogDebug("loadStartedCallback called");
776     Assert(data);
777     ViewLogic* This = static_cast<ViewLogic*>(data);
778     evas_object_focus_set(This->m_currentEwkView, EINA_TRUE);
779
780     // call loadFinish callback to wrt-client
781     if (!This->m_cbs->loadStart.empty()) {
782         This->m_cbs->loadStart(obj);
783     }
784 }
785
786 void ViewLogic::loadFinishedCallback(
787     void* data,
788     Evas_Object* obj,
789     void* /*eventInfo*/)
790 {
791     LogDebug("loadFinishedCallback called");
792     Assert(data);
793     ViewLogic* This = static_cast<ViewLogic*>(data);
794
795     // Fill id/password
796     const char* url = ewk_view_url_get(This->m_currentEwkView);
797     if (NULL == url || strlen(url) == 0) {
798         LogError("url is empty");
799     } else {
800         DPL::OptionalString jsOptionalString =
801             ViewModule::PasswordSupport::jsForAutoFillData(url);
802         if (jsOptionalString.IsNull()) {
803             LogError("Fail to get JS String");
804         } else {
805             std::string jsStr = DPL::ToUTF8String(*jsOptionalString).c_str();
806
807             if (EINA_FALSE == ewk_view_script_execute(
808                     This->m_currentEwkView,
809                     jsStr.c_str(),
810                     didRunJavaScriptCallback,
811                     This))
812             {
813                 LogError("JS for auto fill data failed.");
814             }
815         }
816     }
817
818     // call loadFinish callback to wrt-client
819     if (!This->m_cbs->loadFinish.empty()) {
820         This->m_cbs->loadFinish(obj);
821     }
822
823     // set only encoded bundle
824     double scale = elm_config_scale_get();
825     PluginModuleSupport::setCustomProperties(
826         This->m_ewkContext,
827         &scale,
828         ApplicationDataSingleton::Instance().getEncodedBundle());
829     // check if 'appsevice' event is registed at the current frames.
830     // If so, dispatch the event to frames.
831     PluginModuleSupport::dispatchJavaScriptEvent(
832         This->m_ewkContext,
833         WrtPlugins::W3C::ServiceCustomEvent,
834         NULL);
835
836     // In this case, widget is reloaded in the background.
837     // After finished load, bundle should disconnent callback.
838     if (This->m_isBackgroundReload) {
839         PluginModuleSupport::suspend(This->m_ewkContext);
840         ewk_view_suspend(This->m_currentEwkView);
841         This->m_isBackgroundReload = false;
842     }
843 }
844
845 void ViewLogic::titleChangedCallback(
846     void* data,
847     Evas_Object* /*obj*/,
848     void* eventInfo)
849 {
850     LogDebug("titleChangedCallback called");
851     Assert(data);
852     ViewLogic* This = static_cast<ViewLogic*>(data);
853     Assert(eventInfo);
854     const char* title = static_cast<char*>(eventInfo);
855
856     if (0 == strlen(title)) {
857         LogDebug("title data is empty");
858         return;
859     }
860     LogDebug("Title = [" << title << "]");
861     This->m_schemeSupport->HandleTizenScheme(title,
862                                              This->m_window,
863                                              This->m_currentEwkView);
864 }
865
866 void ViewLogic::loadProgressCallback(
867     void* /*data*/,
868     Evas_Object* /*obj*/,
869     void* eventInfo)
870 {
871     double* progress = static_cast<double*>(eventInfo);
872     LogDebug("didChangeProgressCallback progress = " << *progress);
873 }
874
875 void ViewLogic::loadProgressFinishedCallback(
876     void* data,
877     Evas_Object* /*obj*/,
878     void* /*eventInfo*/)
879 {
880     LogDebug("didFinishProgressCallback");
881     Assert(data);
882     ViewLogic const * const view = static_cast<ViewLogic const * const>(data);
883     if (!view->m_cbs->progressFinish.empty()) {
884         view->m_cbs->progressFinish();
885     }
886 }
887
888 void ViewLogic::processCrashedCallback(
889     void* data,
890     Evas_Object* /*obj*/,
891     void* eventInfo)
892 {
893     LogInfo("processCrashedCallback");
894     Assert(data);
895     ViewLogic const * const view =
896         static_cast<ViewLogic const * const>(data);
897     if (!view->m_cbs->webCrash.empty()) {
898         view->m_cbs->webCrash();
899     }
900     // This flag will be prevented exit() call in the Webkit side
901     if (NULL != eventInfo) {
902         *(static_cast<Eina_Bool*>(eventInfo)) = EINA_TRUE;
903     }
904 }
905
906 void ViewLogic::createWindowCallback(
907     void* data,
908     Evas_Object* obj,
909     void* eventInfo)
910 {
911     LogDebug("createWindowCallback");
912     Assert(data);
913     ViewLogic* This = static_cast<ViewLogic*>(data);
914
915     // First, current webview should be handled by user callback
916     if (!This->m_cbs->bufferUnset.empty()) {
917         This->m_cbs->bufferUnset(obj);
918     }
919
920     // this can be set by executable for specific purpose
921     Evas* canvas = NULL;
922     if (!This->m_cbs->windowCreateBefore.empty()) {
923         // 'obj' is parent webview object
924         This->m_cbs->windowCreateBefore(&canvas, obj);
925     }
926     if (!canvas) {
927         canvas = evas_object_evas_get(This->m_window);
928     }
929
930     // create new ewkview
931     This->createEwkView(canvas);
932     Evas_Object* newEwkView = This->m_currentEwkView;
933
934     // initialize new ewkview
935     This->setStartPage();
936     This->ewkClientInit(newEwkView);
937     This->prepareEwkView(newEwkView);
938
939     // Specific jobs of child, parent webview are handled by each executable
940     if (!This->m_cbs->windowCreateAfter.empty()) {
941         // 'obj' is parent webview, 'newEwkView' is child webview
942         This->m_cbs->windowCreateAfter(obj, newEwkView);
943     }
944
945     // Lastly, new webview should be handled by user callback
946     if (!This->m_cbs->bufferSet.empty()) {
947         This->m_cbs->bufferSet(newEwkView);
948     }
949     *(static_cast<Evas_Object **>(eventInfo)) = newEwkView;
950 }
951
952 void ViewLogic::closeWindowCallback(
953     void* data,
954     Evas_Object* obj,
955     void* /*eventInfo*/)
956 {
957     LogDebug("closeWindowCallback");
958     ViewLogic* This = static_cast<ViewLogic*>(data);
959     This->m_closedEwkView = obj;
960     ecore_idler_add(windowCloseIdlerCallback, This);
961 }
962
963 void ViewLogic::policyNavigationDecideCallback(
964     void* data,
965     Evas_Object* /*obj*/,
966     void* eventInfo)
967 {
968     LogDebug("policyNavigationDecideCallback called");
969     Assert(data);
970     ViewLogic* This = static_cast<ViewLogic*>(data);
971     Assert(eventInfo);
972     Ewk_Policy_Decision* policyDecision =
973         static_cast<Ewk_Policy_Decision*>(eventInfo);
974
975     if (This->m_schemeSupport->filterURIByScheme(policyDecision,
976                                                  false,
977                                                  This->m_model,
978                                                  This->m_window,
979                                                  This->m_currentEwkView))
980     {
981         LogDebug("use");
982         ewk_policy_decision_use(policyDecision);
983     } else {
984         // check whether this is new empty window
985         const char* activeUrl = ewk_view_url_get(This->m_currentEwkView);
986         if (!activeUrl || 0 == strlen(activeUrl)) {
987             /*
988              * The view is empty and scheme has been handled externally. When
989              * user gets back from the external application he'd see blank page
990              * and won't be able to navigate back. This happens when window.open
991              * is used to handle schemes like sms/mms/mailto (for example in
992              * WAC web standards tests: WS-15XX).
993              *
994              * To solve the problem, the empty view is removed from the stack
995              * and the previous one is shown. This is not an elegant solution
996              * but we don't have a better one.
997              */
998             LogInfo("Scheme has been handled externally. Removing empty view.");
999             if (ewk_view_back_possible(This->m_currentEwkView)) {
1000                 // go back to previous WKPage
1001                 ewk_view_back(This->m_currentEwkView);
1002             } else {
1003                 // stop current WKPage
1004                 ewk_view_stop(This->m_currentEwkView);
1005                 ecore_idler_add(windowCloseIdlerCallback, This);
1006             }
1007         }
1008
1009         LogDebug("ignore");
1010         ewk_policy_decision_ignore(policyDecision);
1011     }
1012 }
1013
1014 void ViewLogic::policyNewWindowDecideCallback(
1015     void* data,
1016     Evas_Object* /*obj*/,
1017     void* eventInfo)
1018 {
1019     LogDebug("policyNewWindowDecideCallback called");
1020     Assert(data);
1021     ViewLogic* This = static_cast<ViewLogic*>(data);
1022     Assert(eventInfo);
1023     Ewk_Policy_Decision* policyDecision =
1024         static_cast<Ewk_Policy_Decision*>(eventInfo);
1025
1026     if (This->m_schemeSupport->filterURIByScheme(policyDecision,
1027                                                  true,
1028                                                  This->m_model,
1029                                                  This->m_window,
1030                                                  This->m_currentEwkView))
1031     {
1032         ewk_policy_decision_use(policyDecision);
1033     } else {
1034         // scheme handled
1035         ewk_policy_decision_ignore(policyDecision);
1036     }
1037 }
1038
1039 void ViewLogic::pageResponseDecideCallback(
1040     void* data,
1041     Evas_Object* /*obj*/,
1042     void* eventInfo)
1043 {
1044     LogDebug("pageResponseDecideCallback called");
1045     Assert(data);
1046     ViewLogic* This = static_cast<ViewLogic*>(data);
1047     Assert(eventInfo);
1048     Ewk_Policy_Decision* policyDecision =
1049         static_cast<Ewk_Policy_Decision*>(eventInfo);
1050     Ewk_Policy_Decision_Type policyDecisionType =
1051         ewk_policy_decision_type_get(policyDecision);
1052
1053     if (policyDecisionType == EWK_POLICY_DECISION_USE) {
1054         LogDebug("use");
1055         ewk_policy_decision_use(policyDecision);
1056     } else if (policyDecisionType == EWK_POLICY_DECISION_DOWNLOAD) {
1057         LogDebug("download");
1058         ewk_policy_decision_suspend(policyDecision);
1059
1060         // get uri information
1061         const char* url = ewk_policy_decision_url_get(policyDecision);
1062         if (NULL == url || strlen(url) == 0) {
1063             LogDebug("url data is empty");
1064             ewk_policy_decision_use(policyDecision);
1065             return;
1066         }
1067         LogDebug("url = [" << url << "]");
1068
1069         // get content information
1070         const char* content =
1071             ewk_policy_decision_response_mime_get(policyDecision);
1072         LogDebug("content type = [" << content << "]");
1073
1074         // get cookie information
1075         const char* cookie = ewk_policy_decision_cookie_get(policyDecision);
1076         LogDebug("cookie = [" << cookie << "]");
1077
1078         LogDebug("Content not supported, will be opened in external app");
1079         This->m_appsSupport->downloadRequest(
1080             url,
1081             content,
1082             cookie);
1083         ewk_policy_decision_ignore(policyDecision);
1084     } else if (policyDecisionType == EWK_POLICY_DECISION_IGNORE) {
1085         LogDebug("ignore");
1086         ewk_policy_decision_ignore(policyDecision);
1087     } else {
1088         LogDebug("Type isn't handled");
1089         ewk_policy_decision_ignore(policyDecision);
1090     }
1091 }
1092
1093 void ViewLogic::contextmenuCustomizeCallback(
1094     void* data,
1095     Evas_Object* /*obj*/,
1096     void* eventInfo)
1097 {
1098     LogDebug("contextmenuCustomizeCallback called");
1099     Assert(data);
1100     Assert(eventInfo);
1101     ViewLogic* This = static_cast<ViewLogic*>(const_cast<void*>(data));
1102     Ewk_Context_Menu* menu = static_cast<Ewk_Context_Menu*>(eventInfo);
1103     if ((This->m_model->Type.Get().appType == WrtDB::APP_TYPE_TIZENWEBAPP) &&
1104         (This->m_model->SettingList.Get().getContextMenu()
1105          == ContextMenu_Disable))
1106     {
1107         LogDebug("ContextMenu Disable!!");
1108         for (unsigned int idx = 0; idx < ewk_context_menu_item_count(menu);) {
1109             Ewk_Context_Menu_Item* item = ewk_context_menu_nth_item_get(menu,
1110                                                                         idx);
1111             Assert(item);
1112             ewk_context_menu_item_remove(menu, item);
1113         }
1114     } else {
1115         LogDebug("ContextMenu Enable!!");
1116         int menu_num = ewk_context_menu_item_count(menu);
1117         unsigned int idx = 0;
1118         do {
1119             Ewk_Context_Menu_Item* item = ewk_context_menu_nth_item_get(menu,
1120                                                                         idx);
1121             if (!item) {
1122                 idx++;
1123                 continue;
1124             }
1125             Ewk_Context_Menu_Item_Tag tag = ewk_context_menu_item_tag_get(item);
1126
1127             switch (tag) {
1128             case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_IMAGE_IN_NEW_WINDOW:
1129                 ewk_context_menu_item_remove(menu, item);
1130                 continue;
1131
1132             case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_LINK_IN_NEW_WINDOW:
1133                 ewk_context_menu_item_remove(menu, item);
1134                 continue;
1135
1136             case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_FRAME_IN_NEW_WINDOW:
1137                 ewk_context_menu_item_remove(menu, item);
1138                 continue;
1139
1140             case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_MEDIA_IN_NEW_WINDOW:
1141                 ewk_context_menu_item_remove(menu, item);
1142                 continue;
1143
1144             case EWK_CONTEXT_MENU_ITEM_TAG_SEARCH_WEB:
1145                 ewk_context_menu_item_remove(menu, item);
1146                 continue;
1147
1148             default:
1149                 idx++;
1150                 break;
1151             }
1152         } while (idx < menu_num);
1153     }
1154 }
1155
1156 void ViewLogic::formSubmitCallback(
1157     void* /*data*/,
1158     Evas_Object* /*obj*/,
1159     void* eventInfo)
1160 {
1161     LogDebug("formSubmitCallback called");
1162     Assert(eventInfo);
1163     Ewk_Form_Data* formData = static_cast<Ewk_Form_Data*>(eventInfo);
1164
1165     const char* uri = ewk_form_data_url_get(formData);
1166     if (!uri) {
1167         LogError("URL is empty");
1168         return;
1169     }
1170
1171     Eina_Hash* userData = ewk_form_data_values_get(formData);
1172     ViewModule::PasswordSupport::submitClicked(uri, userData);
1173 }
1174
1175 void ViewLogic::geolocationPermissionRequestCallback(
1176     void* data,
1177     Evas_Object* /*obj*/,
1178     void* eventInfo)
1179 {
1180     Assert(data);
1181     ViewLogic* This = static_cast<ViewLogic*>(data);
1182     Assert(eventInfo);
1183     Ewk_Geolocation_Permission_Data* permissionRequest =
1184         static_cast<Ewk_Geolocation_Permission_Data*>(eventInfo);
1185
1186     if (This->m_securityOriginSupport->isNeedPermissionCheck(
1187             SecurityOriginDB::FEATURE_GEOLOCATION)
1188         == WrtDB::SETTINGS_TYPE_OFF)
1189     {
1190         ewk_geolocation_permission_request_allow_set(
1191             ewk_geolocation_permission_request_get(permissionRequest),
1192             EINA_FALSE);
1193         return;
1194     }
1195     ViewModule::GeolocationSupport::Webkit2::geolocationPermissionRequest(
1196         This->m_window,
1197         This->m_securityOriginSupport->getSecurityOriginDAO(),
1198         eventInfo);
1199 }
1200
1201 void ViewLogic::notificationShowCallback(
1202     void* data,
1203     Evas_Object* /*obj*/,
1204     void* eventInfo)
1205 {
1206     LogDebug("notificationShowCallback called");
1207     Assert(data);
1208     ViewLogic* This = static_cast<ViewLogic*>(data);
1209
1210     Assert(eventInfo);
1211     Ewk_Notification* noti = static_cast<Ewk_Notification*>(eventInfo);
1212
1213     using namespace ViewModule::WebNotification;
1214
1215     WebNotificationDataPtr notiData(
1216         new WebNotificationData(
1217             This->m_model,
1218             ewk_notification_id_get(noti)));
1219
1220     DPL::OptionalString string =
1221         DPL::FromUTF8String(ewk_notification_icon_url_get(noti));
1222     if (!string.IsNull()) {
1223         notiData->m_iconURL = DPL::ToUTF8String(*string);
1224     }
1225     string = DPL::FromUTF8String(ewk_notification_title_get(noti));
1226     if (!string.IsNull()) {
1227         notiData->m_title = DPL::ToUTF8String(*string);
1228     }
1229     string = DPL::FromUTF8String(ewk_notification_body_get(noti));
1230     if (!string.IsNull()) {
1231         notiData->m_body = DPL::ToUTF8String(*string);
1232     }
1233
1234     LogInfo("notification id : " << notiData->m_id);
1235     LogInfo("notification iconURL : " << notiData->m_iconURL);
1236     LogInfo("notification title : " << notiData->m_title);
1237     LogInfo("notification body : " << notiData->m_body);
1238
1239     showWebNotification(notiData);
1240     ewk_notification_showed(This->m_ewkContext, ewk_notification_id_get(noti));
1241 }
1242
1243 void ViewLogic::notificationCancelCallback(
1244     void* /*data*/,
1245     Evas_Object* /*obj*/,
1246     void* /*eventInfo*/)
1247 {
1248     LogDebug("notificationCancelCallback called");
1249 }
1250
1251 void ViewLogic::notificationPermissionRequestCallback(
1252     void* data,
1253     Evas_Object* /*obj*/,
1254     void* eventInfo)
1255 {
1256     LogDebug("notificationPermissionRequestCallback called");
1257     Assert(data);
1258     ViewLogic* This = static_cast<ViewLogic*>(data);
1259     if (This->m_securityOriginSupport->isNeedPermissionCheck(
1260             SecurityOriginDB::FEATURE_WEB_NOTIFICATION)
1261         == WrtDB::SETTINGS_TYPE_OFF)
1262     {
1263         Ewk_Notification_Permission_Request* request =
1264             static_cast<Ewk_Notification_Permission_Request*>(eventInfo);
1265         ewk_notification_permission_request_response(
1266             This->m_ewkContext,
1267             request,
1268             EINA_FALSE);
1269         return;
1270     }
1271
1272     Assert(eventInfo);
1273     ViewModule::WebNotification::webNotificationPermissionRequest(
1274         This->m_window,
1275         This->m_securityOriginSupport->getSecurityOriginDAO(),
1276         This->m_ewkContext,
1277         eventInfo);
1278     return;
1279 }
1280
1281 // EWK Orientation Callback
1282 Eina_Bool ViewLogic::orientationLockCallback(
1283     Evas_Object* obj,
1284     Eina_Bool /*needLock*/,
1285     int orientation,
1286     void* data)
1287 {
1288     LogDebug("orientationLockCallback called");
1289     Assert(data);
1290     ViewLogic* This = static_cast<ViewLogic*>(data);
1291
1292     if (orientation & EWK_SCREEN_ORIENTATION_PORTRAIT_PRIMARY) {
1293         LogDebug("orientation is portrait-primary");
1294         elm_win_rotation_with_resize_set(This->m_window, 0);
1295         ewk_view_orientation_send(obj, 0);
1296     } else if (orientation & EWK_SCREEN_ORIENTATION_LANDSCAPE_PRIMARY) {
1297         LogDebug("orientation is landscape-primary");
1298         elm_win_rotation_with_resize_set(This->m_window, 270);
1299         ewk_view_orientation_send(obj, 90);
1300     } else if (orientation & EWK_SCREEN_ORIENTATION_PORTRAIT_SECONDARY) {
1301         LogDebug("orientation is portrait-secondary");
1302         elm_win_rotation_with_resize_set(This->m_window, 180);
1303         ewk_view_orientation_send(obj, 180);
1304     } else if (orientation & EWK_SCREEN_ORIENTATION_LANDSCAPE_SECONDARY) {
1305         LogDebug("orientation is landscape-secondary");
1306         elm_win_rotation_with_resize_set(This->m_window, 90);
1307         ewk_view_orientation_send(obj, -90);
1308     } else {
1309         LogDebug("Wrong orientation is set");
1310         return EINA_FALSE;
1311     }
1312     return EINA_TRUE;
1313 }
1314
1315 // Fullscreen API callbacks
1316 void ViewLogic::enterFullscreenCallback(
1317     void* data,
1318     Evas_Object* /*obj*/,
1319     void* /*eventInfo*/)
1320 {
1321     LogInfo("enterFullscreenCallback called");
1322     Assert(data);
1323     ViewLogic* This = static_cast<ViewLogic*>(data);
1324     if (!This->m_cbs->toggleFullscreen.empty()) {
1325         This->m_cbs->toggleFullscreen(true);
1326     }
1327 }
1328 void ViewLogic::exitFullscreenCallback(
1329     void* data,
1330     Evas_Object* /*obj*/,
1331     void* /*eventInfo*/)
1332 {
1333     LogInfo("exitFullscreenCallback called");
1334     Assert(data);
1335     ViewLogic* This = static_cast<ViewLogic*>(data);
1336     if (!This->m_cbs->toggleFullscreen.empty()) {
1337         This->m_cbs->toggleFullscreen(false);
1338     }
1339 }
1340
1341 void ViewLogic::imeChangedCallback(
1342     void* data,
1343     Evas_Object* /*obj*/,
1344     void* eventInfo)
1345 {
1346     LogDebug("enter");
1347     Assert(data);
1348     Assert(eventInfo);
1349     ViewLogic* This = static_cast<ViewLogic*>(data);
1350     Eina_Rectangle *rect = static_cast<Eina_Rectangle *>(eventInfo);
1351     This->m_imeWidth = rect->w;
1352     This->m_imeHeight = rect->h;
1353 }
1354
1355 void ViewLogic::imeOpenedCallback(
1356     void* data,
1357     Evas_Object* /*obj*/,
1358     void* /*eventInfo*/)
1359 {
1360     LogDebug("enter");
1361     Assert(data);
1362     ViewLogic* This = static_cast<ViewLogic*>(data);
1363
1364     using namespace WrtPlugins::W3C;
1365     SoftKeyboardChangeArgs args;
1366     args.state = IME_STATE_ON;
1367     args.width = This->m_imeWidth;
1368     args.height = This->m_imeHeight;
1369     This->fireJavascriptEvent(
1370         static_cast<int>(SoftKeyboardChangeCustomEvent),
1371         &args);
1372 }
1373
1374 void ViewLogic::imeClosedCallback(
1375     void* data,
1376     Evas_Object* /*obj*/,
1377     void* /*eventInfo*/)
1378 {
1379     LogDebug("enter");
1380     Assert(data);
1381     ViewLogic* This = static_cast<ViewLogic*>(data);
1382
1383     using namespace WrtPlugins::W3C;
1384     SoftKeyboardChangeArgs args;
1385     args.state = IME_STATE_OFF;
1386
1387     This->fireJavascriptEvent(
1388         static_cast<int>(SoftKeyboardChangeCustomEvent),
1389         &args);
1390 }
1391
1392 void ViewLogic::usermediaPermissionRequestCallback(
1393     void* data,
1394     Evas_Object* /*obj*/,
1395     void* eventInfo)
1396 {
1397     LogDebug("usermediaPermissionRequestCallback called");
1398     Assert(data);
1399     ViewLogic* This = static_cast<ViewLogic*>(data);
1400     ViewModule::UsermediaSupport::usermediaPermissionRequest(This->m_window,
1401                                                              eventInfo);
1402 }
1403
1404 // helper method
1405 CustomHandlerDB::CustomHandlerPtr getCustomHandlerFromData(void* data)
1406 {
1407     Assert(data);
1408     Ewk_Custom_Handlers_Data* handler =
1409         static_cast<Ewk_Custom_Handlers_Data*>(data);
1410     CustomHandlerDB::CustomHandlerPtr customHandler(
1411         new CustomHandlerDB::CustomHandler());
1412     const char* base_url = ewk_custom_handlers_data_base_url_get(handler);
1413     if (base_url) {
1414         LogDebug("base url: " << base_url);
1415         customHandler->base_url = DPL::FromASCIIString(string(base_url));
1416     }
1417     const char* url = ewk_custom_handlers_data_url_get(handler);
1418     if (url) {
1419         LogDebug("url: " << url);
1420         customHandler->url = DPL::FromASCIIString(string(url));
1421     }
1422     const char* target = ewk_custom_handlers_data_target_get(handler);
1423     if (target) {
1424         LogDebug("target: " << target);
1425         customHandler->target = DPL::FromASCIIString(string(target));
1426     }
1427     const char* title = ewk_custom_handlers_data_title_get(handler);
1428     if (title) {
1429         LogDebug("title: " << title);
1430         customHandler->title = DPL::FromASCIIString(string(title));
1431     }
1432     return customHandler;
1433 }
1434
1435 void ViewLogic::attachToCustomHandlersDao()
1436 {
1437     if (!m_attachedToCustomHandlerDao) {
1438         CustomHandlerDB::Interface::attachDatabaseRW();
1439     }
1440 }
1441
1442 void ViewLogic::detachFromCustomHandlersDao()
1443 {
1444     if (m_attachedToCustomHandlerDao) {
1445         CustomHandlerDB::Interface::detachDatabase();
1446     }
1447 }
1448
1449 const int protocolWhiteListLenth = 15;
1450 char const * const protocolWhiteList[protocolWhiteListLenth] = {
1451     "irc",
1452     "geo",
1453     "mailto",
1454     "magnet",
1455     "mms",
1456     "news",
1457     "nntp",
1458     "sip",
1459     "sms",
1460     "smsto",
1461     "ssh",
1462     "tel",
1463     "urn",
1464     "webcal",
1465     "xmpp"
1466 };
1467
1468 const int contentBlackListLenth = 14;
1469 char const * const contentBlackList[contentBlackListLenth] = {
1470     "application/x-www-form-urlencoded",
1471     "application/xhtml+xml",
1472     "application/xml",
1473     "image/gif",
1474     "image/jpeg",
1475     "image/png",
1476     "image/svg+xml",
1477     "multipart/x-mixed-replace",
1478     "text/cache-manifest",
1479     "text/css",
1480     "text/html",
1481     "text/ping",
1482     "text/plain",
1483     "text/xml"
1484 };
1485
1486 /**
1487  * Saves user's response from popup to custom handler. Saves Yes/No and remember
1488  * state.
1489  * @param response
1490  * @param customHandler
1491  */
1492 void saveUserResponse(Wrt::Popup::PopupResponse response,
1493                       CustomHandlerDB::CustomHandlerPtr customHandler)
1494 {
1495     switch (response) {
1496     case Wrt::Popup::YES_DO_REMEMBER:
1497         LogDebug("User allowed, remember");
1498         customHandler->user_decision =
1499             static_cast<CustomHandlerDB::HandlerState>
1500             (CustomHandlerDB::Agreed | CustomHandlerDB::DecisionSaved);
1501         break;
1502     case Wrt::Popup::YES_DONT_REMEMBER:
1503         LogDebug("User allowed, don't remember");
1504         customHandler->user_decision = CustomHandlerDB::Agreed;
1505         break;
1506     case Wrt::Popup::NO_DO_REMEMBER:
1507         LogDebug("User didn't allow, remember");
1508         customHandler->user_decision =
1509             static_cast<CustomHandlerDB::HandlerState>
1510             (CustomHandlerDB::Declined | CustomHandlerDB::DecisionSaved);
1511         break;
1512     case Wrt::Popup::NO_DONT_REMEMBER:
1513         LogDebug("User didn't allow, don't remember");
1514         customHandler->user_decision = CustomHandlerDB::Declined;
1515         break;
1516     }
1517 }
1518
1519 //TODO registration, checking if registered and unregistration can be done in
1520 //common functions for both types of handlers. Only white and black lists
1521 //have to be separated
1522 //TODO attach database only one at the start (not in every callback?)
1523 void ViewLogic::protocolHandlerRegistrationCallback(void* data,
1524                                                     Evas_Object* obj,
1525                                                     void* eventInfo)
1526 {
1527     Assert(data);
1528     LogDebug("enter");
1529     CustomHandlerDB::CustomHandlerPtr customHandler =
1530         getCustomHandlerFromData(eventInfo);
1531
1532     std::string scheme = DPL::ToUTF8String(customHandler->target);
1533     if (scheme.empty()) {
1534         LogError("No scheme provided");
1535         //TODO what about securityError?
1536         return;
1537     }
1538     bool matched = false;
1539     //scheme on whiteList
1540     for (int i = 0; i < protocolWhiteListLenth; ++i) {
1541         if (0 == strcmp(protocolWhiteList[i], scheme.c_str())) {
1542             LogDebug("Match found, protocol can be handled");
1543             matched = true;
1544         }
1545     }
1546     if (!matched) {
1547         //starts with web+ and have at least 5 chars (lowercase ASCII)
1548         if (strncmp("web+", scheme.c_str(), 4) || scheme.length() < 5) {
1549             LogWarning("Scheme neither on whitelist nor starts with \"web+\"");
1550             //throw SecurityException
1551             return;
1552         }
1553         int l = 4;
1554         char c = scheme[l];
1555         while (c != '\0') {
1556             if (c < 'a' || c > 'z') {
1557                 LogWarning("Wrong char inside scheme. "
1558                            << "Only lowercase ASCII letters accepted");
1559                 //throw SecurityException
1560                 return;
1561             }
1562             c = scheme[++l];
1563         }
1564     }
1565
1566     ViewLogic* This = static_cast<ViewLogic*>(data);
1567     LogDebug("Creating handlers dao");
1568     This->attachToCustomHandlersDao();
1569     CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1570     CustomHandlerDB::CustomHandlerPtr handler =
1571         handlersDao.getProtocolHandler(customHandler->target,
1572                                        customHandler->url,
1573                                        customHandler->base_url);
1574     if (handler && (handler->user_decision & CustomHandlerDB::DecisionSaved)) {
1575         LogDebug("Protocol already registered - nothing to do");
1576     } else {
1577         LogDebug("Protocol handler not found");
1578         Wrt::Popup::PopupResponse response =
1579             GlobalSettings::PopupsTestModeEnabled() ? Wrt::Popup::
1580                 YES_DO_REMEMBER :
1581             Wrt::Popup::PopupInvoker().askYesNoCheckbox(
1582                 PROTOCOL_HANDLER_ASK_TITLE,
1583                 PROTOCOL_HANDLER_ASK_MSG,
1584                 PROTOCOL_HANDLER_ASK_REMEMBER);
1585         saveUserResponse(response, customHandler);
1586         if (customHandler->user_decision == CustomHandlerDB::Declined) {
1587             return;
1588         }
1589         handlersDao.registerProtocolHandler(*(customHandler.get()));
1590         if (customHandler->user_decision & CustomHandlerDB::Agreed) {
1591             //TODO remove old default handler somehow from appsvc
1592             LogDebug("Registering appservice entry");
1593             int ret = appsvc_set_defapp(APPSVC_OPERATION_VIEW,
1594                                         NULL,
1595                                         DPL::ToUTF8String(
1596                                             customHandler->target).c_str(),
1597                                         DPL::ToUTF8String(This->m_model->
1598                                                               TizenId).c_str());
1599             if (APPSVC_RET_OK != ret) {
1600                 LogWarning("Appsvc entry failed: " << ret);
1601             }
1602         }
1603         LogDebug("Protocal saved");
1604     }
1605
1606     This->detachFromCustomHandlersDao();
1607 }
1608
1609 void ViewLogic::protocolHandlerIsRegisteredCallback(void* data,
1610                                                     Evas_Object* obj,
1611                                                     void* eventInfo)
1612 {
1613     LogDebug("enter");
1614     CustomHandlerDB::CustomHandlerPtr customHandler = getCustomHandlerFromData(
1615             eventInfo);
1616     ViewLogic* This = static_cast<ViewLogic*>(data);
1617     LogDebug("Creating handlers dao");
1618     This->attachToCustomHandlersDao();
1619     CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1620     CustomHandlerDB::CustomHandlerPtr handler =
1621         handlersDao.getProtocolHandler(customHandler->target,
1622                                        customHandler->url,
1623                                        customHandler->base_url);
1624     if (handler) {
1625         if (handler->user_decision & CustomHandlerDB::Agreed) {
1626             ewk_custom_handlers_data_result_set(
1627                 static_cast<Ewk_Custom_Handlers_Data*>(data),
1628                 EWK_CUSTOM_HANDLERS_REGISTERED);
1629         } else {
1630             ewk_custom_handlers_data_result_set(
1631                 static_cast<Ewk_Custom_Handlers_Data*>(data),
1632                 EWK_CUSTOM_HANDLERS_DECLINED);
1633         }
1634     } else {
1635         ewk_custom_handlers_data_result_set(
1636             static_cast<Ewk_Custom_Handlers_Data*>(data),
1637             EWK_CUSTOM_HANDLERS_NEW);
1638     }
1639     This->detachFromCustomHandlersDao();
1640 }
1641
1642 void ViewLogic::protocolHandlerUnregistrationCallback(void* data,
1643                                                       Evas_Object* obj,
1644                                                       void* eventInfo)
1645 {
1646     LogDebug("enter");
1647     CustomHandlerDB::CustomHandlerPtr customHandler =
1648         getCustomHandlerFromData(eventInfo);
1649     ViewLogic* This = static_cast<ViewLogic*>(data);
1650     LogDebug("Creating handlers dao");
1651     This->attachToCustomHandlersDao();
1652     CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1653     CustomHandlerDB::CustomHandlerPtr handlerCheck =
1654         handlersDao.getProtocolHandler(customHandler->target,
1655                                        customHandler->url,
1656                                        customHandler->base_url);
1657     if (handlerCheck) {
1658         if (handlerCheck->user_decision & CustomHandlerDB::Agreed) {
1659             appsvc_unset_defapp(DPL::ToUTF8String(This->m_model->TizenId).c_str());
1660         }
1661
1662         handlersDao.unregisterProtocolHandler(customHandler->target,
1663                                               customHandler->url,
1664                                               customHandler->base_url);
1665     } else {
1666         LogDebug("Nothing to unregister");
1667     }
1668
1669     This->detachFromCustomHandlersDao();
1670 }
1671
1672 void ViewLogic::contentHandlerRegistrationCallback(void* data,
1673                                                    Evas_Object* obj,
1674                                                    void* eventInfo)
1675 {
1676     Assert(data);
1677     LogDebug("enter");
1678     CustomHandlerDB::CustomHandlerPtr customHandler =
1679         getCustomHandlerFromData(eventInfo);
1680
1681     std::string mimeType = DPL::ToUTF8String(customHandler->target);
1682     if (mimeType.empty()) {
1683         LogError("No mimeType provided.");
1684         return;
1685     }
1686     for (int i = 0; i < contentBlackListLenth; ++i) {
1687         if (0 == strcmp(contentBlackList[i], mimeType.c_str())) {
1688             LogWarning("mimeType blacklisted");
1689             //throw SecurityException
1690             return;
1691         }
1692     }
1693
1694     ViewLogic* This = static_cast<ViewLogic*>(data);
1695     LogDebug("Creating handlers dao");
1696     This->attachToCustomHandlersDao();
1697     CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1698     CustomHandlerDB::CustomHandlerPtr handler =
1699         handlersDao.getContentHandler(customHandler->target,
1700                                       customHandler->url,
1701                                       customHandler->base_url);
1702     if (handler && (handler->user_decision & CustomHandlerDB::DecisionSaved)) {
1703         LogDebug("Protocol already registered - nothing to do");
1704     } else {
1705         LogDebug("Protocol handler not found");
1706         Wrt::Popup::PopupResponse response =
1707             GlobalSettings::PopupsTestModeEnabled() ? Wrt::Popup::
1708                 YES_DO_REMEMBER :
1709             Wrt::Popup::PopupInvoker().askYesNoCheckbox(
1710                 CONTENT_HANDLER_ASK_TITLE,
1711                 CONTENT_HANDLER_ASK_MSG,
1712                 CONTENT_HANDLER_AKS_REMEMBER);
1713         saveUserResponse(response, customHandler);
1714         if (customHandler->user_decision == CustomHandlerDB::Declined) {
1715             return;
1716         }
1717         handlersDao.registerContentHandler(*(customHandler.get()));
1718         if (customHandler->user_decision & CustomHandlerDB::Agreed) {
1719             //TODO remove old default handler somehow from appsvc
1720             LogDebug("Registering appservice entry");
1721             int ret = appsvc_set_defapp(APPSVC_OPERATION_VIEW,
1722                                         DPL::ToUTF8String(
1723                                             customHandler->target).c_str(),
1724                                         NULL,
1725                                         DPL::ToUTF8String(This->m_model->
1726                                                               TizenId).c_str());
1727             if (APPSVC_RET_OK != ret) {
1728                 LogWarning("Appsvc entry failed: " << ret);
1729             }
1730         }
1731         LogDebug("Content saved");
1732     }
1733     This->detachFromCustomHandlersDao();
1734 }
1735
1736 void ViewLogic::contentHandlerIsRegisteredCallback(void* data,
1737                                                    Evas_Object* obj,
1738                                                    void* eventInfo)
1739 {
1740     LogDebug("enter");
1741     CustomHandlerDB::CustomHandlerPtr customHandler =
1742         getCustomHandlerFromData(eventInfo);
1743     ViewLogic* This = static_cast<ViewLogic*>(data);
1744     LogDebug("Creating handlers dao");
1745
1746     This->attachToCustomHandlersDao();
1747     CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1748     CustomHandlerDB::CustomHandlerPtr handler =
1749         handlersDao.getContentHandler(customHandler->target,
1750                                       customHandler->url,
1751                                       customHandler->base_url);
1752     if (handler) {
1753         if (handler->user_decision & CustomHandlerDB::Agreed) {
1754             ewk_custom_handlers_data_result_set(
1755                 static_cast<Ewk_Custom_Handlers_Data*>(data),
1756                 EWK_CUSTOM_HANDLERS_REGISTERED);
1757         } else {
1758             ewk_custom_handlers_data_result_set(
1759                 static_cast<Ewk_Custom_Handlers_Data*>(data),
1760                 EWK_CUSTOM_HANDLERS_DECLINED);
1761         }
1762     } else {
1763         ewk_custom_handlers_data_result_set(
1764             static_cast<Ewk_Custom_Handlers_Data*>(data),
1765             EWK_CUSTOM_HANDLERS_NEW);
1766     }
1767     This->detachFromCustomHandlersDao();
1768 }
1769
1770 void ViewLogic::contentHandlerUnregistrationCallback(void* data,
1771                                                      Evas_Object* obj,
1772                                                      void* eventInfo)
1773 {
1774     LogDebug("enter");
1775     CustomHandlerDB::CustomHandlerPtr customHandler =
1776         getCustomHandlerFromData(eventInfo);
1777     ViewLogic* This = static_cast<ViewLogic*>(data);
1778     LogDebug("Creating handlers dao");
1779     This->attachToCustomHandlersDao();
1780     CustomHandlerDB::CustomHandlerDAO handlersDao(This->m_model->TizenId);
1781     CustomHandlerDB::CustomHandlerPtr handlerCheck =
1782         handlersDao.getContentHandler(customHandler->target,
1783                                       customHandler->url,
1784                                       customHandler->base_url);
1785     if (handlerCheck) {
1786         if (handlerCheck->user_decision & CustomHandlerDB::Agreed) {
1787             appsvc_unset_defapp(DPL::ToUTF8String(This->m_model->TizenId).c_str());
1788         }
1789
1790         handlersDao.unregisterContentHandler(customHandler->target,
1791                                              customHandler->url,
1792                                              customHandler->base_url);
1793     } else {
1794         LogDebug("Nothing to unregister");
1795     }
1796     This->detachFromCustomHandlersDao();
1797 }
1798
1799 void ViewLogic::didRunJavaScriptCallback(
1800     Evas_Object* /*obj*/,
1801     const char* result,
1802     void* /*userData*/)
1803 {
1804     LogInfo("didRunJavaScriptCallback called");
1805     LogInfo("result = " << result);
1806 }
1807
1808 Eina_Bool ViewLogic::windowCloseIdlerCallback(void* data)
1809 {
1810     LogDebug("closeIdlerCallback");
1811     ViewLogic* This = static_cast<ViewLogic*>(data);
1812     This->windowClose();
1813     return ECORE_CALLBACK_CANCEL;
1814 }
1815
1816
1817 void ViewLogic::databaseUsagePermissionRequestCallback(
1818     void* data,
1819     Evas_Object* /*obj*/,
1820     void* eventInfo)
1821 {
1822     LogDebug("databaseUsagePermissionRequestCallback called");
1823     Assert(data);
1824     ViewLogic* This = static_cast<ViewLogic*>(data);
1825     Assert(eventInfo);
1826
1827     if (This->m_securityOriginSupport->isNeedPermissionCheck(
1828             SecurityOriginDB::FEATURE_WEB_DATABASE)
1829         == WrtDB::SETTINGS_TYPE_OFF)
1830     {
1831         // default value is deny
1832         return;
1833     }
1834     ViewModule::WebStorageSupport::webStorageCreatePermissionRequest(
1835         This->m_window,
1836         This->m_securityOriginSupport->getSecurityOriginDAO(),
1837         eventInfo);
1838     return;
1839 }
1840
1841 void ViewLogic::fileSystemPermissionRequestCallback(
1842     void* data,
1843     Evas_Object* /*obj*/,
1844     void* eventInfo)
1845 {
1846     LogDebug("fileSystemPermissionRequestCallback called");
1847     Assert(data);
1848     ViewLogic* This = static_cast<ViewLogic*>(data);
1849
1850     if (This->m_securityOriginSupport->isNeedPermissionCheck(
1851             SecurityOriginDB::FEATURE_FILE_SYSTEM_ACCESS)
1852         == WrtDB::SETTINGS_TYPE_OFF)
1853     {
1854         Ewk_Context_File_System_Permission* fileSystemPermission =
1855             static_cast<Ewk_Context_File_System_Permission*>(eventInfo);
1856         ewk_context_file_system_permission_allow_set(fileSystemPermission,
1857                                                      EINA_FALSE);
1858         return;
1859     }
1860
1861     Assert(eventInfo);
1862     ViewModule::FileSystemSupport::fileSystemPermissionRequest(
1863         This->m_window,
1864         This->m_securityOriginSupport->getSecurityOriginDAO(),
1865         eventInfo);
1866 }
1867
1868 void ViewLogic::certificateConfirmRequestCallback(
1869     void* data,
1870     Evas_Object* /*obj*/,
1871     void* eventInfo)
1872 {
1873     LogDebug("certificateConfirmRequestCallback called");
1874
1875     Assert(data);
1876     ViewLogic* This = static_cast<ViewLogic*>(data);
1877     Assert(eventInfo);
1878     Ewk_Certificate_Policy_Decision* certificatePolicyDecision =
1879         static_cast<Ewk_Certificate_Policy_Decision*>(eventInfo);
1880
1881     bool status = This->askUserForCertificateConfirm();
1882     if (!status) {
1883         ewk_certificate_policy_decision_allowed_set(
1884             certificatePolicyDecision,
1885             EINA_FALSE);
1886     } else {
1887         ewk_certificate_policy_decision_allowed_set(
1888             certificatePolicyDecision,
1889             EINA_TRUE);
1890     }
1891 }
1892
1893 bool ViewLogic::askUserForCertificateConfirm()
1894 {
1895     return Wrt::Popup::PopupInvoker().askYesNo(
1896                CERTIFICATE_CONFIRM_REQUEST_ASK_TITLE,
1897                CERTIFICATE_CONFIRM_REQUEST_ASK_BODY);
1898 }
1899
1900 void ViewLogic::rememberBlockedURI(const DPL::String& inputURI)
1901 {
1902     m_blockedUri = DPL::ToUTF8String(inputURI);
1903     LogInfo("set blocked uri to open browser later : " << m_blockedUri);
1904     return;
1905 }
1906
1907 std::string ViewLogic::requestUriChanged(const DPL::String& changedURL)
1908 {
1909     using namespace ViewModule::SecuritySupport;
1910
1911     std::string url = DPL::ToUTF8String(changedURL);
1912     LogInfo("URL = [" << url << "]");
1913
1914     // check WARP
1915     // If url is same to URICHANGE_BLOCKED_URL,
1916     // this url has been already blocked by willsend.
1917     // So current page should be moved to previous page
1918     if (url == URICHANGE_BLOCKED_URL) {
1919         if (m_model->Type.Get().appType == WrtDB::APP_TYPE_TIZENWEBAPP) {
1920             // block this page and open it in browser
1921             LogDebug("Request was blocked by WARP: " << url.c_str());
1922             if (!m_blockedUri.empty()) {
1923                 LogDebug("open browser : " << m_blockedUri);
1924                 bundle* bundleData = bundle_create();
1925                 appsvc_set_operation(bundleData, APPSVC_OPERATION_VIEW);
1926                 appsvc_set_uri(bundleData, m_blockedUri.c_str());
1927                 CONTROLLER_POST_EVENT(
1928                     ApplicationLauncher,
1929                     ApplicationLauncherEvents::LaunchApplicationByAppService(
1930                         bundleData,
1931                         NULL,
1932                         NULL));
1933                 m_blockedUri = std::string();
1934             }
1935         }
1936         if (ewk_view_back_possible(m_currentEwkView)) {
1937             // go back to previous page
1938             ewk_view_back(m_currentEwkView);
1939         } else {
1940             // stop current page
1941             ewk_view_stop(m_currentEwkView);
1942             ecore_idler_add(windowCloseIdlerCallback, this);
1943         }
1944
1945         // This is used in case of returning previous page
1946         m_currentUri = url;
1947         return URICHANGE_PLUGIN_NO_CHANGE;
1948     }
1949
1950     m_currentUri = url;
1951
1952     // Check if this url with 'http' or 'https' is included in whitelist,
1953     // which has lists of accessible external documents and
1954     // used for ONLY Tizen app
1955     std::string matchedScheme;
1956     std::string matchedUri;
1957     pcrecpp::RE(PATTERN_URI_CHANGE).PartialMatch(url.c_str(),
1958                                                  &matchedUri,
1959                                                  &matchedScheme);
1960     ViewModule::Scheme scheme(matchedScheme);
1961     if (scheme.GetType() == ViewModule::Scheme::HTTP ||
1962         scheme.GetType() == ViewModule::Scheme::HTTPS)
1963     {
1964         if (m_model->Type.Get().appType == WrtDB::APP_TYPE_TIZENWEBAPP) {
1965             if (!checkWhitelist(url.c_str())) {
1966                 LogInfo("This uri is not included in white document list");
1967                 return URICHANGE_PLUGIN_STOP_ONLY;
1968             }
1969             LogInfo("This url is included in WhiteList");
1970         } else {
1971             // For WAC app, WRT should block access of device api
1972             // for external documents
1973             return URICHANGE_PLUGIN_STOP_ONLY;
1974         }
1975     }
1976
1977     // register javascript object for plugins to be used
1978     LogInfo("Register Plugin Objects");
1979     return URICHANGE_PLUGIN_RESTART;
1980 }
1981
1982 void ViewLogic::windowClose()
1983 {
1984     LogDebug("windowClose");
1985     Assert(m_closedEwkView && "no closed webview");
1986
1987     if (1 >= m_ewkViewList.size()) {
1988         if (!m_cbs->webkitExit.empty()) {
1989             m_cbs->webkitExit();
1990         }
1991     } else {
1992         // call user callbacks
1993         if (!m_cbs->bufferUnset.empty()) {
1994             m_cbs->bufferUnset(m_currentEwkView);
1995         }
1996         if (!m_cbs->windowClose.empty()) {
1997             m_cbs->windowClose(m_closedEwkView);
1998         }
1999         removeEwkView(m_closedEwkView);
2000
2001         // get latest ewkView
2002         m_currentEwkView = m_ewkViewList.back();
2003         const char* uri = ewk_view_url_get(m_currentEwkView);
2004         if (NULL == uri || 0 == strlen(uri)) {
2005             m_currentUri.clear();
2006         } else {
2007             m_currentUri = uri;
2008         }
2009
2010         // resume ewkView
2011         /* In case we support many pages in parallel
2012          * then view is not suspended*/
2013         //resumeEwkView(m_currentEwkView);
2014         setEwkViewVisible(m_currentEwkView);
2015
2016         // show ewkView
2017         if (!m_cbs->bufferSet.empty()) {
2018             m_cbs->bufferSet(m_currentEwkView);
2019         }
2020     }
2021 }
2022