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