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