0eb14c921d9e054cdfeec06f69bf2b23652ac859
[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
38 #include <common/application_data.h>
39 #include <common/application_launcher.h>
40 #include <common/scheme.h>
41
42 #include <common/view_logic_apps_support.h>
43 #include <common/view_logic_custom_header_support.h>
44 #include <common/view_logic_password_support.h>
45 #include <common/view_logic_security_support.h>
46 #include <common/view_logic_storage_support.h>
47 #include <common/view_logic_uri_support.h>
48 #include <common/view_logic_user_agent_support.h>
49 #include <common/view_logic_vibration_support.h>
50 #include <common/view_logic_web_notification_support.h>
51 #include <view_logic_scheme_support.h>
52 #include "view_logic_geolocation_support_webkit2.h"
53 #include "bundles/plugin_module_support.h"
54
55 #include <EWebKit2.h>
56 #include <js_overlay_types.h>
57 #include <i_runnable_widget_object.h>
58 #include <PopupInvoker.h>
59 #include <profiling_util.h>
60
61 namespace {
62 const char * const bundlePath = "/usr/lib/wrt-wk2-bundles/libwrt-wk2-bundle.so";
63 const char * const uriBlockedMessageName = "uri_block_msg";
64 const char * const uriChangedMessageName = "uri_changed_msg";
65 const char * const URICHANGE_PLUGIN_STOP_ONLY = "plugin_stop_only";
66 const char * const URICHANGE_PLUGIN_RESTART = "plugin_restart";
67 const char * const URICHANGE_PLUGIN_NO_CHANGE = "plugin_no_change";
68 const char * const URICHANGE_BLOCKED_URL = "null";
69 const char* PATTERN_URI_CHANGE = "^(([^:/\\?#]+)://[^\\?#]*)";
70 const int MAX_NUM_CONTEXT_MENU_ITEMS = 10;
71
72 // WKPageLoaderClient
73 const char * const EWK_LOAD_STARTED = "load,started";
74 const char * const EWK_LOAD_FINISHED = "load,finished";
75 const char * const EWK_TITLE_CHANGED = "title,changed";
76 const char * const EWK_LOAD_PROGRESS = "load,progress";
77 const char * const EWK_LOAD_PROGRESS_FINISHED = "load,progress,finished";
78 const char * const EWK_PROCESS_CRASHED = "process,crashed";
79 // WKPageUIClient
80 const char * const EWK_CREATE_WINDOW = "create,window";
81 const char * const EWK_CLOSE_WINDOW = "close,window";
82 // WKPagePolicyClient
83 const char * const EWK_POLICY_NAVIGATION_DECIDE = "policy,navigation,decide";
84 const char * const EWK_POLICY_NEWWINDOW_DECIDE = "policy,newwindow,decide";
85 const char * const EWK_POLICY_RESPONSE_DECIDE = "policy,response,decide";
86 // WKPageContextMenuClient
87 const char * const EWK_CONTEXTMENU_CUSTOMIZE = "contextmenu,customize";
88 // WKPageFormClient
89 const char * const EWK_FORM_SUBMIT = "form,submit";
90 // EWK Geolocation Callback
91 const char * const EWK_REQUEST_GEOLOCATION_PERMISSION =
92     "request,geolocation,permission";
93 // EWK Notification Callback
94 const char * const EWK_NOTIFICATION_SHOW = "notification,show";
95 const char * const EWK_NOTIFICATION_CANCEL = "notification,cancel";
96 const char * const EWK_NOTIFICATION_PERMISSION_REQUEST =
97     "notification,permission,request";
98 // EWK Vibration Callback
99 const char * const EWK_VIBRATION_VIBRATE = "vibration,vibrate";
100 const char * const EWK_VIBRATION_CANCEL = "vibration,cancel";
101
102 const char * const EWK_CONTEXT_EXCEEDED_QUOATA  = "database,quota,exceeded";
103 const char * const EWK_CONTEXT_FILE_SYSTEM_PERMISSION = "filesystem,permission,request";
104 const char * const EWK_FULLSCREEN_ENTER = "fullscreen,enterfullscreen";
105 const char * const EWK_FULLSCREEN_EXIT = "fullscreen,exitfullscreen";
106
107 // DataBase Use Ask Title
108 const char * const DATABASE_USE_ASK_TITLE = "Increase Database Size?";
109 const char * const FILESYSTEM_USE_ASK_TITLE = "Use FileSystem?";
110 }
111
112 ViewLogic::ViewLogic():
113     m_ewkContext(0),
114     m_currentEwkView(0),
115     m_window(NULL),
116     m_model(0),
117     m_cbs(new WRT::UserDelegates),
118     m_appsSupport(new ViewModule::AppsSupport()),
119     m_vibrationSupport(NULL)
120 {
121 }
122
123 ViewLogic::~ViewLogic ()
124 {
125 }
126
127 void ViewLogic::createWebView(Ewk_Context* context,
128                               Evas_Object* window)
129 {
130     LogDebug("");
131     initializeEwkContext(context);
132     Assert(NULL != m_ewkContext);
133     Assert(window);
134     m_window = window;
135     createEwkView();
136 }
137
138 void ViewLogic::destroyWebView()
139 {
140     if (m_ewkContext) {
141         finalizeEwkContext();
142     }
143 }
144
145 void ViewLogic::initialize()
146 {
147     LogDebug("Initializing");
148     ApplicationLauncherSingleton::Instance().Touch();
149     appcore_set_event_callback(
150         APPCORE_EVENT_LOW_MEMORY,
151         &appcoreLowMemoryCallback,
152         this);
153 }
154
155 void ViewLogic::terminate()
156 {
157     LogDebug("terminating view logic");
158     if (m_model) {
159         hideWidget();
160     } else {
161         LogError("Widget model not created");
162     }
163     LogDebug("done");
164 }
165
166 void ViewLogic::prepareView(WidgetModel* m, const std::string &startUrl)
167 {
168     LogDebug("View prepare");
169
170     Assert(m);
171     m_model = m;
172     m_startUrl = ViewModule::UriSupport::getUri(m_model, startUrl);
173     Assert(NULL != m_ewkContext);
174     Assert(m_window);
175
176     ADD_PROFILING_POINT("initializeSupport", "start");
177     initializeSupport();
178     ADD_PROFILING_POINT("initializeSupport", "stop");
179     setStartPage();
180     ewkClientInit(m_currentEwkView);
181     ADD_PROFILING_POINT("prepareEwkView", "start");
182     prepareEwkView(m_currentEwkView);
183     ADD_PROFILING_POINT("prepareEwkView", "stop");
184     initializePluginLoading();
185 }
186
187 void ViewLogic::showWidget()
188 {
189     LogDebug("showing widget");
190     Assert(NULL != m_currentEwkView && "ewk_view not created at this point");
191     if (m_currentUri.empty()) {
192         LogError("Localized current URI doesn't exist");
193         return;
194     }
195
196     LogInfo("m_currentUri: " << m_currentUri);
197
198     // load page
199     ewk_view_url_set(m_currentEwkView, m_currentUri.c_str());
200
201     if (!m_cbs->bufferSet.empty()) {
202         m_cbs->bufferSet(m_currentEwkView);
203     }
204 }
205
206 void ViewLogic::hideWidget()
207 {
208     LogDebug("hiding widget");
209     ViewModule::StorageSupport::deinitializeStorage(m_model);
210     m_appsSupport->deinitialize();
211
212     // temp
213     // m_vibrationSupport->deinitialize();
214
215     while (m_ewkViewList.size()) {
216         LogInfo("pop webview: " << m_ewkViewList.back());
217         removeEwkView(m_ewkViewList.back());
218     }
219     m_ewkViewList.clear();
220 }
221
222 void ViewLogic::suspendWidget()
223 {
224     LogInfo("Pausing widget");
225     Assert(m_model);
226
227     if (!m_currentEwkView) {
228         LogWarning("Cannot suspend widget without view");
229     } else {
230         suspendWebkit(m_currentEwkView);
231     }
232
233     // call user callback
234     if (!m_cbs->suspend.empty()) {
235         m_cbs->suspend(true);
236     }
237 };
238
239 void ViewLogic::resumeWidget()
240 {
241     LogInfo("Resume widget");
242     Assert(m_model);
243
244     if (m_currentEwkView) {
245         resumeWebkit(m_currentEwkView);
246     }
247
248     if (m_window) {
249         elm_win_activate(m_window);
250     }
251     evas_object_focus_set(m_currentEwkView, EINA_TRUE);
252
253     // call user callback
254     if (!m_cbs->resume.empty()) {
255         m_cbs->resume(true);
256     }
257 };
258
259 void ViewLogic::resetWidget()
260 {
261     LogInfo("Resetting Widget");
262
263     // check if already created webview exists
264     if (!m_ewkViewList.size()) {
265         // create new webview
266         createEwkView();
267         setStartPage();
268         ewkClientInit(m_currentEwkView);
269         prepareEwkView(m_currentEwkView);
270     } else {
271         // check if current url is service url for this tizen service
272         std::string requestedUri =
273                 ViewModule::UriSupport::getUri(m_model, m_startUrl);
274         DPL::OptionalString servicedUri = ViewModule::UriSupport::localizeURI(
275                 DPL::FromUTF8String(requestedUri.c_str()),
276                 m_model);
277
278         const char* currentUri = ewk_view_uri_get(m_currentEwkView);
279         if (!currentUri && 0 == strlen(currentUri)) {
280             LogError("Fail to get uri from ewk_view_uri_get");
281             return;
282         }
283         if (DPL::ToUTF8String(*servicedUri) == currentUri) {
284             // set only encoded bundle
285             double scale = elm_config_scale_get();
286             PluginModuleSupport::setCustomProperties(
287                 m_ewkContext,
288                 &scale,
289                 ApplicationDataSingleton::Instance().getEncodedBundle());
290             // dispatch 'appservice' js event
291             PluginModuleSupport::dispatchJavaScriptEvent(
292                 m_ewkContext,
293                 WrtPlugins::W3C::ServiceCustomEvent,
294                 NULL);
295             ewk_view_reload(m_currentEwkView);
296         } else {
297             m_currentUri = DPL::ToUTF8String(*servicedUri);
298             // inform wrt information for plugin loading to web process
299             PluginModuleSupport::start(
300                 m_ewkContext,
301                 m_model->Handle.Get(),
302                 elm_config_scale_get(),
303                 ApplicationDataSingleton::Instance().getEncodedBundle(),
304                 m_theme.c_str(),
305                 m_model->SettingList.Get().isEncrypted());
306             // load page
307             ewk_view_url_set(m_currentEwkView, m_currentUri.c_str());
308         }
309     }
310
311     resumeWebkit(m_currentEwkView);
312
313     // call user callback
314     if (!m_cbs->reset.empty()) {
315         m_cbs->reset(true);
316     }
317     if (!m_cbs->bufferSet.empty()) {
318         m_cbs->bufferSet(m_currentEwkView);
319     }
320 }
321
322 void ViewLogic::backward()
323 {
324     if (ewk_view_back_possible(m_currentEwkView)) {
325         ewk_view_back(m_currentEwkView);
326     } else {
327         if (1 >= m_ewkViewList.size()) {
328             // If there is no previous page, widget move to backgroud.
329             LogInfo("Widget move to backgroud");
330             elm_win_lower(m_window);
331         } else {
332             // Back to previous webview
333             LogInfo("Widget move to previous webview");
334             ecore_idler_add(windowCloseIdlerCallback, this);
335         }
336     }
337 }
338
339 void ViewLogic::reload()
340 {
341     ewk_view_reload(m_currentEwkView);
342 }
343
344 void ViewLogic::forward()
345 {
346     if (ewk_view_forward_possible(m_currentEwkView)) {
347         ewk_view_forward(m_currentEwkView);
348     }
349 }
350
351 void ViewLogic::reloadStartPage()
352 {
353     LogInfo("Reload Start Page");
354
355     if (m_ewkViewList.size() == 0) {
356         // create new webview
357         createEwkView();
358         ewkClientInit(m_currentEwkView);
359     } else {
360         // close opened windows
361         while (m_ewkViewList.size() > 1) {
362             if (!m_cbs->bufferUnset.empty()) {
363                 m_cbs->bufferUnset(m_currentEwkView);
364             }
365             removeEwkView(m_currentEwkView);
366             m_currentEwkView = m_ewkViewList.back();
367         }
368         LogInfo("Close ewkViews done : m_ewkViewList.size() = "
369                 << m_ewkViewList.size());
370     }
371
372     setStartPage();
373     prepareEwkView(m_currentEwkView);
374     initializePluginLoading();
375
376     // load page
377     ewk_view_url_set(m_currentEwkView, m_currentUri.c_str());
378
379     // show ewkView
380     if (!m_cbs->bufferSet.empty()) {
381         m_cbs->bufferSet(m_currentEwkView);
382     }
383     LogInfo("Reloading Start Page is done!");
384 }
385
386 Evas_Object* ViewLogic::getCurrentWebview()
387 {
388     LogInfo("get current webview");
389     return m_currentEwkView;
390 }
391
392 void ViewLogic::fireJavascriptEvent(int event, void* data)
393 {
394     PluginModuleSupport::dispatchJavaScriptEvent(
395         m_ewkContext,
396         static_cast<WrtPlugins::W3C::CustomEventType>(event),
397         data);
398 }
399
400 void ViewLogic::setUserCallbacks(const WRT::UserDelegatesPtr& cbs)
401 {
402     m_cbs = cbs;
403 }
404
405 void ViewLogic::initializeEwkContext(Ewk_Context* newEwkContext)
406 {
407     LogInfo("initializeEwkContext called");
408     Assert(newEwkContext && "Ewk_Context provided can not be null");
409     // bundle callback setting
410     ewk_context_message_from_injected_bundle_callback_set(
411         newEwkContext,
412         contextMessageFromInjectedBundleCallback,
413         static_cast<void*>(this));
414
415     // proxy server setting
416     char *proxyAddress = vconf_get_str(VCONFKEY_NETWORK_PROXY);
417     if ((!proxyAddress) || (strlen(proxyAddress) == 0)
418         || (strstr(proxyAddress, "0.0.0.0")))
419     {
420         LogInfo("proxy address is empty");
421         ewk_context_proxy_uri_set(newEwkContext, NULL);
422     } else {
423         LogInfo("proxy address [" << proxyAddress << "]");
424         ewk_context_proxy_uri_set(newEwkContext,  proxyAddress);
425     }
426
427     if (proxyAddress) {
428         free(proxyAddress);
429         proxyAddress = NULL;
430     }
431
432     // theme setting
433     const char *theme = elm_theme_get(NULL);
434     if (theme) {
435         m_theme = theme;
436         LogInfo("theme is " << m_theme);
437     }
438
439     // Ewk download callback (WKContextDownloadClient)
440     ewk_context_did_start_download_callback_set(
441         newEwkContext,
442         didStartDownloadCallback,
443         this);
444
445     // set to member value
446     m_ewkContext = newEwkContext;
447 }
448
449 void ViewLogic::finalizeEwkContext()
450 {
451     LogInfo("finalizeEwkContext called");
452     ewk_context_message_from_injected_bundle_callback_set(
453             m_ewkContext,
454             NULL,
455             NULL);
456 //    ewk_context_delete(m_ewkContext);
457 //    m_ewkContext = 0;
458 }
459
460 void ViewLogic::initializeSupport()
461 {
462     // set local stroage database path
463     WrtDB::WidgetDAOReadOnly dao(m_model->Handle.Get());
464     ewk_context_web_storage_path_set(m_ewkContext,
465                                      dao.getPrivateLocalStoragePath().c_str());
466     m_schemeSupport.reset(new SchemeSupport(m_model->Type.Get().appType));
467     ViewModule::StorageSupport::initializeStorage(m_model);
468     m_appsSupport->initialize(m_model);
469
470     // temp
471     // m_vibrationSupport->initialize();
472
473     ViewModule::GeolocationSupport::Webkit2::initialize(m_model->TizenId.Get());
474     ViewModule::GeolocationSupport::Webkit2::
475         adjustGeolocationModuleState(m_currentEwkView);
476 }
477
478 void ViewLogic::initializePluginLoading()
479 {
480     // inform wrt information for plugin loading to web process
481     PluginModuleSupport::start(
482         m_ewkContext,
483         m_model->Handle.Get(),
484         elm_config_scale_get(),
485         ApplicationDataSingleton::Instance().getEncodedBundle(),
486         m_theme.c_str(),
487         m_model->SettingList.Get().isEncrypted());
488 }
489
490 void ViewLogic::ewkClientInit(Evas_Object *wkView) {
491     Assert(NULL != wkView && "ewk_view not created at this point");
492     ViewModule::GeolocationSupport::Webkit2::
493         initialize(m_model->TizenId.Get());
494
495     // WKPageLoaderClient
496     evas_object_smart_callback_add(
497         wkView,
498         EWK_LOAD_STARTED,
499         loadStartedCallback,
500         this);
501     evas_object_smart_callback_add(
502         wkView,
503         EWK_LOAD_FINISHED,
504         loadFinishedCallback,
505         this);
506     evas_object_smart_callback_add(
507         wkView,
508         EWK_TITLE_CHANGED,
509         titleChangedCallback,
510         this);
511     evas_object_smart_callback_add(
512         wkView,
513         EWK_LOAD_PROGRESS,
514         loadProgressCallback,
515         this);
516     evas_object_smart_callback_add(
517         wkView,
518         EWK_LOAD_PROGRESS_FINISHED,
519         loadProgressFinishedCallback,
520         this);
521     evas_object_smart_callback_add(
522         wkView,
523         EWK_PROCESS_CRASHED,
524         processCrashedCallback,
525         this);
526
527     // WKPageUIClient
528     evas_object_smart_callback_add(
529         wkView,
530         EWK_CREATE_WINDOW,
531         createWindowCallback,
532         this);
533     evas_object_smart_callback_add(
534         wkView,
535         EWK_CLOSE_WINDOW,
536         closeWindowCallback,
537         this);
538
539     // WKPagePolicyClient
540     evas_object_smart_callback_add(
541         wkView,
542         EWK_POLICY_NAVIGATION_DECIDE,
543         policyNavigationDecideCallback,
544         this);
545     evas_object_smart_callback_add(
546         wkView,
547         EWK_POLICY_NEWWINDOW_DECIDE,
548         policyNewWindowDecideCallback,
549         this);
550     evas_object_smart_callback_add(
551         wkView,
552         EWK_POLICY_RESPONSE_DECIDE,
553         pageResponseDecideCallback,
554         this);
555
556     // WKPageContextMenuClient
557     evas_object_smart_callback_add(
558         wkView,
559         EWK_CONTEXTMENU_CUSTOMIZE,
560         contextmenuCustomizeCallback,
561         this);
562
563     // WKPageFormClient
564     evas_object_smart_callback_add(
565         wkView,
566         EWK_FORM_SUBMIT,
567         formSubmitCallback,
568         this);
569
570     // EWK Geolocation Callback
571     evas_object_smart_callback_add(
572         wkView,
573         EWK_REQUEST_GEOLOCATION_PERMISSION,
574         geolocationPermissionRequestCallback,
575         this);
576
577     // EWK Notification Callback
578     evas_object_smart_callback_add(
579         wkView,
580         EWK_NOTIFICATION_SHOW,
581         notificationShowCallback,
582         this);
583     evas_object_smart_callback_add(
584         wkView,
585         EWK_NOTIFICATION_CANCEL,
586         notificationCancelCallback,
587         this);
588     evas_object_smart_callback_add(
589         wkView,
590         EWK_NOTIFICATION_PERMISSION_REQUEST,
591         notificationPermissionRequestCallback,
592         this);
593
594     // EWK Vibration Callback
595     evas_object_smart_callback_add(
596         wkView,
597         EWK_VIBRATION_VIBRATE,
598         vibrationVibrateCallback,
599         this);
600     evas_object_smart_callback_add(
601         wkView,
602         EWK_VIBRATION_CANCEL,
603         vibrationCancelCallback,
604         this);
605     evas_object_smart_callback_add(
606         wkView,
607         EWK_CONTEXT_EXCEEDED_QUOATA,
608         databaseUsagePermissionRequestCallback,
609         this);
610     // The followings are provisional comment for preventing popup
611     //evas_object_smart_callback_add(
612         //wkView,
613         //EWK_CONTEXT_FILE_SYSTEM_PERMISSION,
614         //fileSystemPermissionRequestCallback,
615         //this);
616
617     // EWK Orientation Callback
618     ewk_view_orientation_lock_callback_set(
619         wkView,
620         orientationLockCallback,
621         this);
622
623     // Fullscreen API callbacks
624     evas_object_smart_callback_add(
625         wkView,
626         EWK_FULLSCREEN_ENTER,
627         enterFullscreenCallback,
628         this);
629     evas_object_smart_callback_add(
630         wkView,
631         EWK_FULLSCREEN_EXIT,
632         exitFullscreenCallback,
633         this);
634 }
635
636 void ViewLogic::ewkClientDeinit(Evas_Object *wkView) {
637     LogDebug("ewkClientDeinit");
638     Assert(NULL != wkView && "ewk_view not created at this point");
639
640     // WKPageLoaderClient
641     evas_object_smart_callback_del(
642         wkView,
643         EWK_LOAD_STARTED,
644         loadStartedCallback);
645     evas_object_smart_callback_del(
646         wkView,
647         EWK_LOAD_FINISHED,
648         loadFinishedCallback);
649     evas_object_smart_callback_del(
650         wkView,
651         EWK_TITLE_CHANGED,
652         titleChangedCallback);
653     evas_object_smart_callback_del(
654         wkView,
655         EWK_LOAD_PROGRESS,
656         loadProgressCallback);
657     evas_object_smart_callback_del(
658         wkView,
659         EWK_LOAD_PROGRESS_FINISHED,
660         loadProgressFinishedCallback);
661     evas_object_smart_callback_del(
662         wkView,
663         EWK_PROCESS_CRASHED,
664         loadProgressCallback);
665
666     // WKPageUIClient
667     evas_object_smart_callback_del(
668         wkView,
669         EWK_CREATE_WINDOW,
670         createWindowCallback);
671     evas_object_smart_callback_del(
672         wkView,
673         EWK_CLOSE_WINDOW,
674         closeWindowCallback);
675
676     // WKPagePolicyClient
677     evas_object_smart_callback_del(
678         wkView,
679         EWK_POLICY_NAVIGATION_DECIDE,
680         policyNavigationDecideCallback);
681     evas_object_smart_callback_del(
682         wkView,
683         EWK_POLICY_NEWWINDOW_DECIDE,
684         policyNewWindowDecideCallback);
685     evas_object_smart_callback_del(
686         wkView,
687         EWK_POLICY_RESPONSE_DECIDE,
688         pageResponseDecideCallback);
689
690     // WKPageContextMenuClient
691     evas_object_smart_callback_del(
692         wkView,
693         EWK_CONTEXTMENU_CUSTOMIZE,
694         contextmenuCustomizeCallback);
695
696     // WKPageFormClient
697     evas_object_smart_callback_del(
698         wkView,
699         EWK_FORM_SUBMIT,
700         formSubmitCallback);
701
702     // EWK Geolocation Callback
703     evas_object_smart_callback_del(
704         wkView,
705         EWK_REQUEST_GEOLOCATION_PERMISSION,
706         geolocationPermissionRequestCallback);
707
708     // EWK Notification Callback
709     evas_object_smart_callback_del(
710         wkView,
711         EWK_NOTIFICATION_SHOW,
712         notificationShowCallback);
713     evas_object_smart_callback_del(
714         wkView,
715         EWK_NOTIFICATION_CANCEL,
716         notificationCancelCallback);
717     evas_object_smart_callback_del(
718         wkView,
719         EWK_NOTIFICATION_PERMISSION_REQUEST,
720         notificationPermissionRequestCallback);
721
722     // EWK Vibration Callback
723     evas_object_smart_callback_del(
724         wkView,
725         EWK_VIBRATION_VIBRATE,
726         vibrationVibrateCallback);
727     evas_object_smart_callback_del(
728         wkView,
729         EWK_VIBRATION_CANCEL,
730         vibrationCancelCallback);
731
732     evas_object_smart_callback_del(
733         wkView,
734         EWK_CONTEXT_EXCEEDED_QUOATA,
735         databaseUsagePermissionRequestCallback);
736     //The followings are provisional comment for preventing popup
737     //evas_object_smart_callback_del(
738         //wkView,
739         //EWK_CONTEXT_FILE_SYSTEM_PERMISSION,
740         //fileSystemPermissionRequestCallback);
741
742     // EWK Orientation Callback
743     ewk_view_orientation_lock_callback_set(
744         wkView,
745         NULL,
746         NULL);
747 }
748
749 void ViewLogic::createEwkView()
750 {
751     LogDebug("createEwkVeiw");
752     ADD_PROFILING_POINT("ewk_view_add_with_context", "start");
753     Evas_Object* newEwkView = ewk_view_add_with_context(
754         evas_object_evas_get(m_window),
755         m_ewkContext);
756     ADD_PROFILING_POINT("ewk_view_add_with_context", "stop");
757
758     if (!newEwkView) {
759         LogError("WKView creation failed");
760         Assert(false);
761     }
762
763     // set cookie policy
764     // even arguments pass the ewkContext, this API should be called
765     // after webkit Evas_Object is created
766     ewk_context_cookies_policy_set(m_ewkContext, EWK_COOKIE_JAR_ACCEPT_ALWAYS);
767
768     LogInfo("push webview: " << newEwkView);
769     m_ewkViewList.push_back(newEwkView);
770     m_currentEwkView = newEwkView;
771 }
772
773 void ViewLogic::setStartPage()
774 {
775     /* Start URI (as other uris) is now localized
776      * on WebProcess side */
777     m_currentUri = m_startUrl;
778 }
779
780 void ViewLogic::prepareEwkView(Evas_Object *wkView)
781 {
782     LogDebug("prepareEwkView called");
783     Assert(wkView);
784     Ewk_Setting* setting = ewk_view_setting_get(wkView);
785
786     // set user agent
787     auto userAgentString =
788         ViewModule::UserAgentSupport::getUserAgentFromVconf();
789     if (!userAgentString.empty()) {
790         LogDebug("Setting custom user agent as: " << userAgentString);
791         ewk_view_user_agent_set(wkView, userAgentString.c_str());
792     }
793
794     // set custom header : language
795     using namespace ViewModule::CustomHeaderSupport;
796     std::string customHeaderString = getValueByField(ACCEPT_LANGUAGE);
797     if (!customHeaderString.empty()) {
798         LogDebug("custom field=[" << ACCEPT_LANGUAGE << "]");
799         LogDebug("custom value=[" << customHeaderString << "]");
800         ewk_view_custom_header_add(wkView,
801                                    ACCEPT_LANGUAGE.c_str(),
802                                    customHeaderString.c_str());
803     }
804
805     // webkit NPAPI plugins is always on in wrt
806     ewk_setting_enable_plugins_set(setting, EINA_TRUE);
807
808     // The followings are not implemeted yet by webkit2
809     //      ewk_view_setting_accelerated_compositing_enable_set(EINA_TRUE);
810     //      ewk_view_mode_set();
811     //      ewk_view_setting_enable_specified_plugin_set(EINA_TRUE, FLASH_MIME_TYPE);
812     //      ewk_view_setting_html5video_external_player_enable_set(EINA_FALSE);
813     //      ewk_view_show_ime_on_autofocus_set(EINA_TRUE);
814     //      elm_webview_show_magnifier_set(EINA_FALSE);
815     ewk_setting_enable_scripts_set(setting, EINA_TRUE);
816     ewk_setting_auto_load_images_set(setting, EINA_TRUE);
817     ewk_setting_auto_fitting_set(setting, EINA_FALSE);
818
819     // disable zoom option when user click the input field
820     // this option is useful with the normal website
821     // for the make user friendly, disable auto zoom in the webapp
822     // The followings are not implemeted yet by webkit2
823     //      elm_webview_input_field_zoom_set(EINA_FALSE);
824
825     // set cookie database path
826     // The followings are not implemeted yet by webkit2
827     //      ewk_cookies_file_set(dao.getCookieDatabasePath().c_str()));
828
829     // set visibility to WebCore. This value will be used for html5.
830     // also, this value will be changed in the suspend, resume
831     // or create window, close window.
832     ewk_view_page_visibility_state_set(wkView,
833                                        EWK_PAGE_VISIBILITY_STATE_VISIBLE,
834                                        EINA_TRUE);
835 }
836
837 void ViewLogic::removeEwkView(Evas_Object *wkView)
838 {
839     LogInfo("removeEwkView called");
840     Assert(wkView);
841     Assert(0 != m_ewkViewList.size());
842
843     // unregister webview callbacks
844     ewkClientDeinit(wkView);
845
846     // suspend NPAPI plugin - Not implemented by Webkit2
847     //    ewk_view_pause_or_resume_plugins();
848     evas_object_del(wkView);
849     m_ewkViewList.remove(wkView);
850 }
851
852 void ViewLogic::resumeEwkView(Evas_Object *wkView)
853 {
854     LogInfo("resumeEwkView called");
855     Assert(wkView);
856
857     // register webview callback
858     ewkClientInit(wkView);
859
860     // resume webkit
861     resumeWebkit(wkView);
862
863     return;
864 }
865
866 void ViewLogic::suspendEwkView(Evas_Object *wkView)
867 {
868     LogInfo("suspendEwkView called");
869     Assert(wkView);
870
871     // suspend webkit
872     suspendWebkit(wkView);
873
874     // unregister webview callbacks
875     ewkClientDeinit(wkView);
876     return;
877 }
878
879 void ViewLogic::resumeWebkit(Evas_Object *wkView)
880 {
881     LogDebug("resumeWebkit");
882     Assert(wkView);
883
884     // resume NPAPI plugin
885     // The followings are not implemeted yet by webkit2
886     //      ewk_view_pause_or_resume_plugins(false);
887     //      ewk_view_pause_or_resume_video_audio(false);
888     //      ewk_view_javascript_resume();
889     //      ewk_view_enable_render();
890     //      ewk_view_reduce_plugins_frame_rate(false);
891     ewk_view_resume(wkView);
892     ewk_view_visibility_set(wkView, EINA_TRUE);
893     ewk_view_page_visibility_state_set(wkView,
894                                        EWK_PAGE_VISIBILITY_STATE_VISIBLE,
895                                        EINA_FALSE);
896     return;
897 }
898
899 void ViewLogic::suspendWebkit(Evas_Object *wkView)
900 {
901     LogDebug("suspendWebkit");
902     Assert(wkView);
903
904     // suspend the followings
905     // The followings are not implemeted yet by webkit2
906     //      ewk_view_pause_or_resume_plugins(true);
907     //      ewk_view_pause_or_resume_video_audio(true);
908
909     // send visibility event to webpage
910     ewk_view_page_visibility_state_set(wkView,
911                                        EWK_PAGE_VISIBILITY_STATE_HIDDEN,
912                                        EINA_FALSE);
913     ewk_view_suspend(wkView);
914     ewk_view_visibility_set(wkView, EINA_FALSE);
915     return;
916 }
917
918 void ViewLogic::contextMessageFromInjectedBundleCallback(
919         const char* name,
920         const char* body,
921         char** returnData,
922         void* clientInfo)
923 {
924     LogDebug("contextMessageFromInjectedBundleCallback called");
925     Assert(clientInfo);
926     ViewLogic* This = static_cast<ViewLogic*>(clientInfo);
927     // didRecieveMessageFromInjectedBundleCallback - returnData is null
928     // didReceiveSynchronousMessageCallback - returnData isn't null
929     // WKContextInjectedBundleClient bundleClient = {
930     //     kWKContextInjectedBundleClientCurrentVersion,
931     //     static_cast<void*>(this),
932     //     &didRecieveMessageFromInjectedBundleCallback,
933     //     &didReceiveSynchronousMessageCallback
934     // };
935     if (NULL == returnData) {
936         This->didRecieveMessageFromInjectedBundle(name, body);
937     } else {
938         This->didReceiveSynchronousMessage(name, body, returnData);
939     }
940 }
941
942 void ViewLogic::didStartDownloadCallback(
943         const char* downloadUrl,
944         void* data)
945 {
946     LogDebug("didStartDownloadCallback called");
947     Assert(data);
948     ViewLogic* This = static_cast<ViewLogic*>(data);
949     Assert(downloadUrl);
950     LogDebug("download url = " << downloadUrl);
951     This->m_appsSupport->downloadRequest(
952         downloadUrl,
953         NULL,
954         NULL);
955 }
956
957 void ViewLogic::loadStartedCallback(
958         void* data,
959         Evas_Object* /*obj*/,
960         void* /*eventInfo*/)
961 {
962     LogDebug("loadStartedCallback called");
963     Assert(data);
964     ViewLogic* This = static_cast<ViewLogic*>(data);
965     evas_object_focus_set(This->m_currentEwkView, EINA_TRUE);
966 }
967
968 void ViewLogic::loadFinishedCallback(
969         void* data,
970         Evas_Object* /*obj*/,
971         void* /*eventInfo*/)
972 {
973     LogDebug("loadFinishedCallback called");
974     Assert(data);
975     ViewLogic* This = static_cast<ViewLogic*>(data);
976
977     // Fill id/password
978     const char* url = ewk_view_uri_get(This->m_currentEwkView);
979     if (NULL == url || strlen(url) == 0) {
980         LogError("url is empty");
981     } else {
982         DPL::OptionalString jsOptionalString =
983             ViewModule::PasswordSupport::jsForAutoFillData(url);
984         if (jsOptionalString.IsNull()) {
985             LogError("Fail to get JS String");
986         } else {
987             std::string jsStr = DPL::ToUTF8String(*jsOptionalString).c_str();
988             ewk_view_script_execute(
989                 This->m_currentEwkView,
990                 jsStr.c_str(),
991                 didRunJavaScriptCallback,
992                 This);
993         }
994     }
995
996     // call loadFinish callback to wrt-client
997     if (!This->m_cbs->loadFinish.empty()) {
998         This->m_cbs->loadFinish(true);
999     }
1000
1001     // set only encoded bundle
1002     double scale = elm_config_scale_get();
1003     PluginModuleSupport::setCustomProperties(
1004         This->m_ewkContext,
1005         &scale,
1006         ApplicationDataSingleton::Instance().getEncodedBundle());
1007     // check if 'appsevice' event is registed at the current frames.
1008     // If so, dispatch the event to frames.
1009     PluginModuleSupport::dispatchJavaScriptEvent(
1010         This->m_ewkContext,
1011         WrtPlugins::W3C::ServiceCustomEvent,
1012         NULL);
1013 }
1014
1015 void ViewLogic::titleChangedCallback(
1016         void* data,
1017         Evas_Object* /*obj*/,
1018         void* eventInfo)
1019 {
1020     LogDebug("titleChangedCallback called");
1021     Assert(data);
1022     ViewLogic* This = static_cast<ViewLogic*>(data);
1023     Assert(eventInfo);
1024     const char* title = static_cast<char*>(eventInfo);
1025
1026     if (0 == strlen(title)) {
1027         LogDebug("title data is empty");
1028         return;
1029     }
1030     LogDebug("Title = [" << title << "]");
1031     This->m_schemeSupport->HandleTizenScheme(title,
1032                                              This->m_window,
1033                                              This->m_currentEwkView);
1034 }
1035
1036 void ViewLogic::loadProgressCallback(
1037         void* /*data*/,
1038         Evas_Object* /*obj*/,
1039         void* eventInfo)
1040 {
1041     double* progress = static_cast<double*>(eventInfo);
1042     LogDebug("didChangeProgressCallback progress = " << *progress);
1043 }
1044
1045 void ViewLogic::loadProgressFinishedCallback(
1046         void* data,
1047         Evas_Object* /*obj*/,
1048         void* /*eventInfo*/)
1049 {
1050     LogDebug("didFinishProgressCallback");
1051     Assert(data);
1052     ViewLogic const * const view = static_cast<ViewLogic const * const>(data);
1053     if (!view->m_cbs->progressFinish.empty()) {
1054         view->m_cbs->progressFinish();
1055     }
1056 }
1057
1058 void ViewLogic::processCrashedCallback(
1059         void* data,
1060         Evas_Object* /*obj*/,
1061         void* eventInfo)
1062 {
1063     LogInfo("processCrashedCallback");
1064     Assert(data);
1065     ViewLogic const * const view =
1066             static_cast<ViewLogic const * const>(data);
1067     if (!view->m_cbs->webCrash.empty()) {
1068         view->m_cbs->webCrash();
1069     }
1070     // This flag will be prevented exit() call in the Webkit side
1071     if (NULL != eventInfo) {
1072         *(static_cast<Eina_Bool*>(eventInfo)) = EINA_TRUE;
1073     }
1074 }
1075
1076 void ViewLogic::createWindowCallback(
1077         void* data,
1078         Evas_Object* ,
1079         void* eventInfo)
1080 {
1081     LogDebug("createWindowCallback");
1082     Assert(data);
1083     ViewLogic* This = static_cast<ViewLogic*>(data);
1084
1085     Evas_Object* currentEwkView = This->m_currentEwkView;
1086
1087     // suspend current ewkview
1088     /* In case we support many pages in parallel
1089        then view should not be suspended*/
1090     //This->suspendEwkView(currentEwkView);
1091
1092     if (!This->m_cbs->bufferUnset.empty()) {
1093         This->m_cbs->bufferUnset(currentEwkView);
1094     }
1095
1096     // create new ewkview
1097     This->createEwkView();
1098
1099     Evas_Object* newEwkView = This->m_currentEwkView;
1100
1101     // initialize new ewkview
1102     This->setStartPage();
1103     This->ewkClientInit(newEwkView);
1104     This->prepareEwkView(newEwkView);
1105
1106     // show new ewkview
1107     if (!This->m_cbs->bufferUnset.empty()) {
1108         This->m_cbs->bufferSet(newEwkView);
1109     }
1110     *(static_cast<Evas_Object **>(eventInfo)) = newEwkView;
1111 }
1112
1113 void ViewLogic::closeWindowCallback(
1114         void* data,
1115         Evas_Object* /*obj*/,
1116         void* /*eventInfo*/)
1117 {
1118     LogDebug("closeWindowCallback");
1119     ecore_idler_add(windowCloseIdlerCallback, data);
1120 }
1121
1122 void ViewLogic::policyNavigationDecideCallback(
1123         void* data,
1124         Evas_Object* /*obj*/,
1125         void* eventInfo)
1126 {
1127     LogDebug("policyNavigationDecideCallback called");
1128     Assert(data);
1129     ViewLogic* This = static_cast<ViewLogic*>(data);
1130     Assert(eventInfo);
1131     Ewk_Policy_Decision* policyDecision =
1132         static_cast<Ewk_Policy_Decision*>(eventInfo);
1133
1134     if (This->m_schemeSupport->filterURIByScheme(policyDecision,
1135                                                  false,
1136                                                  This->m_model,
1137                                                  This->m_window,
1138                                                  This->m_currentEwkView))
1139     {
1140         LogDebug("use");
1141         ewk_policy_decision_use(policyDecision);
1142     } else {
1143         // check whether this is new empty window
1144         const char* activeUrl = ewk_view_uri_get(This->m_currentEwkView);
1145         if(!activeUrl || 0 == strlen(activeUrl)) {
1146             /*
1147              * The view is empty and scheme has been handled externally. When
1148              * user gets back from the external application he'd see blank page
1149              * and won't be able to navigate back. This happens when window.open
1150              * is used to handle schemes like sms/mms/mailto (for example in
1151              * WAC web standards tests: WS-15XX).
1152              *
1153              * To solve the problem, the empty view is removed from the stack
1154              * and the previous one is shown. This is not an elegant solution
1155              * but we don't have a better one.
1156              */
1157             LogInfo("Scheme has been handled externally. Removing empty view.");
1158             if (ewk_view_back_possible(This->m_currentEwkView)) {
1159                 // go back to previous WKPage
1160                 ewk_view_back(This->m_currentEwkView);
1161             } else {
1162                 // stop current WKPage
1163                 ewk_view_stop(This->m_currentEwkView);
1164                 ecore_idler_add(windowCloseIdlerCallback, This);
1165             }
1166         }
1167
1168         LogDebug("ignore");
1169         ewk_policy_decision_ignore(policyDecision);
1170     }
1171 }
1172
1173 void ViewLogic::policyNewWindowDecideCallback(
1174         void* data,
1175         Evas_Object* /*obj*/,
1176         void* eventInfo)
1177 {
1178     LogDebug("policyNewWindowDecideCallback called");
1179     Assert(data);
1180     ViewLogic* This = static_cast<ViewLogic*>(data);
1181     Assert(eventInfo);
1182     Ewk_Policy_Decision* policyDecision =
1183         static_cast<Ewk_Policy_Decision*>(eventInfo);
1184
1185     if (This->m_schemeSupport->filterURIByScheme(policyDecision,
1186                                                  true,
1187                                                  This->m_model,
1188                                                  This->m_window,
1189                                                  This->m_currentEwkView))
1190     {
1191         ewk_policy_decision_use(policyDecision);
1192     } else {
1193         // scheme handled
1194         ewk_policy_decision_ignore(policyDecision);
1195     }
1196 }
1197
1198 void ViewLogic::pageResponseDecideCallback(
1199         void* data,
1200         Evas_Object* /*obj*/,
1201         void* eventInfo)
1202 {
1203     LogDebug("pageResponseDecideCallback called");
1204     Assert(data);
1205     ViewLogic* This = static_cast<ViewLogic*>(data);
1206     Assert(eventInfo);
1207     Ewk_Policy_Decision* policyDecision =
1208         static_cast<Ewk_Policy_Decision*>(eventInfo);
1209     Ewk_Policy_Decision_Type policyDecisionType =
1210         ewk_policy_decision_type_get(policyDecision);
1211
1212     if (policyDecisionType == EWK_POLICY_DECISION_USE) {
1213         LogDebug("use");
1214         ewk_policy_decision_use(policyDecision);
1215     } else if (policyDecisionType == EWK_POLICY_DECISION_DOWNLOAD) {
1216         LogDebug("download");
1217         ewk_policy_decision_suspend(policyDecision);
1218
1219         // get uri information
1220         const char* url =  ewk_policy_decision_url_get(policyDecision);
1221         if (NULL == url || strlen(url) == 0) {
1222             LogDebug("url data is empty");
1223             ewk_policy_decision_use(policyDecision);
1224             return;
1225         }
1226         LogDebug("url = [" << url << "]");
1227
1228         // get content information
1229         const char* content =
1230             ewk_policy_decision_response_mime_get(policyDecision);
1231         LogDebug("content type = [" << content << "]");
1232
1233         // get cookie information
1234         const char* cookie = ewk_policy_decision_cookie_get(policyDecision);
1235         LogDebug("cookie = [" << cookie << "]");
1236
1237         LogDebug("Content not supported, will be opened in external app");
1238         This->m_appsSupport->downloadRequest(
1239             url,
1240             content,
1241             cookie);
1242         ewk_policy_decision_ignore(policyDecision);
1243     } else if (policyDecisionType == EWK_POLICY_DECISION_IGNORE) {
1244         LogDebug("ignore");
1245         ewk_policy_decision_ignore(policyDecision);
1246     } else {
1247         LogDebug("Type isn't handled");
1248         ewk_policy_decision_ignore(policyDecision);
1249     }
1250 }
1251
1252 void ViewLogic::contextmenuCustomizeCallback(
1253         void* data,
1254         Evas_Object* /*obj*/,
1255         void* eventInfo)
1256 {
1257     LogDebug("contextmenuCustomizeCallback called");
1258     Assert(data);
1259     Assert(eventInfo);
1260     ViewLogic* This = static_cast<ViewLogic*>(const_cast<void*>(data));
1261     Ewk_Context_Menu* menu = static_cast<Ewk_Context_Menu*>(eventInfo);
1262     if ((This->m_model->Type.Get().appType == WrtDB::APP_TYPE_TIZENWEBAPP) &&
1263         (This->m_model->SettingList.Get().getContextMenu()
1264             == ContextMenu_Disable))
1265     {
1266         LogDebug("ContextMenu Disable!!");
1267         for (unsigned int idx = 0; idx < ewk_context_menu_item_count(menu);) {
1268             Ewk_Context_Menu_Item* item = ewk_context_menu_nth_item_get(menu, idx);
1269             Assert(item);
1270             ewk_context_menu_item_remove(menu, item);
1271         }
1272     } else {
1273         LogDebug("ContextMenu Enable!!");
1274         for (unsigned int idx = 0; idx < ewk_context_menu_item_count(menu);) {
1275             Ewk_Context_Menu_Item* item = ewk_context_menu_nth_item_get(menu, idx);
1276             Assert(item);
1277             Ewk_Context_Menu_Item_Tag tag = ewk_context_menu_item_tag_get(item);
1278
1279             switch (tag) {
1280                 case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_IMAGE_IN_NEW_WINDOW:
1281                     ewk_context_menu_item_remove(menu, item);
1282                     break;
1283
1284                 case EWK_CONTEXT_MENU_ITEM_TAG_SEARCH_WEB:
1285                     ewk_context_menu_item_remove(menu, item);
1286                     break;
1287
1288                 default:
1289                     idx++;
1290                     break;
1291             }
1292         }
1293     }
1294 }
1295
1296 void ViewLogic::formSubmitCallback(
1297         void* /*data*/,
1298         Evas_Object* /*obj*/,
1299         void* eventInfo)
1300 {
1301     LogDebug("formSubmitCallback called");
1302     Assert(eventInfo);
1303     Ewk_Form_Data* formData = static_cast<Ewk_Form_Data*>(eventInfo);
1304
1305     const char* uri = ewk_form_data_url_get(formData);
1306     if (!uri) {
1307         LogError("URL is empty");
1308         return;
1309     }
1310
1311     Eina_Hash* userData = ewk_form_data_values_get(formData);
1312     ViewModule::PasswordSupport::submitClicked(uri, userData);
1313 }
1314
1315 void ViewLogic::geolocationPermissionRequestCallback(
1316         void* /*data*/,
1317         Evas_Object* /*obj*/,
1318         void* eventInfo)
1319 {
1320     LogDebug("geolocationPermissionRequestCallback called");
1321     Assert(eventInfo);
1322     ViewModule::GeolocationSupport::Webkit2::
1323         geolocationPermissionRequest(eventInfo);
1324     return;
1325 }
1326
1327 void ViewLogic::notificationShowCallback(
1328         void* data,
1329         Evas_Object* /*obj*/,
1330         void* eventInfo)
1331 {
1332     LogDebug("notificationShowCallback called");
1333     Assert(data);
1334     ViewLogic* This = static_cast<ViewLogic*>(data);
1335
1336     Assert(eventInfo);
1337     Ewk_Notification* noti = static_cast<Ewk_Notification*>(eventInfo);
1338
1339     using namespace ViewModule::WebNotification;
1340
1341     WebNotificationDataPtr notiData(
1342             new WebNotificationData(
1343                 This->m_model,
1344                 ewk_notification_id_get(noti)));
1345
1346     DPL::OptionalString string =
1347         DPL::FromUTF8String(ewk_notification_icon_url_get(noti));
1348     if (!string.IsNull()) {
1349         notiData->m_iconURL = DPL::ToUTF8String(*string);
1350     }
1351     string = DPL::FromUTF8String(ewk_notification_title_get(noti));
1352     if (!string.IsNull()) {
1353         notiData->m_title = DPL::ToUTF8String(*string);
1354     }
1355     string = DPL::FromUTF8String(ewk_notification_body_get(noti));
1356     if (!string.IsNull()) {
1357         notiData->m_body = DPL::ToUTF8String(*string);
1358     }
1359
1360     LogInfo("notification id : " << notiData->m_id);
1361     LogInfo("notification iconURL : " << notiData->m_iconURL);
1362     LogInfo("notification title : " << notiData->m_title);
1363     LogInfo("notification body : " << notiData->m_body);
1364
1365     showWebNotification(notiData);
1366     ewk_notification_showed(This->m_ewkContext, ewk_notification_id_get(noti));
1367 }
1368
1369 void ViewLogic::notificationCancelCallback(
1370         void* /*data*/,
1371         Evas_Object* /*obj*/,
1372         void* /*eventInfo*/)
1373 {
1374     LogDebug("notificationCancelCallback called");
1375 }
1376
1377 void ViewLogic::notificationPermissionRequestCallback(
1378         void* data,
1379         Evas_Object* /*obj*/,
1380         void* eventInfo)
1381 {
1382     LogDebug("notificationPermissionRequestCallback called");
1383     Assert(data);
1384     ViewLogic* This = static_cast<ViewLogic*>(data);
1385
1386     Assert(eventInfo);
1387     Ewk_Notification_Permission_Request* request =
1388         static_cast<Ewk_Notification_Permission_Request*>(eventInfo);
1389     ewk_notification_permission_request_response(
1390         This->m_ewkContext,
1391         request,
1392         EINA_TRUE);
1393     return;
1394 }
1395
1396 void ViewLogic::vibrationVibrateCallback(
1397         void* data,
1398         Evas_Object* /*obj*/,
1399         void* eventInfo)
1400 {
1401     LogDebug("vibrationVibrateCallback called");
1402     Assert(data);
1403     ViewLogic* This = static_cast<ViewLogic*>(data);
1404
1405     Assert(eventInfo);
1406     const long vibrationTime = *(static_cast<const long*>(eventInfo));
1407
1408     // temp
1409     // This->m_vibrationSupport->startVibration(vibrationTime);
1410
1411     return;
1412 }
1413
1414 void ViewLogic::vibrationCancelCallback(
1415         void* data,
1416         Evas_Object* /*obj*/,
1417         void* /*eventInfo*/)
1418 {
1419     LogDebug("vibrationCancelCallback called");
1420     Assert(data);
1421     ViewLogic* This = static_cast<ViewLogic*>(data);
1422
1423     // temp
1424     // This->m_vibrationSupport->stopVibration();
1425
1426     return;
1427 }
1428
1429 // EWK Orientation Callback
1430 Eina_Bool ViewLogic::orientationLockCallback(
1431         Evas_Object* obj,
1432         Eina_Bool /*needLock*/,
1433         int orientation,
1434         void* data)
1435 {
1436     LogDebug("orientationLockCallback called");
1437     Assert(data);
1438     ViewLogic* This = static_cast<ViewLogic*>(data);
1439
1440     if (orientation & EWK_SCREEN_ORIENTATION_PORTRAIT_PRIMARY) {
1441         LogDebug("orientation is portrait-primary");
1442         elm_win_rotation_with_resize_set(This->m_window, 0);
1443         ewk_view_orientation_send(obj, 0);
1444     } else if(orientation & EWK_SCREEN_ORIENTATION_LANDSCAPE_PRIMARY) {
1445         LogDebug("orientation is landscape-primary");
1446         elm_win_rotation_with_resize_set(This->m_window, 270);
1447         ewk_view_orientation_send(obj, 90);
1448     } else if(orientation & EWK_SCREEN_ORIENTATION_PORTRAIT_SECONDARY) {
1449         LogDebug("orientation is portrait-secondary");
1450         elm_win_rotation_with_resize_set(This->m_window, 180);
1451         ewk_view_orientation_send(obj, 180);
1452     } else if(orientation & EWK_SCREEN_ORIENTATION_LANDSCAPE_SECONDARY) {
1453         LogDebug("orientation is landscape-secondary");
1454         elm_win_rotation_with_resize_set(This->m_window, 90);
1455         ewk_view_orientation_send(obj, -90);
1456     } else {
1457         LogDebug("Wrong orientation is set");
1458         return EINA_FALSE;
1459     }
1460     return EINA_TRUE;
1461 }
1462
1463
1464 // Fullscreen API callbacks
1465 void ViewLogic::enterFullscreenCallback(
1466         void* data,
1467         Evas_Object* /*obj*/,
1468         void* /*eventInfo*/)
1469 {
1470     LogInfo("enterFullscreenCallback called");
1471     Assert(data);
1472     ViewLogic* This = static_cast<ViewLogic*>(data);
1473     if (!This->m_cbs->toggleFullscreen.empty()) {
1474         This->m_cbs->toggleFullscreen(true);
1475     }
1476 }
1477 void ViewLogic::exitFullscreenCallback(
1478         void* data,
1479         Evas_Object* /*obj*/,
1480         void* /*eventInfo*/)
1481 {
1482     LogInfo("exitFullscreenCallback called");
1483     Assert(data);
1484     ViewLogic* This = static_cast<ViewLogic*>(data);
1485     if (!This->m_cbs->toggleFullscreen.empty()) {
1486         This->m_cbs->toggleFullscreen(false);
1487     }
1488 }
1489
1490 void ViewLogic::didRunJavaScriptCallback(
1491         Evas_Object* /*obj*/,
1492         const char* result,
1493         void* /*userData*/)
1494 {
1495     LogInfo("didRunJavaScriptCallback called");
1496     LogInfo("result = " << result);
1497 }
1498
1499 Eina_Bool ViewLogic::windowCloseIdlerCallback(void* data)
1500 {
1501     LogDebug("closeIdlerCallback");
1502     ViewLogic* This = static_cast<ViewLogic*>(data);
1503     This->windowClose();
1504     return ECORE_CALLBACK_CANCEL;
1505 }
1506
1507 int ViewLogic::appcoreLowMemoryCallback(void *data)
1508 {
1509     LogInfo("appcoreLowMemoryCallback");
1510     Assert(data);
1511     ViewLogic* This = static_cast<ViewLogic*>(data);
1512
1513     if (NULL == This->m_ewkContext) {
1514         LogInfo("ewk isn't initialize at this moment");
1515     } else {
1516         ewk_context_cache_clear(This->m_ewkContext);
1517         ewk_context_notify_low_memory(This->m_ewkContext);
1518     }
1519
1520     return 0;
1521 }
1522
1523 void ViewLogic::databaseUsagePermissionRequestCallback(
1524     void* data,
1525     Evas_Object* /*obj*/,
1526     void* eventInfo)
1527 {
1528     LogDebug("databaseUsagePermissionRequestCallback called");
1529     Assert(data);
1530     ViewLogic* This = static_cast<ViewLogic*>(data);
1531     This->databaseUsagePermissionRequest(eventInfo);
1532     return;
1533  }
1534
1535 void ViewLogic::databaseUsagePermissionRequest(
1536     void* eventInfo)
1537 {
1538     LogDebug("databaseUsagePermissionRequest called");
1539     Assert(eventInfo);
1540     Ewk_Context_Exceeded_Quota* exceededQuota =
1541         static_cast<Ewk_Context_Exceeded_Quota*>(eventInfo);
1542
1543     bool state = askUserForDatabaseExceedPermission(
1544         exceededQuota);
1545
1546     if (true == state) {
1547         LogDebug("permit");
1548         ewk_context_web_database_exceeded_quota_new_quota_set(
1549             exceededQuota,
1550             ewk_context_web_database_exceeded_quota_expected_usage_get(
1551                 exceededQuota)
1552             + 10*(1024*1024)); //10MB
1553     } else {
1554         LogDebug("deny");
1555     }
1556     return;
1557  }
1558
1559 bool ViewLogic::askUserForDatabaseExceedPermission(
1560     Ewk_Context_Exceeded_Quota* exceededQuota)
1561 {
1562     LogDebug("askUserForDatabaseExceedPermission called");
1563     Ewk_Security_Origin* origin =
1564         ewk_context_web_database_exceeded_quota_security_origin_get(
1565         exceededQuota);
1566     char databaseUseAskTitle[180];
1567
1568     snprintf(databaseUseAskTitle, sizeof(databaseUseAskTitle),
1569             "Do you want to allow %s to use up to %dMB of storage?",
1570             ewk_security_origin_host_get(origin),
1571             static_cast<int>(ewk_context_web_database_exceeded_quota_expected_usage_get(
1572                     exceededQuota) / (1024 * 1024)));
1573
1574     return Wrt::PopupInvoker().askYesNo(
1575         DATABASE_USE_ASK_TITLE,
1576         databaseUseAskTitle);
1577 }
1578
1579 void ViewLogic::fileSystemPermissionRequestCallback(
1580     void* data,
1581     Evas_Object* /*obj*/,
1582     void* eventInfo)
1583 {
1584     LogDebug("filesystemPermissionRequestCallback called");
1585     Assert(data);
1586     ViewLogic* This = static_cast<ViewLogic*>(data);
1587     This->fileSystemPermissionRequest(eventInfo);
1588     return;
1589  }
1590
1591 void ViewLogic::fileSystemPermissionRequest(
1592     void* eventInfo)
1593 {
1594     LogDebug("filesystemPermissionRequest called");
1595     Assert(eventInfo);
1596     Ewk_Context_File_System_Permission* fileSystemPermission =
1597         static_cast<Ewk_Context_File_System_Permission*>(eventInfo);
1598     bool state = askUserForFileSystemPermission(
1599         fileSystemPermission);
1600
1601     if (true == state) {
1602         LogDebug("permit");
1603         ewk_context_file_system_permission_allow_set(
1604             fileSystemPermission, EINA_TRUE);
1605     } else {
1606         LogDebug("deny");
1607     }
1608     return ;
1609  }
1610
1611 bool ViewLogic::askUserForFileSystemPermission(
1612     Ewk_Context_File_System_Permission* fileSystemPermission)
1613 {
1614     LogDebug("askUserForFileSystemPermission called");
1615     Ewk_Security_Origin* origin =
1616         ewk_context_file_system_permission_origin_get(
1617         fileSystemPermission);
1618
1619     char fileSystemPermissionAskTitle[110];
1620     snprintf(fileSystemPermissionAskTitle,
1621         sizeof(fileSystemPermissionAskTitle),
1622         "Do you want to allow %s to use persistent filesystem?",
1623         ewk_security_origin_host_get(origin));
1624
1625     return Wrt::PopupInvoker().askYesNo(
1626         FILESYSTEM_USE_ASK_TITLE,
1627         fileSystemPermissionAskTitle);
1628 }
1629
1630 void ViewLogic::didRecieveMessageFromInjectedBundle(
1631         const char* name,
1632         const char* /*body*/)
1633 {
1634     LogDebug("did recive message " << name);
1635 }
1636
1637 void ViewLogic::didReceiveSynchronousMessage(
1638         const char* name,
1639         const char* body,
1640         char** returnData)
1641 {
1642     LogDebug("didReceiveSynchronousMessage called");
1643     Assert(name);
1644     Assert(returnData);
1645
1646     if (!body) {
1647         LogDebug("body is empty");
1648         *returnData = NULL;
1649         return;
1650     }
1651     if (!strcmp(name, uriBlockedMessageName)) {
1652         LogDebug("received : " << uriBlockedMessageName);
1653         // Currently WebProcess informs obly about blocked
1654         // URI - URI localization and security chekcs are
1655         // done by WebProcess itself (see: wrt-wk2-bundle.cpp
1656         // and bundle_uri_handling.cpp)
1657         rememberBlockedURI(DPL::FromUTF8String(body));
1658         *returnData = NULL;
1659     } else if (!strcmp(name, uriChangedMessageName)) {
1660         LogDebug("received : " << uriChangedMessageName);
1661         std::string ret = requestUriChanged(DPL::FromUTF8String(body));
1662         *returnData =  strdup(ret.c_str());
1663     }
1664 }
1665
1666 void ViewLogic::rememberBlockedURI(const DPL::String& inputURI)
1667 {
1668     m_blockedUri = DPL::ToUTF8String(inputURI);
1669     LogInfo("set blocked uri to open browser later : " << m_blockedUri);
1670     return;
1671 }
1672
1673 std::string ViewLogic::requestUriChanged(const DPL::String& changedURL)
1674 {
1675     using namespace ViewModule::SecuritySupport;
1676
1677     std::string url = DPL::ToUTF8String(changedURL);
1678     LogInfo("URL = [" << url << "]");
1679
1680     // check WARP
1681     // If url is same to URICHANGE_BLOCKED_URL,
1682     // this url has been already blocked by willsend.
1683     // So current page should be moved to previous page
1684     if (url == URICHANGE_BLOCKED_URL)
1685     {
1686         if (m_model->Type.Get().appType == WrtDB::APP_TYPE_TIZENWEBAPP)
1687         {
1688             // block this page and open it in browser
1689             LogDebug("Request was blocked by WARP: " << url.c_str());
1690             if (!m_blockedUri.empty()) {
1691                 LogDebug("open browser : " << m_blockedUri);
1692                 bundle* bundleData = bundle_create();
1693                 appsvc_set_operation(bundleData, APPSVC_OPERATION_VIEW);
1694                 appsvc_set_uri(bundleData, m_blockedUri.c_str());
1695                 CONTROLLER_POST_EVENT(
1696                     ApplicationLauncher,
1697                     ApplicationLauncherEvents::LaunchApplicationByAppService(
1698                         bundleData,
1699                         NULL,
1700                         NULL));
1701                 m_blockedUri = std::string();
1702             }
1703         }
1704         if (ewk_view_back_possible(m_currentEwkView)) {
1705             // go back to previous page
1706             ewk_view_back(m_currentEwkView);
1707         } else {
1708             // stop current page
1709             ewk_view_stop(m_currentEwkView);
1710             ecore_idler_add(windowCloseIdlerCallback, this);
1711         }
1712
1713         // This is used in case of returning previous page
1714         m_currentUri = url;
1715         return URICHANGE_PLUGIN_NO_CHANGE;
1716     }
1717
1718     m_currentUri = url;
1719
1720     // Check if this url with 'http' or 'https' is included in whitelist,
1721     // which has lists of accessible external documents and
1722     // used for ONLY Tizen app
1723     std::string matchedScheme;
1724     std::string matchedUri;
1725     pcrecpp::RE(PATTERN_URI_CHANGE).PartialMatch(url.c_str(),
1726                                                  &matchedUri,
1727                                                  &matchedScheme);
1728     ViewModule::Scheme scheme(matchedScheme);
1729     if (scheme.GetType() == ViewModule::Scheme::HTTP ||
1730         scheme.GetType() == ViewModule::Scheme::HTTPS)
1731     {
1732         if (m_model->Type.Get().appType == WrtDB::APP_TYPE_TIZENWEBAPP) {
1733             if (!checkWhitelist(url.c_str())) {
1734                 LogInfo("This uri is not included in white document list");
1735                 return URICHANGE_PLUGIN_STOP_ONLY;
1736             }
1737             LogInfo("This url is included in WhiteList");
1738         } else {
1739             // For WAC app, WRT should block access of device api
1740             // for external documents
1741             return URICHANGE_PLUGIN_STOP_ONLY;
1742         }
1743     }
1744
1745     // register javascript object for plugins to be used
1746     LogInfo("Register Plugin Objects");
1747     return URICHANGE_PLUGIN_RESTART;
1748 }
1749
1750 void ViewLogic::windowClose()
1751 {
1752     LogDebug("windowClose");
1753
1754     if (1 >= m_ewkViewList.size()) {
1755         if (!m_cbs->windowClose.empty()) {
1756             m_cbs->windowClose();
1757         }
1758     } else {
1759         // hide current ewkView
1760
1761         if (!m_cbs->bufferUnset.empty()) {
1762             m_cbs->bufferUnset(m_currentEwkView);
1763         }
1764         removeEwkView(m_currentEwkView);
1765
1766         // get latest ewkView
1767         m_currentEwkView = m_ewkViewList.back();
1768         const char* uri = ewk_view_uri_get(m_currentEwkView);
1769         if (NULL == uri || 0 == strlen(uri)) {
1770             m_currentUri.clear();
1771         } else {
1772             m_currentUri = uri;
1773         }
1774
1775         // resume ewkView
1776         /* In case we support many pages in parallel
1777            then view is not suspended*/
1778         //resumeEwkView(m_currentEwkView);
1779
1780         // show ewkView
1781         if (!m_cbs->bufferSet.empty()) {
1782             m_cbs->bufferSet(m_currentEwkView);
1783         }
1784     }
1785 }
1786