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