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