[M120 Migration] Add new api for webbrowser to get media device list 68/306968/3
authorwuxiaoliang <xliang.wu@samsung.com>
Fri, 1 Mar 2024 05:37:46 +0000 (13:37 +0800)
committerwuxiaoliang <xliang.wu@samsung.com>
Tue, 5 Mar 2024 01:39:52 +0000 (09:39 +0800)
void ewk_view_media_device_list_get(Evas_Object* o, Ewk_Media_Device_List_Get_Callback callback, void* user_data);
add this api for browser youtube to get audio input/audio output/video input device

Migrated from:
https://review.tizen.org/gerrit/#/c/platform/framework/web/chromium-efl/+/295121/

Change-Id: If3a30453dd05377c206d53cd6bba5ca383ad35a9
Signed-off-by: wuxiaoliang <xliang.wu@samsung.com>
12 files changed:
content/browser/renderer_host/media/media_capture_devices_impl.cc
content/browser/renderer_host/media/media_capture_devices_impl.h
content/browser/renderer_host/media/media_devices_manager.cc
content/browser/renderer_host/media/media_devices_manager.h
content/browser/renderer_host/media/media_stream_manager.cc
content/browser/renderer_host/media/media_stream_manager.h
content/public/browser/media_capture_devices.h
tizen_src/ewk/efl_integration/eweb_view.cc
tizen_src/ewk/efl_integration/eweb_view.h
tizen_src/ewk/efl_integration/public/ewk_view.cc
tizen_src/ewk/efl_integration/web_contents_delegate_efl.cc
tizen_src/ewk/efl_integration/web_contents_delegate_efl.h

index 6676c4d..f42078f 100644 (file)
@@ -126,4 +126,41 @@ void MediaCaptureDevicesImpl::UpdateVideoDevicesOnUIThread(
   video_devices_ = devices;
 }
 
+#if BUILDFLAG(IS_TIZEN_TV)
+void MediaCaptureDevicesImpl::UpdateDeviceInfoOnUIThread(
+    const MediaDeviceEnumeration& device_infos) {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+  if (!device_cb_.is_null())
+    std::move(device_cb_).Run(device_infos);
+}
+
+void MediaCaptureDevicesImpl::OnDeviceInfo(
+    const MediaDeviceEnumeration& device_infos) {
+  if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
+    UpdateDeviceInfoOnUIThread(device_infos);
+  } else {
+    GetUIThreadTaskRunner({})->PostTask(
+        FROM_HERE,
+        base::BindOnce(&MediaCaptureDevicesImpl::UpdateDeviceInfoOnUIThread,
+                       base::Unretained(this), device_infos));
+  }
+}
+
+void MediaCaptureDevicesImpl::GetMediaDeviceList(EnumerationCallback cb) {
+  device_cb_ = std::move(cb);
+  MediaStreamManager* media_stream_manager =
+      BrowserMainLoop::GetInstance()->media_stream_manager();
+  if (media_stream_manager != nullptr) {
+    GetIOThreadTaskRunner({})->PostTask(
+        FROM_HERE, base::BindOnce(&MediaStreamManager::GetMediaDeviceList,
+                                  base::Unretained(media_stream_manager)));
+  } else {
+    LOG(ERROR) << "media_stream_manager is null.";
+    MediaDeviceEnumeration device_infos;
+    std::move(device_cb_).Run(device_infos);
+  }
+}
+#endif
+
 }  // namespace content
