mirror of
				https://bitbucket.org/chromiumembedded/cef
				synced 2025-06-05 21:39:12 +02:00 
			
		
		
		
	Add OnMediaAccessChange notification (fixes issue #3310)
This commit is contained in:
		
							
								
								
									
										2
									
								
								BUILD.gn
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								BUILD.gn
									
									
									
									
									
								
							@@ -591,6 +591,8 @@ static_library("libcef_static") {
 | 
			
		||||
    "libcef/browser/media_router/media_sink_impl.h",
 | 
			
		||||
    "libcef/browser/media_router/media_source_impl.cc",
 | 
			
		||||
    "libcef/browser/media_router/media_source_impl.h",
 | 
			
		||||
    "libcef/browser/media_stream_registrar.cc",
 | 
			
		||||
    "libcef/browser/media_stream_registrar.h",
 | 
			
		||||
    "libcef/browser/menu_manager.cc",
 | 
			
		||||
    "libcef/browser/menu_manager.h",
 | 
			
		||||
    "libcef/browser/menu_model_impl.cc",
 | 
			
		||||
 
 | 
			
		||||
@@ -33,7 +33,7 @@
 | 
			
		||||
// by hand. See the translator.README.txt file in the tools directory for
 | 
			
		||||
// more information.
 | 
			
		||||
//
 | 
			
		||||
// $hash=7e03d64dfcefc287c083e35e5ef9b3fa4f762b1b$
 | 
			
		||||
// $hash=03ae4ba9762510e2b0c19ea29322c20ebaf2e683$
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#ifndef CEF_INCLUDE_CAPI_CEF_CLIENT_CAPI_H_
 | 
			
		||||
@@ -141,8 +141,7 @@ typedef struct _cef_client_t {
 | 
			
		||||
      struct _cef_client_t* self);
 | 
			
		||||
 | 
			
		||||
  ///
 | 
			
		||||
  // Return the handler for permission requests. If no handler is provided
 | 
			
		||||
  // requests be denied by default.
 | 
			
		||||
  // Return the handler for permission requests.
 | 
			
		||||
  ///
 | 
			
		||||
  struct _cef_permission_handler_t*(CEF_CALLBACK* get_permission_handler)(
 | 
			
		||||
      struct _cef_client_t* self);
 | 
			
		||||
 
 | 
			
		||||
@@ -33,7 +33,7 @@
 | 
			
		||||
// by hand. See the translator.README.txt file in the tools directory for
 | 
			
		||||
// more information.
 | 
			
		||||
//
 | 
			
		||||
// $hash=142637539a094a03adc71d2f3f5b711ba64918b1$
 | 
			
		||||
// $hash=5e52ae520b7eda3595683d428aa578bbc776956b$
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#ifndef CEF_INCLUDE_CAPI_CEF_DISPLAY_HANDLER_CAPI_H_
 | 
			
		||||
@@ -154,6 +154,16 @@ typedef struct _cef_display_handler_t {
 | 
			
		||||
      cef_cursor_handle_t cursor,
 | 
			
		||||
      cef_cursor_type_t type,
 | 
			
		||||
      const struct _cef_cursor_info_t* custom_cursor_info);
 | 
			
		||||
 | 
			
		||||
  ///
 | 
			
		||||
  // Called when the browser's access to an audio and/or video source has
 | 
			
		||||
  // changed.
 | 
			
		||||
  ///
 | 
			
		||||
  void(CEF_CALLBACK* on_media_access_change)(
 | 
			
		||||
      struct _cef_display_handler_t* self,
 | 
			
		||||
      struct _cef_browser_t* browser,
 | 
			
		||||
      int has_video_access,
 | 
			
		||||
      int has_audio_access);
 | 
			
		||||
} cef_display_handler_t;
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
 
 | 
			
		||||
@@ -42,13 +42,13 @@
 | 
			
		||||
// way that may cause binary incompatibility with other builds. The universal
 | 
			
		||||
// hash value will change if any platform is affected whereas the platform hash
 | 
			
		||||
// values will change only if that particular platform is affected.
 | 
			
		||||
#define CEF_API_HASH_UNIVERSAL "f0b6806a3e15f849013e58992ef11c99e5cfeb60"
 | 
			
		||||
#define CEF_API_HASH_UNIVERSAL "794a4cf2ad83db17558bd2ca2d721487875a37e8"
 | 
			
		||||
#if defined(OS_WIN)
 | 
			
		||||
#define CEF_API_HASH_PLATFORM "55ba6603a77fcbf93d58a44fbeae9ea52d000153"
 | 
			
		||||
#define CEF_API_HASH_PLATFORM "aa627f71c1cbdf13beeb3fe740337f4cc1cb5dc5"
 | 
			
		||||
#elif defined(OS_MAC)
 | 
			
		||||
#define CEF_API_HASH_PLATFORM "4028739577ee54f7049f354acd724ecee071aa22"
 | 
			
		||||
#define CEF_API_HASH_PLATFORM "6bda80f2ee107a22780193a7af9101eb5a4db8a0"
 | 
			
		||||
#elif defined(OS_LINUX)
 | 
			
		||||
#define CEF_API_HASH_PLATFORM "7464b32d2ed43a15d68a651199fda0c0fe040a8d"
 | 
			
		||||
#define CEF_API_HASH_PLATFORM "c83b942ce72835d0ea01bfc4cab3928b92abdb85"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
 
 | 
			
		||||
@@ -148,6 +148,15 @@ class CefDisplayHandler : public virtual CefBaseRefCounted {
 | 
			
		||||
                              const CefCursorInfo& custom_cursor_info) {
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ///
 | 
			
		||||
  // Called when the browser's access to an audio and/or video source has
 | 
			
		||||
  // changed.
 | 
			
		||||
  ///
 | 
			
		||||
  /*--cef()--*/
 | 
			
		||||
  virtual void OnMediaAccessChange(CefRefPtr<CefBrowser> browser,
 | 
			
		||||
                                   bool has_video_access,
 | 
			
		||||
                                   bool has_audio_access) {}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif  // CEF_INCLUDE_CEF_DISPLAY_HANDLER_H_
 | 
			
		||||
 
 | 
			
		||||
@@ -204,9 +204,10 @@ void CefBrowserHostBase::InitializeBrowser() {
 | 
			
		||||
void CefBrowserHostBase::DestroyBrowser() {
 | 
			
		||||
  CEF_REQUIRE_UIT();
 | 
			
		||||
 | 
			
		||||
  devtools_manager_.reset(nullptr);
 | 
			
		||||
  devtools_manager_.reset();
 | 
			
		||||
  media_stream_registrar_.reset();
 | 
			
		||||
 | 
			
		||||
  platform_delegate_.reset(nullptr);
 | 
			
		||||
  platform_delegate_.reset();
 | 
			
		||||
 | 
			
		||||
  contents_delegate_->RemoveObserver(this);
 | 
			
		||||
  contents_delegate_->ObserveWebContents(nullptr);
 | 
			
		||||
@@ -972,6 +973,14 @@ content::BrowserContext* CefBrowserHostBase::GetBrowserContext() const {
 | 
			
		||||
  return nullptr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CefMediaStreamRegistrar* CefBrowserHostBase::GetMediaStreamRegistrar() {
 | 
			
		||||
  CEF_REQUIRE_UIT();
 | 
			
		||||
  if (!media_stream_registrar_) {
 | 
			
		||||
    media_stream_registrar_ = std::make_unique<CefMediaStreamRegistrar>(this);
 | 
			
		||||
  }
 | 
			
		||||
  return media_stream_registrar_.get();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
views::Widget* CefBrowserHostBase::GetWindowWidget() const {
 | 
			
		||||
  CEF_REQUIRE_UIT();
 | 
			
		||||
  if (!platform_delegate_)
 | 
			
		||||
 
 | 
			
		||||
@@ -15,6 +15,7 @@
 | 
			
		||||
#include "libcef/browser/devtools/devtools_manager.h"
 | 
			
		||||
#include "libcef/browser/file_dialog_manager.h"
 | 
			
		||||
#include "libcef/browser/frame_host_impl.h"
 | 
			
		||||
#include "libcef/browser/media_stream_registrar.h"
 | 
			
		||||
#include "libcef/browser/request_context_impl.h"
 | 
			
		||||
 | 
			
		||||
#include "base/observer_list.h"
 | 
			
		||||
@@ -301,6 +302,7 @@ class CefBrowserHostBase : public CefBrowserHost,
 | 
			
		||||
  CefBrowserContentsDelegate* contents_delegate() const {
 | 
			
		||||
    return contents_delegate_.get();
 | 
			
		||||
  }
 | 
			
		||||
  CefMediaStreamRegistrar* GetMediaStreamRegistrar();
 | 
			
		||||
 | 
			
		||||
  // Returns the Widget owner for the browser window. Only used with windowed
 | 
			
		||||
  // browsers.
 | 
			
		||||
@@ -371,6 +373,8 @@ class CefBrowserHostBase : public CefBrowserHost,
 | 
			
		||||
  // Used for creating and managing DevTools instances.
 | 
			
		||||
  std::unique_ptr<CefDevToolsManager> devtools_manager_;
 | 
			
		||||
 | 
			
		||||
  std::unique_ptr<CefMediaStreamRegistrar> media_stream_registrar_;
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  IMPLEMENT_REFCOUNTING(CefBrowserHostBase);
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -7,6 +7,7 @@
 | 
			
		||||
#include "include/cef_permission_handler.h"
 | 
			
		||||
#include "libcef/browser/browser_host_base.h"
 | 
			
		||||
#include "libcef/browser/media_capture_devices_dispatcher.h"
 | 
			
		||||
#include "libcef/browser/media_stream_registrar.h"
 | 
			
		||||
#include "libcef/common/cef_switches.h"
 | 
			
		||||
 | 
			
		||||
#include "base/command_line.h"
 | 
			
		||||
@@ -20,13 +21,17 @@ class CefMediaAccessQuery {
 | 
			
		||||
 public:
 | 
			
		||||
  using CallbackType = content::MediaResponseCallback;
 | 
			
		||||
 | 
			
		||||
  explicit CefMediaAccessQuery(const content::MediaStreamRequest& request,
 | 
			
		||||
                               CallbackType&& callback)
 | 
			
		||||
      : request_(request), callback_(std::move(callback)) {}
 | 
			
		||||
  CefMediaAccessQuery(CefBrowserHostBase* const browser,
 | 
			
		||||
                      const content::MediaStreamRequest& request,
 | 
			
		||||
                      CallbackType&& callback)
 | 
			
		||||
      : browser_(browser), request_(request), callback_(std::move(callback)) {}
 | 
			
		||||
 | 
			
		||||
  CefMediaAccessQuery(CefMediaAccessQuery&& query)
 | 
			
		||||
      : request_(query.request_), callback_(std::move(query.callback_)) {}
 | 
			
		||||
      : browser_(query.browser_),
 | 
			
		||||
        request_(query.request_),
 | 
			
		||||
        callback_(std::move(query.callback_)) {}
 | 
			
		||||
  CefMediaAccessQuery& operator=(CefMediaAccessQuery&& query) {
 | 
			
		||||
    browser_ = query.browser_;
 | 
			
		||||
    request_ = query.request_;
 | 
			
		||||
    callback_ = std::move(query.callback_);
 | 
			
		||||
    return *this;
 | 
			
		||||
@@ -74,8 +79,20 @@ class CefMediaAccessQuery {
 | 
			
		||||
                     : blink::mojom::MediaStreamRequestResult::OK;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool has_video = false;
 | 
			
		||||
    bool has_audio = false;
 | 
			
		||||
    if (!stream_devices_set->stream_devices.empty()) {
 | 
			
		||||
      blink::mojom::StreamDevices& devices =
 | 
			
		||||
          *stream_devices_set->stream_devices[0];
 | 
			
		||||
      has_video = devices.video_device.has_value();
 | 
			
		||||
      has_audio = devices.audio_device.has_value();
 | 
			
		||||
    }
 | 
			
		||||
    auto media_stream_ui =
 | 
			
		||||
        browser_->GetMediaStreamRegistrar()->MaybeCreateMediaStreamUI(
 | 
			
		||||
            has_video, has_audio);
 | 
			
		||||
 | 
			
		||||
    std::move(callback_).Run(*stream_devices_set, result,
 | 
			
		||||
                             std::unique_ptr<content::MediaStreamUI>());
 | 
			
		||||
                             std::move(media_stream_ui));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
@@ -205,6 +222,7 @@ class CefMediaAccessQuery {
 | 
			
		||||
    return stream_devices_set;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  CefRefPtr<CefBrowserHostBase> browser_;
 | 
			
		||||
  content::MediaStreamRequest request_;
 | 
			
		||||
  CallbackType callback_;
 | 
			
		||||
};
 | 
			
		||||
@@ -281,7 +299,7 @@ void RequestMediaAccessPermission(CefBrowserHostBase* browser,
 | 
			
		||||
                                  content::MediaResponseCallback callback) {
 | 
			
		||||
  CEF_REQUIRE_UIT();
 | 
			
		||||
 | 
			
		||||
  CefMediaAccessQuery query(request, std::move(callback));
 | 
			
		||||
  CefMediaAccessQuery query(browser, request, std::move(callback));
 | 
			
		||||
 | 
			
		||||
  if (CheckCommandLinePermission()) {
 | 
			
		||||
    // Allow all requested permissions.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										108
									
								
								libcef/browser/media_stream_registrar.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								libcef/browser/media_stream_registrar.cc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,108 @@
 | 
			
		||||
// Copyright 2022 The Chromium Embedded Framework Authors. All rights reserved.
 | 
			
		||||
// Use of this source code is governed by a BSD-style license that can be
 | 
			
		||||
// found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
#include "libcef/browser/media_stream_registrar.h"
 | 
			
		||||
 | 
			
		||||
#include "libcef/browser/browser_host_base.h"
 | 
			
		||||
#include "libcef/browser/thread_util.h"
 | 
			
		||||
 | 
			
		||||
class CefMediaStreamUI : public content::MediaStreamUI {
 | 
			
		||||
 public:
 | 
			
		||||
  CefMediaStreamUI(base::WeakPtr<CefMediaStreamRegistrar> registrar,
 | 
			
		||||
                   bool has_video,
 | 
			
		||||
                   bool has_audio)
 | 
			
		||||
      : registrar_(registrar), has_video_(has_video), has_audio_(has_audio) {}
 | 
			
		||||
 | 
			
		||||
  ~CefMediaStreamUI() override {
 | 
			
		||||
    if (registrar_) {
 | 
			
		||||
      registrar_->UnregisterMediaStream(label_);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  CefMediaStreamUI(const CefMediaStreamUI&) = delete;
 | 
			
		||||
  CefMediaStreamUI& operator=(const CefMediaStreamUI&) = delete;
 | 
			
		||||
 | 
			
		||||
  gfx::NativeViewId OnStarted(
 | 
			
		||||
      base::RepeatingClosure stop,
 | 
			
		||||
      SourceCallback source,
 | 
			
		||||
      const std::string& label,
 | 
			
		||||
      std::vector<content::DesktopMediaID> screen_capture_ids,
 | 
			
		||||
      StateChangeCallback state_change) override {
 | 
			
		||||
    if (registrar_) {
 | 
			
		||||
      label_ = label;
 | 
			
		||||
      registrar_->RegisterMediaStream(label, has_video_, has_audio_);
 | 
			
		||||
    }
 | 
			
		||||
    return 0;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void OnDeviceStoppedForSourceChange(
 | 
			
		||||
      const std::string& label,
 | 
			
		||||
      const content::DesktopMediaID& old_media_id,
 | 
			
		||||
      const content::DesktopMediaID& new_media_id) override {}
 | 
			
		||||
 | 
			
		||||
  void OnDeviceStopped(const std::string& label,
 | 
			
		||||
                       const content::DesktopMediaID& media_id) override {}
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  base::WeakPtr<CefMediaStreamRegistrar> registrar_;
 | 
			
		||||
  const bool has_video_;
 | 
			
		||||
  const bool has_audio_;
 | 
			
		||||
  std::string label_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
CefMediaStreamRegistrar::CefMediaStreamRegistrar(CefBrowserHostBase* browser)
 | 
			
		||||
    : browser_(browser) {}
 | 
			
		||||
 | 
			
		||||
std::unique_ptr<content::MediaStreamUI>
 | 
			
		||||
CefMediaStreamRegistrar::MaybeCreateMediaStreamUI(bool has_video,
 | 
			
		||||
                                                  bool has_audio) const {
 | 
			
		||||
  // Only create the object if the callback will be executed.
 | 
			
		||||
  if (auto client = browser_->GetClient()) {
 | 
			
		||||
    if (auto handler = client->GetDisplayHandler()) {
 | 
			
		||||
      return std::make_unique<CefMediaStreamUI>(weak_ptr_factory_.GetWeakPtr(),
 | 
			
		||||
                                                has_video, has_audio);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return nullptr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CefMediaStreamRegistrar::RegisterMediaStream(const std::string& label,
 | 
			
		||||
                                                  bool video,
 | 
			
		||||
                                                  bool audio) {
 | 
			
		||||
  CEF_REQUIRE_UIT();
 | 
			
		||||
  MediaStreamInfo info = {video, audio};
 | 
			
		||||
  registered_streams_.insert(std::make_pair(label, info));
 | 
			
		||||
  NotifyMediaStreamChange();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CefMediaStreamRegistrar::UnregisterMediaStream(const std::string& label) {
 | 
			
		||||
  CEF_REQUIRE_UIT();
 | 
			
		||||
  registered_streams_.erase(label);
 | 
			
		||||
  NotifyMediaStreamChange();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CefMediaStreamRegistrar::NotifyMediaStreamChange() {
 | 
			
		||||
  bool video = false;
 | 
			
		||||
  bool audio = false;
 | 
			
		||||
  for (const auto& media_stream : registered_streams_) {
 | 
			
		||||
    const auto& info = media_stream.second;
 | 
			
		||||
    if (!video)
 | 
			
		||||
      video = info.video;
 | 
			
		||||
    if (!audio)
 | 
			
		||||
      audio = info.audio;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (audio == last_notified_info_.audio &&
 | 
			
		||||
      video == last_notified_info_.video) {
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  last_notified_info_ = {video, audio};
 | 
			
		||||
 | 
			
		||||
  if (auto client = browser_->GetClient()) {
 | 
			
		||||
    if (auto handler = client->GetDisplayHandler()) {
 | 
			
		||||
      handler->OnMediaAccessChange(browser_, video, audio);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										56
									
								
								libcef/browser/media_stream_registrar.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								libcef/browser/media_stream_registrar.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,56 @@
 | 
			
		||||
// Copyright 2022 The Chromium Embedded Framework Authors. All rights reserved.
 | 
			
		||||
// Use of this source code is governed by a BSD-style license that can be
 | 
			
		||||
// found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
#ifndef CEF_LIBCEF_BROWSER_MEDIA_STREAM_REGISTRAR_H_
 | 
			
		||||
#define CEF_LIBCEF_BROWSER_MEDIA_STREAM_REGISTRAR_H_
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <map>
 | 
			
		||||
#include <memory>
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
#include "base/memory/weak_ptr.h"
 | 
			
		||||
#include "content/public/browser/media_stream_request.h"
 | 
			
		||||
 | 
			
		||||
class CefBrowserHostBase;
 | 
			
		||||
class CefMediaStreamUI;
 | 
			
		||||
 | 
			
		||||
class CefMediaStreamRegistrar {
 | 
			
		||||
 public:
 | 
			
		||||
  explicit CefMediaStreamRegistrar(CefBrowserHostBase* browser);
 | 
			
		||||
 | 
			
		||||
  CefMediaStreamRegistrar(const CefMediaStreamRegistrar&) = delete;
 | 
			
		||||
  CefMediaStreamRegistrar& operator=(const CefMediaStreamRegistrar&) = delete;
 | 
			
		||||
 | 
			
		||||
  std::unique_ptr<content::MediaStreamUI> MaybeCreateMediaStreamUI(
 | 
			
		||||
      bool has_video,
 | 
			
		||||
      bool has_audio) const;
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  friend class CefMediaStreamUI;
 | 
			
		||||
 | 
			
		||||
  // Called from CefMediaStreamUI.
 | 
			
		||||
  void RegisterMediaStream(const std::string& label, bool video, bool audio);
 | 
			
		||||
  void UnregisterMediaStream(const std::string& label);
 | 
			
		||||
 | 
			
		||||
  void NotifyMediaStreamChange();
 | 
			
		||||
 | 
			
		||||
  // Guaranteed to outlive this object.
 | 
			
		||||
  CefBrowserHostBase* const browser_;
 | 
			
		||||
 | 
			
		||||
  struct MediaStreamInfo {
 | 
			
		||||
    bool video;
 | 
			
		||||
    bool audio;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  // Current in use media streams.
 | 
			
		||||
  std::map<std::string, MediaStreamInfo> registered_streams_;
 | 
			
		||||
 | 
			
		||||
  // Last notified media stream info.
 | 
			
		||||
  MediaStreamInfo last_notified_info_{};
 | 
			
		||||
 | 
			
		||||
  base::WeakPtrFactory<CefMediaStreamRegistrar> weak_ptr_factory_{this};
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif  // CEF_LIBCEF_BROWSER_MEDIA_STREAM_REGISTRAR_H_
 | 
			
		||||
@@ -9,7 +9,7 @@
 | 
			
		||||
// implementations. See the translator.README.txt file in the tools directory
 | 
			
		||||
// for more information.
 | 
			
		||||
//
 | 
			
		||||
// $hash=5bcef102e9ae42a32b551c3af3decbae11b8b37d$
 | 
			
		||||
// $hash=b492dccf2a5ddb50f50fe1783d8cacd3080714a5$
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include "libcef_dll/cpptoc/display_handler_cpptoc.h"
 | 
			
		||||
@@ -292,6 +292,29 @@ int CEF_CALLBACK display_handler_on_cursor_change(
 | 
			
		||||
  return _retval;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CEF_CALLBACK
 | 
			
		||||
display_handler_on_media_access_change(struct _cef_display_handler_t* self,
 | 
			
		||||
                                       cef_browser_t* browser,
 | 
			
		||||
                                       int has_video_access,
 | 
			
		||||
                                       int has_audio_access) {
 | 
			
		||||
  shutdown_checker::AssertNotShutdown();
 | 
			
		||||
 | 
			
		||||
  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
 | 
			
		||||
 | 
			
		||||
  DCHECK(self);
 | 
			
		||||
  if (!self)
 | 
			
		||||
    return;
 | 
			
		||||
  // Verify param: browser; type: refptr_diff
 | 
			
		||||
  DCHECK(browser);
 | 
			
		||||
  if (!browser)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  // Execute
 | 
			
		||||
  CefDisplayHandlerCppToC::Get(self)->OnMediaAccessChange(
 | 
			
		||||
      CefBrowserCToCpp::Wrap(browser), has_video_access ? true : false,
 | 
			
		||||
      has_audio_access ? true : false);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}  // namespace
 | 
			
		||||
 | 
			
		||||
// CONSTRUCTOR - Do not edit by hand.
 | 
			
		||||
@@ -309,6 +332,7 @@ CefDisplayHandlerCppToC::CefDisplayHandlerCppToC() {
 | 
			
		||||
  GetStruct()->on_loading_progress_change =
 | 
			
		||||
      display_handler_on_loading_progress_change;
 | 
			
		||||
  GetStruct()->on_cursor_change = display_handler_on_cursor_change;
 | 
			
		||||
  GetStruct()->on_media_access_change = display_handler_on_media_access_change;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DESTRUCTOR - Do not edit by hand.
 | 
			
		||||
 
 | 
			
		||||
@@ -9,7 +9,7 @@
 | 
			
		||||
// implementations. See the translator.README.txt file in the tools directory
 | 
			
		||||
// for more information.
 | 
			
		||||
//
 | 
			
		||||
// $hash=f40564d59c337fede5e8c3121ed735166d5e05a3$
 | 
			
		||||
// $hash=ab688c32624070704507d10dc27d430d90f04dd2$
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include "libcef_dll/ctocpp/display_handler_ctocpp.h"
 | 
			
		||||
@@ -277,6 +277,28 @@ bool CefDisplayHandlerCToCpp::OnCursorChange(
 | 
			
		||||
  return _retval ? true : false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
NO_SANITIZE("cfi-icall")
 | 
			
		||||
void CefDisplayHandlerCToCpp::OnMediaAccessChange(CefRefPtr<CefBrowser> browser,
 | 
			
		||||
                                                  bool has_video_access,
 | 
			
		||||
                                                  bool has_audio_access) {
 | 
			
		||||
  shutdown_checker::AssertNotShutdown();
 | 
			
		||||
 | 
			
		||||
  cef_display_handler_t* _struct = GetStruct();
 | 
			
		||||
  if (CEF_MEMBER_MISSING(_struct, on_media_access_change))
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
 | 
			
		||||
 | 
			
		||||
  // Verify param: browser; type: refptr_diff
 | 
			
		||||
  DCHECK(browser.get());
 | 
			
		||||
  if (!browser.get())
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  // Execute
 | 
			
		||||
  _struct->on_media_access_change(_struct, CefBrowserCppToC::Wrap(browser),
 | 
			
		||||
                                  has_video_access, has_audio_access);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CONSTRUCTOR - Do not edit by hand.
 | 
			
		||||
 | 
			
		||||
CefDisplayHandlerCToCpp::CefDisplayHandlerCToCpp() {}
 | 
			
		||||
 
 | 
			
		||||
@@ -9,7 +9,7 @@
 | 
			
		||||
// implementations. See the translator.README.txt file in the tools directory
 | 
			
		||||
// for more information.
 | 
			
		||||
//
 | 
			
		||||
// $hash=f6769db4bda5143d4e42a2e68788b58c68292c1d$
 | 
			
		||||
// $hash=ca2ef5029377f07f196011a3ec686049d3623cce$
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#ifndef CEF_LIBCEF_DLL_CTOCPP_DISPLAY_HANDLER_CTOCPP_H_
 | 
			
		||||
@@ -61,6 +61,9 @@ class CefDisplayHandlerCToCpp
 | 
			
		||||
                      CefCursorHandle cursor,
 | 
			
		||||
                      cef_cursor_type_t type,
 | 
			
		||||
                      const CefCursorInfo& custom_cursor_info) override;
 | 
			
		||||
  void OnMediaAccessChange(CefRefPtr<CefBrowser> browser,
 | 
			
		||||
                           bool has_video_access,
 | 
			
		||||
                           bool has_audio_access) override;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif  // CEF_LIBCEF_DLL_CTOCPP_DISPLAY_HANDLER_CTOCPP_H_
 | 
			
		||||
 
 | 
			
		||||
@@ -49,6 +49,7 @@ class TestSetup {
 | 
			
		||||
  TrackCallback got_success;
 | 
			
		||||
  TrackCallback got_audio;
 | 
			
		||||
  TrackCallback got_video;
 | 
			
		||||
  TrackCallback got_change;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class MediaAccessTestHandler : public TestHandler, public CefPermissionHandler {
 | 
			
		||||
@@ -105,23 +106,14 @@ class MediaAccessTestHandler : public TestHandler, public CefPermissionHandler {
 | 
			
		||||
        "exit?result=${val}&data=${encodeURIComponent(JSON.stringify(data))}`;"
 | 
			
		||||
        "}";
 | 
			
		||||
 | 
			
		||||
    const bool want_audio_device =
 | 
			
		||||
        request_ & CEF_MEDIA_PERMISSION_DEVICE_AUDIO_CAPTURE;
 | 
			
		||||
    const bool want_video_device =
 | 
			
		||||
        request_ & CEF_MEDIA_PERMISSION_DEVICE_VIDEO_CAPTURE;
 | 
			
		||||
    const bool want_desktop_audio =
 | 
			
		||||
        request_ & CEF_MEDIA_PERMISSION_DESKTOP_AUDIO_CAPTURE;
 | 
			
		||||
    const bool want_desktop_video =
 | 
			
		||||
        request_ & CEF_MEDIA_PERMISSION_DESKTOP_VIDEO_CAPTURE;
 | 
			
		||||
 | 
			
		||||
    if (want_audio_device || want_video_device) {
 | 
			
		||||
    if (want_audio_device() || want_video_device()) {
 | 
			
		||||
      page += std::string("navigator.mediaDevices.getUserMedia({audio: ") +
 | 
			
		||||
              (want_audio_device ? "true" : "false") +
 | 
			
		||||
              ", video: " + (want_video_device ? "true" : "false") + "})";
 | 
			
		||||
              (want_audio_device() ? "true" : "false") +
 | 
			
		||||
              ", video: " + (want_video_device() ? "true" : "false") + "})";
 | 
			
		||||
    } else {
 | 
			
		||||
      page += std::string("navigator.mediaDevices.getDisplayMedia({audio: ") +
 | 
			
		||||
              (want_desktop_audio ? "true" : "false") +
 | 
			
		||||
              ", video: " + (want_desktop_video ? "true" : "false") + "})";
 | 
			
		||||
              (want_audio_desktop() ? "true" : "false") +
 | 
			
		||||
              ", video: " + (want_video_desktop() ? "true" : "false") + "})";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    page +=
 | 
			
		||||
@@ -188,7 +180,43 @@ class MediaAccessTestHandler : public TestHandler, public CefPermissionHandler {
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 protected:
 | 
			
		||||
  void OnMediaAccessChange(CefRefPtr<CefBrowser> browser,
 | 
			
		||||
                           bool has_video_access,
 | 
			
		||||
                           bool has_audio_access) override {
 | 
			
		||||
    EXPECT_UI_THREAD();
 | 
			
		||||
    EXPECT_EQ(got_video_device() || got_video_desktop(), has_video_access);
 | 
			
		||||
    EXPECT_EQ(got_audio_device() || got_audio_desktop(), has_audio_access);
 | 
			
		||||
    EXPECT_FALSE(test_setup_->got_change);
 | 
			
		||||
    test_setup_->got_change.yes();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  bool want_audio_device() const {
 | 
			
		||||
    return request_ & CEF_MEDIA_PERMISSION_DEVICE_AUDIO_CAPTURE;
 | 
			
		||||
  }
 | 
			
		||||
  bool want_video_device() const {
 | 
			
		||||
    return request_ & CEF_MEDIA_PERMISSION_DEVICE_VIDEO_CAPTURE;
 | 
			
		||||
  }
 | 
			
		||||
  bool want_audio_desktop() const {
 | 
			
		||||
    return request_ & CEF_MEDIA_PERMISSION_DESKTOP_AUDIO_CAPTURE;
 | 
			
		||||
  }
 | 
			
		||||
  bool want_video_desktop() const {
 | 
			
		||||
    return request_ & CEF_MEDIA_PERMISSION_DESKTOP_VIDEO_CAPTURE;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bool got_audio_device() const {
 | 
			
		||||
    return response_ & CEF_MEDIA_PERMISSION_DEVICE_AUDIO_CAPTURE;
 | 
			
		||||
  }
 | 
			
		||||
  bool got_video_device() const {
 | 
			
		||||
    return response_ & CEF_MEDIA_PERMISSION_DEVICE_VIDEO_CAPTURE;
 | 
			
		||||
  }
 | 
			
		||||
  bool got_audio_desktop() const {
 | 
			
		||||
    return response_ & CEF_MEDIA_PERMISSION_DESKTOP_AUDIO_CAPTURE;
 | 
			
		||||
  }
 | 
			
		||||
  bool got_video_desktop() const {
 | 
			
		||||
    return response_ & CEF_MEDIA_PERMISSION_DESKTOP_VIDEO_CAPTURE;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  TestSetup* const test_setup_;
 | 
			
		||||
  const uint32 request_;
 | 
			
		||||
  const uint32 response_;
 | 
			
		||||
@@ -213,6 +241,7 @@ TEST(MediaAccessTest, DeviceFailureWhenReturningFalse) {
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_success);
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_audio);
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_video);
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_change);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(MediaAccessTest, DeviceFailureWhenReturningNoPermission) {
 | 
			
		||||
@@ -229,6 +258,7 @@ TEST(MediaAccessTest, DeviceFailureWhenReturningNoPermission) {
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_success);
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_audio);
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_video);
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_change);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(MediaAccessTest, DeviceFailureWhenReturningNoPermissionAsync) {
 | 
			
		||||
@@ -246,6 +276,7 @@ TEST(MediaAccessTest, DeviceFailureWhenReturningNoPermissionAsync) {
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_success);
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_audio);
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_video);
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_change);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(MediaAccessTest, DeviceFailureWhenRequestingAudioButReturningVideo) {
 | 
			
		||||
@@ -260,6 +291,7 @@ TEST(MediaAccessTest, DeviceFailureWhenRequestingAudioButReturningVideo) {
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_success);
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_audio);
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_video);
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_change);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(MediaAccessTest, DeviceFailureWhenRequestingVideoButReturningAudio) {
 | 
			
		||||
@@ -274,6 +306,7 @@ TEST(MediaAccessTest, DeviceFailureWhenRequestingVideoButReturningAudio) {
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_success);
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_audio);
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_video);
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_change);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(MediaAccessTest, DevicePartialFailureReturningVideo) {
 | 
			
		||||
@@ -290,6 +323,7 @@ TEST(MediaAccessTest, DevicePartialFailureReturningVideo) {
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_success);
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_audio);
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_video);
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_change);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(MediaAccessTest, DevicePartialFailureReturningAudio) {
 | 
			
		||||
@@ -306,6 +340,7 @@ TEST(MediaAccessTest, DevicePartialFailureReturningAudio) {
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_success);
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_audio);
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_video);
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_change);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(MediaAccessTest, DeviceFailureWhenReturningScreenCapture1) {
 | 
			
		||||
@@ -322,6 +357,7 @@ TEST(MediaAccessTest, DeviceFailureWhenReturningScreenCapture1) {
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_success);
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_audio);
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_video);
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_change);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(MediaAccessTest, DeviceFailureWhenReturningScreenCapture2) {
 | 
			
		||||
@@ -338,6 +374,7 @@ TEST(MediaAccessTest, DeviceFailureWhenReturningScreenCapture2) {
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_success);
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_audio);
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_video);
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_change);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(MediaAccessTest, DeviceFailureWhenReturningScreenCapture3) {
 | 
			
		||||
@@ -352,6 +389,7 @@ TEST(MediaAccessTest, DeviceFailureWhenReturningScreenCapture3) {
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_success);
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_audio);
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_video);
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_change);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(MediaAccessTest, DeviceFailureWhenReturningScreenCapture4) {
 | 
			
		||||
@@ -366,6 +404,7 @@ TEST(MediaAccessTest, DeviceFailureWhenReturningScreenCapture4) {
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_success);
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_audio);
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_video);
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_change);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(MediaAccessTest, DeviceFailureWhenReturningScreenCapture5) {
 | 
			
		||||
@@ -380,6 +419,7 @@ TEST(MediaAccessTest, DeviceFailureWhenReturningScreenCapture5) {
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_success);
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_audio);
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_video);
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_change);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(MediaAccessTest, DeviceFailureWhenReturningScreenCapture6) {
 | 
			
		||||
@@ -394,6 +434,7 @@ TEST(MediaAccessTest, DeviceFailureWhenReturningScreenCapture6) {
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_success);
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_audio);
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_video);
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_change);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(MediaAccessTest, DeviceSuccessAudioOnly) {
 | 
			
		||||
@@ -408,6 +449,7 @@ TEST(MediaAccessTest, DeviceSuccessAudioOnly) {
 | 
			
		||||
  EXPECT_TRUE(test_setup.got_success);
 | 
			
		||||
  EXPECT_TRUE(test_setup.got_audio);
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_video);
 | 
			
		||||
  EXPECT_TRUE(test_setup.got_change);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(MediaAccessTest, DeviceSuccessVideoOnly) {
 | 
			
		||||
@@ -422,6 +464,7 @@ TEST(MediaAccessTest, DeviceSuccessVideoOnly) {
 | 
			
		||||
  EXPECT_TRUE(test_setup.got_success);
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_audio);
 | 
			
		||||
  EXPECT_TRUE(test_setup.got_video);
 | 
			
		||||
  EXPECT_TRUE(test_setup.got_change);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(MediaAccessTest, DeviceSuccessAudioVideo) {
 | 
			
		||||
@@ -439,6 +482,7 @@ TEST(MediaAccessTest, DeviceSuccessAudioVideo) {
 | 
			
		||||
  EXPECT_TRUE(test_setup.got_success);
 | 
			
		||||
  EXPECT_TRUE(test_setup.got_audio);
 | 
			
		||||
  EXPECT_TRUE(test_setup.got_video);
 | 
			
		||||
  EXPECT_TRUE(test_setup.got_change);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(MediaAccessTest, DeviceSuccessAudioVideoAsync) {
 | 
			
		||||
@@ -457,6 +501,7 @@ TEST(MediaAccessTest, DeviceSuccessAudioVideoAsync) {
 | 
			
		||||
  EXPECT_TRUE(test_setup.got_success);
 | 
			
		||||
  EXPECT_TRUE(test_setup.got_audio);
 | 
			
		||||
  EXPECT_TRUE(test_setup.got_video);
 | 
			
		||||
  EXPECT_TRUE(test_setup.got_change);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Screen capture tests
 | 
			
		||||
@@ -474,6 +519,7 @@ TEST(MediaAccessTest, DesktopFailureWhenReturningNoPermission) {
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_success);
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_audio);
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_video);
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_change);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(MediaAccessTest, DesktopFailureWhenRequestingVideoButReturningAudio) {
 | 
			
		||||
@@ -488,6 +534,7 @@ TEST(MediaAccessTest, DesktopFailureWhenRequestingVideoButReturningAudio) {
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_success);
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_audio);
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_video);
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_change);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(MediaAccessTest, DesktopPartialSuccessReturningVideo) {
 | 
			
		||||
@@ -504,6 +551,7 @@ TEST(MediaAccessTest, DesktopPartialSuccessReturningVideo) {
 | 
			
		||||
  EXPECT_TRUE(test_setup.got_success);
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_audio);
 | 
			
		||||
  EXPECT_TRUE(test_setup.got_video);
 | 
			
		||||
  EXPECT_TRUE(test_setup.got_change);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(MediaAccessTest, DesktopPartialFailureReturningAudio) {
 | 
			
		||||
@@ -519,6 +567,7 @@ TEST(MediaAccessTest, DesktopPartialFailureReturningAudio) {
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_success);
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_audio);
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_video);
 | 
			
		||||
  EXPECT_FALSE(test_setup.got_change);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Entry point for creating media access browser test objects.
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user