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