Bug TT-69 Remove private ewk_cookie_manager_persistent_storage_set calls
[profile/tv/apps/web/browser.git] / services / WebKitEngineService / WebView.cpp
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
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 /*
18  * WebView.cpp
19  *
20  *  Created on: Apr 1, 2014
21  *      Author: p.rafalski
22  */
23
24 #include "WebView.h"
25
26 #if defined(USE_EWEBKIT)
27 #include <ewk_chromium.h>
28 #endif
29
30 #include <boost/format.hpp>
31 #include <boost/regex.hpp>
32 #include <boost/algorithm/string/regex.hpp>
33 #include <boost/algorithm/string/classification.hpp>
34 #include <boost/algorithm/string/split.hpp>
35 #include <Elementary.h>
36 #include <Evas.h>
37
38 #include "AbstractWebEngine/AbstractWebEngine.h"
39 #include "AbstractWebEngine/TabThumbCache.h"
40 #include "BrowserAssert.h"
41 #include "BrowserLogger.h"
42 #include "EflTools.h"
43 #include "GeneralTools.h"
44 #include "Tools/WorkQueue.h"
45 #include "ServiceManager.h"
46
47 #define certificate_crt_path CERTS_DIR
48 #define APPLICATION_NAME_FOR_USER_AGENT "SamsungBrowser/1.0"
49
50 using namespace tizen_browser::tools;
51
52 namespace tizen_browser {
53 namespace basic_webengine {
54 namespace webkitengine_service {
55
56 WebView::WebView(Evas_Object * obj, TabId tabId)
57     : m_parent(obj)
58     , m_tabId(tabId)
59     , m_ewkView(NULL)
60     , m_isLoading(false)
61     , m_loadError(false)
62 {
63     config.load("whatever");
64 }
65
66 WebView::~WebView()
67 {
68     BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
69
70     if (m_ewkView) {
71         unregisterCallbacks();
72     }
73 }
74
75 void WebView::init(Evas_Object * opener)
76 {
77 #if defined(USE_EWEBKIT)
78     m_ewkView = ewk_view_add(evas_object_evas_get(m_parent));
79
80     evas_object_data_set(m_ewkView, "_container", this);
81     BROWSER_LOGD("%s:%d %s self=%p", __FILE__, __LINE__, __func__, this);
82
83     evas_object_color_set(m_ewkView, 255, 255, 255, 255);
84     evas_object_size_hint_weight_set(m_ewkView, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
85     evas_object_size_hint_align_set(m_ewkView, EVAS_HINT_FILL, EVAS_HINT_FILL);
86     ewk_view_application_name_for_user_agent_set(m_ewkView, APPLICATION_NAME_FOR_USER_AGENT);
87     //\todo: when value is other than 1.0, scroller is located improperly
88 //    ewk_view_device_pixel_ratio_set(m_ewkView, 1.0f);
89
90 #if PLATFORM(TIZEN)
91     ewk_view_resume(m_ewkView);
92 #endif
93     // set local storage, favion, cookies
94     std::string webkit_path =  boost::any_cast <std::string> (config.get("webkit/dir"));
95
96     if (m_ewkView)
97     {
98         Ewk_Context *context = ewk_view_context_get(m_ewkView);
99         if (context)
100         {
101             ewk_context_cache_model_set(context, EWK_CACHE_MODEL_PRIMARY_WEBBROWSER);
102             ewk_context_favicon_database_directory_set(context, (webkit_path + std::string("/favicon")).c_str());
103         }
104     }
105
106 ///\note Odroid modification - not exists in WebKit API
107 //     ewk_cookie_manager_widget_cookie_directory_set(ewk_context_cookie_manager_get(context), webkit_path.c_str());
108     setupEwkSettings();
109     registerCallbacks();
110 #else
111     m_ewkView = evas_object_rectangle_add(evas_object_evas_get(m_parent));
112 #endif
113 }
114
115 void WebView::registerCallbacks()
116 {
117 #if defined(USE_EWEBKIT)
118     evas_object_smart_callback_add(m_ewkView, "load,started", __loadStarted, this);
119     evas_object_smart_callback_add(m_ewkView, "load,stop", __loadStop, this);
120     evas_object_smart_callback_add(m_ewkView, "load,finished", __loadFinished, this);
121     evas_object_smart_callback_add(m_ewkView, "load,progress", __loadProgress, this);
122     evas_object_smart_callback_add(m_ewkView, "load,error", __loadError, this);
123
124     evas_object_smart_callback_add(m_ewkView, "title,changed", __titleChanged, this);
125     evas_object_smart_callback_add(m_ewkView, "url,changed", __urlChanged, this);
126
127     evas_object_smart_callback_add(m_ewkView, "back,forward,list,changed", __backForwardListChanged, this);
128
129     evas_object_smart_callback_add(m_ewkView, "create,window", __newWindowRequest, this);
130     evas_object_smart_callback_add(m_ewkView, "close,window", __closeWindowRequest, this);
131
132     evas_object_smart_callback_add(m_ewkView, "geolocation,permission,request", __geolocationPermissionRequest, this);
133     evas_object_smart_callback_add(m_ewkView, "usermedia,permission,request", __usermediaPermissionRequest, this);
134     evas_object_smart_callback_add(m_ewkView, "notification,permission,request", __notificationPermissionRequest, this);
135     evas_object_smart_callback_add(m_ewkView, "authentication,request", __authenticationRequest, this);
136     evas_object_smart_callback_add(m_ewkView, "request,certificate,confirm", __requestCertificationConfirm, this);
137
138     evas_object_event_callback_add(m_ewkView, EVAS_CALLBACK_MOUSE_DOWN, __setFocusToEwkView, this);
139     evas_object_smart_callback_add(m_ewkView, "icon,received", __faviconChanged, this);
140
141     evas_object_smart_callback_add(m_ewkView, "editorclient,ime,closed", __IMEClosed, this);
142     evas_object_smart_callback_add(m_ewkView, "editorclient,ime,opened", __IMEOpened, this);
143 #endif
144 }
145
146 void WebView::unregisterCallbacks()
147 {
148 #if defined(USE_EWEBKIT)
149     evas_object_smart_callback_del_full(m_ewkView, "load,started", __loadStarted, this);
150     evas_object_smart_callback_del_full(m_ewkView, "load,stop", __loadStop, this);
151     evas_object_smart_callback_del_full(m_ewkView, "load,finished", __loadFinished, this);
152     evas_object_smart_callback_del_full(m_ewkView, "load,progress", __loadProgress, this);
153     evas_object_smart_callback_del_full(m_ewkView, "load,error", __loadError, this);
154
155     evas_object_smart_callback_del_full(m_ewkView, "title,changed", __titleChanged, this);
156     evas_object_smart_callback_del_full(m_ewkView, "url,changed", __urlChanged, this);
157
158     evas_object_smart_callback_del_full(m_ewkView, "back,forward,list,changed", __backForwardListChanged, this);
159
160     evas_object_smart_callback_del_full(m_ewkView, "create,window", __newWindowRequest, this);
161     evas_object_smart_callback_del_full(m_ewkView, "close,window", __closeWindowRequest, this);
162
163     evas_object_smart_callback_del_full(m_ewkView, "geolocation,permission,request", __geolocationPermissionRequest, this);
164     evas_object_smart_callback_del_full(m_ewkView, "usermedia,permission,request", __usermediaPermissionRequest, this);
165     evas_object_smart_callback_del_full(m_ewkView, "notification,permission,request", __notificationPermissionRequest, this);
166     evas_object_smart_callback_del_full(m_ewkView, "authentication,request", __authenticationRequest, this);
167     evas_object_smart_callback_del_full(m_ewkView, "request,certificate,confirm", __requestCertificationConfirm, this);
168
169     evas_object_event_callback_del(m_ewkView, EVAS_CALLBACK_MOUSE_DOWN, __setFocusToEwkView);
170     evas_object_smart_callback_del_full(m_ewkView, "icon,received", __faviconChanged, this);
171
172     evas_object_smart_callback_del_full(m_ewkView, "editorclient,ime,closed", __IMEClosed, this);
173     evas_object_smart_callback_del_full(m_ewkView, "editorclient,ime,opened", __IMEOpened, this);
174 #endif
175 }
176
177 void WebView::setupEwkSettings()
178 {
179 #if defined(USE_EWEBKIT)
180 #if PLATFORM(TIZEN)
181     Ewk_Settings * settings = ewk_view_settings_get(m_ewkView);
182     ewk_settings_uses_keypad_without_user_action_set(settings, EINA_FALSE);
183 #endif
184 #endif
185 }
186
187 Evas_Object * WebView::getLayout()
188 {
189     return m_ewkView;
190 }
191
192 void WebView::setURI(const std::string & uri)
193 {
194     BROWSER_LOGD("%s:%d %s uri=%s", __FILE__, __LINE__, __func__, uri.c_str());
195 #if defined(USE_EWEBKIT)
196     BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
197     ewk_view_url_set(m_ewkView, uri.c_str());
198     m_loadError = false;
199 #endif
200 }
201
202 std::string WebView::getURI(void)
203 {
204 #if defined(USE_EWEBKIT)
205     BROWSER_LOGD("%s:%d %s uri=%s", __FILE__, __LINE__, __func__, ewk_view_url_get(m_ewkView));
206     return tizen_browser::tools::fromChar(ewk_view_url_get(m_ewkView));
207 #else
208     return std::string();
209 #endif
210 }
211
212 std::string WebView::getTitle(void)
213 {
214     return m_title;
215 }
216
217 void WebView::stopLoading(void)
218 {
219 #if defined(USE_EWEBKIT)
220     ewk_view_stop(m_ewkView);
221 #endif
222     loadStop();
223 }
224
225 void WebView::reload(void)
226 {
227 #if defined(USE_EWEBKIT)
228     if(m_loadError)
229     {
230         m_loadError = false;
231         ewk_view_url_set(m_ewkView, ewk_view_url_get(m_ewkView));
232     }
233     else
234         ewk_view_reload(m_ewkView);
235 #endif
236 }
237
238 void WebView::back(void)
239 {
240 #if defined(USE_EWEBKIT)
241     m_loadError = false;
242     ewk_view_back(m_ewkView);
243 #endif
244 }
245
246 void WebView::forward(void)
247 {
248 #if defined(USE_EWEBKIT)
249     m_loadError = false;
250     ewk_view_forward(m_ewkView);
251 #endif
252 }
253
254 bool WebView::isBackEnabled(void)
255 {
256 #if defined(USE_EWEBKIT)
257     return ewk_view_back_possible(m_ewkView);
258 #else
259     return false;
260 #endif
261 }
262
263 bool WebView::isForwardEnabled(void)
264 {
265 #if defined(USE_EWEBKIT)
266     return ewk_view_forward_possible(m_ewkView);
267 #else
268     return false;
269 #endif
270 }
271
272 bool WebView::isLoading()
273 {
274     return m_isLoading;
275 }
276
277 bool WebView::isLoadError() const
278 {
279     return m_loadError;
280 }
281
282 void WebView::setPrivateMode(bool state)
283 {
284     BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
285     M_ASSERT(m_ewkView);
286
287 #if defined(USE_EWEBKIT)
288 #if PLATFORM(TIZEN)
289     Ewk_Settings * settings = ewk_view_settings_get(m_ewkView);
290 #else
291     Ewk_Settings * settings = ewk_page_group_settings_get(ewk_view_page_group_get(m_ewkView));
292 #endif
293     ewk_settings_private_browsing_enabled_set(settings, state);
294     if (m_ewkView)
295     {
296         Ewk_Context *context = ewk_view_context_get(m_ewkView);
297         if (context)
298         {
299             if(state)
300             {
301                  ewk_cookie_manager_accept_policy_set(ewk_context_cookie_manager_get(context), EWK_COOKIE_ACCEPT_POLICY_NEVER);
302             }
303             else
304             {
305                  ewk_cookie_manager_accept_policy_set(ewk_context_cookie_manager_get(context), EWK_COOKIE_ACCEPT_POLICY_ALWAYS);
306             }
307         }
308     }
309 #endif
310 }
311
312 void WebView::confirmationResult(WebConfirmationPtr confirmation)
313 {
314     BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
315
316 #if defined(USE_EWEBKIT)
317 #if PLATFORM(TIZEN)
318     switch(confirmation->getConfirmationType()) {
319     case WebConfirmation::ConfirmationType::Geolocation: {
320         Ewk_Geolocation_Permission_Request *request = m_confirmationGeolocationMap[confirmation];
321         Eina_Bool result;
322         if (confirmation->getResult() == WebConfirmation::ConfirmationResult::Confirmed)
323             result = EINA_TRUE;
324         else if (confirmation->getResult() == WebConfirmation::ConfirmationResult::Rejected)
325             result = EINA_FALSE;
326         else {
327             BROWSER_LOGE("Wrong ConfirmationResult");
328             break;
329         }
330         // set geolocation permission
331         ewk_geolocation_permission_reply(request, result);
332         ewk_view_resume(m_ewkView);
333
334         // remove from map
335         m_confirmationGeolocationMap.erase(confirmation);
336         break;
337     }
338     case WebConfirmation::ConfirmationType::UserMedia: {
339         Ewk_User_Media_Permission_Request *request = m_confirmationUserMediaMap[confirmation];
340         Eina_Bool result;
341         if (confirmation->getResult() == WebConfirmation::ConfirmationResult::Confirmed)
342             result = EINA_TRUE;
343         else if (confirmation->getResult() == WebConfirmation::ConfirmationResult::Rejected)
344             result = EINA_FALSE;
345         else {
346             BROWSER_LOGE("Wrong ConfirmationResult");
347             break;
348         };
349
350         // set usermedia permission
351         ewk_user_media_permission_reply(request, result);
352         ewk_view_resume(m_ewkView);
353
354         // remove from map
355         m_confirmationUserMediaMap.erase(confirmation);
356         break;
357     }
358     case WebConfirmation::ConfirmationType::Notification: {
359         Ewk_Notification_Permission_Request *request = m_confirmationNotificationMap[confirmation];
360         Eina_Bool result;
361         if (confirmation->getResult() == WebConfirmation::ConfirmationResult::Confirmed)
362             result = EINA_TRUE;
363         else if (confirmation->getResult() == WebConfirmation::ConfirmationResult::Rejected)
364             result = EINA_FALSE;
365         else {
366             BROWSER_LOGE("Wrong ConfirmationResult");
367             break;
368         }
369
370         // set notification permission
371         ewk_notification_permission_reply(request, result);
372         ewk_view_resume(m_ewkView);
373
374         // remove from map
375         m_confirmationNotificationMap.erase(confirmation);
376         break;
377     }
378     case WebConfirmation::ConfirmationType::CertificateConfirmation: {
379         CertificateConfirmationPtr cert = std::dynamic_pointer_cast<CertificateConfirmation, WebConfirmation>(confirmation);
380         Ewk_Certificate_Policy_Decision *request = m_confirmationCertificatenMap[cert];
381         Eina_Bool result;
382         if (cert->getResult() == WebConfirmation::ConfirmationResult::Confirmed)
383             result = EINA_TRUE;
384         else if (cert->getResult() == WebConfirmation::ConfirmationResult::Rejected)
385             result = EINA_FALSE;
386         else {
387             BROWSER_LOGE("Wrong ConfirmationResult");
388             break;
389         }
390
391         // set certificate confirmation
392         BROWSER_LOGE("NOT IMPLEMENTED: Certificate Confirmation handling!");
393
394         // remove from map
395         m_confirmationCertificatenMap.erase(cert);
396         break;
397     }
398     case WebConfirmation::ConfirmationType::Authentication: {
399         AuthenticationConfirmationPtr auth = std::dynamic_pointer_cast<AuthenticationConfirmation, WebConfirmation>(confirmation);
400         Ewk_Auth_Request *request = m_confirmationAuthenticationMap[auth];
401         if (auth->getResult() == WebConfirmation::ConfirmationResult::Confirmed) {
402             BROWSER_LOGE("NOT IMPLEMENTED: Autenthication Request Confirmation handling!");
403         } else if (auth->getResult() == WebConfirmation::ConfirmationResult::Rejected) {
404             BROWSER_LOGE("NOT IMPLEMENTED: Autenthication Request Rejection handling!");
405         } else {
406             BROWSER_LOGE("Wrong ConfirmationResult");
407             break;
408         }
409
410         // remove from map
411         m_confirmationAuthenticationMap.erase(auth);
412         break;
413     }
414     default:
415         break;
416     }
417 #else
418    (void)confirmation;
419 #endif
420 #endif
421 }
422
423 std::shared_ptr<tizen_browser::tools::BrowserImage> WebView::captureSnapshot(int targetWidth, int targetHeight)
424 {
425     BROWSER_LOGD("%s:%d %s NOT IMPLEMENTED, returning empty BrowserImage object", __FILE__, __LINE__, __func__);
426     M_ASSERT(m_ewkView);
427     M_ASSERT(targetWidth);
428     M_ASSERT(targetHeight);
429     Evas_Coord vw, vh;
430     std::shared_ptr<tizen_browser::tools::BrowserImage> noImage = std::make_shared<tizen_browser::tools::BrowserImage>();
431     evas_object_geometry_get(m_ewkView, NULL, NULL, &vw, &vh);
432     if (vw == 0 || vh == 0)
433         return noImage;
434
435     Eina_Rectangle area;
436     double snapshotProportions = (double)(targetWidth) /(double)(targetHeight);
437     double webkitProportions = (double)(vw) /(double)(vh);
438     if (webkitProportions >= snapshotProportions) {
439         // centring position of screenshot
440         area.x = (vw*getZoomFactor()/2) - (vh*getZoomFactor()*snapshotProportions/2);
441         area.y = 0;
442         area.w = vh*getZoomFactor()*snapshotProportions;
443         area.h = vh*getZoomFactor();
444     }
445     else {
446         area.x = 0;
447         area.y = 0;
448         area.w = vw*getZoomFactor();
449         area.h = vw*getZoomFactor()/snapshotProportions;
450     }
451     if (area.w == 0 || area.h == 0)
452         return noImage;
453
454     double scaleW = (double)targetWidth / (double)(area.w);
455     double scaleH = (double)targetHeight / (double)(area.h);
456
457 #if defined(USE_EWEBKIT)
458 #if PLATFORM(TIZEN)
459     Evas_Object *snapshot = nullptr;
460     // TODO use ewk_view_screenshot_contents_get_async API here
461     if (snapshot)
462         return tizen_browser::tools::EflTools::getBrowserImage(snapshot);
463 #endif
464 #endif
465
466     return noImage;
467 }
468
469 #if defined(USE_EWEBKIT)
470 void WebView::__setFocusToEwkView(void * data, Evas * /* e */, Evas_Object * /* obj */, void * /* event_info */)
471 {
472     BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
473
474     WebView * self = reinterpret_cast<WebView *>(data);
475
476     if(!self->hasFocus())
477         self->ewkViewClicked();
478 }
479
480 void WebView::__newWindowRequest(void *data, Evas_Object *, void *out)
481 {
482     BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
483
484     WebView * self = reinterpret_cast<WebView *>(data);
485     BROWSER_LOGD("%s:%d %s self=%p", __FILE__, __LINE__, __func__, self);
486     BROWSER_LOGD("Window creating in tab: %s", self->getTabId().toString().c_str());
487     std::shared_ptr<basic_webengine::AbstractWebEngine<Evas_Object>>  m_webEngine;
488     m_webEngine = std::dynamic_pointer_cast
489     <
490         basic_webengine::AbstractWebEngine<Evas_Object>,tizen_browser::core::AbstractService
491     >
492     (tizen_browser::core::ServiceManager::getInstance().getService("org.tizen.browser.webkitengineservice"));
493     M_ASSERT(m_webEngine);
494
495     /// \todo: Choose newly created tab.
496     TabId id = m_webEngine->addTab(std::string(), &self->getTabId());
497     BROWSER_LOGD("Created tab: %s", id.toString().c_str());
498
499     Evas_Object* tab_ewk_view = m_webEngine->getTabView(id);
500     *static_cast<Evas_Object**>(out) = tab_ewk_view;
501 }
502
503 void WebView::__closeWindowRequest(void *data, Evas_Object *, void *)
504 {
505     BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
506     WebView * self = reinterpret_cast<WebView *>(data);
507     std::shared_ptr<AbstractWebEngine<Evas_Object>> m_webEngine =
508                 std::dynamic_pointer_cast
509                 <basic_webengine::AbstractWebEngine<Evas_Object>,tizen_browser::core::AbstractService>
510                 (tizen_browser::core::ServiceManager::getInstance().getService("org.tizen.browser.webkitengineservice"));
511     m_webEngine->closeTab(self->getTabId());
512 }
513
514 void WebView::__loadStarted(void * data, Evas_Object * /* obj */, void * /* event_info */)
515 {
516     WebView * self = reinterpret_cast<WebView *>(data);
517
518     BROWSER_LOGD("%s:%d\n\t %s", __func__, __LINE__, ewk_view_url_get(self->m_ewkView));
519
520     self->m_isLoading = true;
521     self->loadStarted();
522     tizen_browser::services::TabThumbCache* cache = tizen_browser::services::TabThumbCache::getInstance();
523     cache->clearThumb(self->m_tabId);
524 }
525
526 void WebView::__loadStop(void * data, Evas_Object * /* obj */, void * /* event_info */)
527 {
528     BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
529
530     WebView * self = reinterpret_cast<WebView *>(data);
531     self->m_isLoading = false;
532
533     self->loadStop();
534 }
535
536 void WebView::__loadFinished(void * data, Evas_Object * /* obj */, void * /* event_info */)
537 {
538     BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
539
540     WebView * self = reinterpret_cast<WebView *>(data);
541     self->m_isLoading = false;
542     self->m_loadProgress = 1;
543
544     self->loadFinished();
545     self->loadProgress(self->m_loadProgress);
546     tizen_browser::services::TabThumbCache* cache = tizen_browser::services::TabThumbCache::getInstance();
547     cache->updateThumb(self->m_tabId);
548 }
549
550 void WebView::__loadProgress(void * data, Evas_Object * /* obj */, void * event_info)
551 {
552     BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
553
554     WebView * self = reinterpret_cast<WebView *>(data);
555     self->m_loadProgress = *(double *)event_info;
556
557     self->loadProgress(self->m_loadProgress);
558 }
559
560 void WebView::__loadError(void* data, Evas_Object * obj, void* ewkError)
561 {
562     BROWSER_LOGD("[%s:%d] ", __PRETTY_FUNCTION__, __LINE__);
563
564     WebView *self = reinterpret_cast<WebView*>(data);
565     Ewk_Error *error = reinterpret_cast<Ewk_Error*>(ewkError);
566     Ewk_Error_Type errorType = ewk_error_type_get(error);
567
568     BROWSER_LOGD("[%s:%d] ewk_error_type: %d ",
569                  __PRETTY_FUNCTION__, __LINE__, errorType);
570
571     BROWSER_LOGD("[%s:%d] emiting signal ", __PRETTY_FUNCTION__, __LINE__);
572     int errorCode = ewk_error_code_get(error);
573     if(errorCode == EWK_ERROR_NETWORK_STATUS_CANCELLED)
574     {
575         BROWSER_LOGD("Stop signal emitted");
576         BROWSER_LOGD("Error description: %s", ewk_error_description_get(error));
577         evas_object_smart_callback_call(obj, "load,stop", NULL);
578     }
579     else
580     {
581         self->loadError();
582         self->m_loadError=true;
583     }
584 }
585
586 void WebView::__titleChanged(void * data, Evas_Object * obj, void * /* event_info */)
587 {
588     BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
589
590     WebView * self = reinterpret_cast<WebView *>(data);
591     self->m_title = tizen_browser::tools::fromChar(ewk_view_title_get(obj));
592
593     self->titleChanged(self->m_title);
594 }
595
596 void WebView::__urlChanged(void * data, Evas_Object * /* obj */, void * event_info)
597 {
598     BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
599
600     WebView * self = reinterpret_cast<WebView *>(data);
601     BROWSER_LOGD("URL changed for tab: %s", self->getTabId().toString().c_str());
602     std::shared_ptr<basic_webengine::AbstractWebEngine<Evas_Object>> m_webEngine;
603     m_webEngine = std::dynamic_pointer_cast<basic_webengine::AbstractWebEngine<Evas_Object>, tizen_browser::core::AbstractService>(
604             tizen_browser::core::ServiceManager::getInstance().getService("org.tizen.browser.webkitengineservice"));
605     M_ASSERT(m_webEngine);
606     self->uriChanged(tizen_browser::tools::fromChar(reinterpret_cast<const char *>(event_info)));
607     self->tabIdChecker(self->m_tabId);
608 }
609
610 void WebView::__backForwardListChanged(void * data, Evas_Object * /* obj */, void * /* event_info */)
611 {
612     BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
613
614     WebView * self = reinterpret_cast<WebView *>(data);
615     self->backwardEnableChanged(self->isBackEnabled());
616     self->forwardEnableChanged(self->isForwardEnabled());
617 }
618
619 void WebView::__faviconChanged(void* data, Evas_Object*, void*)
620 {
621     if(data)
622     {
623         WebView * self = static_cast<WebView *>(data);
624         Evas_Object * favicon = ewk_context_icon_database_icon_object_add(ewk_view_context_get(self->m_ewkView), ewk_view_url_get(self->m_ewkView),evas_object_evas_get(self->m_ewkView));
625         if (favicon) {
626             BROWSER_LOGD("[%s:%d] Favicon received", __PRETTY_FUNCTION__, __LINE__);
627             self->faviconImage = tizen_browser::tools::EflTools::getBrowserImage(favicon);
628             evas_object_unref(favicon);
629             self->favIconChanged(self->faviconImage);
630         }
631     }
632 }
633
634 void WebView::__IMEClosed(void* data, Evas_Object*, void*)
635 {
636     BROWSER_LOGD("%s", __func__);
637     WebView * self = reinterpret_cast<WebView *>(data);
638     self->IMEStateChanged(false);
639 }
640
641 void WebView::__IMEOpened(void* data, Evas_Object*, void*)
642 {
643     BROWSER_LOGD("%s", __func__);
644     WebView * self = reinterpret_cast<WebView *>(data);
645     self->IMEStateChanged(true);
646 }
647
648 std::string WebView::securityOriginToUri(const Ewk_Security_Origin *origin)
649 {
650     std::string protocol = tizen_browser::tools::fromChar(ewk_security_origin_protocol_get(origin));
651     std::string uri = tizen_browser::tools::fromChar(ewk_security_origin_host_get(origin));
652     std::string url = (boost::format("%1%://%2%") % protocol % uri).str();
653     return url;
654 }
655
656 void WebView::__geolocationPermissionRequest(void * data, Evas_Object * /* obj */, void * event_info)
657 {
658     BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
659 #if PLATFORM(TIZEN)
660     WebView * self = reinterpret_cast<WebView *>(data);
661
662     Ewk_Geolocation_Permission_Request *request = reinterpret_cast<Ewk_Geolocation_Permission_Request *>(event_info);
663     if (!request)
664         return;
665
666     // suspend webview
667     ewk_view_suspend(self->m_ewkView);
668
669     std::string url = WebView::securityOriginToUri(ewk_geolocation_permission_request_origin_get(request));
670
671     ///\todo add translations
672     std::string message = (boost::format("%1% Requests your location") % url).str();
673
674     WebConfirmationPtr c = std::make_shared<WebConfirmation>(WebConfirmation::ConfirmationType::Geolocation, self->m_tabId, url, message);
675
676     // store
677     self->m_confirmationGeolocationMap[c] = request;
678
679     self->cofirmationRequest(c);
680 #endif
681 }
682
683 void WebView::__usermediaPermissionRequest(void * data, Evas_Object * /* obj */, void * event_info)
684 {
685     BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
686 #if PLATFORM(TIZEN)
687     WebView * self = reinterpret_cast<WebView *>(data);
688
689     Ewk_User_Media_Permission_Request *request = reinterpret_cast<Ewk_User_Media_Permission_Request *>(event_info);
690     if (!request)
691         return;
692
693     // suspend webview
694     ewk_view_suspend(self->m_ewkView);
695
696     ///\todo add translations
697     std::string message = "User media permission request";
698
699     WebConfirmationPtr c = std::make_shared<WebConfirmation>(WebConfirmation::ConfirmationType::UserMedia, self->m_tabId, std::string(), message);
700
701     // store
702     self->m_confirmationUserMediaMap[c] = request;
703
704     self->cofirmationRequest(c);
705 #endif
706 }
707
708 void WebView::__notificationPermissionRequest(void * data, Evas_Object * /* obj */, void * event_info)
709 {
710     BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
711 #if PLATFORM(TIZEN)
712     WebView * self = reinterpret_cast<WebView *>(data);
713
714     Ewk_Notification_Permission_Request *request = reinterpret_cast<Ewk_Notification_Permission_Request *>(event_info);
715     if (!request)
716         return;
717
718     // suspend webview
719     ewk_view_suspend(self->m_ewkView);
720
721     ///\todo add translations
722     std::string message = (boost::format("%1% wants to display notifications") % self->getURI()).str();
723
724     WebConfirmationPtr c = std::make_shared<WebConfirmation>(WebConfirmation::ConfirmationType::Notification, self->m_tabId, self->getURI(), message);
725
726     // store
727     self->m_confirmationNotificationMap[c] = request;
728
729     self->cofirmationRequest(c);
730 #endif
731 }
732
733 void WebView::__authenticationRequest(void * data, Evas_Object * /* obj */, void * event_info)
734 {
735     BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
736 #if PLATFORM(TIZEN)
737     WebView * self = reinterpret_cast<WebView *>(data);
738
739     Ewk_Auth_Request *request = reinterpret_cast<Ewk_Auth_Request *>(event_info);
740     EINA_SAFETY_ON_NULL_RETURN(request);
741
742     std::string url = self->getURI();
743     std::string message = (boost::format("A username and password are being requested by %1%.") % url).str();
744
745     AuthenticationConfirmationPtr c = std::make_shared<AuthenticationConfirmation>(self->m_tabId, url, message);
746
747     self->m_confirmationAuthenticationMap[c] = request;
748
749     self->cofirmationRequest(c);
750 #endif
751 }
752
753 void WebView::__requestCertificationConfirm(void * data , Evas_Object * /* obj */, void * event_info)
754 {
755     BROWSER_LOGD("%s:%d %s", __FILE__, __LINE__, __func__);
756 #if PLATFORM(TIZEN)
757     WebView * self = reinterpret_cast<WebView *>(data);
758
759     Ewk_Certificate_Policy_Decision *request = reinterpret_cast<Ewk_Certificate_Policy_Decision *>(event_info);
760     if (!request)
761         return;
762
763     // suspend webview
764     ewk_view_suspend(self->m_ewkView);
765
766     std::string url = self->getURI();
767
768     ///\todo add translations
769     std::string message = (boost::format("There are problems with the security certificate for this site.<br>%1%") % url).str();
770
771     CertificateConfirmationPtr c = std::make_shared<CertificateConfirmation>(self->m_tabId, url, message);
772
773     c->setResult(tizen_browser::basic_webengine::WebConfirmation::ConfirmationResult::Confirmed);
774
775     // store
776     self->m_confirmationCertificatenMap[c] = request;
777
778     self->cofirmationRequest(c);
779 #endif
780 }
781 #endif
782
783 void WebView::setFocus()
784 {
785     elm_object_focus_set(m_ewkView, EINA_TRUE);
786 }
787
788 void WebView::clearFocus()
789 {
790     elm_object_focus_set(m_ewkView, EINA_FALSE);
791 }
792
793 bool WebView::hasFocus() const
794 {
795     return elm_object_focus_get(m_ewkView) == EINA_TRUE ? true : false;
796 }
797
798 double WebView::getZoomFactor() const
799 {
800     if(EINA_UNLIKELY(m_ewkView == NULL)){
801         return 1.0;
802     }
803
804 #if defined(USE_EWEBKIT)
805     return ewk_view_page_zoom_get(m_ewkView);
806 #else
807     return 1.0;
808 #endif
809 }
810
811 void WebView::setZoomFactor(double zoomFactor)
812 {
813 #if defined(USE_EWEBKIT)
814     if(m_ewkView){
815         //using zoomFactor = 0 sets zoom "fit to screen"
816
817         ewk_view_page_zoom_set(m_ewkView, zoomFactor);
818     }
819 #endif
820 }
821
822
823 const TabId& WebView::getTabId(){
824     return m_tabId;
825 }
826
827
828 std::shared_ptr<tizen_browser::tools::BrowserImage> WebView::getFavicon() {
829     BROWSER_LOGD("%s:%d, TabId: %s", __PRETTY_FUNCTION__, __LINE__, m_tabId.toString().c_str());
830     M_ASSERT(m_ewkView);
831
832 #if defined(USE_EWEBKIT)
833     if (faviconImage.get() == NULL) {
834
835     if (m_ewkView)
836     {
837         Ewk_Context *context = ewk_view_context_get(m_ewkView);
838         if (context)
839         {
840             Evas_Object * favicon = ewk_context_icon_database_icon_object_add(context, ewk_view_url_get(m_ewkView), evas_object_evas_get(m_ewkView));
841
842 #ifndef NDEBUG
843                 int w = 0, h = 0;
844                 evas_object_image_size_get(favicon, &w, &h);
845                 BROWSER_LOGD("[%s]: Info about favicon: w:%d h:%d, type: %s", __func__, w, h, evas_object_type_get(favicon));
846 #endif
847                 if (favicon) {
848                     std::shared_ptr<tizen_browser::tools::BrowserImage>
849                         image = tizen_browser::tools::EflTools::getBrowserImage(favicon);
850
851                     evas_object_unref(favicon);
852
853                     return image;
854                 }
855             } else {
856                 return faviconImage;
857             }
858         }
859     }
860 #endif
861
862     BROWSER_LOGE("[%s:%d]: Returned favicon is empty!", __PRETTY_FUNCTION__, __LINE__);
863     return std::make_shared<tizen_browser::tools::BrowserImage>();
864 }
865
866 void WebView::clearPrivateData()
867 {
868     BROWSER_LOGD("Clearing private data");
869 #if defined(USE_EWEBKIT)
870     if (m_ewkView)
871     {
872         Ewk_Context *context = ewk_view_context_get(m_ewkView);
873         if (context)
874         {
875             ewk_context_web_storage_delete_all(context);
876             ewk_cookie_manager_cookies_clear(ewk_context_cookie_manager_get(context));
877         }
878     }
879 #endif
880 }
881
882 void WebView::searchOnWebsite(const std::string & searchString, int flags)
883 {
884     ///\todo: it should be "0" instead of "1024" for unlimited match count but it doesn't work properly in WebKit
885     Eina_Bool result = ewk_view_text_find(m_ewkView, searchString.c_str(), static_cast<Ewk_Find_Options>(flags), 1024);
886     BROWSER_LOGD("Ewk search; word: %s, result: %d", searchString.c_str(), result);
887 }
888
889 } /* namespace webkitengine_service */
890 } /* end of basic_webengine */
891 } /* end of tizen_browser */
892