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