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