index 7214e2d..3c9db08 100644 (file)
@@ -29,6 +29,12 @@ class MediaCaptureDevicesImpl : public MediaCaptureDevices {
   void OnAudioCaptureDevicesChanged(const blink::MediaStreamDevices& devices);
   void OnVideoCaptureDevicesChanged(const blink::MediaStreamDevices& devices);
 
+#if BUILDFLAG(IS_TIZEN_TV)
+  void GetMediaDeviceList(EnumerationCallback cb) override;
+  void OnDeviceInfo(const MediaDeviceEnumeration& device_info);
+  void UpdateDeviceInfoOnUIThread(const MediaDeviceEnumeration& device_info);
+#endif
+
  private:
   friend struct base::DefaultSingletonTraits<MediaCaptureDevicesImpl>;
   MediaCaptureDevicesImpl();
@@ -46,6 +52,10 @@ class MediaCaptureDevicesImpl : public MediaCaptureDevices {
 
   // A list of cached video capture devices.
   blink::MediaStreamDevices video_devices_;
+
+#if BUILDFLAG(IS_TIZEN_TV)
+  EnumerationCallback device_cb_;
+#endif
 };
 
 }  // namespace content
index f2a3252..880e009 100644 (file)
 #include "media/device_monitors/device_monitor_mac.h"
 #endif
 
+#if BUILDFLAG(IS_TIZEN_TV)
+#include "tizen_src/ewk/efl_integration/common/application_type.h"
+#endif
+
 namespace content {
 
 namespace {
@@ -471,6 +475,21 @@ void MediaDevicesManager::EnumerateDevices(
               request_audio_input_capabilities, std::move(callback)))));
 }
 
+#if BUILDFLAG(IS_TIZEN_TV)
+void MediaDevicesManager::GetMediaDeviceList(EnumerationCallback cb) {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  enum_cb_ = std::move(cb);
+  got_result_.fill(false);
+  for (auto& device : device_infos_)
+    device.clear();
+
+  for (size_t i = 0;
+       i < static_cast<size_t>(MediaDeviceType::kNumMediaDeviceTypes); ++i) {
+    DoEnumerateDevices(static_cast<MediaDeviceType>(i));
+  }
+}
+#endif
+
 uint32_t MediaDevicesManager::SubscribeDeviceChangeNotifications(
     int render_process_id,
     int render_frame_id,
@@ -1009,6 +1028,23 @@ void MediaDevicesManager::DevicesEnumerated(
   } else {
     DoEnumerateDevices(type);
   }
+
+#if BUILDFLAG(IS_TIZEN_TV)
+  // report device list to webbrowser
+  if (IsWebBrowser() && !enum_cb_.is_null()) {
+    got_result_[static_cast<size_t>(type)] = true;
+
+    for (const auto& device : snapshot) {
+      device_infos_[static_cast<size_t>(type)].emplace_back(
+          device.device_id, device.label, device.group_id);
+    }
+
+    bool finish = std::all_of(got_result_.begin(), got_result_.end(),
+                              [](const bool result) { return result == true; });
+    if (finish)
+      std::move(enum_cb_).Run(device_infos_);
+  }
+#endif
 }
 
 void MediaDevicesManager::UpdateSnapshot(
index 7a8a249..449f506 100644 (file)
@@ -165,6 +165,10 @@ class CONTENT_EXPORT MediaDevicesManager
     get_salt_and_origin_cb_ = std::move(callback);
   }
 
+#if BUILDFLAG(IS_TIZEN_TV)
+  void GetMediaDeviceList(EnumerationCallback cb);
+#endif
+
  private:
   friend class MediaDevicesManagerTest;
   struct EnumerationRequest;
@@ -360,6 +364,12 @@ class CONTENT_EXPORT MediaDevicesManager
   mojo::UniqueReceiverSet<blink::mojom::MediaDevicesDispatcherHost>
       dispatcher_hosts_;
 
+#if BUILDFLAG(IS_TIZEN_TV)
+  EnumerationCallback enum_cb_;
+  MediaDeviceEnumeration device_infos_;
+  BoolDeviceTypes got_result_;
+#endif
+
   base::WeakPtrFactory<MediaDevicesManager> weak_factory_{this};
 };
 
index 78a925a..ec5b3b2 100644 (file)
@@ -2454,7 +2454,19 @@ void MediaStreamManager::NotifyMediaStateChanged(uint32_t type,
 
   web_contents_delegate->NotifyMediaStateChanged(type, previous, current);
 }
