From 409e14fe5aff0b1ae3c1d5fb0ff3877a55ee50e7 Mon Sep 17 00:00:00 2001 From: Marshall Greenblatt Date: Thu, 19 Mar 2020 11:34:15 -0400 Subject: [PATCH] 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. --- BUILD.gn | 10 + cef_paths.gypi | 34 +- cef_paths2.gypi | 3 + include/capi/cef_media_router_capi.h | 322 ++++++++++ include/capi/cef_registration_capi.h | 63 ++ include/capi/cef_request_context_capi.h | 9 +- include/cef_api_hash.h | 10 +- include/cef_media_router.h | 300 ++++++++++ include/cef_registration.h | 49 ++ include/cef_request_context.h | 7 + include/internal/cef_types.h | 30 + libcef/browser/browser_context.cc | 20 +- libcef/browser/browser_context.h | 15 + libcef/browser/browser_main.cc | 7 +- .../browser/media_router/media_route_impl.cc | 83 +++ .../browser/media_router/media_route_impl.h | 40 ++ .../browser/media_router/media_router_impl.cc | 290 +++++++++ .../browser/media_router/media_router_impl.h | 49 ++ .../media_router/media_router_manager.cc | 292 +++++++++ .../media_router/media_router_manager.h | 125 ++++ .../browser/media_router/media_sink_impl.cc | 46 ++ libcef/browser/media_router/media_sink_impl.h | 39 ++ .../browser/media_router/media_source_impl.cc | 28 + .../browser/media_router/media_source_impl.h | 35 ++ libcef/browser/prefs/browser_prefs.cc | 3 + libcef/browser/request_context_impl.cc | 20 + libcef/browser/request_context_impl.h | 5 + libcef/common/main_delegate.cc | 28 + libcef_dll/cpptoc/media_observer_cpptoc.cc | 161 +++++ libcef_dll/cpptoc/media_observer_cpptoc.h | 38 ++ libcef_dll/cpptoc/media_route_cpptoc.cc | 139 +++++ libcef_dll/cpptoc/media_route_cpptoc.h | 37 ++ .../media_route_create_callback_cpptoc.cc | 72 +++ .../media_route_create_callback_cpptoc.h | 38 ++ libcef_dll/cpptoc/media_router_cpptoc.cc | 177 ++++++ libcef_dll/cpptoc/media_router_cpptoc.h | 37 ++ libcef_dll/cpptoc/media_sink_cpptoc.cc | 177 ++++++ libcef_dll/cpptoc/media_sink_cpptoc.h | 37 ++ libcef_dll/cpptoc/media_source_cpptoc.cc | 116 ++++ libcef_dll/cpptoc/media_source_cpptoc.h | 37 ++ libcef_dll/cpptoc/registration_cpptoc.cc | 42 ++ libcef_dll/cpptoc/registration_cpptoc.h | 37 ++ libcef_dll/cpptoc/request_context_cpptoc.cc | 20 +- libcef_dll/ctocpp/media_observer_ctocpp.cc | 158 +++++ libcef_dll/ctocpp/media_observer_ctocpp.h | 48 ++ .../media_route_create_callback_ctocpp.cc | 66 ++ .../media_route_create_callback_ctocpp.h | 43 ++ libcef_dll/ctocpp/media_route_ctocpp.cc | 129 ++++ libcef_dll/ctocpp/media_route_ctocpp.h | 44 ++ libcef_dll/ctocpp/media_router_ctocpp.cc | 167 ++++++ libcef_dll/ctocpp/media_router_ctocpp.h | 47 ++ libcef_dll/ctocpp/media_sink_ctocpp.cc | 168 ++++++ libcef_dll/ctocpp/media_sink_ctocpp.h | 46 ++ libcef_dll/ctocpp/media_source_ctocpp.cc | 108 ++++ libcef_dll/ctocpp/media_source_ctocpp.h | 43 ++ libcef_dll/ctocpp/registration_ctocpp.cc | 42 ++ libcef_dll/ctocpp/registration_ctocpp.h | 39 ++ libcef_dll/ctocpp/request_context_ctocpp.cc | 18 +- libcef_dll/ctocpp/request_context_ctocpp.h | 3 +- libcef_dll/wrapper/libcef_dll_dylib.cc | 11 +- libcef_dll/wrapper_types.h | 9 +- tests/cefclient/browser/media_router_test.cc | 491 +++++++++++++++ tests/cefclient/browser/media_router_test.h | 20 + tests/cefclient/browser/resource.h | 37 +- .../browser/resource_util_win_idmap.cc | 3 +- tests/cefclient/browser/test_runner.cc | 4 + tests/cefclient/resources/media_router.html | 562 ++++++++++++++++++ tests/cefclient/resources/other_tests.html | 1 + tests/cefclient/resources/win/cefclient.rc | 1 + 69 files changed, 5402 insertions(+), 33 deletions(-) create mode 100644 include/capi/cef_media_router_capi.h create mode 100644 include/capi/cef_registration_capi.h create mode 100644 include/cef_media_router.h create mode 100644 include/cef_registration.h create mode 100644 libcef/browser/media_router/media_route_impl.cc create mode 100644 libcef/browser/media_router/media_route_impl.h create mode 100644 libcef/browser/media_router/media_router_impl.cc create mode 100644 libcef/browser/media_router/media_router_impl.h create mode 100644 libcef/browser/media_router/media_router_manager.cc create mode 100644 libcef/browser/media_router/media_router_manager.h create mode 100644 libcef/browser/media_router/media_sink_impl.cc create mode 100644 libcef/browser/media_router/media_sink_impl.h create mode 100644 libcef/browser/media_router/media_source_impl.cc create mode 100644 libcef/browser/media_router/media_source_impl.h create mode 100644 libcef_dll/cpptoc/media_observer_cpptoc.cc create mode 100644 libcef_dll/cpptoc/media_observer_cpptoc.h create mode 100644 libcef_dll/cpptoc/media_route_cpptoc.cc create mode 100644 libcef_dll/cpptoc/media_route_cpptoc.h create mode 100644 libcef_dll/cpptoc/media_route_create_callback_cpptoc.cc create mode 100644 libcef_dll/cpptoc/media_route_create_callback_cpptoc.h create mode 100644 libcef_dll/cpptoc/media_router_cpptoc.cc create mode 100644 libcef_dll/cpptoc/media_router_cpptoc.h create mode 100644 libcef_dll/cpptoc/media_sink_cpptoc.cc create mode 100644 libcef_dll/cpptoc/media_sink_cpptoc.h create mode 100644 libcef_dll/cpptoc/media_source_cpptoc.cc create mode 100644 libcef_dll/cpptoc/media_source_cpptoc.h create mode 100644 libcef_dll/cpptoc/registration_cpptoc.cc create mode 100644 libcef_dll/cpptoc/registration_cpptoc.h create mode 100644 libcef_dll/ctocpp/media_observer_ctocpp.cc create mode 100644 libcef_dll/ctocpp/media_observer_ctocpp.h create mode 100644 libcef_dll/ctocpp/media_route_create_callback_ctocpp.cc create mode 100644 libcef_dll/ctocpp/media_route_create_callback_ctocpp.h create mode 100644 libcef_dll/ctocpp/media_route_ctocpp.cc create mode 100644 libcef_dll/ctocpp/media_route_ctocpp.h create mode 100644 libcef_dll/ctocpp/media_router_ctocpp.cc create mode 100644 libcef_dll/ctocpp/media_router_ctocpp.h create mode 100644 libcef_dll/ctocpp/media_sink_ctocpp.cc create mode 100644 libcef_dll/ctocpp/media_sink_ctocpp.h create mode 100644 libcef_dll/ctocpp/media_source_ctocpp.cc create mode 100644 libcef_dll/ctocpp/media_source_ctocpp.h create mode 100644 libcef_dll/ctocpp/registration_ctocpp.cc create mode 100644 libcef_dll/ctocpp/registration_ctocpp.h create mode 100644 tests/cefclient/browser/media_router_test.cc create mode 100644 tests/cefclient/browser/media_router_test.h create mode 100644 tests/cefclient/resources/media_router.html diff --git a/BUILD.gn b/BUILD.gn index 30d84d053..174c794bb 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -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", diff --git a/cef_paths.gypi b/cef_paths.gypi index f6a889ba8..8d6ed0daa 100644 --- a/cef_paths.gypi +++ b/cef_paths.gypi @@ -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', diff --git a/cef_paths2.gypi b/cef_paths2.gypi index e78648dfa..fad6b5c01 100644 --- a/cef_paths2.gypi +++ b/cef_paths2.gypi @@ -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', diff --git a/include/capi/cef_media_router_capi.h b/include/capi/cef_media_router_capi.h new file mode 100644 index 000000000..a07da63da --- /dev/null +++ b/include/capi/cef_media_router_capi.h @@ -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:?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_ diff --git a/include/capi/cef_registration_capi.h b/include/capi/cef_registration_capi.h new file mode 100644 index 000000000..8b7354a1d --- /dev/null +++ b/include/capi/cef_registration_capi.h @@ -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_ diff --git a/include/capi/cef_request_context_capi.h b/include/capi/cef_request_context_capi.h index 87341c654..679204c15 100644 --- a/include/capi/cef_request_context_capi.h +++ b/include/capi/cef_request_context_capi.h @@ -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; /// diff --git a/include/cef_api_hash.h b/include/cef_api_hash.h index f256e1d20..5d817b344 100644 --- a/include/cef_api_hash.h +++ b/include/cef_api_hash.h @@ -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 diff --git a/include/cef_media_router.h b/include/cef_media_router.h new file mode 100644 index 000000000..1d107c42b --- /dev/null +++ b/include/cef_media_router.h @@ -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 +#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 GetGlobalMediaRouter(); + + /// + // Add an observer for MediaRouter events. The observer will remain registered + // until the returned Registration object is destroyed. + /// + /*--cef()--*/ + virtual CefRefPtr AddObserver( + CefRefPtr 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:?clientId="). + /// + /*--cef()--*/ + virtual CefRefPtr 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 source, + CefRefPtr sink, + CefRefPtr 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>& sinks) = 0; + + /// + // The list of available media routes has changed or + // CefMediaRouter::NotifyCurrentRoutes was called. + /// + /*--cef()--*/ + virtual void OnRoutes( + const std::vector>& routes) = 0; + + /// + // The connection state of |route| has changed. + /// + /*--cef()--*/ + virtual void OnRouteStateChanged(CefRefPtr 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 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 GetSource() = 0; + + /// + // Returns the sink associated with this route. + /// + /*--cef()--*/ + virtual CefRefPtr 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 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 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_ diff --git a/include/cef_registration.h b/include/cef_registration.h new file mode 100644 index 000000000..e8e6caadb --- /dev/null +++ b/include/cef_registration.h @@ -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_ diff --git a/include/cef_request_context.h b/include/cef_request_context.h index 2cda5be4e..edb65da6a 100644 --- a/include/cef_request_context.h +++ b/include/cef_request_context.h @@ -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 GetExtension( const CefString& extension_id) = 0; + + /// + // Returns the MediaRouter object associated with this context. + /// + /*--cef()--*/ + virtual CefRefPtr GetMediaRouter() = 0; }; #endif // CEF_INCLUDE_CEF_REQUEST_CONTEXT_H_ diff --git a/include/internal/cef_types.h b/include/internal/cef_types.h index 1423762e0..40596eadb 100644 --- a/include/internal/cef_types.h +++ b/include/internal/cef_types.h @@ -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 diff --git a/libcef/browser/browser_context.cc b/libcef/browser/browser_context.cc index fe79bdddb..e5f4ed694 100644 --- a/libcef/browser/browser_context.cc +++ b/libcef/browser/browser_context.cc @@ -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::DestructorAtExit g_manager = base::LazyInstance::Leaky g_manager = LAZY_INSTANCE_INITIALIZER; #endif +CefBrowserContext* GetSelf(base::WeakPtr 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(); +} diff --git a/libcef/browser/browser_context.h b/libcef/browser/browser_context.h index bd110a183..ddd8545fa 100644 --- a/libcef/browser/browser_context.h +++ b/libcef/browser/browser_context.h @@ -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; + Getter getter() const { return getter_; } + private: // Allow deletion via std::unique_ptr(). friend std::default_delete; @@ -315,6 +325,8 @@ class CefBrowserContext : public ChromeProfileStub, std::unique_ptr download_prefs_; + std::unique_ptr media_router_manager_; + // Map IDs to CefRequestContextHandler objects. CefRequestContextHandlerMap handler_map_; @@ -338,6 +350,9 @@ class CefBrowserContext : public ChromeProfileStub, typedef std::set NodeIdSet; NodeIdSet node_id_set_; + Getter getter_; + base::WeakPtrFactory weak_ptr_factory_; + DISALLOW_COPY_AND_ASSIGN(CefBrowserContext); }; diff --git a/libcef/browser/browser_main.cc b/libcef/browser/browser_main.cc index 59ff5fed2..171442aa9 100644 --- a/libcef/browser/browser_main.cc +++ b/libcef/browser/browser_main.cc @@ -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() { diff --git a/libcef/browser/media_router/media_route_impl.cc b/libcef/browser/media_router/media_route_impl.cc new file mode 100644 index 000000000..928381d54 --- /dev/null +++ b/libcef/browser/media_router/media_route_impl.cc @@ -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 CefMediaRouteImpl::GetSource() { + return new CefMediaSourceImpl(route_.media_source().id()); +} + +CefRefPtr 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(message), message_size); + + if (!CEF_CURRENTLY_ON_UIT()) { + CEF_POST_TASK( + CEF_UIT, + base::BindOnce( + [](CefRefPtr self, std::string message_str) { + self->SendRouteMessageInternal(std::move(message_str)); + }, + CefRefPtr(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); +} diff --git a/libcef/browser/media_router/media_route_impl.h b/libcef/browser/media_router/media_route_impl.h new file mode 100644 index 000000000..9e707c642 --- /dev/null +++ b/libcef/browser/media_router/media_route_impl.h @@ -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 GetSource() override; + CefRefPtr 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_ diff --git a/libcef/browser/media_router/media_router_impl.cc b/libcef/browser/media_router/media_router_impl.cc new file mode 100644 index 000000000..52c4f5e14 --- /dev/null +++ b/libcef/browser/media_router/media_router_impl.cc @@ -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 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> 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> 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 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& 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 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 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(CEF_MRCR_TOTAL_COUNT) == + static_cast(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 CefMediaRouterImpl::AddObserver( + CefRefPtr observer) { + if (!observer) + return nullptr; + CefRefPtr registration = + new CefRegistrationImpl(observer); + InitializeRegistrationOnUIThread(registration); + return registration.get(); +} + +CefRefPtr 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 source, + CefRefPtr sink, + CefRefPtr 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(source.get()); + auto sink_impl = static_cast(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 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 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 route; + if (result.result_code() == media_router::RouteRequestResult::OK && + result.route()) { + route = new CefMediaRouteImpl(*result.route(), browser_context_getter_); + } + + callback->OnMediaRouteCreateFinished( + static_cast(result.result_code()), + result.error(), route); +} + +// static +CefRefPtr CefMediaRouter::GetGlobalMediaRouter() { + return CefRequestContext::GetGlobalContext()->GetMediaRouter(); +} diff --git a/libcef/browser/media_router/media_router_impl.h b/libcef/browser/media_router/media_router_impl.h new file mode 100644 index 000000000..6512f356e --- /dev/null +++ b/libcef/browser/media_router/media_router_impl.h @@ -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 AddObserver( + CefRefPtr observer) override; + CefRefPtr GetSource(const CefString& urn) override; + void NotifyCurrentSinks() override; + void CreateRoute(CefRefPtr source, + CefRefPtr sink, + CefRefPtr callback) override; + void NotifyCurrentRoutes() override; + + private: + void InitializeRegistrationOnUIThread( + CefRefPtr registration); + + void CreateRouteCallback(CefRefPtr 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_ diff --git a/libcef/browser/media_router/media_router_manager.cc b/libcef/browser/media_router/media_router_manager.cc new file mode 100644 index 000000000..d364751c5 --- /dev/null +++ b/libcef/browser/media_router/media_router_manager.cc @@ -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& routes, + const std::vector& + 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 connection_receiver_; + + // Used to send messages to the MRP. + mojo::Remote 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(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(); + + if (!connection.is_null()) { + // PresentationConnection must be used for messaging and status + // notifications if it exists. + state->presentation_connection_ = + std::make_unique(this, route, + std::move(connection)); + } else { + // Fallback if PresentationConnection is not supported. + state->message_observer_ = + std::make_unique(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); +} diff --git a/libcef/browser/media_router/media_router_manager.h b/libcef/browser/media_router/media_router_manager.h new file mode 100644 index 000000000..28b8f864f --- /dev/null +++ b/libcef/browser/media_router/media_router_manager.h @@ -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; + using MediaSinkVector = std::vector; + using MediaMessageVector = std::vector; + + 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 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 presentation_connection_; + + // Used if there is no RoutePresentationConnectionPtr. + std::unique_ptr message_observer_; + std::unique_ptr + 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 observers_; + + media_router::QueryResultManager query_result_manager_; + std::unique_ptr routes_observer_; + + MediaRouteVector routes_; + MediaSinkVector sinks_; + + using RouteStateMap = + std::map>; + RouteStateMap route_state_map_; + + base::WeakPtrFactory weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(CefMediaRouterManager); +}; + +#endif // CEF_LIBCEF_BROWSER_MEDIA_ROUTER_MEDIA_ROUTER_MANAGER_H_ diff --git a/libcef/browser/media_router/media_sink_impl.cc b/libcef/browser/media_router/media_sink_impl.cc new file mode 100644 index 000000000..20ddb3d40 --- /dev/null +++ b/libcef/browser/media_router/media_sink_impl.cc @@ -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 source) { + if (source) { + if (IsCastSink()) + return source->IsCastSource(); + if (IsDialSink()) + return source->IsDialSource(); + } + return false; +} diff --git a/libcef/browser/media_router/media_sink_impl.h b/libcef/browser/media_router/media_sink_impl.h new file mode 100644 index 000000000..139f948b8 --- /dev/null +++ b/libcef/browser/media_router/media_sink_impl.h @@ -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 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_ diff --git a/libcef/browser/media_router/media_source_impl.cc b/libcef/browser/media_router/media_source_impl.cc new file mode 100644 index 000000000..2b722c762 --- /dev/null +++ b/libcef/browser/media_router/media_source_impl.cc @@ -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(); +} diff --git a/libcef/browser/media_router/media_source_impl.h b/libcef/browser/media_router/media_source_impl.h new file mode 100644 index 000000000..8e5015855 --- /dev/null +++ b/libcef/browser/media_router/media_source_impl.h @@ -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_ diff --git a/libcef/browser/prefs/browser_prefs.cc b/libcef/browser/prefs/browser_prefs.cc index d582f1b44..5edffac37 100644 --- a/libcef/browser/prefs/browser_prefs.cc +++ b/libcef/browser/prefs/browser_prefs.cc @@ -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 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 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 = diff --git a/libcef/browser/request_context_impl.cc b/libcef/browser/request_context_impl.cc index 37edf5a63..cc62313a9 100644 --- a/libcef/browser/request_context_impl.cc +++ b/libcef/browser/request_context_impl.cc @@ -594,6 +594,12 @@ CefRefPtr CefRequestContextImpl::GetExtension( return GetBrowserContext()->extension_system()->GetExtension(extension_id); } +CefRefPtr CefRequestContextImpl::GetMediaRouter() { + CefRefPtr 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 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_; } diff --git a/libcef/browser/request_context_impl.h b/libcef/browser/request_context_impl.h index 00a12c1e0..f99ffe613 100644 --- a/libcef/browser/request_context_impl.h +++ b/libcef/browser/request_context_impl.h @@ -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& extension_ids) override; CefRefPtr GetExtension(const CefString& extension_id) override; + CefRefPtr GetMediaRouter() override; const CefRequestContextSettings& settings() const { return config_.settings; } @@ -147,6 +149,9 @@ class CefRequestContextImpl : public CefRequestContext { CefRefPtr callback, CefBrowserContext* browser_context); + void InitializeMediaRouterOnUIThread( + CefRefPtr media_router); + CefBrowserContext* browser_context() const; // We must disassociate from this on destruction. diff --git a/libcef/common/main_delegate.cc b/libcef/common/main_delegate.cc index 507a5e9c7..016c11e6e 100644 --- a/libcef/common/main_delegate.cc +++ b/libcef/common/main_delegate.cc @@ -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 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()) { diff --git a/libcef_dll/cpptoc/media_observer_cpptoc.cc b/libcef_dll/cpptoc/media_observer_cpptoc.cc new file mode 100644 index 000000000..5026161a6 --- /dev/null +++ b/libcef_dll/cpptoc/media_observer_cpptoc.cc @@ -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> sinksList; + if (sinksCount > 0) { + for (size_t i = 0; i < sinksCount; ++i) { + CefRefPtr 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> routesList; + if (routesCount > 0) { + for (size_t i = 0; i < routesCount; ++i) { + CefRefPtr 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 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::kWrapperType = + WT_MEDIA_OBSERVER; diff --git a/libcef_dll/cpptoc/media_observer_cpptoc.h b/libcef_dll/cpptoc/media_observer_cpptoc.h new file mode 100644 index 000000000..77745a05d --- /dev/null +++ b/libcef_dll/cpptoc/media_observer_cpptoc.h @@ -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 { + public: + CefMediaObserverCppToC(); + virtual ~CefMediaObserverCppToC(); +}; + +#endif // CEF_LIBCEF_DLL_CPPTOC_MEDIA_OBSERVER_CPPTOC_H_ diff --git a/libcef_dll/cpptoc/media_route_cpptoc.cc b/libcef_dll/cpptoc/media_route_cpptoc.cc new file mode 100644 index 000000000..a0f3624f3 --- /dev/null +++ b/libcef_dll/cpptoc/media_route_cpptoc.cc @@ -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 _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 _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 +CefCppToCRefCounted:: + UnwrapDerived(CefWrapperType type, cef_media_route_t* s) { + NOTREACHED() << "Unexpected class type: " << type; + return nullptr; +} + +template <> +CefWrapperType CefCppToCRefCounted::kWrapperType = + WT_MEDIA_ROUTE; diff --git a/libcef_dll/cpptoc/media_route_cpptoc.h b/libcef_dll/cpptoc/media_route_cpptoc.h new file mode 100644 index 000000000..a30c27de0 --- /dev/null +++ b/libcef_dll/cpptoc/media_route_cpptoc.h @@ -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 { + public: + CefMediaRouteCppToC(); + virtual ~CefMediaRouteCppToC(); +}; + +#endif // CEF_LIBCEF_DLL_CPPTOC_MEDIA_ROUTE_CPPTOC_H_ diff --git a/libcef_dll/cpptoc/media_route_create_callback_cpptoc.cc b/libcef_dll/cpptoc/media_route_create_callback_cpptoc.cc new file mode 100644 index 000000000..bef28ee2c --- /dev/null +++ b/libcef_dll/cpptoc/media_route_create_callback_cpptoc.cc @@ -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 +CefCppToCRefCounted:: + UnwrapDerived(CefWrapperType type, cef_media_route_create_callback_t* s) { + NOTREACHED() << "Unexpected class type: " << type; + return nullptr; +} + +template <> +CefWrapperType + CefCppToCRefCounted::kWrapperType = + WT_MEDIA_ROUTE_CREATE_CALLBACK; diff --git a/libcef_dll/cpptoc/media_route_create_callback_cpptoc.h b/libcef_dll/cpptoc/media_route_create_callback_cpptoc.h new file mode 100644 index 000000000..019d215fb --- /dev/null +++ b/libcef_dll/cpptoc/media_route_create_callback_cpptoc.h @@ -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 { + public: + CefMediaRouteCreateCallbackCppToC(); + virtual ~CefMediaRouteCreateCallbackCppToC(); +}; + +#endif // CEF_LIBCEF_DLL_CPPTOC_MEDIA_ROUTE_CREATE_CALLBACK_CPPTOC_H_ diff --git a/libcef_dll/cpptoc/media_router_cpptoc.cc b/libcef_dll/cpptoc/media_router_cpptoc.cc new file mode 100644 index 000000000..9bad39142 --- /dev/null +++ b/libcef_dll/cpptoc/media_router_cpptoc.cc @@ -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 _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 _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 _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 +CefCppToCRefCounted:: + UnwrapDerived(CefWrapperType type, cef_media_router_t* s) { + NOTREACHED() << "Unexpected class type: " << type; + return nullptr; +} + +template <> +CefWrapperType CefCppToCRefCounted::kWrapperType = + WT_MEDIA_ROUTER; diff --git a/libcef_dll/cpptoc/media_router_cpptoc.h b/libcef_dll/cpptoc/media_router_cpptoc.h new file mode 100644 index 000000000..e8aaab594 --- /dev/null +++ b/libcef_dll/cpptoc/media_router_cpptoc.h @@ -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 { + public: + CefMediaRouterCppToC(); + virtual ~CefMediaRouterCppToC(); +}; + +#endif // CEF_LIBCEF_DLL_CPPTOC_MEDIA_ROUTER_CPPTOC_H_ diff --git a/libcef_dll/cpptoc/media_sink_cpptoc.cc b/libcef_dll/cpptoc/media_sink_cpptoc.cc new file mode 100644 index 000000000..13e82df7b --- /dev/null +++ b/libcef_dll/cpptoc/media_sink_cpptoc.cc @@ -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 +CefCppToCRefCounted:: + UnwrapDerived(CefWrapperType type, cef_media_sink_t* s) { + NOTREACHED() << "Unexpected class type: " << type; + return nullptr; +} + +template <> +CefWrapperType CefCppToCRefCounted::kWrapperType = + WT_MEDIA_SINK; diff --git a/libcef_dll/cpptoc/media_sink_cpptoc.h b/libcef_dll/cpptoc/media_sink_cpptoc.h new file mode 100644 index 000000000..315e520f9 --- /dev/null +++ b/libcef_dll/cpptoc/media_sink_cpptoc.h @@ -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 { + public: + CefMediaSinkCppToC(); + virtual ~CefMediaSinkCppToC(); +}; + +#endif // CEF_LIBCEF_DLL_CPPTOC_MEDIA_SINK_CPPTOC_H_ diff --git a/libcef_dll/cpptoc/media_source_cpptoc.cc b/libcef_dll/cpptoc/media_source_cpptoc.cc new file mode 100644 index 000000000..09b939436 --- /dev/null +++ b/libcef_dll/cpptoc/media_source_cpptoc.cc @@ -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 +CefCppToCRefCounted:: + UnwrapDerived(CefWrapperType type, cef_media_source_t* s) { + NOTREACHED() << "Unexpected class type: " << type; + return nullptr; +} + +template <> +CefWrapperType CefCppToCRefCounted::kWrapperType = + WT_MEDIA_SOURCE; diff --git a/libcef_dll/cpptoc/media_source_cpptoc.h b/libcef_dll/cpptoc/media_source_cpptoc.h new file mode 100644 index 000000000..e8810bc47 --- /dev/null +++ b/libcef_dll/cpptoc/media_source_cpptoc.h @@ -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 { + public: + CefMediaSourceCppToC(); + virtual ~CefMediaSourceCppToC(); +}; + +#endif // CEF_LIBCEF_DLL_CPPTOC_MEDIA_SOURCE_CPPTOC_H_ diff --git a/libcef_dll/cpptoc/registration_cpptoc.cc b/libcef_dll/cpptoc/registration_cpptoc.cc new file mode 100644 index 000000000..d6202157d --- /dev/null +++ b/libcef_dll/cpptoc/registration_cpptoc.cc @@ -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 +CefCppToCRefCounted::UnwrapDerived(CefWrapperType type, + cef_registration_t* s) { + NOTREACHED() << "Unexpected class type: " << type; + return nullptr; +} + +template <> +CefWrapperType CefCppToCRefCounted::kWrapperType = + WT_REGISTRATION; diff --git a/libcef_dll/cpptoc/registration_cpptoc.h b/libcef_dll/cpptoc/registration_cpptoc.h new file mode 100644 index 000000000..3e1eb52c0 --- /dev/null +++ b/libcef_dll/cpptoc/registration_cpptoc.h @@ -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 { + public: + CefRegistrationCppToC(); + virtual ~CefRegistrationCppToC(); +}; + +#endif // CEF_LIBCEF_DLL_CPPTOC_REGISTRATION_CPPTOC_H_ diff --git a/libcef_dll/cpptoc/request_context_cpptoc.cc b/libcef_dll/cpptoc/request_context_cpptoc.cc index 5184ad893..c252e42fd 100644 --- a/libcef_dll/cpptoc/request_context_cpptoc.cc +++ b/libcef_dll/cpptoc/request_context_cpptoc.cc @@ -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 _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. diff --git a/libcef_dll/ctocpp/media_observer_ctocpp.cc b/libcef_dll/ctocpp/media_observer_ctocpp.cc new file mode 100644 index 000000000..1d43b8d64 --- /dev/null +++ b/libcef_dll/ctocpp/media_observer_ctocpp.cc @@ -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>& 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>& 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 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 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::UnwrapDerived(CefWrapperType type, + CefMediaObserver* c) { + NOTREACHED() << "Unexpected class type: " << type; + return nullptr; +} + +template <> +CefWrapperType CefCToCppRefCounted::kWrapperType = + WT_MEDIA_OBSERVER; diff --git a/libcef_dll/ctocpp/media_observer_ctocpp.h b/libcef_dll/ctocpp/media_observer_ctocpp.h new file mode 100644 index 000000000..e314c4919 --- /dev/null +++ b/libcef_dll/ctocpp/media_observer_ctocpp.h @@ -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 +#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 { + public: + CefMediaObserverCToCpp(); + virtual ~CefMediaObserverCToCpp(); + + // CefMediaObserver methods. + void OnSinks(const std::vector>& sinks) override; + void OnRoutes(const std::vector>& routes) override; + void OnRouteStateChanged(CefRefPtr route, + ConnectionState state) override; + void OnRouteMessageReceived(CefRefPtr route, + const void* message, + size_t message_size) override; +}; + +#endif // CEF_LIBCEF_DLL_CTOCPP_MEDIA_OBSERVER_CTOCPP_H_ diff --git a/libcef_dll/ctocpp/media_route_create_callback_ctocpp.cc b/libcef_dll/ctocpp/media_route_create_callback_ctocpp.cc new file mode 100644 index 000000000..22c00e5ad --- /dev/null +++ b/libcef_dll/ctocpp/media_route_create_callback_ctocpp.cc @@ -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 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:: + UnwrapDerived(CefWrapperType type, CefMediaRouteCreateCallback* c) { + NOTREACHED() << "Unexpected class type: " << type; + return nullptr; +} + +template <> +CefWrapperType + CefCToCppRefCounted::kWrapperType = + WT_MEDIA_ROUTE_CREATE_CALLBACK; diff --git a/libcef_dll/ctocpp/media_route_create_callback_ctocpp.h b/libcef_dll/ctocpp/media_route_create_callback_ctocpp.h new file mode 100644 index 000000000..0d92b94f8 --- /dev/null +++ b/libcef_dll/ctocpp/media_route_create_callback_ctocpp.h @@ -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 { + public: + CefMediaRouteCreateCallbackCToCpp(); + virtual ~CefMediaRouteCreateCallbackCToCpp(); + + // CefMediaRouteCreateCallback methods. + void OnMediaRouteCreateFinished(RouteCreateResult result, + const CefString& error, + CefRefPtr route) override; +}; + +#endif // CEF_LIBCEF_DLL_CTOCPP_MEDIA_ROUTE_CREATE_CALLBACK_CTOCPP_H_ diff --git a/libcef_dll/ctocpp/media_route_ctocpp.cc b/libcef_dll/ctocpp/media_route_ctocpp.cc new file mode 100644 index 000000000..b9f17fa34 --- /dev/null +++ b/libcef_dll/ctocpp/media_route_ctocpp.cc @@ -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 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 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:: + UnwrapDerived(CefWrapperType type, CefMediaRoute* c) { + NOTREACHED() << "Unexpected class type: " << type; + return nullptr; +} + +template <> +CefWrapperType CefCToCppRefCounted::kWrapperType = + WT_MEDIA_ROUTE; diff --git a/libcef_dll/ctocpp/media_route_ctocpp.h b/libcef_dll/ctocpp/media_route_ctocpp.h new file mode 100644 index 000000000..c1f68b6f5 --- /dev/null +++ b/libcef_dll/ctocpp/media_route_ctocpp.h @@ -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 { + public: + CefMediaRouteCToCpp(); + virtual ~CefMediaRouteCToCpp(); + + // CefMediaRoute methods. + CefString GetId() OVERRIDE; + CefRefPtr GetSource() OVERRIDE; + CefRefPtr GetSink() OVERRIDE; + void SendRouteMessage(const void* message, size_t message_size) OVERRIDE; + void Terminate() OVERRIDE; +}; + +#endif // CEF_LIBCEF_DLL_CTOCPP_MEDIA_ROUTE_CTOCPP_H_ diff --git a/libcef_dll/ctocpp/media_router_ctocpp.cc b/libcef_dll/ctocpp/media_router_ctocpp.cc new file mode 100644 index 000000000..d90f7de74 --- /dev/null +++ b/libcef_dll/ctocpp/media_router_ctocpp.cc @@ -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::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 CefMediaRouterCToCpp::AddObserver( + CefRefPtr 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 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 source, + CefRefPtr sink, + CefRefPtr 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:: + UnwrapDerived(CefWrapperType type, CefMediaRouter* c) { + NOTREACHED() << "Unexpected class type: " << type; + return nullptr; +} + +template <> +CefWrapperType CefCToCppRefCounted::kWrapperType = + WT_MEDIA_ROUTER; diff --git a/libcef_dll/ctocpp/media_router_ctocpp.h b/libcef_dll/ctocpp/media_router_ctocpp.h new file mode 100644 index 000000000..7a022bba2 --- /dev/null +++ b/libcef_dll/ctocpp/media_router_ctocpp.h @@ -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 { + public: + CefMediaRouterCToCpp(); + virtual ~CefMediaRouterCToCpp(); + + // CefMediaRouter methods. + CefRefPtr AddObserver( + CefRefPtr observer) OVERRIDE; + CefRefPtr GetSource(const CefString& urn) OVERRIDE; + void NotifyCurrentSinks() OVERRIDE; + void CreateRoute(CefRefPtr source, + CefRefPtr sink, + CefRefPtr callback) OVERRIDE; + void NotifyCurrentRoutes() OVERRIDE; +}; + +#endif // CEF_LIBCEF_DLL_CTOCPP_MEDIA_ROUTER_CTOCPP_H_ diff --git a/libcef_dll/ctocpp/media_sink_ctocpp.cc b/libcef_dll/ctocpp/media_sink_ctocpp.cc new file mode 100644 index 000000000..9b5f85106 --- /dev/null +++ b/libcef_dll/ctocpp/media_sink_ctocpp.cc @@ -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 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:: + UnwrapDerived(CefWrapperType type, CefMediaSink* c) { + NOTREACHED() << "Unexpected class type: " << type; + return nullptr; +} + +template <> +CefWrapperType CefCToCppRefCounted::kWrapperType = + WT_MEDIA_SINK; diff --git a/libcef_dll/ctocpp/media_sink_ctocpp.h b/libcef_dll/ctocpp/media_sink_ctocpp.h new file mode 100644 index 000000000..c6b302ffa --- /dev/null +++ b/libcef_dll/ctocpp/media_sink_ctocpp.h @@ -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 { + 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 source) OVERRIDE; +}; + +#endif // CEF_LIBCEF_DLL_CTOCPP_MEDIA_SINK_CTOCPP_H_ diff --git a/libcef_dll/ctocpp/media_source_ctocpp.cc b/libcef_dll/ctocpp/media_source_ctocpp.cc new file mode 100644 index 000000000..25acc589b --- /dev/null +++ b/libcef_dll/ctocpp/media_source_ctocpp.cc @@ -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:: + UnwrapDerived(CefWrapperType type, CefMediaSource* c) { + NOTREACHED() << "Unexpected class type: " << type; + return nullptr; +} + +template <> +CefWrapperType CefCToCppRefCounted::kWrapperType = + WT_MEDIA_SOURCE; diff --git a/libcef_dll/ctocpp/media_source_ctocpp.h b/libcef_dll/ctocpp/media_source_ctocpp.h new file mode 100644 index 000000000..fd54e19d8 --- /dev/null +++ b/libcef_dll/ctocpp/media_source_ctocpp.h @@ -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 { + 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_ diff --git a/libcef_dll/ctocpp/registration_ctocpp.cc b/libcef_dll/ctocpp/registration_ctocpp.cc new file mode 100644 index 000000000..ad14288c2 --- /dev/null +++ b/libcef_dll/ctocpp/registration_ctocpp.cc @@ -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::UnwrapDerived(CefWrapperType type, + CefRegistration* c) { + NOTREACHED() << "Unexpected class type: " << type; + return nullptr; +} + +template <> +CefWrapperType CefCToCppRefCounted::kWrapperType = + WT_REGISTRATION; diff --git a/libcef_dll/ctocpp/registration_ctocpp.h b/libcef_dll/ctocpp/registration_ctocpp.h new file mode 100644 index 000000000..9485a6851 --- /dev/null +++ b/libcef_dll/ctocpp/registration_ctocpp.h @@ -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 { + public: + CefRegistrationCToCpp(); + virtual ~CefRegistrationCToCpp(); + + // CefRegistration methods. +}; + +#endif // CEF_LIBCEF_DLL_CTOCPP_REGISTRATION_CTOCPP_H_ diff --git a/libcef_dll/ctocpp/request_context_ctocpp.cc b/libcef_dll/ctocpp/request_context_ctocpp.cc index bbdc9d023..b3a9ac4cc 100644 --- a/libcef_dll/ctocpp/request_context_ctocpp.cc +++ b/libcef_dll/ctocpp/request_context_ctocpp.cc @@ -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 CefRequestContextCToCpp::GetExtension( return CefExtensionCToCpp::Wrap(_retval); } +NO_SANITIZE("cfi-icall") +CefRefPtr 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() {} diff --git a/libcef_dll/ctocpp/request_context_ctocpp.h b/libcef_dll/ctocpp/request_context_ctocpp.h index c312e2e80..f5d9f6eca 100644 --- a/libcef_dll/ctocpp/request_context_ctocpp.h +++ b/libcef_dll/ctocpp/request_context_ctocpp.h @@ -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& extension_ids) OVERRIDE; CefRefPtr GetExtension(const CefString& extension_id) OVERRIDE; + CefRefPtr GetMediaRouter() OVERRIDE; }; #endif // CEF_LIBCEF_DLL_CTOCPP_REQUEST_CONTEXT_CTOCPP_H_ diff --git a/libcef_dll/wrapper/libcef_dll_dylib.cc b/libcef_dll/wrapper/libcef_dll_dylib.cc index 49eab3174..5b0d5687a 100644 --- a/libcef_dll/wrapper/libcef_dll_dylib.cc +++ b/libcef_dll/wrapper/libcef_dll_dylib.cc @@ -9,7 +9,7 @@ // implementations. See the translator.README.txt file in the tools directory // for more information. // -// $hash=5e0a3a27b41b550a1dd4985eec9034a6f7c2b7d7$ +// $hash=bf82965f02cafae5a1afc80ab0c976436be9712e$ // #include @@ -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) { diff --git a/libcef_dll/wrapper_types.h b/libcef_dll/wrapper_types.h index ba2fcac9b..fa468c83d 100644 --- a/libcef_dll/wrapper_types.h +++ b/libcef_dll/wrapper_types.h @@ -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, diff --git a/tests/cefclient/browser/media_router_test.cc b/tests/cefclient/browser/media_router_test.cc new file mode 100644 index 000000000..e9e19730c --- /dev/null +++ b/tests/cefclient/browser/media_router_test.cc @@ -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 +#include + +#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 dictionary) { + CefRefPtr value = CefValue::Create(); + value->SetDictionary(dictionary); + return CefWriteJSON(value, JSON_WRITER_DEFAULT); +} + +typedef CefMessageRouterBrowserSide::Callback CallbackType; + +void SendSuccess(CefRefPtr callback, + CefRefPtr result) { + callback->Success(GetJSON(result)); +} + +void SendFailure(CefRefPtr 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 create_callback) + : create_callback_(create_callback) {} + + // CefMediaRouteCreateCallback method: + void OnMediaRouteCreateFinished(RouteCreateResult result, + const CefString& error, + CefRefPtr route) OVERRIDE { + CEF_REQUIRE_UI_THREAD(); + if (result == CEF_MRCR_OK) { + CefRefPtr result = CefDictionaryValue::Create(); + result->SetString(kRouteKey, route->GetId()); + SendSuccess(create_callback_, result); + } else { + SendFailure(create_callback_, kRequestFailedError + result, error); + } + create_callback_ = NULL; + } + + private: + CefRefPtr 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> MediaRouteVector; + typedef std::vector> MediaSinkVector; + + MediaObserver(CefRefPtr media_router, + CefRefPtr subscription_callback) + : media_router_(media_router), + subscription_callback_(subscription_callback) {} + + bool CreateRoute(const std::string& source_urn, + const std::string& sink_id, + CefRefPtr callback, + std::string& error) { + CefRefPtr source = GetSource(source_urn); + if (!source) { + error = "Invalid source: " + source_urn; + return false; + } + + CefRefPtr 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 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 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 payload = CefDictionaryValue::Create(); + CefRefPtr 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 sink = *it; + const std::string& sink_id = sink->GetId(); + sink_map_.insert(std::make_pair(sink_id, sink)); + + CefRefPtr 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 payload = CefDictionaryValue::Create(); + CefRefPtr 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 route = *it; + const std::string& route_id = route->GetId(); + route_map_.insert(std::make_pair(route_id, route)); + + CefRefPtr 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 route, + ConnectionState state) OVERRIDE { + CEF_REQUIRE_UI_THREAD(); + + CefRefPtr payload = CefDictionaryValue::Create(); + payload->SetString(kRouteKey, route->GetId()); + payload->SetInt("connection_state", state); + SendResponse("onRouteStateChanged", payload); + } + + void OnRouteMessageReceived(CefRefPtr route, + const void* message, + size_t message_size) OVERRIDE { + CEF_REQUIRE_UI_THREAD(); + + std::string message_str(static_cast(message), message_size); + + CefRefPtr payload = CefDictionaryValue::Create(); + payload->SetString(kRouteKey, route->GetId()); + payload->SetString(kMessageKey, message_str); + SendResponse("onRouteMessageReceived", payload); + } + + private: + CefRefPtr GetSource(const std::string& source_urn) { + CefRefPtr source = media_router_->GetSource(source_urn); + if (!source || !source->IsValid()) + return NULL; + return source; + } + + CefRefPtr 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 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 payload) { + CefRefPtr result = CefDictionaryValue::Create(); + result->SetString(kNameKey, name); + result->SetDictionary(kPayloadKey, payload); + SendSuccess(subscription_callback_, result); + } + + CefRefPtr media_router_; + CefRefPtr subscription_callback_; + + typedef std::map> SinkMap; + SinkMap sink_map_; + + typedef std::map> 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 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 browser, + CefRefPtr frame, + int64 query_id, + const CefString& request, + bool persistent, + CefRefPtr 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 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 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 browser, + CefRefPtr frame, + int64 query_id) OVERRIDE { + CEF_REQUIRE_UI_THREAD(); + RemoveSubscription(browser->GetIdentifier(), query_id); + } + + private: + static void SendSuccessACK(CefRefPtr callback) { + CefRefPtr result = CefDictionaryValue::Create(); + result->SetBool(kSuccessKey, true); + SendSuccess(callback, result); + } + + // Convert a JSON string to a dictionary value. + static CefRefPtr ParseJSON(const CefString& string) { + CefRefPtr 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 dictionary, + const char* key, + cef_value_type_t value_type, + CefRefPtr 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 observer; + CefRefPtr registration; + }; + + bool CreateSubscription(CefRefPtr browser, + int64 query_id, + CefRefPtr 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 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 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 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 diff --git a/tests/cefclient/browser/media_router_test.h b/tests/cefclient/browser/media_router_test.h new file mode 100644 index 000000000..1671ff02b --- /dev/null +++ b/tests/cefclient/browser/media_router_test.h @@ -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_ diff --git a/tests/cefclient/browser/resource.h b/tests/cefclient/browser/resource.h index 7102b4eb0..6003d1281 100644 --- a/tests/cefclient/browser/resource.h +++ b/tests/cefclient/browser/resource.h @@ -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 diff --git a/tests/cefclient/browser/resource_util_win_idmap.cc b/tests/cefclient/browser/resource_util_win_idmap.cc index ec398263b..545ce49d9 100644 --- a/tests/cefclient/browser/resource_util_win_idmap.cc +++ b/tests/cefclient/browser/resource_util_win_idmap.cc @@ -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}, diff --git a/tests/cefclient/browser/test_runner.cc b/tests/cefclient/browser/test_runner.cc index 590f4d04c..68805e9fc 100644 --- a/tests/cefclient/browser/test_runner.cc +++ b/tests/cefclient/browser/test_runner.cc @@ -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); diff --git a/tests/cefclient/resources/media_router.html b/tests/cefclient/resources/media_router.html new file mode 100644 index 000000000..66d13ea3d --- /dev/null +++ b/tests/cefclient/resources/media_router.html @@ -0,0 +1,562 @@ + + + + +Media Router Example + + +
+
+ Media Router Example +

+ Overview: + Chromium supports communication with devices on the local network via the + Cast and + DIAL 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. +

+

+ Usage: + 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:<appId>?clientId=<clientId>" and DIAL URNs take the form "dial:<appId>", + where <appId> is the registered application ID + and <clientId> 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 + here. +

+
+
+ Source: + +
+ Sink: + +
+ + +
+
+
+
+ +
+
+
+ + diff --git a/tests/cefclient/resources/other_tests.html b/tests/cefclient/resources/other_tests.html index 798aebe46..a92b849da 100644 --- a/tests/cefclient/resources/other_tests.html +++ b/tests/cefclient/resources/other_tests.html @@ -23,6 +23,7 @@
  • JavaScript Performance (2) Tests
  • JavaScript Window Manipulation
  • Local Storage
  • +
  • Media Router (Cast/DIAL)
  • PDF Viewer direct
  • PDF Viewer iframe
  • Preferences
  • diff --git a/tests/cefclient/resources/win/cefclient.rc b/tests/cefclient/resources/win/cefclient.rc index ea7c7c405..77bf9dfaf 100644 --- a/tests/cefclient/resources/win/cefclient.rc +++ b/tests/cefclient/resources/win/cefclient.rc @@ -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"