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