Expose MediaSink device ip/port and model name (see issue #2900)

This commit is contained in:
Marshall Greenblatt 2020-07-14 16:43:57 -04:00
parent 13e3c8b42a
commit e8573173dd
18 changed files with 578 additions and 35 deletions

View File

@ -8,7 +8,7 @@
# by hand. See the translator.README.txt file in the tools directory for
# more information.
#
# $hash=30eed8c81da55c640eb6a491283d1c00fb59d635$
# $hash=72268a78a76d7d91b8ad47f6b6e9f6d9cb04d9cf$
#
{
@ -330,6 +330,8 @@
'libcef_dll/cpptoc/media_router_cpptoc.h',
'libcef_dll/cpptoc/media_sink_cpptoc.cc',
'libcef_dll/cpptoc/media_sink_cpptoc.h',
'libcef_dll/ctocpp/media_sink_device_info_callback_ctocpp.cc',
'libcef_dll/ctocpp/media_sink_device_info_callback_ctocpp.h',
'libcef_dll/cpptoc/media_source_cpptoc.cc',
'libcef_dll/cpptoc/media_source_cpptoc.h',
'libcef_dll/cpptoc/views/menu_button_cpptoc.cc',
@ -638,6 +640,8 @@
'libcef_dll/ctocpp/media_router_ctocpp.h',
'libcef_dll/ctocpp/media_sink_ctocpp.cc',
'libcef_dll/ctocpp/media_sink_ctocpp.h',
'libcef_dll/cpptoc/media_sink_device_info_callback_cpptoc.cc',
'libcef_dll/cpptoc/media_sink_device_info_callback_cpptoc.h',
'libcef_dll/ctocpp/media_source_ctocpp.cc',
'libcef_dll/ctocpp/media_source_ctocpp.h',
'libcef_dll/ctocpp/views/menu_button_ctocpp.cc',

View File

@ -33,7 +33,7 @@
// by hand. See the translator.README.txt file in the tools directory for
// more information.
//
// $hash=a259fab661bc913498ae4f46f8dee1c1e592823d$
// $hash=4f4a0d76efaf87055ebf5e784f5d1b69fafdabc2$
//
#ifndef CEF_INCLUDE_CAPI_CEF_MEDIA_ROUTER_CAPI_H_
@ -50,6 +50,7 @@ extern "C" {
struct _cef_media_observer_t;
struct _cef_media_route_create_callback_t;
struct _cef_media_route_t;
struct _cef_media_sink_device_info_callback_t;
struct _cef_media_sink_t;
struct _cef_media_source_t;
@ -265,6 +266,13 @@ typedef struct _cef_media_sink_t {
cef_media_sink_icon_type_t(CEF_CALLBACK* get_icon_type)(
struct _cef_media_sink_t* self);
///
// Asynchronously retrieves device info.
///
void(CEF_CALLBACK* get_device_info)(
struct _cef_media_sink_t* self,
struct _cef_media_sink_device_info_callback_t* callback);
///
// Returns true (1) if this sink accepts content via Cast.
///
@ -282,6 +290,25 @@ typedef struct _cef_media_sink_t {
struct _cef_media_source_t* source);
} cef_media_sink_t;
///
// Callback structure for cef_media_sink_t::GetDeviceInfo. The functions of this
// structure will be called on the browser process UI thread.
///
typedef struct _cef_media_sink_device_info_callback_t {
///
// Base structure.
///
cef_base_ref_counted_t base;
///
// Method that will be executed asyncronously once device information has been
// retrieved.
///
void(CEF_CALLBACK* on_media_sink_device_info)(
struct _cef_media_sink_device_info_callback_t* self,
const struct _cef_media_sink_device_info_t* device_info);
} cef_media_sink_device_info_callback_t;
///
// Represents a source from which media can be routed. Instances of this object
// are retrieved via cef_media_router_t::GetSource. The functions of this

View File

@ -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 "fb680f6c23c5fb612f22894422b058c8f8833703"
#define CEF_API_HASH_UNIVERSAL "20d95f0b54da45b2ced365aa92c784e348862bd3"
#if defined(OS_WIN)
#define CEF_API_HASH_PLATFORM "b174bf9f140ac8cdfcc8db9185723d8236768496"
#define CEF_API_HASH_PLATFORM "fbe8ca0acbdc4b4050d5e44cbde930177be44edf"
#elif defined(OS_MACOSX)
#define CEF_API_HASH_PLATFORM "a93343f0e769bade840574e1547bd16546afcc9d"
#define CEF_API_HASH_PLATFORM "68ba2cd3b110e52ef2d6b07412155b845b105177"
#elif defined(OS_LINUX)
#define CEF_API_HASH_PLATFORM "92fb849966e00682c42bcf22fa36a689a16c9d9f"
#define CEF_API_HASH_PLATFORM "40e1cf30d708463e32bf65f9d033f98f22a321e8"
#endif
#ifdef __cplusplus

View File

@ -46,6 +46,7 @@ class CefMediaObserver;
class CefMediaRoute;
class CefMediaRouteCreateCallback;
class CefMediaSink;
class CefMediaSinkDeviceInfoCallback;
class CefMediaSource;
///
@ -247,6 +248,13 @@ class CefMediaSink : public virtual CefBaseRefCounted {
/*--cef(default_retval=CEF_MSIT_GENERIC)--*/
virtual IconType GetIconType() = 0;
///
// Asynchronously retrieves device info.
///
/*--cef()--*/
virtual void GetDeviceInfo(
CefRefPtr<CefMediaSinkDeviceInfoCallback> callback) = 0;
///
// Returns true if this sink accepts content via Cast.
///
@ -266,6 +274,22 @@ class CefMediaSink : public virtual CefBaseRefCounted {
virtual bool IsCompatibleWith(CefRefPtr<CefMediaSource> source) = 0;
};
///
// Callback interface for CefMediaSink::GetDeviceInfo. The methods of this
// class will be called on the browser process UI thread.
///
/*--cef(source=client)--*/
class CefMediaSinkDeviceInfoCallback : public virtual CefBaseRefCounted {
public:
///
// Method that will be executed asyncronously once device information has been
// retrieved.
///
/*--cef()--*/
virtual void OnMediaSinkDeviceInfo(
const CefMediaSinkDeviceInfo& device_info) = 0;
};
///
// Represents a source from which media can be routed. Instances of this object
// are retrieved via CefMediaRouter::GetSource. The methods of this class may be

View File

@ -3187,6 +3187,15 @@ typedef enum {
CEF_MSIT_TOTAL_COUNT, // The total number of values.
} cef_media_sink_icon_type_t;
///
// Device information for a MediaSink object.
///
typedef struct _cef_media_sink_device_info_t {
cef_string_t ip_address;
int port;
cef_string_t model_name;
} cef_media_sink_device_info_t;
///
// Represents commands available to TextField.
///

View File

@ -980,4 +980,30 @@ struct CefAudioParametersTraits {
///
typedef CefStructBase<CefAudioParametersTraits> CefAudioParameters;
struct CefMediaSinkDeviceInfoTraits {
typedef cef_media_sink_device_info_t struct_type;
static inline void init(struct_type* s) {}
static inline void clear(struct_type* s) {
cef_string_clear(&s->ip_address);
cef_string_clear(&s->model_name);
}
static inline void set(const struct_type* src,
struct_type* target,
bool copy) {
cef_string_set(src->ip_address.str, src->ip_address.length,
&target->ip_address, copy);
target->port = src->port;
cef_string_set(src->model_name.str, src->model_name.length,
&target->model_name, copy);
}
};
///
// Class representing MediaSink device info.
///
typedef CefStructBase<CefMediaSinkDeviceInfoTraits> CefMediaSinkDeviceInfo;
#endif // CEF_INCLUDE_INTERNAL_CEF_TYPES_WRAPPERS_H_

View File

@ -4,6 +4,84 @@
#include "libcef/browser/media_router/media_sink_impl.h"
#include "libcef/browser/thread_util.h"
#include "base/strings/string_number_conversions.h"
#include "chrome/browser/media/router/discovery/dial/dial_media_sink_service_impl.h"
#include "chrome/browser/media/router/providers/cast/dual_media_sink_service.h"
#include "chrome/common/media_router/discovery/media_sink_internal.h"
#include "chrome/common/media_router/discovery/media_sink_service_base.h"
namespace {
using SinkServiceVector = std::vector<media_router::MediaSinkServiceBase*>;
SinkServiceVector GetSinkServices() {
CEF_REQUIRE_UIT();
auto sink_service = media_router::DualMediaSinkService::GetInstance();
return {sink_service->GetCastMediaSinkServiceImpl(),
sink_service->GetDialMediaSinkServiceImpl()};
}
void GetSinkInternalAndContinue(
SinkServiceVector services,
const media_router::MediaSink::Id& sink_id,
CefRefPtr<CefMediaSinkDeviceInfoCallback> callback) {
CEF_REQUIRE_IOT();
CefMediaSinkDeviceInfo device_info;
const media_router::MediaSinkInternal* sink_internal = nullptr;
for (auto service : services) {
sink_internal = service->GetSinkById(sink_id);
if (sink_internal)
break;
}
if (sink_internal) {
if (sink_internal->is_cast_sink()) {
const auto& cast_data = sink_internal->cast_data();
CefString(&device_info.ip_address) =
cast_data.ip_endpoint.ToStringWithoutPort();
device_info.port = cast_data.ip_endpoint.port();
CefString(&device_info.model_name) = cast_data.model_name;
} else if (sink_internal->is_dial_sink()) {
const auto& dial_data = sink_internal->dial_data();
CefString(&device_info.ip_address) = dial_data.ip_address.ToString();
if (dial_data.app_url.is_valid() && dial_data.app_url.has_port()) {
base::StringToInt(dial_data.app_url.port_piece(), &device_info.port);
}
CefString(&device_info.model_name) = dial_data.model_name;
}
}
// Execute the callback on the UI thread.
CEF_POST_TASK(
CEF_UIT,
base::BindOnce(&CefMediaSinkDeviceInfoCallback::OnMediaSinkDeviceInfo,
callback, device_info));
}
void GetDeviceInfo(const media_router::MediaSink::Id& sink_id,
CefRefPtr<CefMediaSinkDeviceInfoCallback> callback) {
auto next_step = base::BindOnce(
[](const media_router::MediaSink::Id& sink_id,
CefRefPtr<CefMediaSinkDeviceInfoCallback> callback) {
CEF_POST_TASK(CEF_IOT,
base::BindOnce(GetSinkInternalAndContinue,
GetSinkServices(), sink_id, callback));
},
sink_id, callback);
if (CEF_CURRENTLY_ON(CEF_UIT)) {
std::move(next_step).Run();
} else {
CEF_POST_TASK(CEF_UIT, std::move(next_step));
}
}
} // namespace
CefMediaSinkImpl::CefMediaSinkImpl(const media_router::MediaSink& sink)
: sink_(sink) {}
@ -32,6 +110,11 @@ CefMediaSink::IconType CefMediaSinkImpl::GetIconType() {
return static_cast<CefMediaSink::IconType>(sink_.icon_type());
}
void CefMediaSinkImpl::GetDeviceInfo(
CefRefPtr<CefMediaSinkDeviceInfoCallback> callback) {
::GetDeviceInfo(sink_.id(), callback);
}
bool CefMediaSinkImpl::IsCastSink() {
return sink_.provider_id() == media_router::CAST;
}

View File

@ -22,6 +22,8 @@ class CefMediaSinkImpl : public CefMediaSink {
CefString GetName() override;
CefString GetDescription() override;
IconType GetIconType() override;
void GetDeviceInfo(
CefRefPtr<CefMediaSinkDeviceInfoCallback> callback) override;
bool IsCastSink() override;
bool IsDialSink() override;
bool IsCompatibleWith(CefRefPtr<CefMediaSource> source) override;

View File

@ -9,11 +9,12 @@
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=53dca3d842bb3d2f8a329a38759eb623620439a2$
// $hash=67d4596d3230067ea7dfe3c8150e3cf87ac526a5$
//
#include "libcef_dll/cpptoc/media_sink_cpptoc.h"
#include "libcef_dll/cpptoc/media_source_cpptoc.h"
#include "libcef_dll/ctocpp/media_sink_device_info_callback_ctocpp.h"
#include "libcef_dll/shutdown_checker.h"
namespace {
@ -89,6 +90,26 @@ media_sink_get_icon_type(struct _cef_media_sink_t* self) {
return _retval;
}
void CEF_CALLBACK media_sink_get_device_info(
struct _cef_media_sink_t* self,
struct _cef_media_sink_device_info_callback_t* callback) {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Verify param: callback; type: refptr_diff
DCHECK(callback);
if (!callback)
return;
// Execute
CefMediaSinkCppToC::Get(self)->GetDeviceInfo(
CefMediaSinkDeviceInfoCallbackCToCpp::Wrap(callback));
}
int CEF_CALLBACK media_sink_is_cast_sink(struct _cef_media_sink_t* self) {
shutdown_checker::AssertNotShutdown();
@ -153,6 +174,7 @@ CefMediaSinkCppToC::CefMediaSinkCppToC() {
GetStruct()->get_name = media_sink_get_name;
GetStruct()->get_description = media_sink_get_description;
GetStruct()->get_icon_type = media_sink_get_icon_type;
GetStruct()->get_device_info = media_sink_get_device_info;
GetStruct()->is_cast_sink = media_sink_is_cast_sink;
GetStruct()->is_dial_sink = media_sink_is_dial_sink;
GetStruct()->is_compatible_with = media_sink_is_compatible_with;

View File

@ -0,0 +1,78 @@
// Copyright (c) 2020 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.
//
// ---------------------------------------------------------------------------
//
// This file was generated by the CEF translator tool. If making changes by
// hand only do so within the body of existing method and function
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=c22023ad9e7d7d80d72729dbebdf03f0b60f4dc9$
//
#include "libcef_dll/cpptoc/media_sink_device_info_callback_cpptoc.h"
#include "libcef_dll/shutdown_checker.h"
namespace {
// MEMBER FUNCTIONS - Body may be edited by hand.
void CEF_CALLBACK media_sink_device_info_callback_on_media_sink_device_info(
struct _cef_media_sink_device_info_callback_t* self,
const struct _cef_media_sink_device_info_t* device_info) {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Verify param: device_info; type: struct_byref_const
DCHECK(device_info);
if (!device_info)
return;
// Translate param: device_info; type: struct_byref_const
CefMediaSinkDeviceInfo device_infoObj;
if (device_info)
device_infoObj.Set(*device_info, false);
// Execute
CefMediaSinkDeviceInfoCallbackCppToC::Get(self)->OnMediaSinkDeviceInfo(
device_infoObj);
}
} // namespace
// CONSTRUCTOR - Do not edit by hand.
CefMediaSinkDeviceInfoCallbackCppToC::CefMediaSinkDeviceInfoCallbackCppToC() {
GetStruct()->on_media_sink_device_info =
media_sink_device_info_callback_on_media_sink_device_info;
}
// DESTRUCTOR - Do not edit by hand.
CefMediaSinkDeviceInfoCallbackCppToC::~CefMediaSinkDeviceInfoCallbackCppToC() {
shutdown_checker::AssertNotShutdown();
}
template <>
CefRefPtr<CefMediaSinkDeviceInfoCallback>
CefCppToCRefCounted<CefMediaSinkDeviceInfoCallbackCppToC,
CefMediaSinkDeviceInfoCallback,
cef_media_sink_device_info_callback_t>::
UnwrapDerived(CefWrapperType type,
cef_media_sink_device_info_callback_t* s) {
NOTREACHED() << "Unexpected class type: " << type;
return nullptr;
}
template <>
CefWrapperType
CefCppToCRefCounted<CefMediaSinkDeviceInfoCallbackCppToC,
CefMediaSinkDeviceInfoCallback,
cef_media_sink_device_info_callback_t>::kWrapperType =
WT_MEDIA_SINK_DEVICE_INFO_CALLBACK;

View File

@ -0,0 +1,38 @@
// Copyright (c) 2020 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.
//
// ---------------------------------------------------------------------------
//
// This file was generated by the CEF translator tool. If making changes by
// hand only do so within the body of existing method and function
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=5313c2346d5db18dca956f2dac98b73e049a4995$
//
#ifndef CEF_LIBCEF_DLL_CPPTOC_MEDIA_SINK_DEVICE_INFO_CALLBACK_CPPTOC_H_
#define CEF_LIBCEF_DLL_CPPTOC_MEDIA_SINK_DEVICE_INFO_CALLBACK_CPPTOC_H_
#pragma once
#if !defined(WRAPPING_CEF_SHARED)
#error This file can be included wrapper-side only
#endif
#include "include/capi/cef_media_router_capi.h"
#include "include/cef_media_router.h"
#include "libcef_dll/cpptoc/cpptoc_ref_counted.h"
// Wrap a C++ class with a C structure.
// This class may be instantiated and accessed wrapper-side only.
class CefMediaSinkDeviceInfoCallbackCppToC
: public CefCppToCRefCounted<CefMediaSinkDeviceInfoCallbackCppToC,
CefMediaSinkDeviceInfoCallback,
cef_media_sink_device_info_callback_t> {
public:
CefMediaSinkDeviceInfoCallbackCppToC();
virtual ~CefMediaSinkDeviceInfoCallbackCppToC();
};
#endif // CEF_LIBCEF_DLL_CPPTOC_MEDIA_SINK_DEVICE_INFO_CALLBACK_CPPTOC_H_

View File

@ -9,10 +9,11 @@
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=6ffdd140e2cb688f1d7db2eb1e2356a62ac08e5e$
// $hash=8f3906cf08a292e81bf59629cf073c93cf388725$
//
#include "libcef_dll/ctocpp/media_sink_ctocpp.h"
#include "libcef_dll/cpptoc/media_sink_device_info_callback_cpptoc.h"
#include "libcef_dll/ctocpp/media_source_ctocpp.h"
#include "libcef_dll/shutdown_checker.h"
@ -89,6 +90,27 @@ CefMediaSink::IconType CefMediaSinkCToCpp::GetIconType() {
return _retval;
}
NO_SANITIZE("cfi-icall")
void CefMediaSinkCToCpp::GetDeviceInfo(
CefRefPtr<CefMediaSinkDeviceInfoCallback> callback) {
shutdown_checker::AssertNotShutdown();
cef_media_sink_t* _struct = GetStruct();
if (CEF_MEMBER_MISSING(_struct, get_device_info))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: callback; type: refptr_diff
DCHECK(callback.get());
if (!callback.get())
return;
// Execute
_struct->get_device_info(
_struct, CefMediaSinkDeviceInfoCallbackCppToC::Wrap(callback));
}
NO_SANITIZE("cfi-icall") bool CefMediaSinkCToCpp::IsCastSink() {
shutdown_checker::AssertNotShutdown();

View File

@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=9d3af9897a857a63abec8327f84f5d809be603da$
// $hash=d5ab2dbf52c45129296b1ee156ead2f1e3182db8$
//
#ifndef CEF_LIBCEF_DLL_CTOCPP_MEDIA_SINK_CTOCPP_H_
@ -38,6 +38,8 @@ class CefMediaSinkCToCpp : public CefCToCppRefCounted<CefMediaSinkCToCpp,
CefString GetName() OVERRIDE;
CefString GetDescription() OVERRIDE;
IconType GetIconType() OVERRIDE;
void GetDeviceInfo(
CefRefPtr<CefMediaSinkDeviceInfoCallback> callback) OVERRIDE;
bool IsCastSink() OVERRIDE;
bool IsDialSink() OVERRIDE;
bool IsCompatibleWith(CefRefPtr<CefMediaSource> source) OVERRIDE;

View File

@ -0,0 +1,60 @@
// Copyright (c) 2020 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.
//
// ---------------------------------------------------------------------------
//
// This file was generated by the CEF translator tool. If making changes by
// hand only do so within the body of existing method and function
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=c56362ea79609562dacc4bf8303f2bd920ddeada$
//
#include "libcef_dll/ctocpp/media_sink_device_info_callback_ctocpp.h"
#include "libcef_dll/shutdown_checker.h"
// VIRTUAL METHODS - Body may be edited by hand.
NO_SANITIZE("cfi-icall")
void CefMediaSinkDeviceInfoCallbackCToCpp::OnMediaSinkDeviceInfo(
const CefMediaSinkDeviceInfo& device_info) {
shutdown_checker::AssertNotShutdown();
cef_media_sink_device_info_callback_t* _struct = GetStruct();
if (CEF_MEMBER_MISSING(_struct, on_media_sink_device_info))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
_struct->on_media_sink_device_info(_struct, &device_info);
}
// CONSTRUCTOR - Do not edit by hand.
CefMediaSinkDeviceInfoCallbackCToCpp::CefMediaSinkDeviceInfoCallbackCToCpp() {}
// DESTRUCTOR - Do not edit by hand.
CefMediaSinkDeviceInfoCallbackCToCpp::~CefMediaSinkDeviceInfoCallbackCToCpp() {
shutdown_checker::AssertNotShutdown();
}
template <>
cef_media_sink_device_info_callback_t*
CefCToCppRefCounted<CefMediaSinkDeviceInfoCallbackCToCpp,
CefMediaSinkDeviceInfoCallback,
cef_media_sink_device_info_callback_t>::
UnwrapDerived(CefWrapperType type, CefMediaSinkDeviceInfoCallback* c) {
NOTREACHED() << "Unexpected class type: " << type;
return nullptr;
}
template <>
CefWrapperType
CefCToCppRefCounted<CefMediaSinkDeviceInfoCallbackCToCpp,
CefMediaSinkDeviceInfoCallback,
cef_media_sink_device_info_callback_t>::kWrapperType =
WT_MEDIA_SINK_DEVICE_INFO_CALLBACK;

View File

@ -0,0 +1,42 @@
// Copyright (c) 2020 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.
//
// ---------------------------------------------------------------------------
//
// This file was generated by the CEF translator tool. If making changes by
// hand only do so within the body of existing method and function
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=e48d0b8482168d355e04460ea6ea5b7662dbe4fd$
//
#ifndef CEF_LIBCEF_DLL_CTOCPP_MEDIA_SINK_DEVICE_INFO_CALLBACK_CTOCPP_H_
#define CEF_LIBCEF_DLL_CTOCPP_MEDIA_SINK_DEVICE_INFO_CALLBACK_CTOCPP_H_
#pragma once
#if !defined(BUILDING_CEF_SHARED)
#error This file can be included DLL-side only
#endif
#include "include/capi/cef_media_router_capi.h"
#include "include/cef_media_router.h"
#include "libcef_dll/ctocpp/ctocpp_ref_counted.h"
// Wrap a C structure with a C++ class.
// This class may be instantiated and accessed DLL-side only.
class CefMediaSinkDeviceInfoCallbackCToCpp
: public CefCToCppRefCounted<CefMediaSinkDeviceInfoCallbackCToCpp,
CefMediaSinkDeviceInfoCallback,
cef_media_sink_device_info_callback_t> {
public:
CefMediaSinkDeviceInfoCallbackCToCpp();
virtual ~CefMediaSinkDeviceInfoCallbackCToCpp();
// CefMediaSinkDeviceInfoCallback methods.
void OnMediaSinkDeviceInfo(
const CefMediaSinkDeviceInfo& device_info) override;
};
#endif // CEF_LIBCEF_DLL_CTOCPP_MEDIA_SINK_DEVICE_INFO_CALLBACK_CTOCPP_H_

View File

@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=20268db646dcf8aa6d54b2342dbc70a6e624e202$
// $hash=6e7cec57ce98a10f0b0668d47c9935639963c215$
//
#ifndef CEF_LIBCEF_DLL_WRAPPER_TYPES_H_
@ -80,6 +80,7 @@ enum CefWrapperType {
WT_MEDIA_ROUTE_CREATE_CALLBACK,
WT_MEDIA_ROUTER,
WT_MEDIA_SINK,
WT_MEDIA_SINK_DEVICE_INFO_CALLBACK,
WT_MEDIA_SOURCE,
WT_MENU_BUTTON,
WT_MENU_BUTTON_DELEGATE,

View File

@ -93,7 +93,12 @@ class MediaObserver : public CefMediaObserver {
MediaObserver(CefRefPtr<CefMediaRouter> media_router,
CefRefPtr<CallbackType> subscription_callback)
: media_router_(media_router),
subscription_callback_(subscription_callback) {}
subscription_callback_(subscription_callback),
next_sink_query_id_(0),
pending_sink_query_id_(-1),
pending_sink_callbacks_(0U) {}
~MediaObserver() OVERRIDE { ClearSinkInfoMap(); }
bool CreateRoute(const std::string& source_urn,
const std::string& sink_id,
@ -141,35 +146,62 @@ class MediaObserver : public CefMediaObserver {
}
protected:
class DeviceInfoCallback : public CefMediaSinkDeviceInfoCallback {
public:
// Callback to be executed when the device info is available.
typedef base::Callback<void(const std::string& sink_id,
const CefMediaSinkDeviceInfo& device_info)>
CallbackType;
DeviceInfoCallback(const std::string& sink_id, const CallbackType& callback)
: sink_id_(sink_id), callback_(callback) {}
void OnMediaSinkDeviceInfo(
const CefMediaSinkDeviceInfo& device_info) OVERRIDE {
CEF_REQUIRE_UI_THREAD();
callback_.Run(sink_id_, device_info);
callback_.Reset();
}
private:
const std::string sink_id_;
CallbackType callback_;
IMPLEMENT_REFCOUNTING(DeviceInfoCallback);
DISALLOW_COPY_AND_ASSIGN(DeviceInfoCallback);
};
// CefMediaObserver methods:
void OnSinks(const MediaSinkVector& sinks) OVERRIDE {
CEF_REQUIRE_UI_THREAD();
sink_map_.clear();
ClearSinkInfoMap();
CefRefPtr<CefDictionaryValue> payload = CefDictionaryValue::Create();
CefRefPtr<CefListValue> sinks_list = CefListValue::Create();
sinks_list->SetSize(sinks.size());
// Reset pending sink state.
pending_sink_callbacks_ = sinks.size();
pending_sink_query_id_ = ++next_sink_query_id_;
if (sinks.empty()) {
// No sinks, send the response immediately.
SendSinksResponse();
return;
}
DeviceInfoCallback::CallbackType callback = base::Bind(
&MediaObserver::OnSinkDeviceInfo, this, pending_sink_query_id_);
MediaSinkVector::const_iterator it = sinks.begin();
for (size_t idx = 0; it != sinks.end(); ++it, ++idx) {
CefRefPtr<CefMediaSink> sink = *it;
const std::string& sink_id = sink->GetId();
sink_map_.insert(std::make_pair(sink_id, sink));
SinkInfo* info = new SinkInfo;
info->sink = sink;
sink_info_map_.insert(std::make_pair(sink_id, info));
CefRefPtr<CefDictionaryValue> sink_dict = CefDictionaryValue::Create();
sink_dict->SetString("id", sink_id);
sink_dict->SetString("name", sink->GetName());
sink_dict->SetString("desc", sink->GetDescription());
sink_dict->SetInt("icon", sink->GetIconType());
sink_dict->SetString(
"type", sink->IsCastSink() ? "cast"
: sink->IsDialSink() ? "dial" : "unknown");
sinks_list->SetDictionary(idx, sink_dict);
// Request the device info asynchronously. Send the response once all
// callbacks have executed.
sink->GetDeviceInfo(new DeviceInfoCallback(sink_id, callback));
}
payload->SetList("sinks_list", sinks_list);
SendResponse("onSinks", payload);
}
void OnRoutes(const MediaRouteVector& routes) OVERRIDE {
@ -230,12 +262,39 @@ class MediaObserver : public CefMediaObserver {
}
CefRefPtr<CefMediaSink> GetSink(const std::string& sink_id) {
SinkMap::const_iterator it = sink_map_.find(sink_id);
if (it != sink_map_.end())
return it->second;
SinkInfoMap::const_iterator it = sink_info_map_.find(sink_id);
if (it != sink_info_map_.end())
return it->second->sink;
return NULL;
}
void ClearSinkInfoMap() {
SinkInfoMap::const_iterator it = sink_info_map_.begin();
for (; it != sink_info_map_.end(); ++it) {
delete it->second;
}
sink_info_map_.clear();
}
void OnSinkDeviceInfo(int sink_query_id,
const std::string& sink_id,
const CefMediaSinkDeviceInfo& device_info) {
// Discard callbacks that arrive after a new call to OnSinks().
if (sink_query_id != pending_sink_query_id_)
return;
SinkInfoMap::const_iterator it = sink_info_map_.find(sink_id);
if (it != sink_info_map_.end()) {
it->second->device_info = device_info;
}
// Send the response once we've received all expected callbacks.
DCHECK_GT(pending_sink_callbacks_, 0U);
if (--pending_sink_callbacks_ == 0U) {
SendSinksResponse();
}
}
CefRefPtr<CefMediaRoute> GetRoute(const std::string& route_id) {
RouteMap::const_iterator it = route_map_.find(route_id);
if (it != route_map_.end())
@ -251,12 +310,55 @@ class MediaObserver : public CefMediaObserver {
SendSuccess(subscription_callback_, result);
}
void SendSinksResponse() {
CefRefPtr<CefDictionaryValue> payload = CefDictionaryValue::Create();
CefRefPtr<CefListValue> sinks_list = CefListValue::Create();
sinks_list->SetSize(sink_info_map_.size());
SinkInfoMap::const_iterator it = sink_info_map_.begin();
for (size_t idx = 0; it != sink_info_map_.end(); ++it, ++idx) {
const SinkInfo* info = it->second;
CefRefPtr<CefDictionaryValue> sink_dict = CefDictionaryValue::Create();
sink_dict->SetString("id", it->first);
sink_dict->SetString("name", info->sink->GetName());
sink_dict->SetString("desc", info->sink->GetDescription());
sink_dict->SetInt("icon", info->sink->GetIconType());
sink_dict->SetString("ip_address",
CefString(&info->device_info.ip_address));
sink_dict->SetInt("port", info->device_info.port);
sink_dict->SetString("model_name",
CefString(&info->device_info.model_name));
sink_dict->SetString("type",
info->sink->IsCastSink()
? "cast"
: info->sink->IsDialSink() ? "dial" : "unknown");
sinks_list->SetDictionary(idx, sink_dict);
}
payload->SetList("sinks_list", sinks_list);
SendResponse("onSinks", payload);
}
CefRefPtr<CefMediaRouter> media_router_;
CefRefPtr<CallbackType> subscription_callback_;
typedef std::map<std::string, CefRefPtr<CefMediaSink>> SinkMap;
SinkMap sink_map_;
struct SinkInfo {
CefRefPtr<CefMediaSink> sink;
CefMediaSinkDeviceInfo device_info;
};
typedef std::map<std::string, SinkInfo*> SinkInfoMap;
// Used to uniquely identify a call to OnSinks(), for the purpose of
// associating OnMediaSinkDeviceInfo() callbacks.
int next_sink_query_id_;
// State from the most recent call to OnSinks().
SinkInfoMap sink_info_map_;
int pending_sink_query_id_;
size_t pending_sink_callbacks_;
// State from the most recent call to OnRoutes().
typedef std::map<std::string, CefRefPtr<CefMediaRoute>> RouteMap;
RouteMap route_map_;

View File

@ -42,7 +42,7 @@ input, select, textarea, button {
}
.route_controls .control {
width: 400px;
width: 500px;
}
.messages {
@ -276,7 +276,8 @@ function updateSinks(sinks) {
if (oldValues.includes(sink.id))
continue;
var opt = document.createElement('option');
opt.innerHTML = sink.name + ' (' + sink.type + ', ' + getIconTypeLabel(sink.icon) + ')';
opt.innerHTML = sink.name + ' (' + sink.model_name + ', ' + sink.type + ', ' +
getIconTypeLabel(sink.icon) + ', ' + sink.ip_address + ':' + sink.port + ')';
opt.value = sink.id;
sinksSelect.appendChild(opt);
}