Cleanup code
[platform/framework/web/nwrt.git] / src / runtime / web_view_impl.cc
1 // Copyright 2015 Samsung Electronics Co, Ltd. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "runtime/web_view_impl.h"
6
7 #include <ewk_chromium.h>
8 #include <functional>
9 #include <sstream>
10
11 #include "runtime/native_window.h"
12 #include "common/logger.h"
13
14 namespace wrt {
15
16 namespace {
17 // TODO(sngn.lee) : It should be declare in common header
18 const char* kKeyNameBack = "back";
19 const char* kKeyNameMenu = "menu";
20
21 static int ToWebRotation(int r) {
22   switch (r) {
23     case 90:
24       return -90;
25     case 270:
26       return 90;
27   }
28   return r;
29 }
30
31 static int ToNativeRotation(int r) {
32   switch (r) {
33     case -90:
34       return 90;
35     case 90:
36       return 270;
37   }
38   return r;
39 }
40
41 }  // namespace
42
43 WebViewImpl::WebViewImpl(WebView* view,
44                          NativeWindow* window,
45                          Ewk_Context* context)
46     : window_(window),
47       context_(context),
48       ewk_view_(NULL),
49       listener_(NULL),
50       view_(view),
51       fullscreen_(false) {
52   Initialize();
53 }
54
55 WebViewImpl::~WebViewImpl() {
56   Deinitialize();
57   evas_object_del(ewk_view_);
58 }
59
60 void WebViewImpl::LoadUrl(const std::string& url) {
61   ewk_view_url_set(ewk_view_, url.c_str());
62 }
63
64 void WebViewImpl::Suspend() {
65   // suspend webview
66   ewk_view_suspend(ewk_view_);
67 }
68
69 void WebViewImpl::Resume() {
70   // resume webview
71   ewk_view_resume(ewk_view_);
72 }
73
74 void WebViewImpl::Reload() {
75   ewk_view_reload(ewk_view_);
76 }
77
78 void WebViewImpl::SetVisibility(bool show) {
79   ewk_view_visibility_set(ewk_view_, show ? EINA_TRUE : EINA_FALSE);
80 }
81
82
83 bool WebViewImpl::EvalJavascript(const std::string& script) {
84   return ewk_view_script_execute(ewk_view_, script.c_str(), NULL, NULL);
85 }
86
87 void WebViewImpl::Initialize() {
88   ewk_view_ = ewk_view_add_with_context(window_->evas_object(), context_);
89
90   InitKeyCallback();
91   InitLoaderCallback();
92   InitPolicyDecideCallback();
93   InitQuotaExceededCallback();
94   InitIPCMessageCallback();
95   InitOrientaionLockCallback();
96   InitConsoleMessageCallback();
97   InitCustomContextMenuCallback();
98   InitRotationCallback();
99   InitWindowCreateCallback();
100   InitFullscreenCallback();
101   InitNotificationPermissionCallback();
102   InitGeolocationPermissionCallback();
103   InitAuthenticationCallback();
104   InitCertificateAllowCallback();
105
106   // TODO(sngn.lee): "notification,show"
107   // TODO(sngn.lee): "notification,cancel"
108   // TODO(sngn.lee): "protocolhandler,registration,requested"
109   //                  custom protocol handler
110   // TODO(sngn.lee): ewk_view_user_media_permission_callback_set
111
112   // Show webview
113   evas_object_show(ewk_view_);
114 }
115
116 void WebViewImpl::Deinitialize() {
117   auto it = smart_callbacks_.begin();
118   for ( ; it != smart_callbacks_.end(); ++it) {
119     evas_object_smart_callback_del(
120         ewk_view_,
121         it->first.c_str(),
122         it->second);
123   }
124   ea_object_event_callback_del(ewk_view_,
125                                EA_CALLBACK_BACK,
126                                smart_callbacks_["key_callback"]);
127   ewk_view_exceeded_database_quota_callback_set(
128       ewk_view_,
129       NULL,
130       NULL);
131   ewk_view_exceeded_indexed_database_quota_callback_set(
132       ewk_view_,
133       NULL,
134       NULL);
135   ewk_view_exceeded_local_file_system_quota_callback_set(
136       ewk_view_,
137       NULL,
138       NULL);
139   ewk_view_orientation_lock_callback_set(
140       ewk_view_,
141       NULL,
142       NULL);
143   ewk_view_notification_permission_callback_set(
144       ewk_view_,
145       NULL,
146       NULL);
147   ewk_view_geolocation_permission_callback_set(
148       ewk_view_,
149       NULL,
150       NULL);
151   window_->RemoveRotationHandler(rotation_handler_id_);
152 }
153
154 void WebViewImpl::InitKeyCallback() {
155   auto key_callback = [](void* user_data,
156                          Evas_Object* /*obj*/,
157                          void* event_info) -> void {
158     WebViewImpl* self = static_cast<WebViewImpl*>(user_data);
159     Ea_Callback_Type key = static_cast<Ea_Callback_Type>(
160                               reinterpret_cast<int>(event_info));
161     self->OnKeyEvent(key);
162   };
163   ea_object_event_callback_add(ewk_view_,
164                                EA_CALLBACK_BACK,
165                                key_callback,
166                                view_);
167   ea_object_event_callback_add(ewk_view_,
168                                EA_CALLBACK_MORE,
169                                key_callback,
170                                view_);
171   smart_callbacks_["key_callback"] = key_callback;
172 }
173
174 void WebViewImpl::InitLoaderCallback() {
175   // load statred callback
176   auto loadstart_callback = [](void* user_data,
177                                Evas_Object* /*obj*/,
178                                void*) {
179     WebViewImpl* self = static_cast<WebViewImpl*>(user_data);
180     if (self->listener_)
181       self->listener_->OnLoadStart(self->view_);
182   };
183   evas_object_smart_callback_add(ewk_view_,
184                                  "load,started",
185                                  loadstart_callback,
186                                  this);
187   // load finished callback
188   auto loadfinished_callback = [](void* user_data,
189                                   Evas_Object*,
190                                   void*) {
191     WebViewImpl* self = static_cast<WebViewImpl*>(user_data);
192     if (self->listener_)
193       self->listener_->OnLoadFinished(self->view_);
194   };
195   evas_object_smart_callback_add(ewk_view_,
196                                  "load,finished",
197                                  loadfinished_callback,
198                                  this);
199
200   // load progress callback
201   auto loadprogress_callback = [](void* user_data,
202                                   Evas_Object*,
203                                   void* event_info) {
204     WebViewImpl* self = static_cast<WebViewImpl*>(user_data);
205     double* progress = static_cast<double*>(event_info);
206     if (self->listener_)
207       self->listener_->OnLoadProgress(self->view_, *progress);
208   };
209   evas_object_smart_callback_add(ewk_view_,
210                                  "load,progress",
211                                  loadprogress_callback,
212                                  this);
213   // rendered callback
214   auto rendered_callback = [](void* user_data,
215                               Evas_Object*,
216                               void*) {
217     WebViewImpl* self = static_cast<WebViewImpl*>(user_data);
218     if (self->listener_)
219       self->listener_->OnRendered(self->view_);
220   };
221   evas_object_smart_callback_add(ewk_view_,
222                                  "frame,rendered",
223                                  rendered_callback,
224                                  this);
225   smart_callbacks_["load,started"] = loadstart_callback;
226   smart_callbacks_["load,finished"] = loadfinished_callback;
227   smart_callbacks_["load,progress"] = loadprogress_callback;
228   smart_callbacks_["frame,rendered"] = rendered_callback;
229 }
230
231 void WebViewImpl::InitPolicyDecideCallback() {
232   // "policy,navigation,decide"
233   auto navigation_decide_callback = [](void* user_data,
234                                        Evas_Object*,
235                                        void* event_info) {
236     WebViewImpl* self = static_cast<WebViewImpl*>(user_data);
237     Ewk_Policy_Decision* policy =
238             static_cast<Ewk_Policy_Decision*>(event_info);
239     const char* url = ewk_policy_decision_url_get(policy);
240
241     if (self->listener_) {
242       if (self->listener_->OnDidNavigation(self->view_, url))
243         ewk_policy_decision_use(policy);
244       else
245         ewk_policy_decision_ignore(policy);
246     } else {
247       ewk_policy_decision_use(policy);
248     }
249   };
250   evas_object_smart_callback_add(ewk_view_,
251                                  "policy,navigation,decide",
252                                  navigation_decide_callback,
253                                  this);
254
255   // policy,newwindow,decide
256   auto newwindow_decide_callback = [](void* user_data,
257                                       Evas_Object*,
258                                       void* event_info) {
259     WebViewImpl* self = static_cast<WebViewImpl*>(user_data);
260     Ewk_Policy_Decision* policy =
261             static_cast<Ewk_Policy_Decision*>(event_info);
262
263     const char* url = ewk_policy_decision_url_get(policy);
264
265     if (self->listener_) {
266       if (self->listener_->OnDidNavigation(self->view_, url) &&
267          self->listener_->OnDidOpenWindow(self->view_, url)) {
268          ewk_policy_decision_use(policy);
269       } else {
270         ewk_policy_decision_ignore(policy);
271       }
272     } else {
273       ewk_policy_decision_use(policy);
274     }
275   };
276   evas_object_smart_callback_add(ewk_view_,
277                                  "policy,newwindow,decide",
278                                  newwindow_decide_callback,
279                                  this);
280   smart_callbacks_["policy,navigation,decide"] = navigation_decide_callback;
281   smart_callbacks_["policy,newwindow,decide"] = newwindow_decide_callback;
282 }
283
284 void WebViewImpl::InitQuotaExceededCallback() {
285   // TODO(sngn.lee): Need callback interface - OnQutaExceed
286   // check http://tizen.org/privilege/unlimitedstorage
287
288   // callback for database quota exceeded
289   auto database_exceeded_callback = [](Evas_Object* view,
290                                        Ewk_Security_Origin* origin,
291                                        const char*,
292                                        uint64_t,
293                                        void* user_data) -> Eina_Bool {
294     WebViewImpl* self = static_cast<WebViewImpl*>(user_data);
295     if (self == NULL || self->listener_ == NULL)
296       return EINA_TRUE;
297
298     auto result_handler = [view](bool result) {
299       LOGGER(DEBUG) << "database quota Permission Result : " << result;
300       ewk_view_exceeded_database_quota_reply(view, result);
301     };
302     std::stringstream url;
303     url << ewk_security_origin_protocol_get(origin)
304         << "://"
305         << ewk_security_origin_host_get(origin)
306         << ":"
307         << ewk_security_origin_port_get(origin);
308     self->listener_->OnQuotaExceed(
309         self->view_,
310         url.str(),
311         result_handler);
312     return EINA_TRUE;
313   };
314   ewk_view_exceeded_database_quota_callback_set(
315     ewk_view_,
316     database_exceeded_callback,
317     this);
318
319   // callback for indexed database quota exceeded
320   auto indexed_db_exceeded_callback = [](Evas_Object* view,
321                                        Ewk_Security_Origin* origin,
322                                        int64_t,
323                                        void* user_data) -> Eina_Bool {
324     WebViewImpl* self = static_cast<WebViewImpl*>(user_data);
325     if (self == NULL || self->listener_ == NULL)
326       return EINA_TRUE;
327
328     auto result_handler = [view](bool result) {
329       LOGGER(DEBUG) << "indexed db quota Permission Result : " << result;
330       ewk_view_exceeded_indexed_database_quota_reply(view, result);
331     };
332     std::stringstream url;
333     url << ewk_security_origin_protocol_get(origin)
334         << "://"
335         << ewk_security_origin_host_get(origin)
336         << ":"
337         << ewk_security_origin_port_get(origin);
338     self->listener_->OnQuotaExceed(
339         self->view_,
340         url.str(),
341         result_handler);
342     return EINA_TRUE;
343   };
344   ewk_view_exceeded_indexed_database_quota_callback_set(
345     ewk_view_,
346     indexed_db_exceeded_callback,
347     this);
348
349   // callback for localfile quota exceeded
350   auto localfile_exceeded_callback = [](Evas_Object* view,
351                                        Ewk_Security_Origin* origin,
352                                        int64_t,
353                                        void* user_data) -> Eina_Bool {
354     WebViewImpl* self = static_cast<WebViewImpl*>(user_data);
355     if (self == NULL || self->listener_ == NULL)
356       return EINA_TRUE;
357
358     auto result_handler = [view](bool result) {
359       LOGGER(DEBUG) << "local file quota Permission Result : " << result;
360       ewk_view_exceeded_local_file_system_quota_reply(view, result);
361     };
362     std::stringstream url;
363     url << ewk_security_origin_protocol_get(origin)
364         << "://"
365         << ewk_security_origin_host_get(origin)
366         << ":"
367         << ewk_security_origin_port_get(origin);
368     self->listener_->OnQuotaExceed(
369         self->view_,
370         url.str(),
371         result_handler);
372     return EINA_TRUE;
373   };
374   ewk_view_exceeded_local_file_system_quota_callback_set(
375     ewk_view_,
376     localfile_exceeded_callback,
377     this);
378 }
379
380 void WebViewImpl::InitIPCMessageCallback() {
381   // wrt,message
382   auto wrt_message_callback = [](void* user_data,
383                                  Evas_Object*,
384                                  void* event_info) {
385     WebViewImpl* self = static_cast<WebViewImpl*>(user_data);
386     Ewk_IPC_Wrt_Message_Data* msg =
387         static_cast<Ewk_IPC_Wrt_Message_Data*>(event_info);
388     if (self->listener_)
389       self->listener_->OnReceivedWrtMessage(self->view_, msg);
390   };
391   evas_object_smart_callback_add(ewk_view_,
392                                  "wrt,message",
393                                  wrt_message_callback,
394                                  this);
395   smart_callbacks_["wrt,message"] = wrt_message_callback;
396 }
397
398 void WebViewImpl::InitOrientaionLockCallback() {
399   // Orientation lock callback
400   auto orientation_lock_callback = [](Evas_Object*,
401                                       Eina_Bool need_lock,
402                                       int orientation,
403                                       void* user_data) -> Eina_Bool {
404     WebViewImpl* self = static_cast<WebViewImpl*>(user_data);
405     if (self->listener_) {
406       self->listener_->OnOrientationLock(self->view_,
407                                          need_lock,
408                                          ToNativeRotation(orientation));
409     }
410     return EINA_TRUE;
411   };
412   ewk_view_orientation_lock_callback_set(ewk_view_,
413                                          orientation_lock_callback,
414                                          this);
415 }
416
417 void WebViewImpl::InitConsoleMessageCallback() {
418   // console log
419   auto console_message_callback = [](void* user_data,
420                                  Evas_Object*,
421                                  void* event_info) {
422     WebViewImpl* self = static_cast<WebViewImpl*>(user_data);
423     if (!self->listener_) {
424       return;
425     }
426     Ewk_Console_Message* msg = static_cast<Ewk_Console_Message*>(event_info);
427     unsigned int line_number = ewk_console_message_line_get(msg);
428
429     std::stringstream buf;
430     if (line_number) {
431         buf << ewk_console_message_source_get(msg) << ":";
432         buf << line_number << ":";
433     }
434     buf << ewk_console_message_text_get(msg);
435     int level = ewk_console_message_level_get(msg);
436     self->listener_->OnConsoleMessage(buf.str(), level);
437   };
438   evas_object_smart_callback_add(ewk_view_,
439                                  "console,message",
440                                  console_message_callback,
441                                  this);
442   smart_callbacks_["console,message"] = console_message_callback;
443 }
444
445 void WebViewImpl::InitCustomContextMenuCallback() {
446   auto custom_context_menu_callback = [](void* user_data,
447                                          Evas_Object*,
448                                          void* event_info) {
449     Ewk_Context_Menu* contextmenu = static_cast<Ewk_Context_Menu*>(event_info);
450     WebViewImpl* self = static_cast<WebViewImpl*>(user_data);
451     bool disabled = false;
452     if (self->listener_ &&
453         self->listener_->OnContextMenuDisabled(self->view_)) {
454       disabled = true;
455     }
456     int cnt = ewk_context_menu_item_count(contextmenu);
457     for (unsigned idx = cnt-1; idx > 0; --idx) {
458       auto* item = ewk_context_menu_nth_item_get(contextmenu, idx);
459       Ewk_Context_Menu_Item_Tag tag = ewk_context_menu_item_tag_get(item);
460       switch (tag) {
461         case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_IMAGE_IN_NEW_WINDOW:
462         case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_LINK_IN_NEW_WINDOW:
463         case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_FRAME_IN_NEW_WINDOW:
464         case EWK_CONTEXT_MENU_ITEM_TAG_SEARCH_WEB:
465         case EWK_CONTEXT_MENU_ITEM_TAG_DOWNLOAD_IMAGE_TO_DISK:
466           ewk_context_menu_item_remove(contextmenu, item);
467           break;
468         default:
469           if (disabled)
470             ewk_context_menu_item_remove(contextmenu, item);
471       }
472     }
473   };
474   evas_object_smart_callback_add(ewk_view_,
475                                  "contextmenu,customize",
476                                  custom_context_menu_callback,
477                                  this);
478   smart_callbacks_["contextmenu,customize"] = custom_context_menu_callback;
479 }
480
481 void WebViewImpl::InitRotationCallback() {
482   // rotation support
483   ewk_view_orientation_send(ewk_view_, ToWebRotation(window_->rotation()));
484   rotation_handler_id_ = window_->AddRotationHandler(
485                                   std::bind(&WebViewImpl::OnRotation,
486                                   this,
487                                   std::placeholders::_1));
488 }
489
490 void WebViewImpl::InitWindowCreateCallback() {
491   auto create_callback = [](void* user_data,
492                             Evas_Object*,
493                             void* event_info) {
494     WebViewImpl* self = static_cast<WebViewImpl*>(user_data);
495     if (!self->listener_) {
496       return;
497     }
498     WebView* new_view = new WebView(self->window_, self->context_);
499     self->listener_->OnCreatedNewWebView(self->view_, new_view);
500   };
501
502   auto close_callback = [](void* user_data,
503                             Evas_Object*,
504                             void*) {
505     WebViewImpl* self = static_cast<WebViewImpl*>(user_data);
506     if (!self->listener_) {
507       return;
508     }
509     self->listener_->OnClosedWebView(self->view_);
510   };
511   evas_object_smart_callback_add(ewk_view_,
512                                  "create,window",
513                                  create_callback,
514                                  this);
515   evas_object_smart_callback_add(ewk_view_,
516                                  "close,window",
517                                  close_callback,
518                                  this);
519
520   smart_callbacks_["create,window"] = create_callback;
521   smart_callbacks_["close,window"] = close_callback;
522 }
523
524 void WebViewImpl::InitFullscreenCallback() {
525   auto enter_callback = [](void* user_data,
526                             Evas_Object*,
527                             void* /*event_info*/) {
528     WebViewImpl* self = static_cast<WebViewImpl*>(user_data);
529     self->fullscreen_ = true;
530     self->window_->FullScreen(true);
531   };
532   auto exit_callback =  [](void* user_data,
533                             Evas_Object*,
534                             void* /*event_info*/) {
535     WebViewImpl* self = static_cast<WebViewImpl*>(user_data);
536     self->fullscreen_ = false;
537     self->window_->FullScreen(false);
538   };
539   evas_object_smart_callback_add(ewk_view_,
540                                  "fullscreen,enterfullscreen",
541                                  enter_callback,
542                                  this);
543   evas_object_smart_callback_add(ewk_view_,
544                                  "fullscreen,exitfullscreen",
545                                  exit_callback,
546                                  this);
547   smart_callbacks_["fullscreen,enterfullscreen"] = enter_callback;
548   smart_callbacks_["fullscreen,exitfullscreen"] = exit_callback;
549 }
550
551 void WebViewImpl::InitNotificationPermissionCallback() {
552   auto request_callback = [](Evas_Object*,
553                              Ewk_Notification_Permission_Request* request,
554                              void* user_data) {
555     LOGGER(DEBUG) << "Notification Permission Request";
556     WebViewImpl* self = static_cast<WebViewImpl*>(user_data);
557     if (!self->listener_) {
558       ewk_notification_permission_reply(request, EINA_FALSE);
559       return EINA_TRUE;
560     }
561
562     ewk_notification_permission_request_suspend(request);
563     auto result_handler = [request](bool result) {
564       LOGGER(DEBUG) << "Notification Permission Result : %d" << result;
565       ewk_notification_permission_reply(request, result);
566     };
567     const Ewk_Security_Origin* ewk_origin =
568         ewk_notification_permission_request_origin_get(request);
569
570     std::stringstream url;
571     url << ewk_security_origin_protocol_get(ewk_origin)
572         << "://"
573         << ewk_security_origin_host_get(ewk_origin)
574         << ":"
575         << ewk_security_origin_port_get(ewk_origin);
576     self->listener_->OnNotificationPermissionRequest(
577         self->view_,
578         url.str(),
579         result_handler);
580     return EINA_TRUE;
581   };
582   ewk_view_notification_permission_callback_set(ewk_view_,
583                                                 request_callback,
584                                                 this);
585 }
586
587 void WebViewImpl::InitGeolocationPermissionCallback() {
588   auto permission_callback = [](
589       Evas_Object*,
590       Ewk_Geolocation_Permission_Request* request,
591       void* user_data) {
592     LOGGER(DEBUG) << "Geolocation Permission Request";
593     WebViewImpl* self = static_cast<WebViewImpl*>(user_data);
594     if (self == NULL || self->listener_ == NULL) {
595       ewk_geolocation_permission_reply(request, EINA_FALSE);
596       return EINA_TRUE;
597     }
598     ewk_geolocation_permission_request_suspend(request);
599
600     const Ewk_Security_Origin* ewk_origin =
601         ewk_geolocation_permission_request_origin_get(request);
602     auto result_handler = [request](bool result) {
603       LOGGER(DEBUG) << "Geolocation Permission Result : " << result;
604       ewk_geolocation_permission_reply(request, result);
605     };
606
607     std::stringstream url;
608     url << ewk_security_origin_protocol_get(ewk_origin)
609         << "://"
610         << ewk_security_origin_host_get(ewk_origin)
611         << ":"
612         << ewk_security_origin_port_get(ewk_origin);
613
614     self->listener_->OnGeolocationPermissionRequest(
615         self->view_,
616         url.str(),
617         result_handler);
618     return EINA_TRUE;
619   };
620   ewk_view_geolocation_permission_callback_set(ewk_view_,
621                                                permission_callback,
622                                                this);
623 }
624
625 void WebViewImpl::InitAuthenticationCallback() {
626   auto auth_callback = [](void* user_data,
627                           Evas_Object*,
628                           void* event_info) {
629     LOGGER(DEBUG) << "Authentication Request";
630     WebViewImpl* self = static_cast<WebViewImpl*>(user_data);
631     Ewk_Auth_Challenge* auth_challenge =
632         static_cast<Ewk_Auth_Challenge*>(event_info);
633
634     if (self == NULL || self->listener_ == NULL) {
635       ewk_auth_challenge_credential_cancel(auth_challenge);
636       return;
637     }
638     auto result_handler = [auth_challenge](bool submit,
639                                     const std::string& id,
640                                     const std::string& password) {
641       LOGGER(DEBUG) << "Authentication Result : submit = " << submit;
642       if (!submit) {
643         ewk_auth_challenge_credential_cancel(auth_challenge);
644         return;
645       }
646       ewk_auth_challenge_credential_use(auth_challenge,
647                                         id.c_str(),
648                                         password.c_str());
649     };
650     ewk_auth_challenge_suspend(auth_challenge);
651     const char* message =
652         ewk_auth_challenge_realm_get(auth_challenge);
653     std::string url = self->GetUrl();
654     self->listener_->OnAuthenticationRequest(self->view_,
655                                              url,
656                                              message,
657                                              result_handler);
658   };
659   // "authentication,challenge"
660   evas_object_smart_callback_add(ewk_view_,
661                                  "authentication,challenge",
662                                  auth_callback,
663                                  this);
664   smart_callbacks_["authentication,challenge"] = auth_callback;
665 }
666
667 void WebViewImpl::InitCertificateAllowCallback() {
668   auto certi_callback = [](void* user_data,
669                            Evas_Object*,
670                            void* event_info) {
671     WebViewImpl* self = static_cast<WebViewImpl*>(user_data);
672     Ewk_Certificate_Policy_Decision* policy =
673       static_cast<Ewk_Certificate_Policy_Decision*>(event_info);
674
675     if (self == NULL || self->listener_ == NULL) {
676       ewk_certificate_policy_decision_allowed_set(policy, EINA_FALSE);
677       return;
678     }
679
680     ewk_certificate_policy_decision_suspend(policy);
681     auto result_handler = [policy](bool allow) {
682       ewk_certificate_policy_decision_allowed_set(policy, allow);
683     };
684
685     auto ptr = ewk_certificate_policy_decision_url_get(policy);
686     std::string url(ptr ? ptr : "");
687     ptr = ewk_certificate_policy_decision_certificate_pem_get(policy);
688     std::string pem(ptr ? ptr : "");
689     self->listener_->OnCertificateAllowRequest(self->view_,
690                                                url,
691                                                pem,
692                                                result_handler);
693   };
694   evas_object_smart_callback_add(ewk_view_,
695                                  "request,certificate,confirm",
696                                  certi_callback,
697                                  this);
698   smart_callbacks_["request,certificate,confirm"] = certi_callback;
699 }
700
701
702 std::string WebViewImpl::GetUrl() {
703   return std::string(ewk_view_url_get(ewk_view_));
704 }
705
706 Evas_Object* WebViewImpl::evas_object() const {
707   return ewk_view_;
708 }
709
710 void WebViewImpl::OnRotation(int degree) {
711   ewk_view_orientation_send(ewk_view_, ToWebRotation(degree));
712 }
713
714 void WebViewImpl::OnKeyEvent(Ea_Callback_Type key_type) {
715   std::string keyname;
716   if (key_type == EA_CALLBACK_BACK) {
717     if (fullscreen_) {
718       ewk_view_fullscreen_exit(ewk_view_);
719       return;
720     }
721     if (EINA_TRUE == ewk_view_text_selection_clear(ewk_view_)) {
722       return;
723     }
724     keyname = kKeyNameBack;
725   } else if (key_type == EA_CALLBACK_MORE) {
726     keyname = kKeyNameMenu;
727   } else {
728     return;
729   }
730
731   if (listener_)
732     listener_->OnHardwareKey(view_, keyname);
733 }
734
735 void WebViewImpl::SetEventListener(WebView::EventListener* listener) {
736   listener_ = listener;
737 }
738
739 void WebViewImpl::SetAppInfo(const std::string& app_name,
740                              const std::string& version) {
741   std::string ua = app_name + "/" + version;
742   ewk_view_application_name_for_user_agent_set(ewk_view_, ua.c_str());
743 }
744 bool WebViewImpl::SetUserAgent(const std::string& user_agent) {
745   return ewk_view_user_agent_set(ewk_view_, user_agent.c_str());
746 }
747
748 }  // namespace wrt