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