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