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