Add support for media device discovery and messaging (fixes issue #2900)

Chromium supports communication with media devices on the local network via
the Cast and DIAL protocols. This takes two primary forms:

1. Messaging, where strings representing state information are passed between
   the client and a dedicated receiver app on the media device. The receiver
   app communicates directly with an app-specific backend service to retrieve
   and possibly control media playback.
2. Tab/desktop mirroring, where the media contents are streamed directly from
   the browser to a generic streaming app on the media device and playback is
   controlled by the browser.

This change adds support for device discovery and messaging (but not
mirroring) with functionality exposed via the new CefMediaRouter interface.

To test: Navigate to http://tests/media_router in cefclient and follow the
on-screen instructions.
This commit is contained in:
Marshall Greenblatt 2020-03-19 11:34:15 -04:00
parent fecd582035
commit 03fd5b15da
69 changed files with 5402 additions and 33 deletions

View File

@ -473,6 +473,16 @@ static_library("libcef_static") {
"libcef/browser/javascript_dialog_manager.h",
"libcef/browser/media_capture_devices_dispatcher.cc",
"libcef/browser/media_capture_devices_dispatcher.h",
"libcef/browser/media_router/media_route_impl.cc",
"libcef/browser/media_router/media_route_impl.h",
"libcef/browser/media_router/media_router_impl.cc",
"libcef/browser/media_router/media_router_impl.h",
"libcef/browser/media_router/media_router_manager.cc",
"libcef/browser/media_router/media_router_manager.h",
"libcef/browser/media_router/media_sink_impl.cc",
"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/menu_manager.cc",
"libcef/browser/menu_manager.h",
"libcef/browser/menu_model_impl.cc",

View File

@ -8,7 +8,7 @@
# by hand. See the translator.README.txt file in the tools directory for
# more information.
#
# $hash=98198bc4243deb46c848735f0d5499aa4891e535$
# $hash=578c0aef11c3c7840679e480069fc9031c628e25$
#
{
@ -43,6 +43,7 @@
'include/cef_keyboard_handler.h',
'include/cef_life_span_handler.h',
'include/cef_load_handler.h',
'include/cef_media_router.h',
'include/cef_menu_model.h',
'include/cef_menu_model_delegate.h',
'include/cef_navigation_entry.h',
@ -53,6 +54,7 @@
'include/cef_print_settings.h',
'include/cef_process_message.h',
'include/cef_process_util.h',
'include/cef_registration.h',
'include/cef_render_handler.h',
'include/cef_render_process_handler.h',
'include/cef_request.h',
@ -136,6 +138,7 @@
'include/capi/cef_keyboard_handler_capi.h',
'include/capi/cef_life_span_handler_capi.h',
'include/capi/cef_load_handler_capi.h',
'include/capi/cef_media_router_capi.h',
'include/capi/cef_menu_model_capi.h',
'include/capi/cef_menu_model_delegate_capi.h',
'include/capi/cef_navigation_entry_capi.h',
@ -146,6 +149,7 @@
'include/capi/cef_print_settings_capi.h',
'include/capi/cef_process_message_capi.h',
'include/capi/cef_process_util_capi.h',
'include/capi/cef_registration_capi.h',
'include/capi/cef_render_handler_capi.h',
'include/capi/cef_render_process_handler_capi.h',
'include/capi/cef_request_capi.h',
@ -308,6 +312,18 @@
'libcef_dll/cpptoc/list_value_cpptoc.h',
'libcef_dll/ctocpp/load_handler_ctocpp.cc',
'libcef_dll/ctocpp/load_handler_ctocpp.h',
'libcef_dll/ctocpp/media_observer_ctocpp.cc',
'libcef_dll/ctocpp/media_observer_ctocpp.h',
'libcef_dll/cpptoc/media_route_cpptoc.cc',
'libcef_dll/cpptoc/media_route_cpptoc.h',
'libcef_dll/ctocpp/media_route_create_callback_ctocpp.cc',
'libcef_dll/ctocpp/media_route_create_callback_ctocpp.h',
'libcef_dll/cpptoc/media_router_cpptoc.cc',
'libcef_dll/cpptoc/media_router_cpptoc.h',
'libcef_dll/cpptoc/media_sink_cpptoc.cc',
'libcef_dll/cpptoc/media_sink_cpptoc.h',
'libcef_dll/cpptoc/media_source_cpptoc.cc',
'libcef_dll/cpptoc/media_source_cpptoc.h',
'libcef_dll/cpptoc/views/menu_button_cpptoc.cc',
'libcef_dll/cpptoc/views/menu_button_cpptoc.h',
'libcef_dll/ctocpp/views/menu_button_delegate_ctocpp.cc',
@ -346,6 +362,8 @@
'libcef_dll/ctocpp/read_handler_ctocpp.h',
'libcef_dll/ctocpp/register_cdm_callback_ctocpp.cc',
'libcef_dll/ctocpp/register_cdm_callback_ctocpp.h',
'libcef_dll/cpptoc/registration_cpptoc.cc',
'libcef_dll/cpptoc/registration_cpptoc.h',
'libcef_dll/ctocpp/render_handler_ctocpp.cc',
'libcef_dll/ctocpp/render_handler_ctocpp.h',
'libcef_dll/ctocpp/render_process_handler_ctocpp.cc',
@ -598,6 +616,18 @@
'libcef_dll/ctocpp/list_value_ctocpp.h',
'libcef_dll/cpptoc/load_handler_cpptoc.cc',
'libcef_dll/cpptoc/load_handler_cpptoc.h',
'libcef_dll/cpptoc/media_observer_cpptoc.cc',
'libcef_dll/cpptoc/media_observer_cpptoc.h',
'libcef_dll/ctocpp/media_route_ctocpp.cc',
'libcef_dll/ctocpp/media_route_ctocpp.h',
'libcef_dll/cpptoc/media_route_create_callback_cpptoc.cc',
'libcef_dll/cpptoc/media_route_create_callback_cpptoc.h',
'libcef_dll/ctocpp/media_router_ctocpp.cc',
'libcef_dll/ctocpp/media_router_ctocpp.h',
'libcef_dll/ctocpp/media_sink_ctocpp.cc',
'libcef_dll/ctocpp/media_sink_ctocpp.h',
'libcef_dll/ctocpp/media_source_ctocpp.cc',
'libcef_dll/ctocpp/media_source_ctocpp.h',
'libcef_dll/ctocpp/views/menu_button_ctocpp.cc',
'libcef_dll/ctocpp/views/menu_button_ctocpp.h',
'libcef_dll/cpptoc/views/menu_button_delegate_cpptoc.cc',
@ -636,6 +666,8 @@
'libcef_dll/cpptoc/read_handler_cpptoc.h',
'libcef_dll/cpptoc/register_cdm_callback_cpptoc.cc',
'libcef_dll/cpptoc/register_cdm_callback_cpptoc.h',
'libcef_dll/ctocpp/registration_ctocpp.cc',
'libcef_dll/ctocpp/registration_ctocpp.h',
'libcef_dll/cpptoc/render_handler_cpptoc.cc',
'libcef_dll/cpptoc/render_handler_cpptoc.h',
'libcef_dll/cpptoc/render_process_handler_cpptoc.cc',

View File

@ -238,6 +238,8 @@
'tests/cefclient/browser/main_context.h',
'tests/cefclient/browser/main_context_impl.cc',
'tests/cefclient/browser/main_context_impl.h',
'tests/cefclient/browser/media_router_test.cc',
'tests/cefclient/browser/media_router_test.h',
'tests/cefclient/browser/osr_dragdrop_events.h',
'tests/cefclient/browser/osr_renderer.h',
'tests/cefclient/browser/osr_renderer.cc',
@ -287,6 +289,7 @@
'tests/cefclient/resources/drm.html',
'tests/cefclient/resources/localstorage.html',
'tests/cefclient/resources/logo.png',
'tests/cefclient/resources/media_router.html',
'tests/cefclient/resources/menu_icon.1x.png',
'tests/cefclient/resources/menu_icon.2x.png',
'tests/cefclient/resources/other_tests.html',

View File

@ -0,0 +1,322 @@
// Copyright (c) 2020 Marshall A. Greenblatt. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the name Chromium Embedded
// Framework nor the names of its contributors may be used to endorse
// or promote products derived from this software without specific prior
// written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// ---------------------------------------------------------------------------
//
// This file was generated by the CEF translator tool and should not edited
// by hand. See the translator.README.txt file in the tools directory for
// more information.
//
// $hash=a7070419332ec8f6d6e4df898c8eb666b988970a$
//
#ifndef CEF_INCLUDE_CAPI_CEF_MEDIA_ROUTER_CAPI_H_
#define CEF_INCLUDE_CAPI_CEF_MEDIA_ROUTER_CAPI_H_
#pragma once
#include "include/capi/cef_base_capi.h"
#include "include/capi/cef_registration_capi.h"
#ifdef __cplusplus
extern "C" {
#endif
struct _cef_media_observer_t;
struct _cef_media_route_create_callback_t;
struct _cef_media_route_t;
struct _cef_media_sink_t;
struct _cef_media_source_t;
///
// Supports discovery of and communication with media devices on the local
// network via the Cast and DIAL protocols. The functions of this structure may
// be called on any browser process thread unless otherwise indicated.
///
typedef struct _cef_media_router_t {
///
// Base structure.
///
cef_base_ref_counted_t base;
///
// Add an observer for MediaRouter events. The observer will remain registered
// until the returned Registration object is destroyed.
///
struct _cef_registration_t*(CEF_CALLBACK* add_observer)(
struct _cef_media_router_t* self,
struct _cef_media_observer_t* observer);
///
// Returns a MediaSource object for the specified media source URN. Supported
// URN schemes include "cast:" and "dial:", and will be already known by the
// client application (e.g. "cast:<appId>?clientId=<clientId>").
///
struct _cef_media_source_t*(CEF_CALLBACK* get_source)(
struct _cef_media_router_t* self,
const cef_string_t* urn);
///
// Trigger an asynchronous call to cef_media_observer_t::OnSinks on all
// registered observers.
///
void(CEF_CALLBACK* notify_current_sinks)(struct _cef_media_router_t* self);
///
// Create a new route between |source| and |sink|. Source and sink must be
// valid, compatible (as reported by cef_media_sink_t::IsCompatibleWith), and
// a route between them must not already exist. |callback| will be executed on
// success or failure. If route creation succeeds it will also trigger an
// asynchronous call to cef_media_observer_t::OnRoutes on all registered
// observers.
///
void(CEF_CALLBACK* create_route)(
struct _cef_media_router_t* self,
struct _cef_media_source_t* source,
struct _cef_media_sink_t* sink,
struct _cef_media_route_create_callback_t* callback);
///
// Trigger an asynchronous call to cef_media_observer_t::OnRoutes on all
// registered observers.
///
void(CEF_CALLBACK* notify_current_routes)(struct _cef_media_router_t* self);
} cef_media_router_t;
///
// Returns the MediaRouter object associated with the global request context.
// Equivalent to calling cef_request_context_t::cef_request_context_get_global_c
// ontext()->get_media_router().
///
CEF_EXPORT cef_media_router_t* cef_media_router_get_global();
///
// Implemented by the client to observe MediaRouter events and registered via
// cef_media_router_t::AddObserver. The functions of this structure will be
// called on the browser process UI thread.
///
typedef struct _cef_media_observer_t {
///
// Base structure.
///
cef_base_ref_counted_t base;
///
// The list of available media sinks has changed or
// cef_media_router_t::NotifyCurrentSinks was called.
///
void(CEF_CALLBACK* on_sinks)(struct _cef_media_observer_t* self,
size_t sinksCount,
struct _cef_media_sink_t* const* sinks);
///
// The list of available media routes has changed or
// cef_media_router_t::NotifyCurrentRoutes was called.
///
void(CEF_CALLBACK* on_routes)(struct _cef_media_observer_t* self,
size_t routesCount,
struct _cef_media_route_t* const* routes);
///
// The connection state of |route| has changed.
///
void(CEF_CALLBACK* on_route_state_changed)(
struct _cef_media_observer_t* self,
struct _cef_media_route_t* route,
cef_media_route_connection_state_t state);
///
// A message was recieved over |route|. |message| is only valid for the scope
// of this callback and should be copied if necessary.
///
void(CEF_CALLBACK* on_route_message_received)(
struct _cef_media_observer_t* self,
struct _cef_media_route_t* route,
const void* message,
size_t message_size);
} cef_media_observer_t;
///
// Represents the route between a media source and sink. Instances of this
// object are created via cef_media_router_t::CreateRoute and retrieved via
// cef_media_observer_t::OnRoutes. Contains the status and metadata of a routing
// operation. The functions of this structure may be called on any browser
// process thread unless otherwise indicated.
///
typedef struct _cef_media_route_t {
///
// Base structure.
///
cef_base_ref_counted_t base;
///
// Returns the ID for this route.
///
// The resulting string must be freed by calling cef_string_userfree_free().
cef_string_userfree_t(CEF_CALLBACK* get_id)(struct _cef_media_route_t* self);
///
// Returns the source associated with this route.
///
struct _cef_media_source_t*(CEF_CALLBACK* get_source)(
struct _cef_media_route_t* self);
///
// Returns the sink associated with this route.
///
struct _cef_media_sink_t*(CEF_CALLBACK* get_sink)(
struct _cef_media_route_t* self);
///
// Send a message over this route. |message| will be copied if necessary.
///
void(CEF_CALLBACK* send_route_message)(struct _cef_media_route_t* self,
const void* message,
size_t message_size);
///
// Terminate this route. Will result in an asynchronous call to
// cef_media_observer_t::OnRoutes on all registered observers.
///
void(CEF_CALLBACK* terminate)(struct _cef_media_route_t* self);
} cef_media_route_t;
///
// Callback structure for cef_media_router_t::CreateRoute. The functions of this
// structure will be called on the browser process UI thread.
///
typedef struct _cef_media_route_create_callback_t {
///
// Base structure.
///
cef_base_ref_counted_t base;
///
// Method that will be executed when the route creation has finished. |result|
// will be CEF_MRCR_OK if the route creation succeeded. |error| will be a
// description of the error if the route creation failed. |route| is the
// resulting route, or NULL if the route creation failed.
///
void(CEF_CALLBACK* on_media_route_create_finished)(
struct _cef_media_route_create_callback_t* self,
cef_media_route_create_result_t result,
const cef_string_t* error,
struct _cef_media_route_t* route);
} cef_media_route_create_callback_t;
///
// Represents a sink to which media can be routed. Instances of this object are
// retrieved via cef_media_observer_t::OnSinks. The functions of this structure
// may be called on any browser process thread unless otherwise indicated.
///
typedef struct _cef_media_sink_t {
///
// Base structure.
///
cef_base_ref_counted_t base;
///
// Returns the ID for this sink.
///
// The resulting string must be freed by calling cef_string_userfree_free().
cef_string_userfree_t(CEF_CALLBACK* get_id)(struct _cef_media_sink_t* self);
///
// Returns true (1) if this sink is valid.
///
int(CEF_CALLBACK* is_valid)(struct _cef_media_sink_t* self);
///
// Returns the name of this sink.
///
// The resulting string must be freed by calling cef_string_userfree_free().
cef_string_userfree_t(CEF_CALLBACK* get_name)(struct _cef_media_sink_t* self);
///
// Returns the description of this sink.
///
// The resulting string must be freed by calling cef_string_userfree_free().
cef_string_userfree_t(CEF_CALLBACK* get_description)(
struct _cef_media_sink_t* self);
///
// Returns true (1) if this sink accepts content via Cast.
///
int(CEF_CALLBACK* is_cast_sink)(struct _cef_media_sink_t* self);
///
// Returns true (1) if this sink accepts content via DIAL.
///
int(CEF_CALLBACK* is_dial_sink)(struct _cef_media_sink_t* self);
///
// Returns true (1) if this sink is compatible with |source|.
///
int(CEF_CALLBACK* is_compatible_with)(struct _cef_media_sink_t* self,
struct _cef_media_source_t* source);
} cef_media_sink_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
// structure may be called on any browser process thread unless otherwise
// indicated.
///
typedef struct _cef_media_source_t {
///
// Base structure.
///
cef_base_ref_counted_t base;
///
// Returns the ID (media source URN or URL) for this source.
///
// The resulting string must be freed by calling cef_string_userfree_free().
cef_string_userfree_t(CEF_CALLBACK* get_id)(struct _cef_media_source_t* self);
///
// Returns true (1) if this source is valid.
///
int(CEF_CALLBACK* is_valid)(struct _cef_media_source_t* self);
///
// Returns true (1) if this source outputs its content via Cast.
///
int(CEF_CALLBACK* is_cast_source)(struct _cef_media_source_t* self);
///
// Returns true (1) if this source outputs its content via DIAL.
///
int(CEF_CALLBACK* is_dial_source)(struct _cef_media_source_t* self);
} cef_media_source_t;
#ifdef __cplusplus
}
#endif
#endif // CEF_INCLUDE_CAPI_CEF_MEDIA_ROUTER_CAPI_H_

View File

@ -0,0 +1,63 @@
// Copyright (c) 2020 Marshall A. Greenblatt. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the name Chromium Embedded
// Framework nor the names of its contributors may be used to endorse
// or promote products derived from this software without specific prior
// written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// ---------------------------------------------------------------------------
//
// This file was generated by the CEF translator tool and should not edited
// by hand. See the translator.README.txt file in the tools directory for
// more information.
//
// $hash=029e237cf80f94a25453bac5a9b1e0765bb56f37$
//
#ifndef CEF_INCLUDE_CAPI_CEF_REGISTRATION_CAPI_H_
#define CEF_INCLUDE_CAPI_CEF_REGISTRATION_CAPI_H_
#pragma once
#include "include/capi/cef_base_capi.h"
#ifdef __cplusplus
extern "C" {
#endif
///
// Generic callback structure used for managing the lifespan of a registration.
///
typedef struct _cef_registration_t {
///
// Base structure.
///
cef_base_ref_counted_t base;
} cef_registration_t;
#ifdef __cplusplus
}
#endif
#endif // CEF_INCLUDE_CAPI_CEF_REGISTRATION_CAPI_H_

View File

@ -33,7 +33,7 @@
// by hand. See the translator.README.txt file in the tools directory for
// more information.
//
// $hash=2b01472d9b9a8cc9d1b2e669c91c2849bdb162e9$
// $hash=7ce0953f069204a4dd2037c4a05ac9454c5e66a6$
//
#ifndef CEF_INCLUDE_CAPI_CEF_REQUEST_CONTEXT_CAPI_H_
@ -44,6 +44,7 @@
#include "include/capi/cef_cookie_capi.h"
#include "include/capi/cef_extension_capi.h"
#include "include/capi/cef_extension_handler_capi.h"
#include "include/capi/cef_media_router_capi.h"
#include "include/capi/cef_values_capi.h"
#ifdef __cplusplus
@ -353,6 +354,12 @@ typedef struct _cef_request_context_t {
struct _cef_extension_t*(CEF_CALLBACK* get_extension)(
struct _cef_request_context_t* self,
const cef_string_t* extension_id);
///
// Returns the MediaRouter object associated with this context.
///
struct _cef_media_router_t*(CEF_CALLBACK* get_media_router)(
struct _cef_request_context_t* self);
} cef_request_context_t;
///

View File

@ -34,7 +34,7 @@
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=da85b3ecfdc813ae487499df87d048a5f8031538$
// $hash=af15b08731cc133c3974ceb18002b146a53b9c9e$
//
#ifndef CEF_INCLUDE_API_HASH_H_
@ -47,13 +47,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 "736999b199a558cb5a5a37309bda51a45f9c2549"
#define CEF_API_HASH_UNIVERSAL "f76dc8c40e454ef26318d0f83312dadaf909e4c5"
#if defined(OS_WIN)
#define CEF_API_HASH_PLATFORM "e5eac77b557780b50862f5a770d20f3fd6a4c98f"
#define CEF_API_HASH_PLATFORM "831ef33853bb8575bcd097ba65851d4d98a08db8"
#elif defined(OS_MACOSX)
#define CEF_API_HASH_PLATFORM "2fde0819a2ff07f996c6d996ae54c6181549a122"
#define CEF_API_HASH_PLATFORM "0944363458590a23d84e99eb1b81372be6784b97"
#elif defined(OS_LINUX)
#define CEF_API_HASH_PLATFORM "b1a576d94b3c3e398f1fe7dadfe4442f195d7028"
#define CEF_API_HASH_PLATFORM "dfd012193a93782cd4b041f4cd71e1e8f2ca401e"
#endif
#ifdef __cplusplus

300
include/cef_media_router.h Normal file
View File

@ -0,0 +1,300 @@
// Copyright (c) 2020 Marshall A. Greenblatt. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the name Chromium Embedded
// Framework nor the names of its contributors may be used to endorse
// or promote products derived from this software without specific prior
// written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// ---------------------------------------------------------------------------
//
// The contents of this file must follow a specific format in order to
// support the CEF translator tool. See the translator.README.txt file in the
// tools directory for more information.
//
#ifndef CEF_INCLUDE_CEF_MEDIA_ROUTER_H_
#define CEF_INCLUDE_CEF_MEDIA_ROUTER_H_
#pragma once
#include <vector>
#include "include/cef_base.h"
#include "include/cef_registration.h"
class CefMediaObserver;
class CefMediaRoute;
class CefMediaRouteCreateCallback;
class CefMediaSink;
class CefMediaSource;
///
// Supports discovery of and communication with media devices on the local
// network via the Cast and DIAL protocols. The methods of this class may be
// called on any browser process thread unless otherwise indicated.
///
/*--cef(source=library)--*/
class CefMediaRouter : public virtual CefBaseRefCounted {
public:
///
// Returns the MediaRouter object associated with the global request context.
// Equivalent to calling
// CefRequestContext::GetGlobalContext()->GetMediaRouter().
///
/*--cef()--*/
static CefRefPtr<CefMediaRouter> GetGlobalMediaRouter();
///
// Add an observer for MediaRouter events. The observer will remain registered
// until the returned Registration object is destroyed.
///
/*--cef()--*/
virtual CefRefPtr<CefRegistration> AddObserver(
CefRefPtr<CefMediaObserver> observer) = 0;
///
// Returns a MediaSource object for the specified media source URN. Supported
// URN schemes include "cast:" and "dial:", and will be already known by the
// client application (e.g. "cast:<appId>?clientId=<clientId>").
///
/*--cef()--*/
virtual CefRefPtr<CefMediaSource> GetSource(const CefString& urn) = 0;
///
// Trigger an asynchronous call to CefMediaObserver::OnSinks on all
// registered observers.
///
/*--cef()--*/
virtual void NotifyCurrentSinks() = 0;
///
// Create a new route between |source| and |sink|. Source and sink must be
// valid, compatible (as reported by CefMediaSink::IsCompatibleWith), and a
// route between them must not already exist. |callback| will be executed
// on success or failure. If route creation succeeds it will also trigger an
// asynchronous call to CefMediaObserver::OnRoutes on all registered
// observers.
///
/*--cef()--*/
virtual void CreateRoute(CefRefPtr<CefMediaSource> source,
CefRefPtr<CefMediaSink> sink,
CefRefPtr<CefMediaRouteCreateCallback> callback) = 0;
///
// Trigger an asynchronous call to CefMediaObserver::OnRoutes on all
// registered observers.
///
/*--cef()--*/
virtual void NotifyCurrentRoutes() = 0;
};
///
// Implemented by the client to observe MediaRouter events and registered via
// CefMediaRouter::AddObserver. The methods of this class will be called on the
// browser process UI thread.
///
/*--cef(source=client)--*/
class CefMediaObserver : public virtual CefBaseRefCounted {
public:
typedef cef_media_route_connection_state_t ConnectionState;
///
// The list of available media sinks has changed or
// CefMediaRouter::NotifyCurrentSinks was called.
///
/*--cef()--*/
virtual void OnSinks(const std::vector<CefRefPtr<CefMediaSink>>& sinks) = 0;
///
// The list of available media routes has changed or
// CefMediaRouter::NotifyCurrentRoutes was called.
///
/*--cef()--*/
virtual void OnRoutes(
const std::vector<CefRefPtr<CefMediaRoute>>& routes) = 0;
///
// The connection state of |route| has changed.
///
/*--cef()--*/
virtual void OnRouteStateChanged(CefRefPtr<CefMediaRoute> route,
ConnectionState state) = 0;
///
// A message was recieved over |route|. |message| is only valid for
// the scope of this callback and should be copied if necessary.
///
/*--cef()--*/
virtual void OnRouteMessageReceived(CefRefPtr<CefMediaRoute> route,
const void* message,
size_t message_size) = 0;
};
///
// Represents the route between a media source and sink. Instances of this
// object are created via CefMediaRouter::CreateRoute and retrieved via
// CefMediaObserver::OnRoutes. Contains the status and metadata of a
// routing operation. The methods of this class may be called on any browser
// process thread unless otherwise indicated.
///
/*--cef(source=library)--*/
class CefMediaRoute : public virtual CefBaseRefCounted {
public:
///
// Returns the ID for this route.
///
/*--cef()--*/
virtual CefString GetId() = 0;
///
// Returns the source associated with this route.
///
/*--cef()--*/
virtual CefRefPtr<CefMediaSource> GetSource() = 0;
///
// Returns the sink associated with this route.
///
/*--cef()--*/
virtual CefRefPtr<CefMediaSink> GetSink() = 0;
///
// Send a message over this route. |message| will be copied if necessary.
///
/*--cef()--*/
virtual void SendRouteMessage(const void* message, size_t message_size) = 0;
///
// Terminate this route. Will result in an asynchronous call to
// CefMediaObserver::OnRoutes on all registered observers.
///
/*--cef()--*/
virtual void Terminate() = 0;
};
///
// Callback interface for CefMediaRouter::CreateRoute. The methods of this
// class will be called on the browser process UI thread.
///
/*--cef(source=client)--*/
class CefMediaRouteCreateCallback : public virtual CefBaseRefCounted {
public:
typedef cef_media_route_create_result_t RouteCreateResult;
///
// Method that will be executed when the route creation has finished. |result|
// will be CEF_MRCR_OK if the route creation succeeded. |error| will be a
// description of the error if the route creation failed. |route| is the
// resulting route, or empty if the route creation failed.
///
/*--cef(optional_param=error,optional_param=route)--*/
virtual void OnMediaRouteCreateFinished(RouteCreateResult result,
const CefString& error,
CefRefPtr<CefMediaRoute> route) = 0;
};
///
// Represents a sink to which media can be routed. Instances of this object are
// retrieved via CefMediaObserver::OnSinks. The methods of this class may
// be called on any browser process thread unless otherwise indicated.
///
/*--cef(source=library)--*/
class CefMediaSink : public virtual CefBaseRefCounted {
public:
///
// Returns the ID for this sink.
///
/*--cef()--*/
virtual CefString GetId() = 0;
///
// Returns true if this sink is valid.
///
/*--cef()--*/
virtual bool IsValid() = 0;
///
// Returns the name of this sink.
///
/*--cef()--*/
virtual CefString GetName() = 0;
///
// Returns the description of this sink.
///
/*--cef()--*/
virtual CefString GetDescription() = 0;
///
// Returns true if this sink accepts content via Cast.
///
/*--cef()--*/
virtual bool IsCastSink() = 0;
///
// Returns true if this sink accepts content via DIAL.
///
/*--cef()--*/
virtual bool IsDialSink() = 0;
///
// Returns true if this sink is compatible with |source|.
///
/*--cef()--*/
virtual bool IsCompatibleWith(CefRefPtr<CefMediaSource> source) = 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
// called on any browser process thread unless otherwise indicated.
///
/*--cef(source=library)--*/
class CefMediaSource : public virtual CefBaseRefCounted {
public:
///
// Returns the ID (media source URN or URL) for this source.
///
/*--cef()--*/
virtual CefString GetId() = 0;
///
// Returns true if this source is valid.
///
/*--cef()--*/
virtual bool IsValid() = 0;
///
// Returns true if this source outputs its content via Cast.
///
/*--cef()--*/
virtual bool IsCastSource() = 0;
///
// Returns true if this source outputs its content via DIAL.
///
/*--cef()--*/
virtual bool IsDialSource() = 0;
};
#endif // CEF_INCLUDE_CEF_MEDIA_ROUTER_H_

View File

@ -0,0 +1,49 @@
// Copyright (c) 2020 Marshall A. Greenblatt. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the name Chromium Embedded
// Framework nor the names of its contributors may be used to endorse
// or promote products derived from this software without specific prior
// written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// ---------------------------------------------------------------------------
//
// The contents of this file must follow a specific format in order to
// support the CEF translator tool. See the translator.README.txt file in the
// tools directory for more information.
//
#ifndef CEF_INCLUDE_CEF_REGISTRATION_H_
#define CEF_INCLUDE_CEF_REGISTRATION_H_
#pragma once
#include "include/cef_base.h"
///
// Generic callback interface used for managing the lifespan of a registration.
///
/*--cef(source=library)--*/
class CefRegistration : public virtual CefBaseRefCounted {};
#endif // CEF_INCLUDE_CEF_REGISTRATION_H_

View File

@ -44,6 +44,7 @@
#include "include/cef_cookie.h"
#include "include/cef_extension.h"
#include "include/cef_extension_handler.h"
#include "include/cef_media_router.h"
#include "include/cef_values.h"
class CefRequestContextHandler;
@ -361,6 +362,12 @@ class CefRequestContext : public virtual CefBaseRefCounted {
/*--cef()--*/
virtual CefRefPtr<CefExtension> GetExtension(
const CefString& extension_id) = 0;
///
// Returns the MediaRouter object associated with this context.
///
/*--cef()--*/
virtual CefRefPtr<CefMediaRouter> GetMediaRouter() = 0;
};
#endif // CEF_INCLUDE_CEF_REQUEST_CONTEXT_H_

View File

@ -2973,6 +2973,36 @@ typedef struct _cef_composition_underline_t {
cef_composition_underline_style_t style;
} cef_composition_underline_t;
///
// Result codes for CefMediaRouter::CreateRoute. These constants match
// their equivalents in Chromium's route_request_result.h and should not be
// renumbered.
///
typedef enum {
CEF_MRCR_UNKNOWN_ERROR = 0,
CEF_MRCR_OK = 1,
CEF_MRCR_TIMED_OUT = 2,
CEF_MRCR_ROUTE_NOT_FOUND = 3,
CEF_MRCR_SINK_NOT_FOUND = 4,
CEF_MRCR_INVALID_ORIGIN = 5,
CEF_MRCR_NO_SUPPORTED_PROVIDER = 7,
CEF_MRCR_CANCELLED = 8,
CEF_MRCR_ROUTE_ALREADY_EXISTS = 9,
CEF_MRCR_TOTAL_COUNT = 11 // The total number of values.
} cef_media_route_create_result_t;
///
// Connection state for a MediaRoute object.
///
typedef enum {
CEF_MRCS_UNKNOWN,
CEF_MRCS_CONNECTING,
CEF_MRCS_CONNECTED,
CEF_MRCS_CLOSED,
CEF_MRCS_TERMINATED,
} cef_media_route_connection_state_t;
#ifdef __cplusplus
}
#endif

View File

@ -11,6 +11,7 @@
#include "libcef/browser/context.h"
#include "libcef/browser/download_manager_delegate.h"
#include "libcef/browser/extensions/extension_system.h"
#include "libcef/browser/media_router/media_router_manager.h"
#include "libcef/browser/prefs/browser_prefs.h"
#include "libcef/browser/request_context_impl.h"
#include "libcef/browser/ssl_host_state_delegate.h"
@ -164,6 +165,11 @@ base::LazyInstance<ImplManager>::DestructorAtExit g_manager =
base::LazyInstance<ImplManager>::Leaky g_manager = LAZY_INSTANCE_INITIALIZER;
#endif
CefBrowserContext* GetSelf(base::WeakPtr<CefBrowserContext> self) {
CEF_REQUIRE_UIT();
return self.get();
}
} // namespace
// Creates and manages VisitedLinkEventListener objects for each
@ -220,8 +226,9 @@ class CefVisitedLinkListener : public visitedlink::VisitedLinkWriter::Listener {
};
CefBrowserContext::CefBrowserContext(const CefRequestContextSettings& settings)
: settings_(settings) {
: settings_(settings), weak_ptr_factory_(this) {
g_manager.Get().AddImpl(this);
getter_ = base::BindRepeating(GetSelf, weak_ptr_factory_.GetWeakPtr());
}
CefBrowserContext::~CefBrowserContext() {
@ -233,6 +240,9 @@ CefBrowserContext::~CefBrowserContext() {
// Unregister the context first to avoid re-entrancy during shutdown.
g_manager.Get().RemoveImpl(this, cache_path_);
// Destroy objects that may hold references to the MediaRouter.
media_router_manager_.reset();
// Send notifications to clean up objects associated with this Profile.
MaybeSendDestroyedNotification();
@ -812,3 +822,11 @@ bool CefBrowserContext::IsPrintPreviewSupported() const {
return !GetPrefs()->GetBoolean(prefs::kPrintPreviewDisabled);
}
CefMediaRouterManager* CefBrowserContext::GetMediaRouterManager() {
CEF_REQUIRE_UIT();
if (!media_router_manager_) {
media_router_manager_.reset(new CefMediaRouterManager(this));
}
return media_router_manager_.get();
}

View File

@ -13,8 +13,10 @@
#include "libcef/browser/request_context_handler_map.h"
#include "libcef/browser/resource_context.h"
#include "base/callback.h"
#include "base/files/file_path.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "chrome/browser/download/download_prefs.h"
#include "chrome/common/plugin.mojom.h"
#include "components/proxy_config/pref_proxy_config_tracker.h"
@ -84,6 +86,7 @@
*/
class CefDownloadManagerDelegate;
class CefMediaRouterManager;
class CefRequestContextImpl;
class CefSSLHostStateDelegate;
class CefVisitedLinkListener;
@ -279,6 +282,13 @@ class CefBrowserContext : public ChromeProfileStub,
// Returns true if this context supports print preview.
bool IsPrintPreviewSupported() const;
CefMediaRouterManager* GetMediaRouterManager();
// Returns the BrowserContext, or nullptr if the BrowserContext has already
// been destroyed.
using Getter = base::RepeatingCallback<CefBrowserContext*()>;
Getter getter() const { return getter_; }
private:
// Allow deletion via std::unique_ptr().
friend std::default_delete<CefBrowserContext>;
@ -315,6 +325,8 @@ class CefBrowserContext : public ChromeProfileStub,
std::unique_ptr<DownloadPrefs> download_prefs_;
std::unique_ptr<CefMediaRouterManager> media_router_manager_;
// Map IDs to CefRequestContextHandler objects.
CefRequestContextHandlerMap handler_map_;
@ -338,6 +350,9 @@ class CefBrowserContext : public ChromeProfileStub,
typedef std::set<int> NodeIdSet;
NodeIdSet node_id_set_;
Getter getter_;
base::WeakPtrFactory<CefBrowserContext> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(CefBrowserContext);
};

View File

@ -50,6 +50,7 @@
#include "ui/wm/core/wm_state.h"
#if defined(OS_WIN)
#include "chrome/browser/chrome_browser_main_win.h"
#include "components/os_crypt/os_crypt.h"
#include "ui/base/cursor/cursor_loader_win.h"
#endif
@ -124,7 +125,11 @@ void CefBrowserMainParts::PreMainMessageLoopStart() {
DCHECK(local_state);
bool os_crypt_init = OSCrypt::Init(local_state);
DCHECK(os_crypt_init);
#endif
// installer_util references strings that are normally compiled into
// setup.exe. In Chrome, these strings are in the locale files.
ChromeBrowserMainPartsWin::SetupInstallerUtilStrings();
#endif // defined(OS_WIN)
}
void CefBrowserMainParts::PostMainMessageLoopStart() {

View File

@ -0,0 +1,83 @@
// 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.
#include "libcef/browser/media_router/media_route_impl.h"
#include "libcef/browser/media_router/media_router_manager.h"
#include "libcef/browser/media_router/media_sink_impl.h"
#include "libcef/browser/media_router/media_source_impl.h"
#include "libcef/browser/thread_util.h"
namespace {
// Do not keep a reference to the object returned by this method.
CefBrowserContext* GetBrowserContext(const CefBrowserContext::Getter& getter) {
CEF_REQUIRE_UIT();
DCHECK(!getter.is_null());
// Will return nullptr if the BrowserContext has been destroyed.
return getter.Run();
}
} // namespace
CefMediaRouteImpl::CefMediaRouteImpl(
const media_router::MediaRoute& route,
const CefBrowserContext::Getter& browser_context_getter)
: route_(route), browser_context_getter_(browser_context_getter) {
CEF_REQUIRE_UIT();
}
CefString CefMediaRouteImpl::GetId() {
return route_.media_route_id();
}
CefRefPtr<CefMediaSource> CefMediaRouteImpl::GetSource() {
return new CefMediaSourceImpl(route_.media_source().id());
}
CefRefPtr<CefMediaSink> CefMediaRouteImpl::GetSink() {
return new CefMediaSinkImpl(route_.media_sink_id(), route_.media_sink_name());
}
void CefMediaRouteImpl::SendRouteMessage(const void* message,
size_t message_size) {
std::string message_str(reinterpret_cast<const char*>(message), message_size);
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(
CEF_UIT,
base::BindOnce(
[](CefRefPtr<CefMediaRouteImpl> self, std::string message_str) {
self->SendRouteMessageInternal(std::move(message_str));
},
CefRefPtr<CefMediaRouteImpl>(this), std::move(message_str)));
return;
}
SendRouteMessageInternal(std::move(message_str));
}
void CefMediaRouteImpl::Terminate() {
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(CEF_UIT, base::BindOnce(&CefMediaRouteImpl::Terminate, this));
return;
}
auto browser_context = GetBrowserContext(browser_context_getter_);
if (!browser_context)
return;
browser_context->GetMediaRouterManager()->TerminateRoute(
route_.media_route_id());
}
void CefMediaRouteImpl::SendRouteMessageInternal(std::string message) {
auto browser_context = GetBrowserContext(browser_context_getter_);
if (!browser_context)
return;
browser_context->GetMediaRouterManager()->SendRouteMessage(
route_.media_route_id(), message);
}

View File

@ -0,0 +1,40 @@
// 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.
#ifndef CEF_LIBCEF_BROWSER_MEDIA_ROUTER_MEDIA_ROUTE_IMPL_H_
#define CEF_LIBCEF_BROWSER_MEDIA_ROUTER_MEDIA_ROUTE_IMPL_H_
#pragma once
#include "include/cef_media_router.h"
#include "libcef/browser/browser_context.h"
#include "chrome/common/media_router/media_route.h"
// Implementation of the CefMediaRoute interface. Only created on the UI thread.
class CefMediaRouteImpl : public CefMediaRoute {
public:
CefMediaRouteImpl(const media_router::MediaRoute& route,
const CefBrowserContext::Getter& browser_context_getter);
// CefMediaRoute methods.
CefString GetId() override;
CefRefPtr<CefMediaSource> GetSource() override;
CefRefPtr<CefMediaSink> GetSink() override;
void SendRouteMessage(const void* message, size_t message_size) override;
void Terminate() override;
const media_router::MediaRoute& route() const { return route_; }
private:
void SendRouteMessageInternal(std::string message);
// Read-only after creation.
const media_router::MediaRoute route_;
const CefBrowserContext::Getter browser_context_getter_;
IMPLEMENT_REFCOUNTING(CefMediaRouteImpl);
DISALLOW_COPY_AND_ASSIGN(CefMediaRouteImpl);
};
#endif // CEF_LIBCEF_BROWSER_MEDIA_ROUTER_MEDIA_ROUTE_IMPL_H_

View File

@ -0,0 +1,290 @@
// 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.
#include "libcef/browser/media_router/media_router_impl.h"
#include "libcef/browser/media_router/media_route_impl.h"
#include "libcef/browser/media_router/media_router_manager.h"
#include "libcef/browser/media_router/media_sink_impl.h"
#include "libcef/browser/media_router/media_source_impl.h"
#include "libcef/browser/thread_util.h"
namespace {
// Do not keep a reference to the object returned by this method.
CefBrowserContext* GetBrowserContext(const CefBrowserContext::Getter& getter) {
CEF_REQUIRE_UIT();
DCHECK(!getter.is_null());
// Will return nullptr if the BrowserContext has been destroyed.
return getter.Run();
}
} // namespace
class CefRegistrationImpl : public CefRegistration,
public CefMediaRouterManager::Observer {
public:
explicit CefRegistrationImpl(CefRefPtr<CefMediaObserver> observer)
: observer_(observer) {
DCHECK(observer_);
}
~CefRegistrationImpl() override {
CEF_REQUIRE_UIT();
// May be null if OnMediaRouterDestroyed was called.
if (browser_context_getter_.is_null())
return;
auto browser_context = GetBrowserContext(browser_context_getter_);
if (!browser_context)
return;
browser_context->GetMediaRouterManager()->RemoveObserver(this);
}
void Initialize(const CefBrowserContext::Getter& browser_context_getter) {
CEF_REQUIRE_UIT();
DCHECK(!browser_context_getter.is_null());
DCHECK(browser_context_getter_.is_null());
browser_context_getter_ = browser_context_getter;
auto browser_context = GetBrowserContext(browser_context_getter_);
if (!browser_context)
return;
browser_context->GetMediaRouterManager()->AddObserver(this);
}
private:
// CefMediaRouterManager::Observer methods:
void OnMediaRouterDestroyed() override { browser_context_getter_.Reset(); }
void OnMediaSinks(
const CefMediaRouterManager::MediaSinkVector& sinks) override {
std::vector<CefRefPtr<CefMediaSink>> cef_sinks;
for (const auto& sink : sinks) {
cef_sinks.push_back(new CefMediaSinkImpl(sink.sink));
}
observer_->OnSinks(cef_sinks);
}
void OnMediaRoutes(
const CefMediaRouterManager::MediaRouteVector& routes) override {
std::vector<CefRefPtr<CefMediaRoute>> cef_routes;
for (const auto& route : routes) {
cef_routes.push_back(MakeCefRoute(route));
}
observer_->OnRoutes(cef_routes);
}
void OnMediaRouteMessages(
const media_router::MediaRoute& route,
const CefMediaRouterManager::MediaMessageVector& messages) override {
CefRefPtr<CefMediaRoute> cef_route = MakeCefRoute(route);
for (const auto& message : messages) {
if (message->type == media_router::mojom::RouteMessage::Type::TEXT) {
if (message->message.has_value()) {
const std::string& str = *(message->message);
observer_->OnRouteMessageReceived(cef_route, str.c_str(), str.size());
}
} else if (message->type ==
media_router::mojom::RouteMessage::Type::BINARY) {
if (message->data.has_value()) {
const std::vector<uint8_t>& data = *(message->data);
observer_->OnRouteMessageReceived(cef_route, data.data(),
data.size());
}
}
}
}
void OnMediaRouteStateChange(
const media_router::MediaRoute& route,
const content::PresentationConnectionStateChangeInfo& info) override {
observer_->OnRouteStateChanged(MakeCefRoute(route),
ToConnectionState(info.state));
}
CefRefPtr<CefMediaRoute> MakeCefRoute(const media_router::MediaRoute& route) {
return new CefMediaRouteImpl(route, browser_context_getter_);
}
static CefMediaObserver::ConnectionState ToConnectionState(
blink::mojom::PresentationConnectionState state) {
switch (state) {
case blink::mojom::PresentationConnectionState::CONNECTING:
return CEF_MRCS_CONNECTING;
case blink::mojom::PresentationConnectionState::CONNECTED:
return CEF_MRCS_CONNECTED;
case blink::mojom::PresentationConnectionState::CLOSED:
return CEF_MRCS_CLOSED;
case blink::mojom::PresentationConnectionState::TERMINATED:
return CEF_MRCS_TERMINATED;
}
NOTREACHED();
return CEF_MRCS_UNKNOWN;
}
CefRefPtr<CefMediaObserver> observer_;
CefBrowserContext::Getter browser_context_getter_;
IMPLEMENT_REFCOUNTING_DELETE_ON_UIT(CefRegistrationImpl);
DISALLOW_COPY_AND_ASSIGN(CefRegistrationImpl);
};
CefMediaRouterImpl::CefMediaRouterImpl() {
// Verify that our enum matches Chromium's values.
static_assert(
static_cast<int>(CEF_MRCR_TOTAL_COUNT) ==
static_cast<int>(media_router::RouteRequestResult::TOTAL_COUNT),
"enum mismatch");
}
void CefMediaRouterImpl::Initialize(
const CefBrowserContext::Getter& browser_context_getter) {
CEF_REQUIRE_UIT();
DCHECK(!browser_context_getter.is_null());
DCHECK(browser_context_getter_.is_null());
browser_context_getter_ = browser_context_getter;
}
CefRefPtr<CefRegistration> CefMediaRouterImpl::AddObserver(
CefRefPtr<CefMediaObserver> observer) {
if (!observer)
return nullptr;
CefRefPtr<CefRegistrationImpl> registration =
new CefRegistrationImpl(observer);
InitializeRegistrationOnUIThread(registration);
return registration.get();
}
CefRefPtr<CefMediaSource> CefMediaRouterImpl::GetSource(const CefString& urn) {
if (urn.empty())
return nullptr;
// Check for a valid URL and supported Cast/DIAL schemes.
GURL presentation_url(urn.ToString());
if (!media_router::IsValidPresentationUrl(presentation_url)) {
return nullptr;
}
if (presentation_url.SchemeIsHTTPOrHTTPS()) {
// We don't support tab/desktop mirroring, which is what Cast uses for
// arbitrary HTTP/HTTPS URLs (see CastMediaSource).
return nullptr;
}
return new CefMediaSourceImpl(presentation_url);
}
void CefMediaRouterImpl::NotifyCurrentSinks() {
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(
CEF_UIT, base::BindOnce(&CefMediaRouterImpl::NotifyCurrentSinks, this));
return;
}
auto browser_context = GetBrowserContext(browser_context_getter_);
if (!browser_context)
return;
browser_context->GetMediaRouterManager()->NotifyCurrentSinks();
}
void CefMediaRouterImpl::CreateRoute(
CefRefPtr<CefMediaSource> source,
CefRefPtr<CefMediaSink> sink,
CefRefPtr<CefMediaRouteCreateCallback> callback) {
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(CEF_UIT, base::BindOnce(&CefMediaRouterImpl::CreateRoute,
this, source, sink, callback));
return;
}
std::string error;
auto browser_context = GetBrowserContext(browser_context_getter_);
if (!browser_context) {
error = "Context has already been destroyed";
} else if (!source || !source->IsValid()) {
error = "Source is empty or invalid";
} else if (!sink || !sink->IsValid()) {
error = "Sink is empty or invalid";
} else if (!sink->IsCompatibleWith(source)) {
error = "Sink is not compatible with source";
}
if (!error.empty()) {
LOG(WARNING) << "Media route creation failed: " << error;
if (callback) {
callback->OnMediaRouteCreateFinished(CEF_MRCR_UNKNOWN_ERROR, error,
nullptr);
}
return;
}
auto source_impl = static_cast<CefMediaSourceImpl*>(source.get());
auto sink_impl = static_cast<CefMediaSinkImpl*>(sink.get());
browser_context->GetMediaRouterManager()->CreateRoute(
source_impl->source().id(), sink_impl->sink().id(), url::Origin(),
base::BindOnce(&CefMediaRouterImpl::CreateRouteCallback, this, callback));
}
void CefMediaRouterImpl::NotifyCurrentRoutes() {
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(CEF_UIT, base::BindOnce(
&CefMediaRouterImpl::NotifyCurrentRoutes, this));
return;
}
auto browser_context = GetBrowserContext(browser_context_getter_);
if (!browser_context)
return;
browser_context->GetMediaRouterManager()->NotifyCurrentRoutes();
}
void CefMediaRouterImpl::InitializeRegistrationOnUIThread(
CefRefPtr<CefRegistrationImpl> registration) {
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(
CEF_UIT,
base::BindOnce(&CefMediaRouterImpl::InitializeRegistrationOnUIThread,
this, registration));
return;
}
registration->Initialize(browser_context_getter_);
}
void CefMediaRouterImpl::CreateRouteCallback(
CefRefPtr<CefMediaRouteCreateCallback> callback,
const media_router::RouteRequestResult& result) {
CEF_REQUIRE_UIT();
if (result.result_code() != media_router::RouteRequestResult::OK) {
LOG(WARNING) << "Media route creation failed: " << result.error() << " ("
<< result.result_code() << ")";
}
if (!callback)
return;
CefRefPtr<CefMediaRoute> route;
if (result.result_code() == media_router::RouteRequestResult::OK &&
result.route()) {
route = new CefMediaRouteImpl(*result.route(), browser_context_getter_);
}
callback->OnMediaRouteCreateFinished(
static_cast<cef_media_route_create_result_t>(result.result_code()),
result.error(), route);
}
// static
CefRefPtr<CefMediaRouter> CefMediaRouter::GetGlobalMediaRouter() {
return CefRequestContext::GetGlobalContext()->GetMediaRouter();
}

