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