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