View File

@ -0,0 +1,49 @@
// 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.
#ifndef CEF_LIBCEF_BROWSER_MEDIA_ROUTER_MEDIA_ROUTER_IMPL_H_
#define CEF_LIBCEF_BROWSER_MEDIA_ROUTER_MEDIA_ROUTER_IMPL_H_
#pragma once
#include "include/cef_media_router.h"
#include "libcef/browser/browser_context.h"
#include "chrome/common/media_router/mojom/media_router.mojom.h"
class CefRegistrationImpl;
// Implementation of the CefMediaRouter interface. May be created on any thread.
class CefMediaRouterImpl : public CefMediaRouter {
public:
CefMediaRouterImpl();
// Called on the UI thread after object creation and before any other object
// methods are executed on the UI thread.
void Initialize(const CefBrowserContext::Getter& browser_context_getter);
// CefMediaRouter methods.
CefRefPtr<CefRegistration> AddObserver(
CefRefPtr<CefMediaObserver> observer) override;
CefRefPtr<CefMediaSource> GetSource(const CefString& urn) override;
void NotifyCurrentSinks() override;
void CreateRoute(CefRefPtr<CefMediaSource> source,
CefRefPtr<CefMediaSink> sink,
CefRefPtr<CefMediaRouteCreateCallback> callback) override;
void NotifyCurrentRoutes() override;
private:
void InitializeRegistrationOnUIThread(
CefRefPtr<CefRegistrationImpl> registration);
void CreateRouteCallback(CefRefPtr<CefMediaRouteCreateCallback> callback,
const media_router::RouteRequestResult& result);
// Only accessed on the UI thread. Will be non-null after Initialize().
CefBrowserContext::Getter browser_context_getter_;
IMPLEMENT_REFCOUNTING(CefMediaRouterImpl);
DISALLOW_COPY_AND_ASSIGN(CefMediaRouterImpl);
};
#endif // CEF_LIBCEF_BROWSER_MEDIA_ROUTER_MEDIA_ROUTER_IMPL_H_

