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