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