[M120 Migration][VD] Support EWK Scroll API for TV WebBrowser
[platform/framework/web/chromium-efl.git] / tizen_src / ewk / efl_integration / eweb_view.cc
index 2124d99..ce6088c 100644 (file)
@@ -9,7 +9,6 @@
 #include <Elementary.h>
 
 #include "base/command_line.h"
-#include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/functional/bind.h"
 #include "base/json/json_string_value_serializer.h"
 #endif
 
 #if BUILDFLAG(IS_TIZEN_TV)
+#include "browser/mixed_content_observer.h"
 #include "common/application_type.h"
 #include "devtools_port_manager.h"
+#include "private/ewk_file_chooser_request_private.h"
 #include "public/ewk_media_downloadable_font_info.h"
-#include "browser/mixed_content_observer.h"
+#include "public/ewk_media_parental_rating_info.h"
+#include "public/ewk_media_playback_info_product.h"
+#include "public/ewk_media_subtitle_info_product.h"
+#include "public/ewk_user_media_internal.h"
+#include "third_party/blink/public/platform/web_media_player.h"
 #endif
 
 #if defined(TIZEN_PEPPER_EXTENSIONS)
@@ -165,6 +170,21 @@ void GetEinaRectFromGfxRect(const gfx::Rect& gfx_rect,
 #if BUILDFLAG(IS_TIZEN)
 static Eina_Bool RotateWindowCb(void* data, int type, void* event) {
   auto wv = static_cast<EWebView*>(data);
+#if defined(TIZEN_TBM_SUPPORT)
+  if (wv->rwhva() && wv->rwhva()->GetCompositor() &&
+      wv->rwhva()->GetCompositor()->use_tbm_surface_for_offscreen_rendering()) {
+    Ecore_Wl2_Event_Window_Rotation* rotateEvent =
+        static_cast<Ecore_Wl2_Event_Window_Rotation*>(event);
+    if (rotateEvent != nullptr) {
+      LOG(INFO) << "For NUI app, new ori " << rotateEvent->angle;
+      wv->SetOrientation(rotateEvent->angle);
+    }
+    return ECORE_CALLBACK_PASS_ON;
+  }
+#endif
+  LOG(INFO) << "New ori "
+            << ecore_evas_rotation_get(
+                   ecore_evas_ecore_evas_get(wv->GetEvas()));
   wv->SetOrientation(
       ecore_evas_rotation_get(ecore_evas_ecore_evas_get(wv->GetEvas())));
   return ECORE_CALLBACK_PASS_ON;
@@ -299,24 +319,17 @@ content::WebViewDelegate::WebContentsCreateCallback
     EWebView::create_new_window_web_contents_cb_ =
         base::BindRepeating(&NullCreateWebContents);
 
-EWebView* EWebView::FromEvasObject(Evas_Object* eo) {
-  return WebViewDelegateEwk::GetInstance().GetWebViewFromEvasObject(eo);
-}
-
-void EWebView::OnViewFocusIn(void* data, Evas*, Evas_Object*, void*) {
-  auto view = static_cast<EWebView*>(data);
-  view->SetFocus(EINA_TRUE);
-}
-
-void EWebView::OnViewFocusOut(void* data, Evas*, Evas_Object*, void*) {
-  auto view = static_cast<EWebView*>(data);
-  view->SetFocus(EINA_FALSE);
+EWebView* EWebView::FromEwkView(Evas_Object* ewk_view) {
+  return WebViewDelegateEwk::GetInstance().GetEWebViewFromEwkView(ewk_view);
 }
 
 void EWebView::VisibleContentChangedCallback(void* user_data,
                                              Evas_Object* /*object*/,
                                              void* event_info) {
   auto view = static_cast<EWebView*>(user_data);
+  if (!view->GetSelectionController()) {
+    return;
+  }
   auto rect = static_cast<Eina_Rectangle*>(event_info);
   view->GetSelectionController()->SetCustomVisibleViewRect(
       gfx::Rect(rect->x, rect->y, rect->w, rect->h));
@@ -369,10 +382,6 @@ EWebView::EWebView(Ewk_Context* context, Evas_Object* ewk_view)
                                    OnCustomScrollBeginCallback, this);
     evas_object_smart_callback_add(ewk_view_, kCustomScrollEndSignalName,
                                    OnCustomScrollEndCallback, this);
-    evas_object_event_callback_add(ewk_view_, EVAS_CALLBACK_FOCUS_IN,
-                                   OnViewFocusIn, this);
-    evas_object_event_callback_add(ewk_view_, EVAS_CALLBACK_FOCUS_OUT,
-                                   OnViewFocusOut, this);
 #if BUILDFLAG(IS_TIZEN)
     window_rotate_handler_ = ecore_event_handler_add(
       ECORE_WL2_EVENT_WINDOW_ROTATE, RotateWindowCb, this);
@@ -444,6 +453,7 @@ void EWebView::Initialize() {
 
 EWebView::~EWebView() {
   LOG(INFO) << "EWebView: " << this;
+  weak_factory_.InvalidateWeakPtrs();
   auto cbce = static_cast<ContentBrowserClientEfl*>(
       content::GetContentClientExport()->browser());
   cbce->RemoveAcceptLangsChangedCallback(accept_langs_changed_callback_);
@@ -490,6 +500,9 @@ EWebView::~EWebView() {
   select_picker_.reset();
   context_menu_.reset();
   mhtml_callback_map_.Clear();
+#if BUILDFLAG(IS_TIZEN_TV)
+  is_video_playing_callback_map_.Clear();
+#endif
 
   compositor_observer_.reset();
 
@@ -508,10 +521,6 @@ EWebView::~EWebView() {
   gin_native_bridge_dispatcher_host_.reset();
 
   if (ewk_view_) {
-    evas_object_event_callback_del(ewk_view_, EVAS_CALLBACK_FOCUS_IN,
-                                   OnViewFocusIn);
-    evas_object_event_callback_del(ewk_view_, EVAS_CALLBACK_FOCUS_OUT,
-                                   OnViewFocusOut);
     evas_object_smart_callback_del(ewk_view_, kVisibleContentChangedSignalName,
                                    VisibleContentChangedCallback);
     evas_object_smart_callback_del(ewk_view_, kCustomScrollBeginSignalName,
@@ -553,19 +562,23 @@ void EWebView::ResetContextMenuController() {
 
 #if BUILDFLAG(IS_TIZEN_TV)
 void EWebView::RunPendingSetFocus(Eina_Bool focus) {
-  if (!web_contents_ || !rwhva() || (HasFocus() == focus))
+  SetFocusInternal(focus);
+}
+
+void EWebView::SetFocusInternal(Eina_Bool focus) {
+  if (!rwhva() || !rwhva()->offscreen_helper() || (HasFocus() == focus))
     return;
   rwhva()->offscreen_helper()->Focus(focus);
 }
 #endif
 
 void EWebView::SetFocus(Eina_Bool focus) {
-  if (!web_contents_ || !rwhva() || (HasFocus() == focus))
+  if (!web_contents_)
     return;
 
 #if BUILDFLAG(IS_TIZEN_TV)
   if (web_contents_->GetPrimaryMainFrame()->IsRenderFrameLive()) {
-    rwhva()->offscreen_helper()->Focus(focus);
+    SetFocusInternal(focus);
 
     if (pending_setfocus_closure_)
       pending_setfocus_closure_.Reset();
@@ -580,7 +593,7 @@ void EWebView::SetFocus(Eina_Bool focus) {
 }
 
 Eina_Bool EWebView::HasFocus() const {
-  if (!rwhva())
+  if (!rwhva() || !rwhva()->offscreen_helper())
     return EINA_FALSE;
 
   return rwhva()->offscreen_helper()->HasFocus() ? EINA_TRUE : EINA_FALSE;
@@ -623,6 +636,9 @@ bool EWebView::SetPageVisibility(
 
 bool EWebView::CreateNewWindow(
     content::WebViewDelegate::WebContentsCreateCallback cb) {
+#if BUILDFLAG(IS_TIZEN_TV)
+  LOG(INFO) << __FUNCTION__;
+#endif
   create_new_window_web_contents_cb_ = cb;
   Evas_Object* new_object = NULL;
   SmartCallback<EWebViewCallbacks::CreateNewWindow>().call(&new_object);
@@ -768,6 +784,20 @@ void EWebView::SetFloatVideoWindowState(bool enabled) {
 
     rwhi->SetFloatVideoWindowState(enabled);
 }
+
+void EWebView::SuspendNetworkLoading() {
+  RenderWidgetHostImpl* rwhi = static_cast<RenderWidgetHostImpl*>(
+      web_contents_->GetRenderViewHost()->GetWidget());
+
+  rwhi->SuspendNetworkLoading();
+}
+
+void EWebView::ResumeNetworkLoading() {
+  RenderWidgetHostImpl* rwhi = static_cast<RenderWidgetHostImpl*>(
+      web_contents_->GetRenderViewHost()->GetWidget());
+
+  rwhi->ResumeNetworkLoading();
+}
 #endif // IS_TIZEN_TV
 
 double EWebView::GetTextZoomFactor() const {
@@ -826,13 +856,22 @@ void EWebView::EnterDragState() {
 #endif
 
 void EWebView::SetOrientation(int orientation) {
+  LOG(INFO) << "New ori " << orientation << " GetOrientation "
+            << GetOrientation();
   if (GetOrientation() == orientation)
     return;
+  SetRotationChanged(true);
 
   if (orientation == 0 || orientation == 90 || orientation == 180 ||
       orientation == 270) {
 #if !defined(USE_AURA)
     GetWebContentsViewEfl()->SetOrientation(orientation);
+#else
+#if BUILDFLAG(IS_TIZEN)
+    TRACE_EVENT2("viz", "EWebView::SetOrientation", "orientation", orientation,
+                 "this", (void*)this);
+    wcva()->SetOrientation(orientation);
+#endif
 #endif
     int width = 0;
     int height = 0;
@@ -853,8 +892,12 @@ int EWebView::GetOrientation() {
 #if !defined(USE_AURA)
   return GetWebContentsViewEfl()->GetOrientation();
 #else
+#if BUILDFLAG(IS_TIZEN)
+  return wcva()->GetOrientation();
+#else
   return 0;
 #endif
+#endif
 }
 
 void EWebView::Show() {
@@ -1008,6 +1051,31 @@ void EWebView::SetMouseEventsEnabled(bool enabled) {
   rwhva()->offscreen_helper()->SetTouchEventsEnabled(!enabled);
 }
 
+bool EWebView::SetKeyEventsEnabled(bool enabled) {
+  if (!rwhva() || !rwhva()->aura_efl_helper()) {
+    LOG(WARNING) << "RWHV is not created yet!";
+    return false;
+  }
+
+  if (key_events_enabled_ == enabled)
+    return true;
+
+  key_events_enabled_ = enabled;
+  rwhva()->aura_efl_helper()->SetKeyEventsEnabled(enabled);
+  return true;
+}
+
+void EWebView::SendKeyEvent(Evas_Object* ewk_view,
+                            void* key_event,
+                            bool is_press) {
+  if (!rwhva() || !rwhva()->aura_efl_helper()) {
+    LOG(WARNING) << "RWHV is not created yet!";
+    return;
+  }
+
+  rwhva()->aura_efl_helper()->SendKeyEvent(ewk_view, key_event, is_press);
+}
+
 namespace {
 
 class JavaScriptCallbackDetails {
@@ -1267,13 +1335,11 @@ void EWebView::SetViewLoadErrorPageCallback(
 }
 
 // Remove below code while ewk_error_cancellation_get has been implemented.
-const char* EWebView::InvokeViewLoadErrorPageCallback(
-    const GURL& url,
-    int error_code,
-    const std::string& error_description) {
-  std::unique_ptr<_Ewk_Error> err(
-      new _Ewk_Error(error_code, url.possibly_invalid_spec().c_str(),
-                     error_description.c_str()));
+const char* EWebView::InvokeViewLoadErrorPageCallback(const GURL& url,
+                                                      int error_code,
+                                                      bool is_cancellation) {
+  std::unique_ptr<_Ewk_Error> err(new _Ewk_Error(
+      error_code, is_cancellation, url.possibly_invalid_spec().c_str()));
   _Ewk_Error_Page error_page;
 
   LOG(INFO) << "EWebView::InvokeLoadErrorPageCallback url: "
@@ -1346,12 +1412,13 @@ void EWebView::HandleLongPressGesture(
   convertedParams.x += x;
   convertedParams.y += y;
 
+  bool show_context_menu_now = true;
   if (GetSelectionController() && GetSelectionController()->GetLongPressed()) {
-    bool show_context_menu_now =
-        !GetSelectionController()->HandleLongPressEvent(convertedPoint,
-                                                        convertedParams);
-    if (show_context_menu_now)
-      ShowContextMenuInternal(convertedParams);
+    show_context_menu_now = !GetSelectionController()->HandleLongPressEvent(
+        convertedPoint, convertedParams);
+  }
+  if (show_context_menu_now) {
+    ShowContextMenuInternal(convertedParams);
   }
 }
 
@@ -1437,7 +1504,7 @@ void EWebView::UpdateContextMenuWithParams(
 }
 
 Eina_Bool EWebView::DelayedPopulateAndShowContextMenu(void* data) {
-  if (IsMobileProfile) {
+  if (IsMobileProfile()) {
     EWebView* view = static_cast<EWebView*>(data);
     if (view) {
       if (view->context_menu_ &&
@@ -1642,6 +1709,10 @@ SelectionControllerEfl* EWebView::GetSelectionController() const {
 }
 
 void EWebView::SelectFocusedLink() {
+  if (!rwhva()) {
+    return;
+  }
+
   rwhva()->host()->SelectFocusedLink();
 }
 
@@ -2188,9 +2259,9 @@ bool EWebView::GetMHTMLData(Ewk_View_MHTML_Data_Get_Callback callback,
   if (!render_view_host)
     return false;
 
+#if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
   MHTMLCallbackDetails* callback_details = new MHTMLCallbackDetails;
   callback_details->Set(callback, user_data);
-#if !defined(EWK_BRINGUP)  // FIXME: m94 bringup
   int mhtml_callback_id = mhtml_callback_map_.Add(callback_details);
   return render_view_host->Send(new EwkViewMsg_GetMHTMLData(
       render_view_host->GetRoutingID(), mhtml_callback_id));
@@ -2504,28 +2575,20 @@ bool EWebView::IsDragging() const {
   return wcva()->wcva_helper()->IsDragging();
 }
 
-void EWebView::ShowFileChooser(content::RenderFrameHost* render_frame_host,
-                               const blink::mojom::FileChooserParams& params) {
+void EWebView::ShowFileChooser(
+    scoped_refptr<content::FileSelectListener> listener,
+    const blink::mojom::FileChooserParams& params) {
+#if BUILDFLAG(IS_TIZEN_TV)
+  LOG(INFO) << "File chooser request callback.";
+  file_chooser_request_.reset(new _Ewk_File_Chooser_Request(
+      std::move(listener), params.accept_types, params.mode));
+  SmartCallback<EWebViewCallbacks::FileChooserRequest>().call(
+      file_chooser_request_.get());
+#else
   if (!IsMobileProfile() && !IsWearableProfile())
     return;
-
-#if !defined(EWK_BRINGUP)  // FIXME: m71 bringup
-  if (params.capture) {
-    const std::string capture_types[] = {"video/*", "audio/*", "image/*"};
-    unsigned int capture_types_num =
-        sizeof(capture_types) / sizeof(*capture_types);
-    for (unsigned int i = 0; i < capture_types_num; ++i) {
-      for (unsigned int j = 0; j < params.accept_types.size(); ++j) {
-        if (UTF16ToUTF8(params.accept_types[j]) == capture_types[i]) {
-          filechooser_mode_ = params.mode;
-          LaunchCamera(params.accept_types[j]);
-          return;
-        }
-      }
-    }
-  }
   file_chooser_.reset(
-      new content::FileChooserControllerEfl(render_frame_host, &params));
+      new content::FileChooserControllerEfl(std::move(listener), params));
   file_chooser_->Open();
 #endif
 }
@@ -2718,6 +2781,17 @@ void EWebView::InvokeEdgeScrollByCallback(const gfx::Point& offset,
 }
 #endif
 
+#if BUILDFLAG(IS_TIZEN_TV)
+void EWebView::InvokeScrollbarThumbFocusChangedCallback(
+    Ewk_Scrollbar_Orientation orientation,
+    bool focused) {
+  Ewk_Scrollbar_Data data;
+  data.orientation = orientation;
+  data.focused = focused;
+  SmartCallback<EWebViewCallbacks::DidChagneScrollbarsThumbFocus>().call(&data);
+}
+#endif
+
 void EWebView::HandleRendererProcessCrash() {
   content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
       base::BindOnce(&EWebView::InvokeWebProcessCrashedCallback,
@@ -2872,71 +2946,6 @@ void EWebView::InitializeWindowTreeHost() {
     host_view->SetSize(bounds.size());
 }
 
-#if BUILDFLAG(IS_TIZEN) && !defined(EWK_BRINGUP)
-void EWebView::cameraResultCb(service_h request,
-                              service_h reply,
-                              service_result_e result,
-                              void* data) {
-  if (!IsMobileProfile() && !IsWearableProfile())
-    return;
-
-  EWebView* webview = static_cast<EWebView*>(data);
-  RenderViewHost* render_view_host =
-      webview->web_contents_->GetRenderViewHost();
-  if (result == SERVICE_RESULT_SUCCEEDED) {
-    int ret = -1;
-    char** filesarray;
-    int number;
-    ret = service_get_extra_data_array(reply, SERVICE_DATA_SELECTED,
-                                       &filesarray, &number);
-    if (filesarray) {
-      for (int i = 0; i < number; i++) {
-        std::vector<ui::SelectedFileInfo> files;
-        if (!render_view_host) {
-          return;
-        }
-        if (filesarray[i]) {
-          GURL url(filesarray[i]);
-          if (!url.is_valid()) {
-            base::FilePath path(url.SchemeIsFile() ? url.path()
-                                                   : filesarray[i]);
-            files.push_back(ui::SelectedFileInfo(path, base::FilePath()));
-          }
-        }
-        render_view_host->FilesSelectedInChooser(files,
-                                                 webview->filechooser_mode_);
-      }
-    }
-  } else {
-    std::vector<ui::SelectedFileInfo> files;
-    if (render_view_host) {
-      render_view_host->FilesSelectedInChooser(files,
-                                               webview->filechooser_mode_);
-    }
-  }
-}
-
-bool EWebView::LaunchCamera(std::u16string mimetype) {
-  service_h svcHandle = 0;
-  if (service_create(&svcHandle) < 0 || !svcHandle) {
-    LOG(ERROR) << __FUNCTION__ << " Service Creation Failed ";
-    return false;
-  }
-  service_set_operation(svcHandle, SERVICE_OPERATION_CREATE_CONTENT);
-  service_set_mime(svcHandle, UTF16ToUTF8(mimetype).c_str());
-  service_add_extra_data(svcHandle, "CALLER", "Browser");
-
-  int ret = service_send_launch_request(svcHandle, cameraResultCb, this);
-  if (ret != SERVICE_ERROR_NONE) {
-    LOG(ERROR) << __FUNCTION__ << " Service Launch Failed ";
-    service_destroy(svcHandle);
-    return false;
-  }
-  service_destroy(svcHandle);
-  return true;
-}
-#endif
-
 void EWebView::UrlRequestSet(
     const char* url,
     content::NavigationController::LoadURLType loadtype,
@@ -3119,6 +3128,11 @@ void EWebView::SendDelayedMessages(RenderViewHost* render_view_host) {
     return;
   }
 
+#if BUILDFLAG(IS_TIZEN_TV)
+  if (pending_setfocus_closure_)
+    std::move(pending_setfocus_closure_).Run();
+#endif
+
   for (auto iter = delayed_messages_.begin(); iter != delayed_messages_.end();
        ++iter) {
     IPC::Message* message = *iter;
@@ -3219,6 +3233,39 @@ void EWebView::ClearLabels() {
   if (rwhva())
     rwhva()->offscreen_helper()->ClearLabels();
 }
+
+void EWebView::SetTranslatedURL(const char* url) {
+  if (!rwhva() || !rwhva()->aura_efl_helper())
+    return;
+  rwhva()->aura_efl_helper()->SetTranslatedURL(std::string(url));
+  LOG(INFO) << "translate_url:" << url;
+}
+
+bool EWebView::IsVideoPlaying(Ewk_Is_Video_Playing_Callback callback,
+                              void* user_data) {
+  IsVideoPlayingCallback* cb = new IsVideoPlayingCallback(callback, user_data);
+  int callback_id = is_video_playing_callback_map_.Add(cb);
+
+  if (!rwhva() || !rwhva()->aura_efl_helper()) {
+    LOG(ERROR) << "rwhva() or rwhva()->aura_efl_helper() is false";
+    return false;
+  }
+  rwhva()->aura_efl_helper()->RequestVideoPlaying(callback_id);
+  return true;
+}
+
+void EWebView::InvokeIsVideoPlayingCallback(bool is_playing, int callback_id) {
+  IsVideoPlayingCallback* callback =
+      is_video_playing_callback_map_.Lookup(callback_id);
+  if (!callback) {
+    LOG(INFO) << "callback is null";
+    return;
+  }
+
+  LOG(INFO) << __func__ << " ; is_playing : " << is_playing;
+  callback->Run(ewk_view(), is_playing);
+  is_video_playing_callback_map_.Remove(callback_id);
+}
 #endif
 
 void EWebView::RequestManifest(Ewk_View_Request_Manifest_Callback callback,
@@ -3389,6 +3436,116 @@ void EWebView::AddDynamicCertificatePath(const std::string& host,
                                          const std::string& cert_path) {
   web_contents_->AddDynamicCertificatePath(host, cert_path);
 }
+
+void EWebView::NotifySubtitleState(int state, double time_stamp) {
+  LOG(INFO) << "subtitle state: " << state
+            << ",(0-Play : 1-Pause : 2-SeekStart : 3-SeekComplete : 4-Stop "
+               ":5-Resume)";
+  switch (state) {
+    case blink::WebMediaPlayer::kSubtitlePause:
+      SmartCallback<EWebViewCallbacks::SubtitlePause>().call();
+      break;
+    case blink::WebMediaPlayer::kSubtitleStop:
+      SmartCallback<EWebViewCallbacks::SubtitleStop>().call();
+      break;
+    case blink::WebMediaPlayer::kSubtitleResume:
+      SmartCallback<EWebViewCallbacks::SubtitleResume>().call();
+      break;
+    case blink::WebMediaPlayer::kSubtitleSeekStart: {
+      double ts = time_stamp;
+      SmartCallback<EWebViewCallbacks::SubtitleSeekStart>().call(&ts);
+    } break;
+    case blink::WebMediaPlayer::kSubtitleSeekComplete:
+      SmartCallback<EWebViewCallbacks::SubtitleSeekComplete>().call();
+      break;
+    default:
+      NOTREACHED();
+      break;
+  }
+}
+
+void EWebView::NotifySubtitlePlay(int active_track_id,
+                                  const char* url,
+                                  const char* lang) {
+  LOG(INFO) << "id:" << active_track_id << ",url:" << url << ",lang:" << lang;
+  Ewk_Media_Subtitle_Info* subtitle_info =
+      ewkMediaSubtitleInfoCreate(active_track_id, url, lang, 0);
+  SmartCallback<EWebViewCallbacks::SubtitlePlay>().call(
+      static_cast<void*>(subtitle_info));
+  ewkMediaSubtitleInfoDelete(subtitle_info);
+}
+
+void EWebView::NotifySubtitleData(int track_id,
+                                  double time_stamp,
+                                  const std::string& data,
+                                  unsigned int size) {
+  const void* buffer = static_cast<const void*>(data.c_str());
+  Ewk_Media_Subtitle_Data* subtitle_data =
+      ewkMediaSubtitleDataCreate(track_id, time_stamp, buffer, size);
+  SmartCallback<EWebViewCallbacks::SubtitleNotifyData>().call(
+      static_cast<void*>(subtitle_data));
+  ewkMediaSubtitleDataDelete(subtitle_data);
+}
+
+void EWebView::UpdateCurrentTime(double current_time) {
+  current_time_ = current_time;
+}
+
+void EWebView::UpdateEventData(void* data) {
+  LOG(INFO) << "EWebView::UpdateEventData data:" << (char*)data;
+  SmartCallback<EWebViewCallbacks::EVENTData>().call(data);
+}
+
+void EWebView::NotifyParentalRatingInfo(const char* info, const char* url) {
+  LOG(INFO) << "info:" << info << ",url:" << url;
+  Ewk_Media_Parental_Rating_Info* data =
+      ewkMediaParentalRatingInfoCreate(info, url);
+  SmartCallback<EWebViewCallbacks::ParentalRatingInfo>().call(
+      static_cast<void*>(data));
+  ewkMediaParentalRatingInfoDelete(data);
+}
+
+void EWebView::SetParentalRatingResult(const char* url, bool is_pass) {
+  LOG(INFO) << "SetParentalRatingResult,url:" << url
+            << ",pass:" << std::boolalpha << is_pass;
+
+  if (!rwhva() || !rwhva()->aura_efl_helper()){
+    LOG(ERROR) << "rwhva() or rwhva()->aura_efl_helper() is false";
+    return;
+  }
+  rwhva()->aura_efl_helper()->SetParentalRatingResult(
+      static_cast<std::string>(url), is_pass);
+}
+void EWebView::NotifyFirstTimeStamp(unsigned long long timestamp,
+                                    int time_base_num,
+                                    int time_base_den) {
+  Ewk_First_Timestamp_Info* info =
+      ewkFirstTimeStampInfoCreate(timestamp, time_base_num, time_base_den);
+  SmartCallback<EWebViewCallbacks::FirstTimestamp>().call(
+      static_cast<void*>(info));
+  ewkFirstTimeStampInfoDelete(info);
+}
+
+void EWebView::NotifyPESData(const std::string& buf,
+                             unsigned int len,
+                             int media_position) {
+  const void* data = static_cast<const void*>(buf.c_str());
+  Ewk_PES_Info* info = ewkPESInfoCreate(data, len, media_position);
+  SmartCallback<EWebViewCallbacks::PESData>().call(static_cast<void*>(info));
+  ewkPESInfoDelete(info);
+}
+
+void EWebView::SetPreferSubtitleLang(const char* lang_list) {
+  LOG(INFO) << "SetPreferSubtitleLang: " << lang_list;
+  const std::string lang(lang_list ? lang_list : "");
+
+  if (!rwhva()) {
+    LOG(ERROR) << "rwhva() is null";
+    return;
+  }
+
+  rwhva()->aura_efl_helper()->SetPreferSubtitleLang(lang);
+}
 #endif
 
 bool EWebView::SetVisibility(bool enable) {
@@ -3467,4 +3624,157 @@ bool EWebView::SetMixedContents(bool allow) {
       MixedContentObserver::FromWebContents(web_contents_.get());
   return mixed_content_observer->MixedContentReply(allow);
 }
+
+void EWebView::NotifyDownloadableFontInfo(const char* scheme_id_uri,
+                                          const char* value,
+                                          const char* data,
+                                          int type) {
+  LOG(INFO) << "scheme_id_uri:" << scheme_id_uri << ",value:" << value
+            << ",data:" << data << ",type:" << type;
+  Ewk_Media_Downloadable_Font_Info* info =
+      ewkMediaDownloadableFontInfoCreate(scheme_id_uri, value, data, type);
+  SmartCallback<EWebViewCallbacks::DownloadableFontInfo>().call(
+      static_cast<void*>(info));
+  ewkMediaDownloadableFontInfoDelete(info);
+}
+
+std::vector<std::string> EWebView::NotifyPlaybackState(int state,
+                                                       int player_id,
+                                                       const char* url,
+                                                       const char* mime_type) {
+  std::vector<std::string> data;
+  Ewk_Media_Playback_Info* playback_info =
+      ewkMediaPlaybackInfoCreate(player_id, url, mime_type);
+
+  LOG(INFO)
+      << "player_id:" << player_id << ",state: " << state
+      << "(0-load : 1-videoready : 2-ready : 3-start : 4-finish : 5-stop)";
+  switch (state) {
+    case kPlaybackLoad:
+      SmartCallback<EWebViewCallbacks::PlaybackLoad>().call(
+          static_cast<void*>(playback_info));
+      break;
+    case kPlaybackReady:
+      SmartCallback<EWebViewCallbacks::PlaybackReady>().call(
+          static_cast<void*>(playback_info));
+      break;
+    case kPlaybackStart:
+      SmartCallback<EWebViewCallbacks::PlaybackStart>().call(
+          static_cast<void*>(playback_info));
+      break;
+    case kPlaybackFinish:
+      SmartCallback<EWebViewCallbacks::PlaybackFinish>().call(
+          static_cast<void*>(playback_info));
+      break;
+    case kPlaybackStop:
+      SmartCallback<EWebViewCallbacks::PlaybackStop>().call(
+          static_cast<void*>(playback_info));
+      break;
+    default:
+      NOTREACHED();
+      data.push_back("");
+      ewkMediaPlaybackInfoDelete(playback_info);
+      return data;
+  }
+
+  bool media_resource_acquired =
+      ewk_media_playback_info_media_resource_acquired_get(playback_info)
+          ? true
+          : false;
+  data.push_back(media_resource_acquired ? "mediaResourceAcquired" : "");
+  const char* translated_url =
+      ewk_media_playback_info_translated_url_get(playback_info);
+  data.push_back(translated_url ? std::string(translated_url) : "");
+  const char* drm_info = ewk_media_playback_info_drm_info_get(playback_info);
+  data.push_back(drm_info ? std::string(drm_info) : "");
+
+  LOG(INFO) << "evasObject: " << ewk_view_
+            << ", media_resource_acquired :" << media_resource_acquired
+            << ", translated_url:" << translated_url
+            << ", drm_info:" << drm_info;
+  ewkMediaPlaybackInfoDelete(playback_info);
+  return data;
+}
+
+void EWebView::NotifyMediaStateChanged(uint32_t device_type,
+                                       uint32_t previous,
+                                       uint32_t current) {
+  LOG(INFO) << "NotifyMediaStateChanged type : " << device_type
+            << " ;previous: " << previous << " ; current: " << current;
+  Ewk_User_Media_State_Info* user_media_state_info =
+      new _Ewk_User_Media_State_Info;
+  user_media_state_info->device_type =
+      static_cast<Ewk_User_Media_Device_Type>(device_type);
+  user_media_state_info->previous_state = previous;
+  user_media_state_info->current_state = current;
+  SmartCallback<EWebViewCallbacks::UserMediaState>().call(
+      static_cast<void*>(user_media_state_info));
+
+  delete user_media_state_info;
+}
+
+void EWebView::SetHighBitRate(Eina_Bool high_bitrate) {
+  LOG(INFO) << "high_bitrate: " << std::boolalpha << high_bitrate;
+  is_high_bitrate_ = high_bitrate;
+}
+
+void EWebView::OnDeviceListed(const MediaDeviceEnumeration& devices) {
+  int device_count = 0;
+  EwkMediaDeviceInfo* device_list = nullptr;
+  for (const auto& device : devices)
+    device_count += device.size();
+
+  device_list =
+      (EwkMediaDeviceInfo*)malloc(sizeof(EwkMediaDeviceInfo) * device_count);
+  if (!device_list) {
+    LOG(ERROR) << "malloc EwkMediaDeviceInfo failed";
+    device_cb_.Run(device_list, 0);
+    return;
+  }
+
+  int idx = 0;
+  for (int i = 0; i < NUM_MEDIA_DEVICE_TYPES; i++) {
+    blink::WebMediaDeviceInfoArray array = devices[i];
+    for (const auto& device : array) {
+      LOG(INFO) << "OnDeviceListed type:" << i
+                << ",device_id:" << device.device_id
+                << ",lable:" << device.label;
+
+      // convert device info to ewk structure
+      EwkMediaDeviceInfo* data = &device_list[idx++];
+      data->device_id = eina_stringshare_add(device.device_id.c_str());
+      data->label = eina_stringshare_add(device.label.c_str());
+      data->type = static_cast<EwkMediaDeviceType>(i);
+      data->connected = true;
+    }
+  }
+
+  device_cb_.Run(device_list, device_count);
+
+  // free data
+  for (int i = 0; i < device_count; i++) {
+    EwkMediaDeviceInfo* device = &device_list[i];
+    if (device->device_id)
+      eina_stringshare_del(device->device_id);
+    if (device->label)
+      eina_stringshare_del(device->label);
+  }
+  if (device_list) {
+    free(device_list);
+    device_list = NULL;
+  }
+}
+
+void EWebView::GetMediaDeviceList(Ewk_Media_Device_List_Get_Callback callback,
+                                  void* userData) {
+  if (!web_contents_delegate_) {
+    LOG(ERROR) << "no web_contents_delegate_";
+    return;
+  }
+
+  device_cb_.Set(callback, userData);
+
+  web_contents_delegate_->GetMediaDeviceList(
+      base::BindOnce(&EWebView::OnDeviceListed, weak_factory_.GetWeakPtr()));
+}
 #endif