View File

@ -0,0 +1,292 @@
// 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.
#include "libcef/browser/media_router/media_router_manager.h"
#include "libcef/browser/browser_context.h"
#include "libcef/browser/thread_util.h"
#include "chrome/browser/media/router/media_router_factory.h"
#include "chrome/browser/media/router/media_routes_observer.h"
#include "chrome/browser/media/router/route_message_observer.h"
#include "chrome/browser/media/router/route_message_util.h"
namespace {
const int kTimeoutMs = 5 * 1000;
const char kDefaultPresentationUrl[] = "https://google.com";
} // namespace
class CefMediaRoutesObserver : public media_router::MediaRoutesObserver {
public:
explicit CefMediaRoutesObserver(CefMediaRouterManager* manager)
: media_router::MediaRoutesObserver(manager->GetMediaRouter()),
manager_(manager) {}
void OnRoutesUpdated(const std::vector<media_router::MediaRoute>& routes,
const std::vector<media_router::MediaRoute::Id>&
joinable_route_ids) override {
manager_->routes_ = routes;
manager_->NotifyCurrentRoutes();
}
private:
CefMediaRouterManager* const manager_;
DISALLOW_COPY_AND_ASSIGN(CefMediaRoutesObserver);
};
// Used to receive messages if PresentationConnection is not supported.
class CefRouteMessageObserver : public media_router::RouteMessageObserver {
public:
CefRouteMessageObserver(CefMediaRouterManager* manager,
const media_router::MediaRoute& route)
: media_router::RouteMessageObserver(manager->GetMediaRouter(),
route.media_route_id()),
manager_(manager),
route_(route) {}
void OnMessagesReceived(
CefMediaRouterManager::MediaMessageVector messages) override {
manager_->OnMessagesReceived(route_, messages);
}
private:
CefMediaRouterManager* const manager_;
const media_router::MediaRoute route_;
DISALLOW_COPY_AND_ASSIGN(CefRouteMessageObserver);
};
// Used for messaging and route status notifications with Cast.
class CefPresentationConnection : public blink::mojom::PresentationConnection {
public:
explicit CefPresentationConnection(
CefMediaRouterManager* manager,
const media_router::MediaRoute& route,
media_router::mojom::RoutePresentationConnectionPtr connections)
: manager_(manager),
route_(route),
connection_receiver_(this, std::move(connections->connection_receiver)),
connection_remote_(std::move(connections->connection_remote)) {}
void OnMessage(
blink::mojom::PresentationConnectionMessagePtr message) override {
CefMediaRouterManager::MediaMessageVector messages;
if (message->is_message()) {
messages.push_back(media_router::message_util::RouteMessageFromString(
message->get_message()));
} else if (message->is_data()) {
messages.push_back(media_router::message_util::RouteMessageFromData(
message->get_data()));
}
if (!messages.empty()) {
manager_->OnMessagesReceived(route_, messages);
}
}
void DidChangeState(
blink::mojom::PresentationConnectionState state) override {
// May result in |this| being deleted, so post async and allow the call
// stack to unwind.
CEF_POST_TASK(
CEF_UIT,
base::BindOnce(&CefMediaRouterManager::OnRouteStateChange,
manager_->weak_ptr_factory_.GetWeakPtr(), route_,
content::PresentationConnectionStateChangeInfo(state)));
}
void DidClose(
blink::mojom::PresentationConnectionCloseReason reason) override {
DidChangeState(blink::mojom::PresentationConnectionState::CLOSED);
}
void SendRouteMessage(const std::string& message) {
connection_remote_->OnMessage(
blink::mojom::PresentationConnectionMessage::NewMessage(message));
}
private:
CefMediaRouterManager* const manager_;
const media_router::MediaRoute route_;
// Used to receive messages from the MRP.
mojo::Receiver<blink::mojom::PresentationConnection> connection_receiver_;
// Used to send messages to the MRP.
mojo::Remote<blink::mojom::PresentationConnection> connection_remote_;
DISALLOW_COPY_AND_ASSIGN(CefPresentationConnection);
};
CefMediaRouterManager::CefMediaRouterManager(CefBrowserContext* browser_context)
: browser_context_(browser_context),
query_result_manager_(GetMediaRouter()),
weak_ptr_factory_(this) {
// Perform initialization.
GetMediaRouter()->OnUserGesture();
query_result_manager_.AddObserver(this);
// A non-empty presentation URL to required for discovery of Cast devices.
query_result_manager_.SetSourcesForCastMode(
media_router::MediaCastMode::PRESENTATION,
{media_router::MediaSource::ForPresentationUrl(
GURL(kDefaultPresentationUrl))},
url::Origin());
routes_observer_ = std::make_unique<CefMediaRoutesObserver>(this);
}
CefMediaRouterManager::~CefMediaRouterManager() {
CEF_REQUIRE_UIT();
for (auto& observer : observers_) {
observers_.RemoveObserver(&observer);
observer.OnMediaRouterDestroyed();
}
query_result_manager_.RemoveObserver(this);
}
void CefMediaRouterManager::AddObserver(Observer* observer) {
CEF_REQUIRE_UIT();
observers_.AddObserver(observer);
}
void CefMediaRouterManager::RemoveObserver(Observer* observer) {
CEF_REQUIRE_UIT();
observers_.RemoveObserver(observer);
}
void CefMediaRouterManager::NotifyCurrentSinks() {
CEF_REQUIRE_UIT();
for (auto& observer : observers_) {
observer.OnMediaSinks(sinks_);
}
}
void CefMediaRouterManager::NotifyCurrentRoutes() {
CEF_REQUIRE_UIT();
for (auto& observer : observers_) {
observer.OnMediaRoutes(routes_);
}
}
void CefMediaRouterManager::CreateRoute(
const media_router::MediaSource::Id& source_id,
const media_router::MediaSink::Id& sink_id,
const url::Origin& origin,
CreateRouteResultCallback callback) {
GetMediaRouter()->CreateRoute(
source_id, sink_id, origin, nullptr /* web_contents */,
base::BindOnce(&CefMediaRouterManager::OnCreateRoute,
weak_ptr_factory_.GetWeakPtr(), std::move(callback)),
base::TimeDelta::FromMilliseconds(kTimeoutMs), false /* incognito */);
}
void CefMediaRouterManager::SendRouteMessage(
const media_router::MediaRoute::Id& route_id,
const std::string& message) {
// Must use PresentationConnection to send messages if it exists.
auto state = GetRouteState(route_id);
if (state && state->presentation_connection_) {
state->presentation_connection_->SendRouteMessage(message);
return;
}
GetMediaRouter()->SendRouteMessage(route_id, message);
}
void CefMediaRouterManager::TerminateRoute(
const media_router::MediaRoute::Id& route_id) {
GetMediaRouter()->TerminateRoute(route_id);
}
void CefMediaRouterManager::OnResultsUpdated(const MediaSinkVector& sinks) {
sinks_ = sinks;
NotifyCurrentSinks();
}
media_router::MediaRouter* CefMediaRouterManager::GetMediaRouter() const {
CEF_REQUIRE_UIT();
return media_router::MediaRouterFactory::GetApiForBrowserContext(
browser_context_);
}
void CefMediaRouterManager::OnCreateRoute(
CreateRouteResultCallback callback,
media_router::mojom::RoutePresentationConnectionPtr connection,
const media_router::RouteRequestResult& result) {
CEF_REQUIRE_UIT();
if (result.route()) {
CreateRouteState(*result.route(), std::move(connection));
}
std::move(callback).Run(result);
}
void CefMediaRouterManager::OnRouteStateChange(
const media_router::MediaRoute& route,
const content::PresentationConnectionStateChangeInfo& info) {
CEF_REQUIRE_UIT();
if (info.state == blink::mojom::PresentationConnectionState::CLOSED ||
info.state == blink::mojom::PresentationConnectionState::TERMINATED) {
RemoveRouteState(route.media_route_id());
}
for (auto& observer : observers_) {
observer.OnMediaRouteStateChange(route, info);
}
}
void CefMediaRouterManager::OnMessagesReceived(
const media_router::MediaRoute& route,
const MediaMessageVector& messages) {
CEF_REQUIRE_UIT();
for (auto& observer : observers_) {
observer.OnMediaRouteMessages(route, messages);
}
}
void CefMediaRouterManager::CreateRouteState(
const media_router::MediaRoute& route,
media_router::mojom::RoutePresentationConnectionPtr connection) {
const auto route_id = route.media_route_id();
auto state = std::make_unique<RouteState>();
if (!connection.is_null()) {
// PresentationConnection must be used for messaging and status
// notifications if it exists.
state->presentation_connection_ =
std::make_unique<CefPresentationConnection>(this, route,
std::move(connection));
} else {
// Fallback if PresentationConnection is not supported.
state->message_observer_ =
std::make_unique<CefRouteMessageObserver>(this, route);
state->state_subscription_ =
GetMediaRouter()->AddPresentationConnectionStateChangedCallback(
route_id,
base::BindRepeating(&CefMediaRouterManager::OnRouteStateChange,
weak_ptr_factory_.GetWeakPtr(), route));
}
route_state_map_.insert(std::make_pair(route_id, std::move(state)));
}
CefMediaRouterManager::RouteState* CefMediaRouterManager::GetRouteState(
const media_router::MediaRoute::Id& route_id) {
const auto it = route_state_map_.find(route_id);
if (it != route_state_map_.end())
return it->second.get();
return nullptr;
}
void CefMediaRouterManager::RemoveRouteState(
const media_router::MediaRoute::Id& route_id) {
auto it = route_state_map_.find(route_id);
if (it != route_state_map_.end())
route_state_map_.erase(it);
}

View File

@ -0,0 +1,125 @@
// 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.
#ifndef CEF_LIBCEF_BROWSER_MEDIA_ROUTER_MEDIA_ROUTER_MANAGER_H_
#define CEF_LIBCEF_BROWSER_MEDIA_ROUTER_MEDIA_ROUTER_MANAGER_H_
#pragma once
#include "include/cef_media_router.h"
#include "libcef/browser/browser_context.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "chrome/browser/media/router/media_router.h"
#include "chrome/browser/ui/media_router/query_result_manager.h"
#include "chrome/common/media_router/mojom/media_router.mojom.h"
class CefBrowserContext;
class CefMediaRoutesObserver;
class CefPresentationConnection;
class CefRouteMessageObserver;
// Manages CEF usage of MediaRouter. Owned by CefBrowserContext and only
// accessed on the UI thread.
class CefMediaRouterManager
: public media_router::QueryResultManager::Observer {
public:
using MediaRouteVector = std::vector<media_router::MediaRoute>;
using MediaSinkVector = std::vector<media_router::MediaSinkWithCastModes>;
using MediaMessageVector = std::vector<media_router::mojom::RouteMessagePtr>;
class Observer : public base::CheckedObserver {
public:
virtual void OnMediaRouterDestroyed() = 0;
virtual void OnMediaSinks(const MediaSinkVector& sinks) = 0;
virtual void OnMediaRoutes(const MediaRouteVector& routes) = 0;
virtual void OnMediaRouteMessages(const media_router::MediaRoute& route,
const MediaMessageVector& messages) = 0;
virtual void OnMediaRouteStateChange(
const media_router::MediaRoute& route,
const content::PresentationConnectionStateChangeInfo& info) = 0;
protected:
~Observer() override {}
};
explicit CefMediaRouterManager(CefBrowserContext* browser_context);
~CefMediaRouterManager() override;
// |observer| must outlive this object or be removed.
void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer);
void NotifyCurrentSinks();
void NotifyCurrentRoutes();
using CreateRouteResultCallback =
base::OnceCallback<void(const media_router::RouteRequestResult& result)>;
void CreateRoute(const media_router::MediaSource::Id& source_id,
const media_router::MediaSink::Id& sink_id,
const url::Origin& origin,
CreateRouteResultCallback callback);
void SendRouteMessage(const media_router::MediaRoute::Id& route_id,
const std::string& message);
void TerminateRoute(const media_router::MediaRoute::Id& route_id);
// QueryResultManager::Observer methods.
void OnResultsUpdated(const MediaSinkVector& sinks) override;
private:
friend class CefMediaRoutesObserver;
friend class CefPresentationConnection;
friend class CefRouteMessageObserver;
// Do not keep a reference to the object returned by this method.
media_router::MediaRouter* GetMediaRouter() const;
void OnCreateRoute(
CreateRouteResultCallback callback,
media_router::mojom::RoutePresentationConnectionPtr connection,
const media_router::RouteRequestResult& result);
void OnRouteStateChange(
const media_router::MediaRoute& route,
const content::PresentationConnectionStateChangeInfo& info);
void OnMessagesReceived(const media_router::MediaRoute& route,
const MediaMessageVector& messages);
struct RouteState {
std::unique_ptr<CefPresentationConnection> presentation_connection_;
// Used if there is no RoutePresentationConnectionPtr.
std::unique_ptr<CefRouteMessageObserver> message_observer_;
std::unique_ptr<media_router::PresentationConnectionStateSubscription>
state_subscription_;
};
void CreateRouteState(
const media_router::MediaRoute& route,
media_router::mojom::RoutePresentationConnectionPtr connection);
RouteState* GetRouteState(const media_router::MediaRoute::Id& route_id);
void RemoveRouteState(const media_router::MediaRoute::Id& route_id);
CefBrowserContext* const browser_context_;
base::ObserverList<Observer> observers_;
media_router::QueryResultManager query_result_manager_;
std::unique_ptr<CefMediaRoutesObserver> routes_observer_;
MediaRouteVector routes_;
MediaSinkVector sinks_;
using RouteStateMap =
std::map<media_router::MediaRoute::Id, std::unique_ptr<RouteState>>;
RouteStateMap route_state_map_;
base::WeakPtrFactory<CefMediaRouterManager> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(CefMediaRouterManager);
};
#endif // CEF_LIBCEF_BROWSER_MEDIA_ROUTER_MEDIA_ROUTER_MANAGER_H_

View File

