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