+
+void MediaStreamManager::GotDeviceInfo(
+    const MediaDeviceEnumeration& device_info) {
+  MediaCaptureDevicesImpl::GetInstance()->OnDeviceInfo(device_info);
+}
+
+void MediaStreamManager::GetMediaDeviceList() {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  media_devices_manager_->GetMediaDeviceList(base::BindOnce(
+      &MediaStreamManager::GotDeviceInfo, base::Unretained(this)));
+}
 #endif
+
 void MediaStreamManager::SetUpRequest(const std::string& label) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
 
index 4434172..9883428 100644 (file)
@@ -342,12 +342,13 @@ class CONTENT_EXPORT MediaStreamManager
   // capture device is plugged in or unplugged.
   void NotifyDevicesChanged(blink::mojom::MediaDeviceType stream_type,
                             const blink::WebMediaDeviceInfoArray& devices);
-
 #if BUILDFLAG(IS_TIZEN_TV)
   // Notify media(camera/microphone) status change to web browser.
   void NotifyMediaStateChanged(uint32_t type,
                                uint32_t previous,
                                uint32_t current);
+  void GetMediaDeviceList();
+  void GotDeviceInfo(const MediaDeviceEnumeration& device_info);
 #endif
 
   // This method is called when an audio or video device is removed. It makes
index 1581e3a..1260f66 100644 (file)
@@ -9,6 +9,10 @@
 #include "media/base/video_facing.h"
 #include "third_party/blink/public/common/mediastream/media_stream_request.h"
 
+#if BUILDFLAG(IS_TIZEN_TV)
+#include "third_party/blink/public/common/mediastream/media_devices.h"
+#endif
+
 namespace content {
 
 // This is a singleton class, used to get Audio/Video devices, it must be
@@ -26,6 +30,16 @@ class CONTENT_EXPORT  MediaCaptureDevices {
       media::VideoCaptureObserver* observer) = 0;
   virtual void RemoveAllVideoCaptureObservers() = 0;
 
+#if BUILDFLAG(IS_TIZEN_TV)
+  using MediaDeviceEnumeration =
+      std::array<blink::WebMediaDeviceInfoArray,
+                 static_cast<size_t>(
+                     blink::mojom::MediaDeviceType::kNumMediaDeviceTypes)>;
+  using EnumerationCallback =
+      base::OnceCallback<void(const MediaDeviceEnumeration&)>;
+  virtual void GetMediaDeviceList(EnumerationCallback cb) = 0;
+#endif
+
  private:
   // This interface should only be implemented inside content.
   friend class MediaCaptureDevicesImpl;
index 98e9661..c6f8160 100644 (file)
@@ -431,6 +431,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_);
@@ -3424,4 +3425,64 @@ 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
index f870b65..de4f3d8 100644 (file)
 #include "public/ewk_value_product.h"
 #endif
 