@ -0,0 +1,46 @@
// 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.
#include "libcef/browser/media_router/media_sink_impl.h"
CefMediaSinkImpl::CefMediaSinkImpl(const media_router::MediaSink& sink)
: sink_(sink) {}
CefMediaSinkImpl::CefMediaSinkImpl(const media_router::MediaSink::Id& sink_id,
const std::string& sink_name)
: sink_(sink_id, sink_name, media_router::SinkIconType::GENERIC) {}
CefString CefMediaSinkImpl::GetId() {
return sink_.id();
}
bool CefMediaSinkImpl::IsValid() {
return true;
}
CefString CefMediaSinkImpl::GetName() {
return sink_.name();
}
CefString CefMediaSinkImpl::GetDescription() {
return sink_.description().value_or("");
}
bool CefMediaSinkImpl::IsCastSink() {
return sink_.provider_id() == media_router::CAST;
}
bool CefMediaSinkImpl::IsDialSink() {
return sink_.provider_id() == media_router::DIAL;
}
bool CefMediaSinkImpl::IsCompatibleWith(CefRefPtr<CefMediaSource> source) {
if (source) {
if (IsCastSink())
return source->IsCastSource();
if (IsDialSink())
return source->IsDialSource();
}
return false;
}

View File

@ -0,0 +1,39 @@
// 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.
#ifndef CEF_LIBCEF_BROWSER_MEDIA_ROUTER_MEDIA_SINK_IMPL_H_
#define CEF_LIBCEF_BROWSER_MEDIA_ROUTER_MEDIA_SINK_IMPL_H_
#pragma once
#include "include/cef_media_router.h"
#include "chrome/common/media_router/media_sink.h"
// Implementation of the CefMediaSink interface. May be created on any thread.
class CefMediaSinkImpl : public CefMediaSink {
public:
explicit CefMediaSinkImpl(const media_router::MediaSink& sink);
CefMediaSinkImpl(const media_router::MediaSink::Id& sink_id,
const std::string& sink_name);
// CefMediaSink methods.
CefString GetId() override;
bool IsValid() override;
CefString GetName() override;
CefString GetDescription() override;
bool IsCastSink() override;
bool IsDialSink() override;
bool IsCompatibleWith(CefRefPtr<CefMediaSource> source) override;
const media_router::MediaSink& sink() const { return sink_; }
private:
// Read-only after creation.
const media_router::MediaSink sink_;
IMPLEMENT_REFCOUNTING(CefMediaSinkImpl);
DISALLOW_COPY_AND_ASSIGN(CefMediaSinkImpl);
};
#endif // CEF_LIBCEF_BROWSER_MEDIA_ROUTER_MEDIA_SINK_IMPL_H_

View File

@ -0,0 +1,28 @@
// 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.
#include "libcef/browser/media_router/media_source_impl.h"
CefMediaSourceImpl::CefMediaSourceImpl(
const media_router::MediaSource::Id& source_id)
: source_(source_id) {}
CefMediaSourceImpl::CefMediaSourceImpl(const GURL& presentation_url)
: source_(presentation_url) {}
CefString CefMediaSourceImpl::GetId() {
return source_.id();
}
bool CefMediaSourceImpl::IsValid() {
return source_.IsValid();
}
bool CefMediaSourceImpl::IsCastSource() {
return !IsDialSource();
}
bool CefMediaSourceImpl::IsDialSource() {
return source_.IsDialSource();
}

View File

@ -0,0 +1,35 @@
// 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.
#ifndef CEF_LIBCEF_BROWSER_MEDIA_ROUTER_MEDIA_SOURCE_IMPL_H_
#define CEF_LIBCEF_BROWSER_MEDIA_ROUTER_MEDIA_SOURCE_IMPL_H_
#pragma once
#include "include/cef_media_router.h"
#include "chrome/common/media_router/media_source.h"
// Implementation of the CefMediaSource interface. May be created on any thread.
class CefMediaSourceImpl : public CefMediaSource {
public:
explicit CefMediaSourceImpl(const media_router::MediaSource::Id& source_id);
explicit CefMediaSourceImpl(const GURL& presentation_url);
// CefMediaSource methods.
CefString GetId() override;
bool IsValid() override;
bool IsCastSource() override;
bool IsDialSource() override;
const media_router::MediaSource& source() const { return source_; }
private:
// Read-only after creation.
const media_router::MediaSource source_;
IMPLEMENT_REFCOUNTING(CefMediaSourceImpl);
DISALLOW_COPY_AND_ASSIGN(CefMediaSourceImpl);
};
#endif // CEF_LIBCEF_BROWSER_MEDIA_ROUTER_MEDIA_SOURCE_IMPL_H_

View File

