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