+#if BUILDFLAG(IS_TIZEN_TV)
+#include "third_party/blink/public/common/mediastream/media_devices.h"
+#endif
+
 namespace aura {
 namespace client {
 class FocusClient;
@@ -290,6 +294,28 @@ class DidChangeThemeColorCallback {
   void* user_data_;
 };
 
+#if BUILDFLAG(IS_TIZEN_TV)
+class GetMediaDeviceCallback {
+ public:
+  GetMediaDeviceCallback() : func_(nullptr), user_data_(nullptr) {}
+
+  void Set(Ewk_Media_Device_List_Get_Callback func, void* user_data) {
+    func_ = func;
+    user_data_ = user_data;
+  }
+
+  void Run(EwkMediaDeviceInfo* device_list, int size) {
+    if (func_) {
+      (func_)(device_list, size, user_data_);
+    }
+  }
+
+ private:
+  Ewk_Media_Device_List_Get_Callback func_;
+  void* user_data_;
+};
+#endif
+
 class WebViewAsyncRequestHitTestDataCallback;
 class JavaScriptDialogManagerEfl;
 class PermissionPopupManager;
@@ -750,6 +776,12 @@ class EWebView {
                                uint32_t current);
   void SetHighBitRate(Eina_Bool is_high_bitrate);
   bool IsHighBitRate() const { return is_high_bitrate_; }
+
+  void GetMediaDeviceList(Ewk_Media_Device_List_Get_Callback callback,
+                          void* userData);
+  using MediaDeviceEnumeration =
+      std::array<blink::WebMediaDeviceInfoArray, NUM_MEDIA_DEVICE_TYPES>;
+  void OnDeviceListed(const MediaDeviceEnumeration& devices);
 #endif  // IS_TIZEN_TV
 
   void SetDidChangeThemeColorCallback(
@@ -863,6 +895,10 @@ class EWebView {
 
   base::IDMap<BackgroundColorGetCallback*> background_color_get_callback_map_;
 
+#if BUILDFLAG(IS_TIZEN_TV)
+  GetMediaDeviceCallback device_cb_;
+#endif
+
   gfx::Size contents_size_;
   double progress_;
   mutable std::string title_;
@@ -983,6 +1019,7 @@ class EWebView {
 #endif
 
   Ecore_Timer* delayed_show_context_menu_timer_ = nullptr;
+  base::WeakPtrFactory<EWebView> weak_factory_{this};
 };
 
 const unsigned int g_default_tilt_motion_sensitivity = 3;
index 27c36b5..a96a0cb 100644 (file)
@@ -1859,7 +1859,14 @@ void ewk_view_request_manifest(Evas_Object* o,
 }
 
 void ewk_view_media_device_list_get(Evas_Object* o, Ewk_Media_Device_List_Get_Callback callback, void* user_data) {
-  //TODO
+#if BUILDFLAG(IS_TIZEN_TV)
+  LOG(INFO) << "ewk_view_media_device_list_get called";
+  EWK_VIEW_IMPL_GET_OR_RETURN(o, impl);
+  EINA_SAFETY_ON_NULL_RETURN(callback);
+  impl->GetMediaDeviceList(callback, user_data);
+#else
+  LOG_EWK_API_MOCKUP("Only for Tizen TV.");
+#endif
 }
 
 void ewk_view_run_mixed_content_confirm_callback_set(
index 5435c2e..4825a63 100644 (file)
@@ -219,6 +219,10 @@ void WebContentsDelegateEfl::NotifyMediaStateChanged(uint32_t type,
 
   web_view_->NotifyMediaStateChanged(type, previous, current);
 }
+
+void WebContentsDelegateEfl::GetMediaDeviceList(EnumerationCallback cb) {
+  MediaCaptureDevices::GetInstance()->GetMediaDeviceList(std::move(cb));
+}
 #endif
 
 void WebContentsDelegateEfl::NavigationStateChanged(
index 9eca28d..55f3d7f 100644 (file)
 #include "public/ewk_view_internal.h"
 #include "third_party/blink/public/mojom/manifest/manifest.mojom.h"
 
+#if BUILDFLAG(IS_TIZEN_TV)
+#include "third_party/blink/public/common/mediastream/media_devices.h"
+#endif
+
 class JavaScriptDialogManagerEfl;
 
 namespace content {
@@ -142,6 +146,11 @@ class WebContentsDelegateEfl : public WebContentsDelegate {
                                uint32_t previous,
                                uint32_t current) override;
   bool IsHighBitRate() const override;
+  using MediaDeviceEnumeration =
+      std::array<blink::WebMediaDeviceInfoArray, NUM_MEDIA_DEVICE_TYPES>;
+  using EnumerationCallback =
+      base::OnceCallback<void(const MediaDeviceEnumeration&)>;
+  void GetMediaDeviceList(EnumerationCallback cb);
 #endif
 
 #if defined(TIZEN_AUTOFILL)