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