@ -18,6 +18,7 @@
#include "base/values.h"
#include "chrome/browser/accessibility/accessibility_ui.h"
#include "chrome/browser/download/download_prefs.h"
#include "chrome/browser/media/router/media_router_feature.h"
#include "chrome/browser/net/prediction_options.h"
#include "chrome/browser/net/profile_network_context_service.h"
#include "chrome/browser/net/system_network_context_manager.h"
@ -177,6 +178,7 @@ std::unique_ptr<PrefService> CreatePrefService(Profile* profile,
CefMediaCaptureDevicesDispatcher::RegisterPrefs(registry.get());
certificate_transparency::prefs::RegisterPrefs(registry.get());
flags_ui::PrefServiceFlagsStorage::RegisterPrefs(registry.get());
media_router::RegisterLocalStatePrefs(registry.get());
PluginInfoHostImpl::RegisterUserPrefs(registry.get());
PrefProxyConfigTrackerImpl::RegisterPrefs(registry.get());
ProfileNetworkContextService::RegisterLocalStatePrefs(registry.get());
@ -225,6 +227,7 @@ std::unique_ptr<PrefService> CreatePrefService(Profile* profile,
extensions::ExtensionPrefs::RegisterProfilePrefs(registry.get());
HostContentSettingsMap::RegisterProfilePrefs(registry.get());
language::LanguagePrefs::RegisterProfilePrefs(registry.get());
media_router::RegisterProfilePrefs(registry.get());
ProfileNetworkContextService::RegisterProfilePrefs(registry.get());
const std::string& locale =

View File

@ -594,6 +594,12 @@ CefRefPtr<CefExtension> CefRequestContextImpl::GetExtension(
return GetBrowserContext()->extension_system()->GetExtension(extension_id);
}
CefRefPtr<CefMediaRouter> CefRequestContextImpl::GetMediaRouter() {
CefRefPtr<CefMediaRouterImpl> media_router = new CefMediaRouterImpl();
InitializeMediaRouterOnUIThread(media_router);
return media_router.get();
}
void CefRequestContextImpl::OnRenderFrameCreated(int render_process_id,
int render_frame_id,
int frame_tree_node_id,
@ -761,6 +767,20 @@ void CefRequestContextImpl::ResolveHostInternal(
helper->Start(browser_context, origin);
}
void CefRequestContextImpl::InitializeMediaRouterOnUIThread(
CefRefPtr<CefMediaRouterImpl> media_router) {
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(
CEF_UIT,
base::Bind(&CefRequestContextImpl::InitializeMediaRouterOnUIThread,
this, media_router));
return;
}
auto browser_context = GetBrowserContext();
media_router->Initialize(browser_context->getter());
}
CefBrowserContext* CefRequestContextImpl::browser_context() const {
return browser_context_;
}

View File

@ -8,6 +8,7 @@
#include "include/cef_request_context.h"
#include "libcef/browser/browser_context.h"
#include "libcef/browser/media_router/media_router_impl.h"
#include "libcef/browser/thread_util.h"
class CefBrowserContext;
@ -75,6 +76,7 @@ class CefRequestContextImpl : public CefRequestContext {
bool HasExtension(const CefString& extension_id) override;
bool GetExtensions(std::vector<CefString>& extension_ids) override;
CefRefPtr<CefExtension> GetExtension(const CefString& extension_id) override;
CefRefPtr<CefMediaRouter> GetMediaRouter() override;
const CefRequestContextSettings& settings() const { return config_.settings; }
@ -147,6 +149,9 @@ class CefRequestContextImpl : public CefRequestContext {
CefRefPtr<CefResolveCallback> callback,
CefBrowserContext* browser_context);
void InitializeMediaRouterOnUIThread(
CefRefPtr<CefMediaRouterImpl> media_router);
CefBrowserContext* browser_context() const;
// We must disassociate from this on destruction.

View File

@ -30,6 +30,7 @@
#include "base/synchronization/waitable_event.h"
#include "base/threading/thread.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/media/router/media_router_feature.h"
#include "chrome/child/pdf_child_init.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
@ -637,6 +638,33 @@ bool CefMainDelegate::BasicStartupComplete(int* exit_code) {
command_line->AppendSwitchASCII(switches::kDisableFeatures,
disable_features_str);
}
std::vector<std::string> enable_features;
if (media_router::kDialMediaRouteProvider.default_state ==
base::FEATURE_DISABLED_BY_DEFAULT) {
// Enable discovery of DIAL devices.
enable_features.push_back(media_router::kDialMediaRouteProvider.name);
}
if (media_router::kCastMediaRouteProvider.default_state ==
base::FEATURE_DISABLED_BY_DEFAULT) {
// Enable discovery of Cast devices.
enable_features.push_back(media_router::kCastMediaRouteProvider.name);
}
if (!enable_features.empty()) {
DCHECK(!base::FeatureList::GetInstance());
std::string enable_features_str =
command_line->GetSwitchValueASCII(switches::kEnableFeatures);
for (auto feature_str : enable_features) {
if (!enable_features_str.empty())
enable_features_str += ",";
enable_features_str += feature_str;
}
command_line->AppendSwitchASCII(switches::kEnableFeatures,
enable_features_str);
}
}
if (content_client_.application().get()) {

View File

@ -0,0 +1,161 @@
// 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=35f0e881b5a98c1da73789ecb72254fbe254a350$
//
#include "libcef_dll/cpptoc/media_observer_cpptoc.h"
#include "libcef_dll/ctocpp/media_route_ctocpp.h"
#include "libcef_dll/ctocpp/media_sink_ctocpp.h"
#include "libcef_dll/shutdown_checker.h"
namespace {
// MEMBER FUNCTIONS - Body may be edited by hand.
void CEF_CALLBACK
media_observer_on_sinks(struct _cef_media_observer_t* self,
size_t sinksCount,
struct _cef_media_sink_t* const* sinks) {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Verify param: sinks; type: refptr_vec_diff_byref_const
DCHECK(sinksCount == 0 || sinks);
if (sinksCount > 0 && !sinks)
return;
// Translate param: sinks; type: refptr_vec_diff_byref_const
std::vector<CefRefPtr<CefMediaSink>> sinksList;
if (sinksCount > 0) {
for (size_t i = 0; i < sinksCount; ++i) {
CefRefPtr<CefMediaSink> sinksVal = CefMediaSinkCToCpp::Wrap(sinks[i]);
sinksList.push_back(sinksVal);
}
}
// Execute
CefMediaObserverCppToC::Get(self)->OnSinks(sinksList);
}
void CEF_CALLBACK
media_observer_on_routes(struct _cef_media_observer_t* self,
size_t routesCount,
struct _cef_media_route_t* const* routes) {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Verify param: routes; type: refptr_vec_diff_byref_const
DCHECK(routesCount == 0 || routes);
if (routesCount > 0 && !routes)
return;
// Translate param: routes; type: refptr_vec_diff_byref_const
std::vector<CefRefPtr<CefMediaRoute>> routesList;
if (routesCount > 0) {
for (size_t i = 0; i < routesCount; ++i) {
CefRefPtr<CefMediaRoute> routesVal = CefMediaRouteCToCpp::Wrap(routes[i]);
routesList.push_back(routesVal);
}
}
// Execute
CefMediaObserverCppToC::Get(self)->OnRoutes(routesList);
}
void CEF_CALLBACK media_observer_on_route_state_changed(
struct _cef_media_observer_t* self,
struct _cef_media_route_t* route,
cef_media_route_connection_state_t state) {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Verify param: route; type: refptr_diff
DCHECK(route);
if (!route)
return;
// Execute
CefMediaObserverCppToC::Get(self)->OnRouteStateChanged(
CefMediaRouteCToCpp::Wrap(route), state);
}
void CEF_CALLBACK
media_observer_on_route_message_received(struct _cef_media_observer_t* self,
struct _cef_media_route_t* route,
const void* message,
size_t message_size) {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Verify param: route; type: refptr_diff
DCHECK(route);
if (!route)
return;
// Verify param: message; type: simple_byaddr
DCHECK(message);
if (!message)
return;
// Execute
CefMediaObserverCppToC::Get(self)->OnRouteMessageReceived(
CefMediaRouteCToCpp::Wrap(route), message, message_size);
}
} // namespace
// CONSTRUCTOR - Do not edit by hand.
CefMediaObserverCppToC::CefMediaObserverCppToC() {
GetStruct()->on_sinks = media_observer_on_sinks;
GetStruct()->on_routes = media_observer_on_routes;
GetStruct()->on_route_state_changed = media_observer_on_route_state_changed;
GetStruct()->on_route_message_received =
media_observer_on_route_message_received;
}
// DESTRUCTOR - Do not edit by hand.
CefMediaObserverCppToC::~CefMediaObserverCppToC() {
shutdown_checker::AssertNotShutdown();
}
template <>
CefRefPtr<CefMediaObserver> CefCppToCRefCounted<
CefMediaObserverCppToC,
CefMediaObserver,
cef_media_observer_t>::UnwrapDerived(CefWrapperType type,
cef_media_observer_t* s) {
NOTREACHED() << "Unexpected class type: " << type;
return nullptr;
}
template <>
CefWrapperType CefCppToCRefCounted<CefMediaObserverCppToC,
CefMediaObserver,
cef_media_observer_t>::kWrapperType =
WT_MEDIA_OBSERVER;

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=14ef1b6f920a375e585174e4057c66221f3e1c05$
//
#ifndef CEF_LIBCEF_DLL_CPPTOC_MEDIA_OBSERVER_CPPTOC_H_
#define CEF_LIBCEF_DLL_CPPTOC_MEDIA_OBSERVER_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 CefMediaObserverCppToC
: public CefCppToCRefCounted<CefMediaObserverCppToC,
CefMediaObserver,
cef_media_observer_t> {
public:
CefMediaObserverCppToC();
virtual ~CefMediaObserverCppToC();
};
#endif // CEF_LIBCEF_DLL_CPPTOC_MEDIA_OBSERVER_CPPTOC_H_

View File

@ -0,0 +1,139 @@
// 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=47181b936b29037dd4ff5169d7175ac538f5be56$
//
#include "libcef_dll/cpptoc/media_route_cpptoc.h"
#include "libcef_dll/cpptoc/media_sink_cpptoc.h"
#include "libcef_dll/cpptoc/media_source_cpptoc.h"
#include "libcef_dll/shutdown_checker.h"
namespace {
// MEMBER FUNCTIONS - Body may be edited by hand.
cef_string_userfree_t CEF_CALLBACK
media_route_get_id(struct _cef_media_route_t* self) {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return NULL;
// Execute
CefString _retval = CefMediaRouteCppToC::Get(self)->GetId();
// Return type: string
return _retval.DetachToUserFree();
}
struct _cef_media_source_t* CEF_CALLBACK
media_route_get_source(struct _cef_media_route_t* self) {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return NULL;
// Execute
CefRefPtr<CefMediaSource> _retval =
CefMediaRouteCppToC::Get(self)->GetSource();
// Return type: refptr_same
return CefMediaSourceCppToC::Wrap(_retval);
}
struct _cef_media_sink_t* CEF_CALLBACK
media_route_get_sink(struct _cef_media_route_t* self) {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return NULL;
// Execute
CefRefPtr<CefMediaSink> _retval = CefMediaRouteCppToC::Get(self)->GetSink();
// Return type: refptr_same
return CefMediaSinkCppToC::Wrap(_retval);
}
void CEF_CALLBACK
media_route_send_route_message(struct _cef_media_route_t* self,
const void* message,
size_t message_size) {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Verify param: message; type: simple_byaddr
DCHECK(message);
if (!message)
return;
// Execute
CefMediaRouteCppToC::Get(self)->SendRouteMessage(message, message_size);
}
void CEF_CALLBACK media_route_terminate(struct _cef_media_route_t* self) {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Execute
CefMediaRouteCppToC::Get(self)->Terminate();
}
} // namespace
// CONSTRUCTOR - Do not edit by hand.
CefMediaRouteCppToC::CefMediaRouteCppToC() {
GetStruct()->get_id = media_route_get_id;
GetStruct()->get_source = media_route_get_source;
GetStruct()->get_sink = media_route_get_sink;
GetStruct()->send_route_message = media_route_send_route_message;
GetStruct()->terminate = media_route_terminate;
}
// DESTRUCTOR - Do not edit by hand.
CefMediaRouteCppToC::~CefMediaRouteCppToC() {
shutdown_checker::AssertNotShutdown();
}
template <>
CefRefPtr<CefMediaRoute>
CefCppToCRefCounted<CefMediaRouteCppToC, CefMediaRoute, cef_media_route_t>::
UnwrapDerived(CefWrapperType type, cef_media_route_t* s) {
NOTREACHED() << "Unexpected class type: " << type;
return nullptr;
}
template <>
CefWrapperType CefCppToCRefCounted<CefMediaRouteCppToC,
CefMediaRoute,
cef_media_route_t>::kWrapperType =
WT_MEDIA_ROUTE;

View File

@ -0,0 +1,37 @@
// 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=26fe0f9bd956318d0e6c7e0216024b5b839429c2$
//
#ifndef CEF_LIBCEF_DLL_CPPTOC_MEDIA_ROUTE_CPPTOC_H_
#define CEF_LIBCEF_DLL_CPPTOC_MEDIA_ROUTE_CPPTOC_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/cpptoc/cpptoc_ref_counted.h"
// Wrap a C++ class with a C structure.
// This class may be instantiated and accessed DLL-side only.
class CefMediaRouteCppToC : public CefCppToCRefCounted<CefMediaRouteCppToC,
CefMediaRoute,
cef_media_route_t> {
public:
CefMediaRouteCppToC();
virtual ~CefMediaRouteCppToC();
};
#endif // CEF_LIBCEF_DLL_CPPTOC_MEDIA_ROUTE_CPPTOC_H_

View File

@ -0,0 +1,72 @@
// 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=a27462c4bcc0ef4856230997718f95edae5c1ef1$
//
#include "libcef_dll/cpptoc/media_route_create_callback_cpptoc.h"
#include "libcef_dll/ctocpp/media_route_ctocpp.h"
#include "libcef_dll/shutdown_checker.h"
namespace {
// MEMBER FUNCTIONS - Body may be edited by hand.
void CEF_CALLBACK media_route_create_callback_on_media_route_create_finished(
struct _cef_media_route_create_callback_t* self,
cef_media_route_create_result_t result,
const cef_string_t* error,
cef_media_route_t* route) {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Unverified params: error, route
// Execute
CefMediaRouteCreateCallbackCppToC::Get(self)->OnMediaRouteCreateFinished(
result, CefString(error), CefMediaRouteCToCpp::Wrap(route));
}
} // namespace
// CONSTRUCTOR - Do not edit by hand.
CefMediaRouteCreateCallbackCppToC::CefMediaRouteCreateCallbackCppToC() {
GetStruct()->on_media_route_create_finished =
media_route_create_callback_on_media_route_create_finished;
}
// DESTRUCTOR - Do not edit by hand.
CefMediaRouteCreateCallbackCppToC::~CefMediaRouteCreateCallbackCppToC() {
shutdown_checker::AssertNotShutdown();
}
template <>
CefRefPtr<CefMediaRouteCreateCallback>
CefCppToCRefCounted<CefMediaRouteCreateCallbackCppToC,
CefMediaRouteCreateCallback,
cef_media_route_create_callback_t>::
UnwrapDerived(CefWrapperType type, cef_media_route_create_callback_t* s) {
NOTREACHED() << "Unexpected class type: " << type;
return nullptr;
}
template <>
CefWrapperType
CefCppToCRefCounted<CefMediaRouteCreateCallbackCppToC,
CefMediaRouteCreateCallback,
cef_media_route_create_callback_t>::kWrapperType =
WT_MEDIA_ROUTE_CREATE_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=8085b195054f43f67d4ee21d8b69b9e0ee8e2ac3$
//
#ifndef CEF_LIBCEF_DLL_CPPTOC_MEDIA_ROUTE_CREATE_CALLBACK_CPPTOC_H_
#define CEF_LIBCEF_DLL_CPPTOC_MEDIA_ROUTE_CREATE_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 CefMediaRouteCreateCallbackCppToC
: public CefCppToCRefCounted<CefMediaRouteCreateCallbackCppToC,
CefMediaRouteCreateCallback,
cef_media_route_create_callback_t> {
public:
CefMediaRouteCreateCallbackCppToC();
virtual ~CefMediaRouteCreateCallbackCppToC();
};
#endif // CEF_LIBCEF_DLL_CPPTOC_MEDIA_ROUTE_CREATE_CALLBACK_CPPTOC_H_

View File

@ -0,0 +1,177 @@
// 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=6b52fceffec99c0f274b5031266c20da5480d0c1$
//
#include "libcef_dll/cpptoc/media_router_cpptoc.h"
#include "libcef_dll/cpptoc/media_sink_cpptoc.h"
#include "libcef_dll/cpptoc/media_source_cpptoc.h"
#include "libcef_dll/cpptoc/registration_cpptoc.h"
#include "libcef_dll/ctocpp/media_observer_ctocpp.h"
#include "libcef_dll/ctocpp/media_route_create_callback_ctocpp.h"
#include "libcef_dll/shutdown_checker.h"
// GLOBAL FUNCTIONS - Body may be edited by hand.
CEF_EXPORT cef_media_router_t* cef_media_router_get_global() {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
CefRefPtr<CefMediaRouter> _retval = CefMediaRouter::GetGlobalMediaRouter();
// Return type: refptr_same
return CefMediaRouterCppToC::Wrap(_retval);
}
namespace {
// MEMBER FUNCTIONS - Body may be edited by hand.
struct _cef_registration_t* CEF_CALLBACK
media_router_add_observer(struct _cef_media_router_t* self,
struct _cef_media_observer_t* observer) {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return NULL;
// Verify param: observer; type: refptr_diff
DCHECK(observer);
if (!observer)
return NULL;
// Execute
CefRefPtr<CefRegistration> _retval =
CefMediaRouterCppToC::Get(self)->AddObserver(
CefMediaObserverCToCpp::Wrap(observer));
// Return type: refptr_same
return CefRegistrationCppToC::Wrap(_retval);
}
struct _cef_media_source_t* CEF_CALLBACK
media_router_get_source(struct _cef_media_router_t* self,
const cef_string_t* urn) {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return NULL;
// Verify param: urn; type: string_byref_const
DCHECK(urn);
if (!urn)
return NULL;
// Execute
CefRefPtr<CefMediaSource> _retval =
CefMediaRouterCppToC::Get(self)->GetSource(CefString(urn));
// Return type: refptr_same
return CefMediaSourceCppToC::Wrap(_retval);
}
void CEF_CALLBACK
media_router_notify_current_sinks(struct _cef_media_router_t* self) {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Execute
CefMediaRouterCppToC::Get(self)->NotifyCurrentSinks();
}
void CEF_CALLBACK
media_router_create_route(struct _cef_media_router_t* self,
struct _cef_media_source_t* source,
struct _cef_media_sink_t* sink,
struct _cef_media_route_create_callback_t* callback) {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Verify param: source; type: refptr_same
DCHECK(source);
if (!source)
return;
// Verify param: sink; type: refptr_same
DCHECK(sink);
if (!sink)
return;
// Verify param: callback; type: refptr_diff
DCHECK(callback);
if (!callback)
return;
// Execute
CefMediaRouterCppToC::Get(self)->CreateRoute(
CefMediaSourceCppToC::Unwrap(source), CefMediaSinkCppToC::Unwrap(sink),
CefMediaRouteCreateCallbackCToCpp::Wrap(callback));
}
void CEF_CALLBACK
media_router_notify_current_routes(struct _cef_media_router_t* self) {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Execute
CefMediaRouterCppToC::Get(self)->NotifyCurrentRoutes();
}
} // namespace
// CONSTRUCTOR - Do not edit by hand.
CefMediaRouterCppToC::CefMediaRouterCppToC() {
GetStruct()->add_observer = media_router_add_observer;
GetStruct()->get_source = media_router_get_source;
GetStruct()->notify_current_sinks = media_router_notify_current_sinks;
GetStruct()->create_route = media_router_create_route;
GetStruct()->notify_current_routes = media_router_notify_current_routes;
}
// DESTRUCTOR - Do not edit by hand.
CefMediaRouterCppToC::~CefMediaRouterCppToC() {
shutdown_checker::AssertNotShutdown();
}
template <>
CefRefPtr<CefMediaRouter>
CefCppToCRefCounted<CefMediaRouterCppToC, CefMediaRouter, cef_media_router_t>::
UnwrapDerived(CefWrapperType type, cef_media_router_t* s) {
NOTREACHED() << "Unexpected class type: " << type;
return nullptr;
}
template <>
CefWrapperType CefCppToCRefCounted<CefMediaRouterCppToC,
CefMediaRouter,
cef_media_router_t>::kWrapperType =
WT_MEDIA_ROUTER;

View File

@ -0,0 +1,37 @@
// 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=cea747c7202b95684b7208a312da818ddb094c0a$
//
#ifndef CEF_LIBCEF_DLL_CPPTOC_MEDIA_ROUTER_CPPTOC_H_
#define CEF_LIBCEF_DLL_CPPTOC_MEDIA_ROUTER_CPPTOC_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/cpptoc/cpptoc_ref_counted.h"
// Wrap a C++ class with a C structure.
// This class may be instantiated and accessed DLL-side only.
class CefMediaRouterCppToC : public CefCppToCRefCounted<CefMediaRouterCppToC,
CefMediaRouter,
cef_media_router_t> {
public:
CefMediaRouterCppToC();
virtual ~CefMediaRouterCppToC();
};
#endif // CEF_LIBCEF_DLL_CPPTOC_MEDIA_ROUTER_CPPTOC_H_

View File

@ -0,0 +1,177 @@
// 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=cbbac244f39cc1d644b0db80a3f7234399286368$
//
#include "libcef_dll/cpptoc/media_sink_cpptoc.h"
#include "libcef_dll/cpptoc/media_source_cpptoc.h"
#include "libcef_dll/shutdown_checker.h"
namespace {
// MEMBER FUNCTIONS - Body may be edited by hand.
cef_string_userfree_t CEF_CALLBACK
media_sink_get_id(struct _cef_media_sink_t* self) {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return NULL;
// Execute
CefString _retval = CefMediaSinkCppToC::Get(self)->GetId();
// Return type: string
return _retval.DetachToUserFree();
}
int CEF_CALLBACK media_sink_is_valid(struct _cef_media_sink_t* self) {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return 0;
// Execute
bool _retval = CefMediaSinkCppToC::Get(self)->IsValid();
// Return type: bool
return _retval;
}
cef_string_userfree_t CEF_CALLBACK
media_sink_get_name(struct _cef_media_sink_t* self) {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return NULL;
// Execute
CefString _retval = CefMediaSinkCppToC::Get(self)->GetName();
// Return type: string
return _retval.DetachToUserFree();
}
cef_string_userfree_t CEF_CALLBACK
media_sink_get_description(struct _cef_media_sink_t* self) {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return NULL;
// Execute
CefString _retval = CefMediaSinkCppToC::Get(self)->GetDescription();
// Return type: string
return _retval.DetachToUserFree();
}
int CEF_CALLBACK media_sink_is_cast_sink(struct _cef_media_sink_t* self) {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return 0;
// Execute
bool _retval = CefMediaSinkCppToC::Get(self)->IsCastSink();
// Return type: bool
return _retval;
}
int CEF_CALLBACK media_sink_is_dial_sink(struct _cef_media_sink_t* self) {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return 0;
// Execute
bool _retval = CefMediaSinkCppToC::Get(self)->IsDialSink();
// Return type: bool
return _retval;
}
int CEF_CALLBACK
media_sink_is_compatible_with(struct _cef_media_sink_t* self,
struct _cef_media_source_t* source) {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return 0;
// Verify param: source; type: refptr_same
DCHECK(source);
if (!source)
return 0;
// Execute
bool _retval = CefMediaSinkCppToC::Get(self)->IsCompatibleWith(
CefMediaSourceCppToC::Unwrap(source));
// Return type: bool
return _retval;
}
} // namespace
// CONSTRUCTOR - Do not edit by hand.
CefMediaSinkCppToC::CefMediaSinkCppToC() {
GetStruct()->get_id = media_sink_get_id;
GetStruct()->is_valid = media_sink_is_valid;
GetStruct()->get_name = media_sink_get_name;
GetStruct()->get_description = media_sink_get_description;
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;
}
// DESTRUCTOR - Do not edit by hand.
CefMediaSinkCppToC::~CefMediaSinkCppToC() {
shutdown_checker::AssertNotShutdown();
}
template <>
CefRefPtr<CefMediaSink>
CefCppToCRefCounted<CefMediaSinkCppToC, CefMediaSink, cef_media_sink_t>::
UnwrapDerived(CefWrapperType type, cef_media_sink_t* s) {
NOTREACHED() << "Unexpected class type: " << type;
return nullptr;
}
template <>
CefWrapperType CefCppToCRefCounted<CefMediaSinkCppToC,
CefMediaSink,
cef_media_sink_t>::kWrapperType =
WT_MEDIA_SINK;

View File

@ -0,0 +1,37 @@
// 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=409478c735898bd4e13315183e185a80ae570b74$
//
#ifndef CEF_LIBCEF_DLL_CPPTOC_MEDIA_SINK_CPPTOC_H_
#define CEF_LIBCEF_DLL_CPPTOC_MEDIA_SINK_CPPTOC_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/cpptoc/cpptoc_ref_counted.h"
// Wrap a C++ class with a C structure.
// This class may be instantiated and accessed DLL-side only.
class CefMediaSinkCppToC : public CefCppToCRefCounted<CefMediaSinkCppToC,
CefMediaSink,
cef_media_sink_t> {
public:
CefMediaSinkCppToC();
virtual ~CefMediaSinkCppToC();
};
#endif // CEF_LIBCEF_DLL_CPPTOC_MEDIA_SINK_CPPTOC_H_

View File

@ -0,0 +1,116 @@
// 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=ddd51b3c8020de1b10b00eef06d745a498168323$
//
#include "libcef_dll/cpptoc/media_source_cpptoc.h"
#include "libcef_dll/shutdown_checker.h"
namespace {
// MEMBER FUNCTIONS - Body may be edited by hand.
cef_string_userfree_t CEF_CALLBACK
media_source_get_id(struct _cef_media_source_t* self) {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return NULL;
// Execute
CefString _retval = CefMediaSourceCppToC::Get(self)->GetId();
// Return type: string
return _retval.DetachToUserFree();
}
int CEF_CALLBACK media_source_is_valid(struct _cef_media_source_t* self) {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return 0;
// Execute
bool _retval = CefMediaSourceCppToC::Get(self)->IsValid();
// Return type: bool
return _retval;
}
int CEF_CALLBACK media_source_is_cast_source(struct _cef_media_source_t* self) {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return 0;
// Execute
bool _retval = CefMediaSourceCppToC::Get(self)->IsCastSource();
// Return type: bool
return _retval;
}
int CEF_CALLBACK media_source_is_dial_source(struct _cef_media_source_t* self) {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return 0;
// Execute
bool _retval = CefMediaSourceCppToC::Get(self)->IsDialSource();
// Return type: bool
return _retval;
}
} // namespace
// CONSTRUCTOR - Do not edit by hand.
CefMediaSourceCppToC::CefMediaSourceCppToC() {
GetStruct()->get_id = media_source_get_id;
GetStruct()->is_valid = media_source_is_valid;
GetStruct()->is_cast_source = media_source_is_cast_source;
GetStruct()->is_dial_source = media_source_is_dial_source;
}
// DESTRUCTOR - Do not edit by hand.
CefMediaSourceCppToC::~CefMediaSourceCppToC() {
shutdown_checker::AssertNotShutdown();
}
template <>
CefRefPtr<CefMediaSource>
CefCppToCRefCounted<CefMediaSourceCppToC, CefMediaSource, cef_media_source_t>::
UnwrapDerived(CefWrapperType type, cef_media_source_t* s) {
NOTREACHED() << "Unexpected class type: " << type;
return nullptr;
}
template <>
CefWrapperType CefCppToCRefCounted<CefMediaSourceCppToC,
CefMediaSource,
cef_media_source_t>::kWrapperType =
WT_MEDIA_SOURCE;

View File

@ -0,0 +1,37 @@
// 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=aceafab724145242461fc9f5e7c76a365bb6d54c$
//
#ifndef CEF_LIBCEF_DLL_CPPTOC_MEDIA_SOURCE_CPPTOC_H_
#define CEF_LIBCEF_DLL_CPPTOC_MEDIA_SOURCE_CPPTOC_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/cpptoc/cpptoc_ref_counted.h"
// Wrap a C++ class with a C structure.
// This class may be instantiated and accessed DLL-side only.
class CefMediaSourceCppToC : public CefCppToCRefCounted<CefMediaSourceCppToC,
CefMediaSource,
cef_media_source_t> {
public:
CefMediaSourceCppToC();
virtual ~CefMediaSourceCppToC();
};
#endif // CEF_LIBCEF_DLL_CPPTOC_MEDIA_SOURCE_CPPTOC_H_

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=37c8c576c5bccd43f6124095e4ad55e88bc1a185$
//
#include "libcef_dll/cpptoc/registration_cpptoc.h"
#include "libcef_dll/shutdown_checker.h"
// CONSTRUCTOR - Do not edit by hand.
CefRegistrationCppToC::CefRegistrationCppToC() {}
// DESTRUCTOR - Do not edit by hand.
CefRegistrationCppToC::~CefRegistrationCppToC() {
shutdown_checker::AssertNotShutdown();
}
template <>
CefRefPtr<CefRegistration>
CefCppToCRefCounted<CefRegistrationCppToC,
CefRegistration,
cef_registration_t>::UnwrapDerived(CefWrapperType type,
cef_registration_t* s) {
NOTREACHED() << "Unexpected class type: " << type;
return nullptr;
}
template <>
CefWrapperType CefCppToCRefCounted<CefRegistrationCppToC,
CefRegistration,
cef_registration_t>::kWrapperType =
WT_REGISTRATION;

View File

@ -0,0 +1,37 @@
// 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=e27d69c1509e74c7f5d69f5829c27fa65e47fc2d$
//
#ifndef CEF_LIBCEF_DLL_CPPTOC_REGISTRATION_CPPTOC_H_
#define CEF_LIBCEF_DLL_CPPTOC_REGISTRATION_CPPTOC_H_
#pragma once
#if !defined(BUILDING_CEF_SHARED)
#error This file can be included DLL-side only
#endif
#include "include/capi/cef_registration_capi.h"
#include "include/cef_registration.h"
#include "libcef_dll/cpptoc/cpptoc_ref_counted.h"
// Wrap a C++ class with a C structure.
// This class may be instantiated and accessed DLL-side only.
class CefRegistrationCppToC : public CefCppToCRefCounted<CefRegistrationCppToC,
CefRegistration,
cef_registration_t> {
public:
CefRegistrationCppToC();
virtual ~CefRegistrationCppToC();
};
#endif // CEF_LIBCEF_DLL_CPPTOC_REGISTRATION_CPPTOC_H_

View File

@ -9,13 +9,14 @@
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=4af6d074b7de62b759a9555a0b0246e57c290328$
// $hash=5168000f75f7911dce0bffcf47341e4ee1c2a275$
//
#include "libcef_dll/cpptoc/request_context_cpptoc.h"
#include "libcef_dll/cpptoc/cookie_manager_cpptoc.h"
#include "libcef_dll/cpptoc/dictionary_value_cpptoc.h"
#include "libcef_dll/cpptoc/extension_cpptoc.h"
#include "libcef_dll/cpptoc/media_router_cpptoc.h"
#include "libcef_dll/cpptoc/value_cpptoc.h"
#include "libcef_dll/ctocpp/completion_callback_ctocpp.h"
#include "libcef_dll/ctocpp/extension_handler_ctocpp.h"
@ -540,6 +541,22 @@ request_context_get_extension(struct _cef_request_context_t* self,
return CefExtensionCppToC::Wrap(_retval);
}
cef_media_router_t* CEF_CALLBACK
request_context_get_media_router(struct _cef_request_context_t* self) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return NULL;
// Execute
CefRefPtr<CefMediaRouter> _retval =
CefRequestContextCppToC::Get(self)->GetMediaRouter();
// Return type: refptr_same
return CefMediaRouterCppToC::Wrap(_retval);
}
} // namespace
// CONSTRUCTOR - Do not edit by hand.
@ -573,6 +590,7 @@ CefRequestContextCppToC::CefRequestContextCppToC() {
GetStruct()->has_extension = request_context_has_extension;
GetStruct()->get_extensions = request_context_get_extensions;
GetStruct()->get_extension = request_context_get_extension;
GetStruct()->get_media_router = request_context_get_media_router;
}
// DESTRUCTOR - Do not edit by hand.

View File

@ -0,0 +1,158 @@
// 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=6eed652a4bd13cf685980f7ea0b838d73e6071ba$
//
#include "libcef_dll/ctocpp/media_observer_ctocpp.h"
#include "libcef_dll/cpptoc/media_route_cpptoc.h"
#include "libcef_dll/cpptoc/media_sink_cpptoc.h"
#include "libcef_dll/shutdown_checker.h"
// VIRTUAL METHODS - Body may be edited by hand.
NO_SANITIZE("cfi-icall")
void CefMediaObserverCToCpp::OnSinks(
const std::vector<CefRefPtr<CefMediaSink>>& sinks) {
shutdown_checker::AssertNotShutdown();
cef_media_observer_t* _struct = GetStruct();
if (CEF_MEMBER_MISSING(_struct, on_sinks))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Translate param: sinks; type: refptr_vec_diff_byref_const
const size_t sinksCount = sinks.size();
cef_media_sink_t** sinksList = NULL;
if (sinksCount > 0) {
sinksList = new cef_media_sink_t*[sinksCount];
DCHECK(sinksList);
if (sinksList) {
for (size_t i = 0; i < sinksCount; ++i) {
sinksList[i] = CefMediaSinkCppToC::Wrap(sinks[i]);
}
}
}
// Execute
_struct->on_sinks(_struct, sinksCount, sinksList);
// Restore param:sinks; type: refptr_vec_diff_byref_const
if (sinksList)
delete[] sinksList;
}
NO_SANITIZE("cfi-icall")
void CefMediaObserverCToCpp::OnRoutes(
const std::vector<CefRefPtr<CefMediaRoute>>& routes) {
shutdown_checker::AssertNotShutdown();
cef_media_observer_t* _struct = GetStruct();
if (CEF_MEMBER_MISSING(_struct, on_routes))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Translate param: routes; type: refptr_vec_diff_byref_const
const size_t routesCount = routes.size();
cef_media_route_t** routesList = NULL;
if (routesCount > 0) {
routesList = new cef_media_route_t*[routesCount];
DCHECK(routesList);
if (routesList) {
for (size_t i = 0; i < routesCount; ++i) {
routesList[i] = CefMediaRouteCppToC::Wrap(routes[i]);
}
}
}
// Execute
_struct->on_routes(_struct, routesCount, routesList);
// Restore param:routes; type: refptr_vec_diff_byref_const
if (routesList)
delete[] routesList;
}
NO_SANITIZE("cfi-icall")
void CefMediaObserverCToCpp::OnRouteStateChanged(CefRefPtr<CefMediaRoute> route,
ConnectionState state) {
shutdown_checker::AssertNotShutdown();
cef_media_observer_t* _struct = GetStruct();
if (CEF_MEMBER_MISSING(_struct, on_route_state_changed))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: route; type: refptr_diff
DCHECK(route.get());
if (!route.get())
return;
// Execute
_struct->on_route_state_changed(_struct, CefMediaRouteCppToC::Wrap(route),
state);
}
NO_SANITIZE("cfi-icall")
void CefMediaObserverCToCpp::OnRouteMessageReceived(
CefRefPtr<CefMediaRoute> route,
const void* message,
size_t message_size) {
shutdown_checker::AssertNotShutdown();
cef_media_observer_t* _struct = GetStruct();
if (CEF_MEMBER_MISSING(_struct, on_route_message_received))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: route; type: refptr_diff
DCHECK(route.get());
if (!route.get())
return;
// Verify param: message; type: simple_byaddr
DCHECK(message);
if (!message)
return;
// Execute
_struct->on_route_message_received(_struct, CefMediaRouteCppToC::Wrap(route),
message, message_size);
}
// CONSTRUCTOR - Do not edit by hand.
CefMediaObserverCToCpp::CefMediaObserverCToCpp() {}
// DESTRUCTOR - Do not edit by hand.
CefMediaObserverCToCpp::~CefMediaObserverCToCpp() {
shutdown_checker::AssertNotShutdown();
}
template <>
cef_media_observer_t*
CefCToCppRefCounted<CefMediaObserverCToCpp,
CefMediaObserver,
cef_media_observer_t>::UnwrapDerived(CefWrapperType type,
CefMediaObserver* c) {
NOTREACHED() << "Unexpected class type: " << type;
return nullptr;
}
template <>
CefWrapperType CefCToCppRefCounted<CefMediaObserverCToCpp,
CefMediaObserver,
cef_media_observer_t>::kWrapperType =
WT_MEDIA_OBSERVER;

View File

@ -0,0 +1,48 @@
// 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=4c2e71870e5f8a31052431a5242f91392607502d$
//
#ifndef CEF_LIBCEF_DLL_CTOCPP_MEDIA_OBSERVER_CTOCPP_H_
#define CEF_LIBCEF_DLL_CTOCPP_MEDIA_OBSERVER_CTOCPP_H_
#pragma once
#if !defined(BUILDING_CEF_SHARED)
#error This file can be included DLL-side only
#endif
#include <vector>
#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 CefMediaObserverCToCpp
: public CefCToCppRefCounted<CefMediaObserverCToCpp,
CefMediaObserver,
cef_media_observer_t> {
public:
CefMediaObserverCToCpp();
virtual ~CefMediaObserverCToCpp();
// CefMediaObserver methods.
void OnSinks(const std::vector<CefRefPtr<CefMediaSink>>& sinks) override;
void OnRoutes(const std::vector<CefRefPtr<CefMediaRoute>>& routes) override;
void OnRouteStateChanged(CefRefPtr<CefMediaRoute> route,
ConnectionState state) override;
void OnRouteMessageReceived(CefRefPtr<CefMediaRoute> route,
const void* message,
size_t message_size) override;
};
#endif // CEF_LIBCEF_DLL_CTOCPP_MEDIA_OBSERVER_CTOCPP_H_

View File

@ -0,0 +1,66 @@
// 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=93dd08de00931b1c00ec0307cc70496455936b0c$
//
#include "libcef_dll/ctocpp/media_route_create_callback_ctocpp.h"
#include "libcef_dll/cpptoc/media_route_cpptoc.h"
#include "libcef_dll/shutdown_checker.h"
// VIRTUAL METHODS - Body may be edited by hand.
NO_SANITIZE("cfi-icall")
void CefMediaRouteCreateCallbackCToCpp::OnMediaRouteCreateFinished(
RouteCreateResult result,
const CefString& error,
CefRefPtr<CefMediaRoute> route) {
shutdown_checker::AssertNotShutdown();
cef_media_route_create_callback_t* _struct = GetStruct();
if (CEF_MEMBER_MISSING(_struct, on_media_route_create_finished))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Unverified params: error, route
// Execute
_struct->on_media_route_create_finished(_struct, result, error.GetStruct(),
CefMediaRouteCppToC::Wrap(route));
}
// CONSTRUCTOR - Do not edit by hand.
CefMediaRouteCreateCallbackCToCpp::CefMediaRouteCreateCallbackCToCpp() {}
// DESTRUCTOR - Do not edit by hand.
CefMediaRouteCreateCallbackCToCpp::~CefMediaRouteCreateCallbackCToCpp() {
shutdown_checker::AssertNotShutdown();
}
template <>
cef_media_route_create_callback_t*
CefCToCppRefCounted<CefMediaRouteCreateCallbackCToCpp,
CefMediaRouteCreateCallback,
cef_media_route_create_callback_t>::
UnwrapDerived(CefWrapperType type, CefMediaRouteCreateCallback* c) {
NOTREACHED() << "Unexpected class type: " << type;
return nullptr;
}
template <>
CefWrapperType
CefCToCppRefCounted<CefMediaRouteCreateCallbackCToCpp,
CefMediaRouteCreateCallback,
cef_media_route_create_callback_t>::kWrapperType =
WT_MEDIA_ROUTE_CREATE_CALLBACK;

View File

@ -0,0 +1,43 @@
// 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=ac5657bccd7830fde1d3dddfad69d87dff2ae684$
//
#ifndef CEF_LIBCEF_DLL_CTOCPP_MEDIA_ROUTE_CREATE_CALLBACK_CTOCPP_H_
#define CEF_LIBCEF_DLL_CTOCPP_MEDIA_ROUTE_CREATE_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 CefMediaRouteCreateCallbackCToCpp
: public CefCToCppRefCounted<CefMediaRouteCreateCallbackCToCpp,
CefMediaRouteCreateCallback,
cef_media_route_create_callback_t> {
public:
CefMediaRouteCreateCallbackCToCpp();
virtual ~CefMediaRouteCreateCallbackCToCpp();
// CefMediaRouteCreateCallback methods.
void OnMediaRouteCreateFinished(RouteCreateResult result,
const CefString& error,
CefRefPtr<CefMediaRoute> route) override;
};
#endif // CEF_LIBCEF_DLL_CTOCPP_MEDIA_ROUTE_CREATE_CALLBACK_CTOCPP_H_

View File

@ -0,0 +1,129 @@
// 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=7fe34c4b79d10a88bfcf5ec46a54cf52d3657e87$
//
#include "libcef_dll/ctocpp/media_route_ctocpp.h"
#include "libcef_dll/ctocpp/media_sink_ctocpp.h"
#include "libcef_dll/ctocpp/media_source_ctocpp.h"
#include "libcef_dll/shutdown_checker.h"
// VIRTUAL METHODS - Body may be edited by hand.
NO_SANITIZE("cfi-icall") CefString CefMediaRouteCToCpp::GetId() {
shutdown_checker::AssertNotShutdown();
cef_media_route_t* _struct = GetStruct();
if (CEF_MEMBER_MISSING(_struct, get_id))
return CefString();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
cef_string_userfree_t _retval = _struct->get_id(_struct);
// Return type: string
CefString _retvalStr;
_retvalStr.AttachToUserFree(_retval);
return _retvalStr;
}
NO_SANITIZE("cfi-icall")
CefRefPtr<CefMediaSource> CefMediaRouteCToCpp::GetSource() {
shutdown_checker::AssertNotShutdown();
cef_media_route_t* _struct = GetStruct();
if (CEF_MEMBER_MISSING(_struct, get_source))
return nullptr;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
cef_media_source_t* _retval = _struct->get_source(_struct);
// Return type: refptr_same
return CefMediaSourceCToCpp::Wrap(_retval);
}
NO_SANITIZE("cfi-icall")
CefRefPtr<CefMediaSink> CefMediaRouteCToCpp::GetSink() {
shutdown_checker::AssertNotShutdown();
cef_media_route_t* _struct = GetStruct();
if (CEF_MEMBER_MISSING(_struct, get_sink))
return nullptr;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
cef_media_sink_t* _retval = _struct->get_sink(_struct);
// Return type: refptr_same
return CefMediaSinkCToCpp::Wrap(_retval);
}
NO_SANITIZE("cfi-icall")
void CefMediaRouteCToCpp::SendRouteMessage(const void* message,
size_t message_size) {
shutdown_checker::AssertNotShutdown();
cef_media_route_t* _struct = GetStruct();
if (CEF_MEMBER_MISSING(_struct, send_route_message))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: message; type: simple_byaddr
DCHECK(message);
if (!message)
return;
// Execute
_struct->send_route_message(_struct, message, message_size);
}
NO_SANITIZE("cfi-icall") void CefMediaRouteCToCpp::Terminate() {
shutdown_checker::AssertNotShutdown();
cef_media_route_t* _struct = GetStruct();
if (CEF_MEMBER_MISSING(_struct, terminate))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
_struct->terminate(_struct);
}
// CONSTRUCTOR - Do not edit by hand.
CefMediaRouteCToCpp::CefMediaRouteCToCpp() {}
// DESTRUCTOR - Do not edit by hand.
CefMediaRouteCToCpp::~CefMediaRouteCToCpp() {
shutdown_checker::AssertNotShutdown();
}
template <>
cef_media_route_t*
CefCToCppRefCounted<CefMediaRouteCToCpp, CefMediaRoute, cef_media_route_t>::
UnwrapDerived(CefWrapperType type, CefMediaRoute* c) {
NOTREACHED() << "Unexpected class type: " << type;
return nullptr;
}
template <>
CefWrapperType CefCToCppRefCounted<CefMediaRouteCToCpp,
CefMediaRoute,
cef_media_route_t>::kWrapperType =
WT_MEDIA_ROUTE;

View File

@ -0,0 +1,44 @@
// 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=cb792f909646d1ccd3644877ce2393080465471a$
//
#ifndef CEF_LIBCEF_DLL_CTOCPP_MEDIA_ROUTE_CTOCPP_H_
#define CEF_LIBCEF_DLL_CTOCPP_MEDIA_ROUTE_CTOCPP_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/ctocpp/ctocpp_ref_counted.h"
// Wrap a C structure with a C++ class.
// This class may be instantiated and accessed wrapper-side only.
class CefMediaRouteCToCpp : public CefCToCppRefCounted<CefMediaRouteCToCpp,
CefMediaRoute,
cef_media_route_t> {
public:
CefMediaRouteCToCpp();
virtual ~CefMediaRouteCToCpp();
// CefMediaRoute methods.
CefString GetId() OVERRIDE;
CefRefPtr<CefMediaSource> GetSource() OVERRIDE;
CefRefPtr<CefMediaSink> GetSink() OVERRIDE;
void SendRouteMessage(const void* message, size_t message_size) OVERRIDE;
void Terminate() OVERRIDE;
};
#endif // CEF_LIBCEF_DLL_CTOCPP_MEDIA_ROUTE_CTOCPP_H_

View File

@ -0,0 +1,167 @@
// 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=4b8ab6373fcb0a84a818c2c5ef8982600346f34b$
//
#include "libcef_dll/ctocpp/media_router_ctocpp.h"
#include "libcef_dll/cpptoc/media_observer_cpptoc.h"
#include "libcef_dll/cpptoc/media_route_create_callback_cpptoc.h"
#include "libcef_dll/ctocpp/media_sink_ctocpp.h"
#include "libcef_dll/ctocpp/media_source_ctocpp.h"
#include "libcef_dll/ctocpp/registration_ctocpp.h"
#include "libcef_dll/shutdown_checker.h"
// STATIC METHODS - Body may be edited by hand.
NO_SANITIZE("cfi-icall")
CefRefPtr<CefMediaRouter> CefMediaRouter::GetGlobalMediaRouter() {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
cef_media_router_t* _retval = cef_media_router_get_global();
// Return type: refptr_same
return CefMediaRouterCToCpp::Wrap(_retval);
}
// VIRTUAL METHODS - Body may be edited by hand.
NO_SANITIZE("cfi-icall")
CefRefPtr<CefRegistration> CefMediaRouterCToCpp::AddObserver(
CefRefPtr<CefMediaObserver> observer) {
shutdown_checker::AssertNotShutdown();
cef_media_router_t* _struct = GetStruct();
if (CEF_MEMBER_MISSING(_struct, add_observer))
return nullptr;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: observer; type: refptr_diff
DCHECK(observer.get());
if (!observer.get())
return nullptr;
// Execute
cef_registration_t* _retval =
_struct->add_observer(_struct, CefMediaObserverCppToC::Wrap(observer));
// Return type: refptr_same
return CefRegistrationCToCpp::Wrap(_retval);
}
NO_SANITIZE("cfi-icall")
CefRefPtr<CefMediaSource> CefMediaRouterCToCpp::GetSource(
const CefString& urn) {
shutdown_checker::AssertNotShutdown();
cef_media_router_t* _struct = GetStruct();
if (CEF_MEMBER_MISSING(_struct, get_source))
return nullptr;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: urn; type: string_byref_const
DCHECK(!urn.empty());
if (urn.empty())
return nullptr;
// Execute
cef_media_source_t* _retval = _struct->get_source(_struct, urn.GetStruct());
// Return type: refptr_same
return CefMediaSourceCToCpp::Wrap(_retval);
}
NO_SANITIZE("cfi-icall") void CefMediaRouterCToCpp::NotifyCurrentSinks() {
shutdown_checker::AssertNotShutdown();
cef_media_router_t* _struct = GetStruct();
if (CEF_MEMBER_MISSING(_struct, notify_current_sinks))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
_struct->notify_current_sinks(_struct);
}
NO_SANITIZE("cfi-icall")
void CefMediaRouterCToCpp::CreateRoute(
CefRefPtr<CefMediaSource> source,
CefRefPtr<CefMediaSink> sink,
CefRefPtr<CefMediaRouteCreateCallback> callback) {
shutdown_checker::AssertNotShutdown();
cef_media_router_t* _struct = GetStruct();
if (CEF_MEMBER_MISSING(_struct, create_route))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: source; type: refptr_same
DCHECK(source.get());
if (!source.get())
return;
// Verify param: sink; type: refptr_same
DCHECK(sink.get());
if (!sink.get())
return;
// Verify param: callback; type: refptr_diff
DCHECK(callback.get());
if (!callback.get())
return;
// Execute
_struct->create_route(_struct, CefMediaSourceCToCpp::Unwrap(source),
CefMediaSinkCToCpp::Unwrap(sink),
CefMediaRouteCreateCallbackCppToC::Wrap(callback));
}
NO_SANITIZE("cfi-icall") void CefMediaRouterCToCpp::NotifyCurrentRoutes() {
shutdown_checker::AssertNotShutdown();
cef_media_router_t* _struct = GetStruct();
if (CEF_MEMBER_MISSING(_struct, notify_current_routes))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
_struct->notify_current_routes(_struct);
}
// CONSTRUCTOR - Do not edit by hand.
CefMediaRouterCToCpp::CefMediaRouterCToCpp() {}
// DESTRUCTOR - Do not edit by hand.
CefMediaRouterCToCpp::~CefMediaRouterCToCpp() {
shutdown_checker::AssertNotShutdown();
}
template <>
cef_media_router_t*
CefCToCppRefCounted<CefMediaRouterCToCpp, CefMediaRouter, cef_media_router_t>::
UnwrapDerived(CefWrapperType type, CefMediaRouter* c) {
NOTREACHED() << "Unexpected class type: " << type;
return nullptr;
}
template <>
CefWrapperType CefCToCppRefCounted<CefMediaRouterCToCpp,
CefMediaRouter,
cef_media_router_t>::kWrapperType =
WT_MEDIA_ROUTER;

View File

@ -0,0 +1,47 @@
// 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=e3d62de09a699415a839cadda52cca2582d90063$
//
#ifndef CEF_LIBCEF_DLL_CTOCPP_MEDIA_ROUTER_CTOCPP_H_
#define CEF_LIBCEF_DLL_CTOCPP_MEDIA_ROUTER_CTOCPP_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/ctocpp/ctocpp_ref_counted.h"
// Wrap a C structure with a C++ class.
// This class may be instantiated and accessed wrapper-side only.
class CefMediaRouterCToCpp : public CefCToCppRefCounted<CefMediaRouterCToCpp,
CefMediaRouter,
cef_media_router_t> {
public:
CefMediaRouterCToCpp();
virtual ~CefMediaRouterCToCpp();
// CefMediaRouter methods.
CefRefPtr<CefRegistration> AddObserver(
CefRefPtr<CefMediaObserver> observer) OVERRIDE;
CefRefPtr<CefMediaSource> GetSource(const CefString& urn) OVERRIDE;
void NotifyCurrentSinks() OVERRIDE;
void CreateRoute(CefRefPtr<CefMediaSource> source,
CefRefPtr<CefMediaSink> sink,
CefRefPtr<CefMediaRouteCreateCallback> callback) OVERRIDE;
void NotifyCurrentRoutes() OVERRIDE;
};
#endif // CEF_LIBCEF_DLL_CTOCPP_MEDIA_ROUTER_CTOCPP_H_

View File

@ -0,0 +1,168 @@
// 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=bb39ec5e546482b707c1e01a83fc1b064d96a4e6$
//
#include "libcef_dll/ctocpp/media_sink_ctocpp.h"
#include "libcef_dll/ctocpp/media_source_ctocpp.h"
#include "libcef_dll/shutdown_checker.h"
// VIRTUAL METHODS - Body may be edited by hand.
NO_SANITIZE("cfi-icall") CefString CefMediaSinkCToCpp::GetId() {
shutdown_checker::AssertNotShutdown();
cef_media_sink_t* _struct = GetStruct();
if (CEF_MEMBER_MISSING(_struct, get_id))
return CefString();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
cef_string_userfree_t _retval = _struct->get_id(_struct);
// Return type: string
CefString _retvalStr;
_retvalStr.AttachToUserFree(_retval);
return _retvalStr;
}
NO_SANITIZE("cfi-icall") bool CefMediaSinkCToCpp::IsValid() {
shutdown_checker::AssertNotShutdown();
cef_media_sink_t* _struct = GetStruct();
if (CEF_MEMBER_MISSING(_struct, is_valid))
return false;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
int _retval = _struct->is_valid(_struct);
// Return type: bool
return _retval ? true : false;
}
NO_SANITIZE("cfi-icall") CefString CefMediaSinkCToCpp::GetName() {
shutdown_checker::AssertNotShutdown();
cef_media_sink_t* _struct = GetStruct();
if (CEF_MEMBER_MISSING(_struct, get_name))
return CefString();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
cef_string_userfree_t _retval = _struct->get_name(_struct);
// Return type: string
CefString _retvalStr;
_retvalStr.AttachToUserFree(_retval);
return _retvalStr;
}
NO_SANITIZE("cfi-icall") CefString CefMediaSinkCToCpp::GetDescription() {
shutdown_checker::AssertNotShutdown();
cef_media_sink_t* _struct = GetStruct();
if (CEF_MEMBER_MISSING(_struct, get_description))
return CefString();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
cef_string_userfree_t _retval = _struct->get_description(_struct);
// Return type: string
CefString _retvalStr;
_retvalStr.AttachToUserFree(_retval);
return _retvalStr;
}
NO_SANITIZE("cfi-icall") bool CefMediaSinkCToCpp::IsCastSink() {
shutdown_checker::AssertNotShutdown();
cef_media_sink_t* _struct = GetStruct();
if (CEF_MEMBER_MISSING(_struct, is_cast_sink))
return false;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
int _retval = _struct->is_cast_sink(_struct);
// Return type: bool
return _retval ? true : false;
}
NO_SANITIZE("cfi-icall") bool CefMediaSinkCToCpp::IsDialSink() {
shutdown_checker::AssertNotShutdown();
cef_media_sink_t* _struct = GetStruct();
if (CEF_MEMBER_MISSING(_struct, is_dial_sink))
return false;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
int _retval = _struct->is_dial_sink(_struct);
// Return type: bool
return _retval ? true : false;
}
NO_SANITIZE("cfi-icall")
bool CefMediaSinkCToCpp::IsCompatibleWith(CefRefPtr<CefMediaSource> source) {
shutdown_checker::AssertNotShutdown();
cef_media_sink_t* _struct = GetStruct();
if (CEF_MEMBER_MISSING(_struct, is_compatible_with))
return false;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: source; type: refptr_same
DCHECK(source.get());
if (!source.get())
return false;
// Execute
int _retval = _struct->is_compatible_with(
_struct, CefMediaSourceCToCpp::Unwrap(source));
// Return type: bool
return _retval ? true : false;
}
// CONSTRUCTOR - Do not edit by hand.
CefMediaSinkCToCpp::CefMediaSinkCToCpp() {}
// DESTRUCTOR - Do not edit by hand.
CefMediaSinkCToCpp::~CefMediaSinkCToCpp() {
shutdown_checker::AssertNotShutdown();
}
template <>
cef_media_sink_t*
CefCToCppRefCounted<CefMediaSinkCToCpp, CefMediaSink, cef_media_sink_t>::
UnwrapDerived(CefWrapperType type, CefMediaSink* c) {
NOTREACHED() << "Unexpected class type: " << type;
return nullptr;
}
template <>
CefWrapperType CefCToCppRefCounted<CefMediaSinkCToCpp,
CefMediaSink,
cef_media_sink_t>::kWrapperType =
WT_MEDIA_SINK;

View File

@ -0,0 +1,46 @@
// 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=d69c0bdadc802bc7cb970c316f3a0ed8529c5f9c$
//
#ifndef CEF_LIBCEF_DLL_CTOCPP_MEDIA_SINK_CTOCPP_H_
#define CEF_LIBCEF_DLL_CTOCPP_MEDIA_SINK_CTOCPP_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/ctocpp/ctocpp_ref_counted.h"
// Wrap a C structure with a C++ class.
// This class may be instantiated and accessed wrapper-side only.
class CefMediaSinkCToCpp : public CefCToCppRefCounted<CefMediaSinkCToCpp,
CefMediaSink,
cef_media_sink_t> {
public:
CefMediaSinkCToCpp();
virtual ~CefMediaSinkCToCpp();
// CefMediaSink methods.
CefString GetId() OVERRIDE;
bool IsValid() OVERRIDE;
CefString GetName() OVERRIDE;
CefString GetDescription() OVERRIDE;
bool IsCastSink() OVERRIDE;
bool IsDialSink() OVERRIDE;
bool IsCompatibleWith(CefRefPtr<CefMediaSource> source) OVERRIDE;
};
#endif // CEF_LIBCEF_DLL_CTOCPP_MEDIA_SINK_CTOCPP_H_

View File

@ -0,0 +1,108 @@
// 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=2b4f20db4eccd1429c748f39db19852cd1644b4a$
//
#include "libcef_dll/ctocpp/media_source_ctocpp.h"
#include "libcef_dll/shutdown_checker.h"
// VIRTUAL METHODS - Body may be edited by hand.
NO_SANITIZE("cfi-icall") CefString CefMediaSourceCToCpp::GetId() {
shutdown_checker::AssertNotShutdown();
cef_media_source_t* _struct = GetStruct();
if (CEF_MEMBER_MISSING(_struct, get_id))
return CefString();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
cef_string_userfree_t _retval = _struct->get_id(_struct);
// Return type: string
CefString _retvalStr;
_retvalStr.AttachToUserFree(_retval);
return _retvalStr;
}
NO_SANITIZE("cfi-icall") bool CefMediaSourceCToCpp::IsValid() {
shutdown_checker::AssertNotShutdown();
cef_media_source_t* _struct = GetStruct();
if (CEF_MEMBER_MISSING(_struct, is_valid))
return false;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
int _retval = _struct->is_valid(_struct);
// Return type: bool
return _retval ? true : false;
}
NO_SANITIZE("cfi-icall") bool CefMediaSourceCToCpp::IsCastSource() {
shutdown_checker::AssertNotShutdown();
cef_media_source_t* _struct = GetStruct();
if (CEF_MEMBER_MISSING(_struct, is_cast_source))
return false;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
int _retval = _struct->is_cast_source(_struct);
// Return type: bool
return _retval ? true : false;
}
NO_SANITIZE("cfi-icall") bool CefMediaSourceCToCpp::IsDialSource() {
shutdown_checker::AssertNotShutdown();
cef_media_source_t* _struct = GetStruct();
if (CEF_MEMBER_MISSING(_struct, is_dial_source))
return false;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
int _retval = _struct->is_dial_source(_struct);
// Return type: bool
return _retval ? true : false;
}
// CONSTRUCTOR - Do not edit by hand.
CefMediaSourceCToCpp::CefMediaSourceCToCpp() {}
// DESTRUCTOR - Do not edit by hand.
CefMediaSourceCToCpp::~CefMediaSourceCToCpp() {
shutdown_checker::AssertNotShutdown();
}
template <>
cef_media_source_t*
CefCToCppRefCounted<CefMediaSourceCToCpp, CefMediaSource, cef_media_source_t>::
UnwrapDerived(CefWrapperType type, CefMediaSource* c) {
NOTREACHED() << "Unexpected class type: " << type;
return nullptr;
}
template <>
CefWrapperType CefCToCppRefCounted<CefMediaSourceCToCpp,
CefMediaSource,
cef_media_source_t>::kWrapperType =
WT_MEDIA_SOURCE;

View File

@ -0,0 +1,43 @@
// 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=73aeb0f58611c0d7a9fa13f1d9268912e0fba0bd$
//
#ifndef CEF_LIBCEF_DLL_CTOCPP_MEDIA_SOURCE_CTOCPP_H_
#define CEF_LIBCEF_DLL_CTOCPP_MEDIA_SOURCE_CTOCPP_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/ctocpp/ctocpp_ref_counted.h"
// Wrap a C structure with a C++ class.
// This class may be instantiated and accessed wrapper-side only.
class CefMediaSourceCToCpp : public CefCToCppRefCounted<CefMediaSourceCToCpp,
CefMediaSource,
cef_media_source_t> {
public:
CefMediaSourceCToCpp();
virtual ~CefMediaSourceCToCpp();
// CefMediaSource methods.
CefString GetId() OVERRIDE;
bool IsValid() OVERRIDE;
bool IsCastSource() OVERRIDE;
bool IsDialSource() OVERRIDE;
};
#endif // CEF_LIBCEF_DLL_CTOCPP_MEDIA_SOURCE_CTOCPP_H_

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=89f0f0c0ae2485adbf8140a419969901e5766b51$
//
#include "libcef_dll/ctocpp/registration_ctocpp.h"
#include "libcef_dll/shutdown_checker.h"
// CONSTRUCTOR - Do not edit by hand.
CefRegistrationCToCpp::CefRegistrationCToCpp() {}
// DESTRUCTOR - Do not edit by hand.
CefRegistrationCToCpp::~CefRegistrationCToCpp() {
shutdown_checker::AssertNotShutdown();
}
template <>
cef_registration_t*
CefCToCppRefCounted<CefRegistrationCToCpp,
CefRegistration,
cef_registration_t>::UnwrapDerived(CefWrapperType type,
CefRegistration* c) {
NOTREACHED() << "Unexpected class type: " << type;
return nullptr;
}
template <>
CefWrapperType CefCToCppRefCounted<CefRegistrationCToCpp,
CefRegistration,
cef_registration_t>::kWrapperType =
WT_REGISTRATION;

View File

@ -0,0 +1,39 @@
// 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=6d458b0a8e42e3f3347d5101f8d3f1f88264ecc7$
//
#ifndef CEF_LIBCEF_DLL_CTOCPP_REGISTRATION_CTOCPP_H_
#define CEF_LIBCEF_DLL_CTOCPP_REGISTRATION_CTOCPP_H_
#pragma once
#if !defined(WRAPPING_CEF_SHARED)
#error This file can be included wrapper-side only
#endif
#include "include/capi/cef_registration_capi.h"
#include "include/cef_registration.h"
#include "libcef_dll/ctocpp/ctocpp_ref_counted.h"
// Wrap a C structure with a C++ class.
// This class may be instantiated and accessed wrapper-side only.
class CefRegistrationCToCpp : public CefCToCppRefCounted<CefRegistrationCToCpp,
CefRegistration,
cef_registration_t> {
public:
CefRegistrationCToCpp();
virtual ~CefRegistrationCToCpp();
// CefRegistration methods.
};
#endif // CEF_LIBCEF_DLL_CTOCPP_REGISTRATION_CTOCPP_H_

View File

@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=dd21194253186ee403d7ffe5098e87b030eeb4c8$
// $hash=a29d8f9e49143e42a0ae0204c7d439c76b3c371c$
//
#include "libcef_dll/ctocpp/request_context_ctocpp.h"
@ -21,6 +21,7 @@
#include "libcef_dll/ctocpp/cookie_manager_ctocpp.h"
#include "libcef_dll/ctocpp/dictionary_value_ctocpp.h"
#include "libcef_dll/ctocpp/extension_ctocpp.h"
#include "libcef_dll/ctocpp/media_router_ctocpp.h"
#include "libcef_dll/ctocpp/value_ctocpp.h"
#include "libcef_dll/transfer_util.h"
@ -525,6 +526,21 @@ CefRefPtr<CefExtension> CefRequestContextCToCpp::GetExtension(
return CefExtensionCToCpp::Wrap(_retval);
}
NO_SANITIZE("cfi-icall")
CefRefPtr<CefMediaRouter> CefRequestContextCToCpp::GetMediaRouter() {
cef_request_context_t* _struct = GetStruct();
if (CEF_MEMBER_MISSING(_struct, get_media_router))
return nullptr;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
cef_media_router_t* _retval = _struct->get_media_router(_struct);
// Return type: refptr_same
return CefMediaRouterCToCpp::Wrap(_retval);
}
// CONSTRUCTOR - Do not edit by hand.
CefRequestContextCToCpp::CefRequestContextCToCpp() {}

View File

@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=d962f641e63a8dd86bdb44eb058c39d97db7f880$
// $hash=7841eec57c44171080b5d958ca03760cbe23f22b$
//
#ifndef CEF_LIBCEF_DLL_CTOCPP_REQUEST_CONTEXT_CTOCPP_H_
@ -75,6 +75,7 @@ class CefRequestContextCToCpp
bool HasExtension(const CefString& extension_id) OVERRIDE;
bool GetExtensions(std::vector<CefString>& extension_ids) OVERRIDE;
CefRefPtr<CefExtension> GetExtension(const CefString& extension_id) OVERRIDE;
CefRefPtr<CefMediaRouter> GetMediaRouter() OVERRIDE;
};
#endif // CEF_LIBCEF_DLL_CTOCPP_REQUEST_CONTEXT_CTOCPP_H_

