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