View File

@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=5e0a3a27b41b550a1dd4985eec9034a6f7c2b7d7$
// $hash=bf82965f02cafae5a1afc80ab0c976436be9712e$
//
#include <dlfcn.h>
@ -23,6 +23,7 @@
#include "include/capi/cef_drag_data_capi.h"
#include "include/capi/cef_file_util_capi.h"
#include "include/capi/cef_image_capi.h"
#include "include/capi/cef_media_router_capi.h"
#include "include/capi/cef_menu_model_capi.h"
#include "include/capi/cef_origin_whitelist_capi.h"
#include "include/capi/cef_parser_capi.h"
@ -201,6 +202,7 @@ typedef struct _cef_cookie_manager_t* (
struct _cef_completion_callback_t*);
typedef struct _cef_drag_data_t* (*cef_drag_data_create_ptr)();
typedef struct _cef_image_t* (*cef_image_create_ptr)();
typedef struct _cef_media_router_t* (*cef_media_router_get_global_ptr)();
typedef struct _cef_menu_model_t* (*cef_menu_model_create_ptr)(
struct _cef_menu_model_delegate_t*);
typedef struct _cef_print_settings_t* (*cef_print_settings_create_ptr)();
@ -575,6 +577,7 @@ struct libcef_pointers {
cef_cookie_manager_get_global_manager;
cef_drag_data_create_ptr cef_drag_data_create;
cef_image_create_ptr cef_image_create;
cef_media_router_get_global_ptr cef_media_router_get_global;
cef_menu_model_create_ptr cef_menu_model_create;
cef_print_settings_create_ptr cef_print_settings_create;
cef_process_message_create_ptr cef_process_message_create;
@ -788,6 +791,7 @@ int libcef_init_pointers(const char* path) {
INIT_ENTRY(cef_cookie_manager_get_global_manager);
INIT_ENTRY(cef_drag_data_create);
INIT_ENTRY(cef_image_create);
INIT_ENTRY(cef_media_router_get_global);
INIT_ENTRY(cef_menu_model_create);
INIT_ENTRY(cef_print_settings_create);
INIT_ENTRY(cef_process_message_create);
@ -1301,6 +1305,11 @@ NO_SANITIZE("cfi-icall") struct _cef_image_t* cef_image_create() {
return g_libcef_pointers.cef_image_create();
}
NO_SANITIZE("cfi-icall")
struct _cef_media_router_t* cef_media_router_get_global() {
return g_libcef_pointers.cef_media_router_get_global();
}
NO_SANITIZE("cfi-icall")
struct _cef_menu_model_t* cef_menu_model_create(
struct _cef_menu_model_delegate_t* delegate) {

View File

@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=946864e8254e77f0555d607d1d99a8ba3f1c45db$
// $hash=089392d929a9f7a3ca4fe7f53d63b98536505261$
//
#ifndef CEF_LIBCEF_DLL_WRAPPER_TYPES_H_
@ -73,6 +73,12 @@ enum CefWrapperType {
WT_LIFE_SPAN_HANDLER,
WT_LIST_VALUE,
WT_LOAD_HANDLER,
WT_MEDIA_OBSERVER,
WT_MEDIA_ROUTE,
WT_MEDIA_ROUTE_CREATE_CALLBACK,
WT_MEDIA_ROUTER,
WT_MEDIA_SINK,
WT_MEDIA_SOURCE,
WT_MENU_BUTTON,
WT_MENU_BUTTON_DELEGATE,
WT_MENU_BUTTON_PRESSED_LOCK,
@ -92,6 +98,7 @@ enum CefWrapperType {
WT_PROCESS_MESSAGE,
WT_READ_HANDLER,
WT_REGISTER_CDM_CALLBACK,
WT_REGISTRATION,
WT_RENDER_HANDLER,
WT_RENDER_PROCESS_HANDLER,
WT_REQUEST,

View File

@ -0,0 +1,491 @@
// 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.
#include "tests/cefclient/browser/media_router_test.h"
#include <string>
#include <vector>
#include "include/base/cef_logging.h"
#include "include/cef_media_router.h"
#include "include/cef_parser.h"
#include "tests/cefclient/browser/test_runner.h"
namespace client {
namespace media_router_test {
namespace {
const char kTestUrlPath[] = "/media_router";
// Application-specific error codes.
const int kMessageFormatError = 1;
const int kRequestFailedError = 2;
// Message strings.
const char kNameKey[] = "name";
const char kNameValueSubscribe[] = "subscribe";
const char kNameValueCreateRoute[] = "createRoute";
const char kNameValueTerminateRoute[] = "terminateRoute";
const char kNameValueSendMessage[] = "sendMessage";
const char kSourceKey[] = "source_urn";
const char kSinkKey[] = "sink_id";
const char kRouteKey[] = "route_id";
const char kMessageKey[] = "message";
const char kSuccessKey[] = "success";
const char kPayloadKey[] = "payload";
// Convert a dictionary value to a JSON string.
CefString GetJSON(CefRefPtr<CefDictionaryValue> dictionary) {
CefRefPtr<CefValue> value = CefValue::Create();
value->SetDictionary(dictionary);
return CefWriteJSON(value, JSON_WRITER_DEFAULT);
}
typedef CefMessageRouterBrowserSide::Callback CallbackType;
void SendSuccess(CefRefPtr<CallbackType> callback,
CefRefPtr<CefDictionaryValue> result) {
callback->Success(GetJSON(result));
}
void SendFailure(CefRefPtr<CallbackType> callback,
int error_code,
const std::string& error_message) {
callback->Failure(error_code, error_message);
}
// Callback for CefMediaRouter::CreateRoute.
class MediaRouteCreateCallback : public CefMediaRouteCreateCallback {
public:
explicit MediaRouteCreateCallback(CefRefPtr<CallbackType> create_callback)
: create_callback_(create_callback) {}
// CefMediaRouteCreateCallback method:
void OnMediaRouteCreateFinished(RouteCreateResult result,
const CefString& error,
CefRefPtr<CefMediaRoute> route) OVERRIDE {
CEF_REQUIRE_UI_THREAD();
if (result == CEF_MRCR_OK) {
CefRefPtr<CefDictionaryValue> result = CefDictionaryValue::Create();
result->SetString(kRouteKey, route->GetId());
SendSuccess(create_callback_, result);
} else {
SendFailure(create_callback_, kRequestFailedError + result, error);
}
create_callback_ = NULL;
}
private:
CefRefPtr<CallbackType> create_callback_;
IMPLEMENT_REFCOUNTING(MediaRouteCreateCallback);
DISALLOW_COPY_AND_ASSIGN(MediaRouteCreateCallback);
};
// Observes MediaRouter events. Only accessed on the UI thread.
class MediaObserver : public CefMediaObserver {
public:
typedef std::vector<CefRefPtr<CefMediaRoute>> MediaRouteVector;
typedef std::vector<CefRefPtr<CefMediaSink>> MediaSinkVector;
MediaObserver(CefRefPtr<CefMediaRouter> media_router,
CefRefPtr<CallbackType> subscription_callback)
: media_router_(media_router),
subscription_callback_(subscription_callback) {}
bool CreateRoute(const std::string& source_urn,
const std::string& sink_id,
CefRefPtr<CallbackType> callback,
std::string& error) {
CefRefPtr<CefMediaSource> source = GetSource(source_urn);
if (!source) {
error = "Invalid source: " + source_urn;
return false;
}
CefRefPtr<CefMediaSink> sink = GetSink(sink_id);
if (!sink) {
error = "Invalid sink: " + sink_id;
return false;
}
media_router_->CreateRoute(source, sink,
new MediaRouteCreateCallback(callback));
return true;
}
bool TerminateRoute(const std::string& route_id, std::string& error) {
CefRefPtr<CefMediaRoute> route = GetRoute(route_id);
if (!route) {
error = "Invalid route: " + route_id;
return false;
}
route->Terminate();
return true;
}
bool SendRouteMessage(const std::string& route_id,
const std::string& message,
std::string& error) {
CefRefPtr<CefMediaRoute> route = GetRoute(route_id);
if (!route) {
error = "Invalid route: " + route_id;
return false;
}
route->SendRouteMessage(message.c_str(), message.size());
return true;
}
protected:
// CefMediaObserver methods:
void OnSinks(const MediaSinkVector& sinks) OVERRIDE {
CEF_REQUIRE_UI_THREAD();
sink_map_.clear();
CefRefPtr<CefDictionaryValue> payload = CefDictionaryValue::Create();
CefRefPtr<CefListValue> sinks_list = CefListValue::Create();
sinks_list->SetSize(sinks.size());
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));
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->SetString(
"type", sink->IsCastSink() ? "cast"
: sink->IsDialSink() ? "dial" : "unknown");
sinks_list->SetDictionary(idx, sink_dict);
}
payload->SetList("sinks_list", sinks_list);
SendResponse("onSinks", payload);
}
void OnRoutes(const MediaRouteVector& routes) OVERRIDE {
CEF_REQUIRE_UI_THREAD();
route_map_.clear();
CefRefPtr<CefDictionaryValue> payload = CefDictionaryValue::Create();
CefRefPtr<CefListValue> routes_list = CefListValue::Create();
routes_list->SetSize(routes.size());
MediaRouteVector::const_iterator it = routes.begin();
for (size_t idx = 0; it != routes.end(); ++it, ++idx) {
CefRefPtr<CefMediaRoute> route = *it;
const std::string& route_id = route->GetId();
route_map_.insert(std::make_pair(route_id, route));
CefRefPtr<CefDictionaryValue> route_dict = CefDictionaryValue::Create();
route_dict->SetString("id", route_id);
route_dict->SetString(kSourceKey, route->GetSource()->GetId());
route_dict->SetString(kSinkKey, route->GetSink()->GetId());
routes_list->SetDictionary(idx, route_dict);
}
payload->SetList("routes_list", routes_list);
SendResponse("onRoutes", payload);
}
void OnRouteStateChanged(CefRefPtr<CefMediaRoute> route,
ConnectionState state) OVERRIDE {
CEF_REQUIRE_UI_THREAD();
CefRefPtr<CefDictionaryValue> payload = CefDictionaryValue::Create();
payload->SetString(kRouteKey, route->GetId());
payload->SetInt("connection_state", state);
SendResponse("onRouteStateChanged", payload);
}
void OnRouteMessageReceived(CefRefPtr<CefMediaRoute> route,
const void* message,
size_t message_size) OVERRIDE {
CEF_REQUIRE_UI_THREAD();
std::string message_str(static_cast<const char*>(message), message_size);
CefRefPtr<CefDictionaryValue> payload = CefDictionaryValue::Create();
payload->SetString(kRouteKey, route->GetId());
payload->SetString(kMessageKey, message_str);
SendResponse("onRouteMessageReceived", payload);
}
private:
CefRefPtr<CefMediaSource> GetSource(const std::string& source_urn) {
CefRefPtr<CefMediaSource> source = media_router_->GetSource(source_urn);
if (!source || !source->IsValid())
return NULL;
return source;
}
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;
return NULL;
}
CefRefPtr<CefMediaRoute> GetRoute(const std::string& route_id) {
RouteMap::const_iterator it = route_map_.find(route_id);
if (it != route_map_.end())
return it->second;
return NULL;
}
void SendResponse(const std::string& name,
CefRefPtr<CefDictionaryValue> payload) {
CefRefPtr<CefDictionaryValue> result = CefDictionaryValue::Create();
result->SetString(kNameKey, name);
result->SetDictionary(kPayloadKey, payload);
SendSuccess(subscription_callback_, result);
}
CefRefPtr<CefMediaRouter> media_router_;
CefRefPtr<CallbackType> subscription_callback_;
typedef std::map<std::string, CefRefPtr<CefMediaSink>> SinkMap;
SinkMap sink_map_;
typedef std::map<std::string, CefRefPtr<CefMediaRoute>> RouteMap;
RouteMap route_map_;
IMPLEMENT_REFCOUNTING(MediaObserver);
DISALLOW_COPY_AND_ASSIGN(MediaObserver);
};
// Handle messages in the browser process. Only accessed on the UI thread.
class Handler : public CefMessageRouterBrowserSide::Handler {
public:
typedef std::vector<std::string> NameVector;
Handler() { CEF_REQUIRE_UI_THREAD(); }
virtual ~Handler() {
SubscriptionStateMap::iterator it = subscription_state_map_.begin();
for (; it != subscription_state_map_.end(); ++it) {
delete it->second;
}
}
// Called due to cefQuery execution in media_router.html.
bool OnQuery(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
int64 query_id,
const CefString& request,
bool persistent,
CefRefPtr<Callback> callback) OVERRIDE {
CEF_REQUIRE_UI_THREAD();
// Only handle messages from the test URL.
const std::string& url = frame->GetURL();
if (!test_runner::IsTestURL(url, kTestUrlPath))
return false;
// Parse |request| as a JSON dictionary.
CefRefPtr<CefDictionaryValue> request_dict = ParseJSON(request);
if (!request_dict) {
SendFailure(callback, kMessageFormatError, "Incorrect message format");
return true;
}
// Verify the "name" key.
if (!VerifyKey(request_dict, kNameKey, VTYPE_STRING, callback))
return true;
const std::string& message_name = request_dict->GetString(kNameKey);
if (message_name == kNameValueSubscribe) {
// Subscribe to notifications from the media router.
if (!persistent) {
SendFailure(callback, kMessageFormatError,
"Subscriptions must be persistent");
return true;
}
if (!CreateSubscription(browser, query_id, callback)) {
SendFailure(callback, kRequestFailedError,
"Browser is already subscribed");
}
return true;
}
// All other messages require a current subscription.
CefRefPtr<MediaObserver> media_observer =
GetMediaObserver(browser->GetIdentifier());
if (!media_observer) {
SendFailure(callback, kRequestFailedError,
"Browser is not currently subscribed");
}
if (message_name == kNameValueCreateRoute) {
// Create a new route.
// Verify the "source_urn" key.
if (!VerifyKey(request_dict, kSourceKey, VTYPE_STRING, callback))
return true;
// Verify the "sink_id" key.
if (!VerifyKey(request_dict, kSinkKey, VTYPE_STRING, callback))
return true;
const std::string& source_urn = request_dict->GetString(kSourceKey);
const std::string& sink_id = request_dict->GetString(kSinkKey);
// |callback| will be executed once the route is created.
std::string error;
if (!media_observer->CreateRoute(source_urn, sink_id, callback, error)) {
SendFailure(callback, kRequestFailedError, error);
}
return true;
} else if (message_name == kNameValueTerminateRoute) {
// Terminate an existing route.
// Verify the "route" key.
if (!VerifyKey(request_dict, kRouteKey, VTYPE_STRING, callback))
return true;
const std::string& route_id = request_dict->GetString(kRouteKey);
std::string error;
if (!media_observer->TerminateRoute(route_id, error)) {
SendFailure(callback, kRequestFailedError, error);
} else {
SendSuccessACK(callback);
}
return true;
} else if (message_name == kNameValueSendMessage) {
// Send a route message.
// Verify the "route_id" key.
if (!VerifyKey(request_dict, kRouteKey, VTYPE_STRING, callback))
return true;
// Verify the "message" key.
if (!VerifyKey(request_dict, kMessageKey, VTYPE_STRING, callback))
return true;
const std::string& route_id = request_dict->GetString(kRouteKey);
const std::string& message = request_dict->GetString(kMessageKey);
std::string error;
if (!media_observer->SendRouteMessage(route_id, message, error)) {
SendFailure(callback, kRequestFailedError, error);
} else {
SendSuccessACK(callback);
}
return true;
}
return false;
}
void OnQueryCanceled(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
int64 query_id) OVERRIDE {
CEF_REQUIRE_UI_THREAD();
RemoveSubscription(browser->GetIdentifier(), query_id);
}
private:
static void SendSuccessACK(CefRefPtr<Callback> callback) {
CefRefPtr<CefDictionaryValue> result = CefDictionaryValue::Create();
result->SetBool(kSuccessKey, true);
SendSuccess(callback, result);
}
// Convert a JSON string to a dictionary value.
static CefRefPtr<CefDictionaryValue> ParseJSON(const CefString& string) {
CefRefPtr<CefValue> value = CefParseJSON(string, JSON_PARSER_RFC);
if (value.get() && value->GetType() == VTYPE_DICTIONARY)
return value->GetDictionary();
return nullptr;
}
// Verify that |key| exists in |dictionary| and has type |value_type|. Fails
// |callback| and returns false on failure.
static bool VerifyKey(CefRefPtr<CefDictionaryValue> dictionary,
const char* key,
cef_value_type_t value_type,
CefRefPtr<Callback> callback) {
if (!dictionary->HasKey(key) || dictionary->GetType(key) != value_type) {
SendFailure(
callback, kMessageFormatError,
"Missing or incorrectly formatted message key: " + std::string(key));
return false;
}
return true;
}
// Subscription state associated with a single browser.
struct SubscriptionState {
int64 query_id;
CefRefPtr<MediaObserver> observer;
CefRefPtr<CefRegistration> registration;
};
bool CreateSubscription(CefRefPtr<CefBrowser> browser,
int64 query_id,
CefRefPtr<Callback> callback) {
const int browser_id = browser->GetIdentifier();
if (subscription_state_map_.find(browser_id) !=
subscription_state_map_.end()) {
// An subscription already exists for this browser.
return false;
}
CefRefPtr<CefMediaRouter> media_router =
browser->GetHost()->GetRequestContext()->GetMediaRouter();
SubscriptionState* state = new SubscriptionState();
state->query_id = query_id;
state->observer = new MediaObserver(media_router, callback);
state->registration = media_router->AddObserver(state->observer);
subscription_state_map_.insert(std::make_pair(browser_id, state));
// Trigger sink and route callbacks.
media_router->NotifyCurrentSinks();
media_router->NotifyCurrentRoutes();
return true;
}
void RemoveSubscription(int browser_id, int64 query_id) {
SubscriptionStateMap::iterator it =
subscription_state_map_.find(browser_id);
if (it != subscription_state_map_.end() &&
it->second->query_id == query_id) {
delete it->second;
subscription_state_map_.erase(it);
}
}
CefRefPtr<MediaObserver> GetMediaObserver(int browser_id) {
SubscriptionStateMap::const_iterator it =
subscription_state_map_.find(browser_id);
if (it != subscription_state_map_.end()) {
return it->second->observer;
}
return NULL;
}
// Map of browser ID to SubscriptionState object.
typedef std::map<int, SubscriptionState*> SubscriptionStateMap;
SubscriptionStateMap subscription_state_map_;
DISALLOW_COPY_AND_ASSIGN(Handler);
};
} // namespace
void CreateMessageHandlers(test_runner::MessageHandlerSet& handlers) {
handlers.insert(new Handler());
}
} // namespace media_router_test
} // namespace client

View File

@ -0,0 +1,20 @@
// 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.
#ifndef CEF_TESTS_CEFCLIENT_BROWSER_MEDIA_ROUTER_TEST_H_
#define CEF_TESTS_CEFCLIENT_BROWSER_MEDIA_ROUTER_TEST_H_
#pragma once
#include "tests/cefclient/browser/test_runner.h"
namespace client {
namespace media_router_test {
// Create message handlers. Called from test_runner.cc.
void CreateMessageHandlers(test_runner::MessageHandlerSet& handlers);
} // namespace media_router_test
} // namespace client
#endif // CEF_TESTS_CEFCLIENT_BROWSER_MEDIA_ROUTER_TEST_H_

View File

@ -50,24 +50,25 @@
#define IDS_DRM_HTML 1003
#define IDS_LOCALSTORAGE_HTML 1004
#define IDS_LOGO_PNG 1005
#define IDS_MENU_ICON_1X_PNG 1006
#define IDS_MENU_ICON_2X_PNG 1007
#define IDS_OSRTEST_HTML 1008
#define IDS_OTHER_TESTS_HTML 1009
#define IDS_PDF_HTML 1010
#define IDS_PDF_PDF 1011
#define IDS_PERFORMANCE_HTML 1012
#define IDS_PERFORMANCE2_HTML 1013
#define IDS_PREFERENCES_HTML 1014
#define IDS_RESPONSE_FILTER_HTML 1015
#define IDS_SERVER_HTML 1016
#define IDS_TRANSPARENCY_HTML 1017
#define IDS_URLREQUEST_HTML 1018
#define IDS_WEBSOCKET_HTML 1019
#define IDS_WINDOW_HTML 1020
#define IDS_WINDOW_ICON_1X_PNG 1021
#define IDS_WINDOW_ICON_2X_PNG 1022
#define IDS_XMLHTTPREQUEST_HTML 1023
#define IDS_MEDIA_ROUTER_HTML 1006
#define IDS_MENU_ICON_1X_PNG 1007
#define IDS_MENU_ICON_2X_PNG 1008
#define IDS_OSRTEST_HTML 1009
#define IDS_OTHER_TESTS_HTML 1010
#define IDS_PDF_HTML 1011
#define IDS_PDF_PDF 1012
#define IDS_PERFORMANCE_HTML 1013
#define IDS_PERFORMANCE2_HTML 1014
#define IDS_PREFERENCES_HTML 1015
#define IDS_RESPONSE_FILTER_HTML 1016
#define IDS_SERVER_HTML 1017
#define IDS_TRANSPARENCY_HTML 1018
#define IDS_URLREQUEST_HTML 1019
#define IDS_WEBSOCKET_HTML 1020
#define IDS_WINDOW_HTML 1021
#define IDS_WINDOW_ICON_1X_PNG 1022
#define IDS_WINDOW_ICON_2X_PNG 1023
#define IDS_XMLHTTPREQUEST_HTML 1024
#define IDS_EXTENSIONS_SET_PAGE_COLOR_ICON_PNG 1030
#define IDS_EXTENSIONS_SET_PAGE_COLOR_MANIFEST_JSON 1031

View File

@ -26,8 +26,9 @@ int GetResourceId(const char* resource_name) {
IDS_EXTENSIONS_SET_PAGE_COLOR_POPUP_HTML},
{"extensions/set_page_color/popup.js",
IDS_EXTENSIONS_SET_PAGE_COLOR_POPUP_JS},
{"logo.png", IDS_LOGO_PNG},
{"localstorage.html", IDS_LOCALSTORAGE_HTML},
{"logo.png", IDS_LOGO_PNG},
{"media_router.html", IDS_MEDIA_ROUTER_HTML},
{"menu_icon.1x.png", IDS_MENU_ICON_1X_PNG},
{"menu_icon.2x.png", IDS_MENU_ICON_2X_PNG},
{"osr_test.html", IDS_OSRTEST_HTML},

View File

@ -20,6 +20,7 @@
#include "tests/cefclient/browser/dialog_test.h"
#include "tests/cefclient/browser/drm_test.h"
#include "tests/cefclient/browser/main_context.h"
#include "tests/cefclient/browser/media_router_test.h"
#include "tests/cefclient/browser/preferences_test.h"
#include "tests/cefclient/browser/resource.h"
#include "tests/cefclient/browser/response_filter_test.h"
@ -882,6 +883,9 @@ void CreateMessageHandlers(MessageHandlerSet& handlers) {
// Create the drm test handlers.
drm_test::CreateMessageHandlers(handlers);
// Create the media router test handlers.
media_router_test::CreateMessageHandlers(handlers);
// Create the preferences test handlers.
preferences_test::CreateMessageHandlers(handlers);

View File

@ -0,0 +1,562 @@
<html>
<head>
<style>
body {
font-family: Verdana, Arial;
font-size: 12px;
}
/* Give the same font styling to form elements. */
input, select, textarea, button {
font-family: inherit;
font-size: inherit;
}
.content {
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
}
.description {
padding-bottom: 5px;
}
.description .title {
font-size: 120%;
font-weight: bold;
}
.route_controls {
flex: 0;
align-self: center;
text-align: right;
padding-bottom: 5px;
}
.route_controls .label {
display: inline-block;
vertical-align: top;
font-weight: bold;
}
.route_controls .control {
width: 400px;
}
.messages {
flex: 1;
min-height: 100px;
border: 1px solid gray;
overflow: auto;
}
.messages .message {
padding: 3px;
border-bottom: 1px solid #cccbca;
}
.messages .message .timestamp {
font-size: 90%;
font-style: italic;
}
.messages .status {
background-color: #d6d6d6; /* light gray */
}
.messages .sent {
background-color: #c5e8fc; /* light blue */
}
.messages .recv {
background-color: #fcf4e3; /* light yellow */
}
.message_controls {
flex: 0;
text-align: right;
padding-top: 5px;
}
.message_controls textarea {
width: 100%;
height: 10em;
}
</style>
<script language="JavaScript">
// Application state.
var demoMode = false;
var currentSubscriptionId = null;
var currentRouteId = null;
// List of currently supported source protocols.
var allowedSourceProtocols = ['cast', 'dial'];
// Values from cef_media_route_connection_state_t.
var CEF_MRCS_UNKNOWN = 0;
var CEF_MRCS_CONNECTING = 1;
var CEF_MRCS_CONNECTED = 2;
var CEF_MRCS_CLOSED = 3;
var CEF_MRCS_TERMINATED = 4;
function getStateLabel(state) {
switch (state) {
case CEF_MRCS_CONNECTING: return "CONNECTING";
case CEF_MRCS_CONNECTED: return "CONNECTED";
case CEF_MRCS_CLOSED: return "CLOSED";
case CEF_MRCS_TERMINATED: return "TERMINATED";
default: break;
}
return "UNKNOWN";
}
///
// Manage show/hide of default text for form elements.
///
// Default messages that are shown until the user focuses on the input field.
var defaultSourceText = 'Enter URN here and click "Create Route"';
var defaultMessageText = 'Enter message contents here and click "Send Message"';
function getDefaultText(control) {
if (control === 'source')
return defaultSourceText;
if (control === 'message')
return defaultMessageText;
return null;
}
function hideDefaultText(control) {
var element = document.getElementById(control);
var defaultText = getDefaultText(control);
if (element.value === defaultText)
element.value = '';
}
function showDefaultText(control) {
var element = document.getElementById(control);
var defaultText = getDefaultText(control);
if (element.value === '')
element.value = defaultText;
}
function initDefaultText() {
showDefaultText('source');
showDefaultText('message');
}
///
// Retrieve current form values. Return null if validation fails.
///
function getCurrentSource() {
var sourceInput = document.getElementById('source');
var value = sourceInput.value;
if (value === defaultSourceText || value.length === 0 || value.indexOf(':') < 0) {
return null;
}
// Validate the URN value.
try {
var url = new URL(value);
if ((url.hostname.length === 0 && url.pathname.length === 0) ||
!allowedSourceProtocols.includes(url.protocol.slice(0, -1))) {
return null;
}
} catch (e) {
return null;
}
return value;
}
function getCurrentSink() {
var sinksSelect = document.getElementById('sink');
if (sinksSelect.options.length === 0)
return null;
return sinksSelect.value;
}
function getCurrentMessage() {
var messageInput = document.getElementById('message');
if (messageInput.value === defaultMessageText || messageInput.value.length === 0)
return null;
return messageInput.value;
}
///
// Set disabled state of form elements.
///
function updateControls() {
document.getElementById('source').disabled = hasRoute();
document.getElementById('sink').disabled = hasRoute();
document.getElementById('create_route').disabled =
hasRoute() || getCurrentSource() === null || getCurrentSink() === null;
document.getElementById('terminate_route').disabled = !hasRoute();
document.getElementById('message').disabled = !hasRoute();
document.getElementById('send_message').disabled = !hasRoute() || getCurrentMessage() === null;
}
///
// Manage the media sinks list.
///
/*
Expected format for |sinks| is:
[
{
name: string,
type: string ('cast' or 'dial'),
id: string
}, ...
]
*/
function updateSinks(sinks) {
var sinksSelect = document.getElementById('sink');
// Currently selected value.
var selectedValue = sinksSelect.options.length === 0 ? null : sinksSelect.value;
// Build a list of old (existing) values.
var oldValues = [];
for (var i = 0; i < sinksSelect.options.length; ++i) {
oldValues.push(sinksSelect.options[i].value);
}
// Build a list of new (possibly new or existing) values.
var newValues = [];
for(var i = 0; i < sinks.length; i++) {
newValues.push(sinks[i].id);
}
// Remove old values that no longer exist.
for (var i = sinksSelect.options.length - 1; i >= 0; --i) {
if (!newValues.includes(sinksSelect.options[i].value)) {
sinksSelect.remove(i);
}
}
// Add new values that don't already exist.
for(var i = 0; i < sinks.length; i++) {
var sink = sinks[i];
if (oldValues.includes(sink.id))
continue;
var opt = document.createElement('option');
opt.innerHTML = sink.name + ' (' + sink.type + ')';
opt.value = sink.id;
sinksSelect.appendChild(opt);
}
if (sinksSelect.options.length === 0) {
selectedValue = null;
} else if (!newValues.includes(selectedValue)) {
// The previously selected value no longer exists.
// Select the first value in the new list.
selectedValue = sinksSelect.options[0].value;
sinksSelect.value = selectedValue;
}
updateControls();
return selectedValue;
}
///
// Manage the current media route.
///
function hasRoute() {
return currentRouteId !== null;
}
function createRoute() {
console.assert(!hasRoute());
var source = getCurrentSource();
console.assert(source !== null);
var sink = getCurrentSink();
console.assert(sink !== null);
if (demoMode) {
onRouteCreated('demo-route-id');
return;
}
sendCefQuery(
{name: 'createRoute', source_urn: source, sink_id: sink},
(message) => onRouteCreated(JSON.parse(message).route_id)
);
}
function onRouteCreated(route_id) {
currentRouteId = route_id;
showStatusMessage('Route ' + route_id + '\ncreated');
updateControls();
}
function terminateRoute() {
console.assert(hasRoute());
var source = getCurrentSource();
console.assert(source !== null);
var sink = getCurrentSink();
console.assert(sink !== null);
if (demoMode) {
onRouteTerminated();
return;
}
sendCefQuery(
{name: 'terminateRoute', route_id: currentRouteId},
(unused) => {}
);
}
function onRouteTerminated() {
showStatusMessage('Route ' + currentRouteId + '\nterminated');
currentRouteId = null;
updateControls();
}
///
// Manage messages.
///
function sendMessage() {
console.assert(hasRoute());
var message = getCurrentMessage();
console.assert(message !== null);
if (demoMode) {
showSentMessage(message);
setTimeout(function(){ if (hasRoute()) { recvMessage('Demo ACK for: ' + message); } }, 1000);
return;
}
sendCefQuery(
{name: 'sendMessage', route_id: currentRouteId, message: message},
(unused) => showSentMessage(message)
);
}
function recvMessage(message) {
console.assert(hasRoute());
console.assert(message !== undefined && message !== null && message.length > 0);
showRecvMessage(message);
}
function showStatusMessage(message) {
showMessage('status', message);
}
function showSentMessage(message) {
showMessage('sent', message);
}
function showRecvMessage(message) {
showMessage('recv', message);
}
function showMessage(type, message) {
if (!['status', 'sent', 'recv'].includes(type)) {
console.warn('Invalid message type: ' + type);
return;
}
if (message[0] === '{') {
try {
// Pretty print JSON strings.
message = JSON.stringify(JSON.parse(message), null, 2);
} catch(e) {}
}
var messagesDiv = document.getElementById('messages');
var newDiv = document.createElement("div");
newDiv.innerHTML =
'<span class="timestamp">' + (new Date().toLocaleString()) +
' (' + type.toUpperCase() + ')</span><br/>';
// Escape any HTML tags or entities in |message|.
var pre = document.createElement('pre');
pre.appendChild(document.createTextNode(message));
newDiv.appendChild(pre);
newDiv.className = 'message ' + type;
messagesDiv.appendChild(newDiv);
// Always scroll to bottom.
messagesDiv.scrollTop = messagesDiv.scrollHeight;
}
///
// Manage communication with native code in media_router_test.cc.
///
function onCefError(code, message) {
showStatusMessage('ERROR: ' + message + ' (' + code + ')');
}
function sendCefQuery(payload, onSuccess, onFailure=onCefError, persistent=false) {
// Results in a call to the OnQuery method in media_router_test.cc
return window.cefQuery({
request: JSON.stringify(payload),
onSuccess: onSuccess,
onFailure: onFailure,
persistent: persistent
});
}
/*
Expected format for |message| is:
{
name: string,
payload: dictionary
}
*/
function onCefSubscriptionMessage(message) {
if (message.name === 'onSinks') {
// List of sinks.
updateSinks(message.payload.sinks_list);
} else if (message.name === 'onRouteStateChanged') {
// Route status changed.
if (message.payload.route_id === currentRouteId) {
var connection_state = message.payload.connection_state;
showStatusMessage('Route ' + currentRouteId +
'\nconnection state ' + getStateLabel(connection_state) +
' (' + connection_state + ')');
if ([CEF_MRCS_CLOSED, CEF_MRCS_TERMINATED].includes(connection_state)) {
onRouteTerminated();
}
}
} else if (message.name === 'onRouteMessageReceived') {
// Route message received.
if (message.payload.route_id === currentRouteId) {
recvMessage(message.payload.message);
}
}
}
// Subscribe to ongoing message notifications from the native code.
function startCefSubscription() {
currentSubscriptionId = sendCefQuery(
{name: 'subscribe'},
(message) => onCefSubscriptionMessage(JSON.parse(message)),
(code, message) => {
onCefError(code, message);
currentSubscriptionId = null;
},
true
);
}
function stopCefSubscription() {
if (currentSubscriptionId !== null) {
// Results in a call to the OnQueryCanceled method in media_router_test.cc
window.cefQueryCancel(currentSubscriptionId);
}
}
///
// Example app load/unload.
///
function initDemoMode() {
demoMode = true;
var sinks = [
{
name: 'Sink 1',
type: 'cast',
id: 'sink1'
},
{
name: 'Sink 2',
type: 'dial',
id: 'sink2'
}
];
updateSinks(sinks);
showStatusMessage('Running in Demo mode.');
showSentMessage('Demo sent message.');
showRecvMessage('Demo recv message.');
}
function onLoad() {
initDefaultText();
if (window.cefQuery === undefined) {
// Initialize demo mode when running outside of CEF.
// This supports development and testing of the HTML/JS behavior outside
// of a cefclient build.
initDemoMode();
return;
}
startCefSubscription()
}
function onUnload() {
if (demoMode)
return;
if (hasRoute())
terminateRoute();
stopCefSubscription();
}
</script>
<title>Media Router Example</title>
</head>
<body bgcolor="white" onLoad="onLoad()" onUnload="onUnload()">
<div class="content">
<div class="description">
<span class="title">Media Router Example</span>
<p>
<b>Overview:</b>
Chromium supports communication with devices on the local network via the
<a href="https://blog.oakbits.com/google-cast-protocol-overview.html" target="_blank">Cast</a> and
<a href="http://www.dial-multiscreen.org/" target="_blank">DIAL</a> protocols.
CEF exposes this functionality via the CefMediaRouter interface which is demonstrated by this test.
Test code is implemented in resources/media_router.html and browser/media_router_test.cc.
</p>
<p>
<b>Usage:</b>
Devices available on your local network will be discovered automatically and populated in the "Sink" list.
Enter a URN for "Source", select an available device from the "Sink" list, and click the "Create Route" button.
Cast URNs take the form "cast:<i>&lt;appId&gt;</i>?clientId=<i>&lt;clientId&gt;</i>" and DIAL URNs take the form "dial:<i>&lt;appId&gt;</i>",
where <i>&lt;appId&gt;</i> is the <a href="https://developers.google.com/cast/docs/registration" target="_blank">registered application ID</a>
and <i>&lt;clientId&gt;</i> is an arbitrary numeric identifier.
Status information and messages will be displayed in the center of the screen.
After creating a route you can send messages to the receiver app using the textarea at the bottom of the screen.
Messages are usually in JSON format with a example of Cast communication to be found
<a href="https://bitbucket.org/chromiumembedded/cef/issues/2900/add-mediarouter-support-for-cast-receiver#comment-56680326" target="_blank">here</a>.
</p>
</div>
<div class="route_controls">
<span class="label">Source:</span>
<input type="text" id="source" class="control" onInput="updateControls()" onFocus="hideDefaultText('source')" onBlur="showDefaultText('source')"/>
<br/>
<span class="label">Sink:</span>
<select id="sink" size="3" class="control"></select>
<br/>
<input type="button" id="create_route" onclick="createRoute()" value="Create Route" disabled/>
<input type="button" id="terminate_route" onclick="terminateRoute()" value="Terminate Route" disabled/>
</div>
<div id="messages" class="messages">
</div>
<div class="message_controls">
<textarea id="message" onInput="updateControls()" onFocus="hideDefaultText('message')" onBlur="showDefaultText('message')" disabled></textarea>
<br/><input type="button" id="send_message" onclick="sendMessage()" value="Send Message" disabled/>
</div>
</div>
</body>
</html>

View File

@ -23,6 +23,7 @@
<li><a href="performance2">JavaScript Performance (2) Tests</a></li>
<li><a href="window">JavaScript Window Manipulation</a></li>
<li><a href="localstorage">Local Storage</a></li>
<li><a href="media_router">Media Router (Cast/DIAL)</a></li>
<li><a href="pdf.pdf">PDF Viewer direct</a></li>
<li><a href="pdf">PDF Viewer iframe</a></li>
<li><a href="preferences">Preferences</a></li>

View File

@ -35,6 +35,7 @@ IDS_DRAGGABLE_HTML BINARY "..\\draggable.html"
IDS_DRM_HTML BINARY "..\\drm.html"
IDS_LOCALSTORAGE_HTML BINARY "..\\localstorage.html"
IDS_LOGO_PNG BINARY "..\\logo.png"
IDS_MEDIA_ROUTER_HTML BINARY "..\\media_router.html"
IDS_MENU_ICON_1X_PNG BINARY "..\\menu_icon.1x.png"
IDS_MENU_ICON_2X_PNG BINARY "..\\menu_icon.2x.png"
IDS_OSRTEST_HTML BINARY "..\\..\\..\\shared\\resources\\osr_test.html"