1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255
|
// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_MEDIA_ROUTER_BROWSER_MEDIA_ROUTER_H_
#define COMPONENTS_MEDIA_ROUTER_BROWSER_MEDIA_ROUTER_H_
#include <stdint.h>
#include <string>
#include <vector>
#include "base/callback_list.h"
#include "base/functional/callback.h"
#include "base/time/time.h"
#include "base/values.h"
#include "build/build_config.h"
#include "components/keyed_service/core/keyed_service.h"
#include "components/media_router/browser/mirroring_media_controller_host.h"
#include "components/media_router/browser/presentation_connection_message_observer.h"
#include "components/media_router/common/media_route.h"
#include "components/media_router/common/media_route_provider_helper.h"
#include "components/media_router/common/media_sink.h"
#include "components/media_router/common/media_source.h"
#include "components/media_router/common/mojom/media_router.mojom.h"
#include "components/sessions/core/session_id.h"
#include "content/public/browser/presentation_service_delegate.h"
#include "media/base/flinging_controller.h"
#include "third_party/blink/public/mojom/presentation/presentation.mojom.h"
#if !BUILDFLAG(IS_ANDROID)
#include "components/media_router/browser/logger_impl.h"
#include "components/media_router/browser/media_router_debugger.h"
#include "components/media_router/common/mojom/media_controller.mojom.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#endif // !BUILDFLAG(IS_ANDROID)
namespace content {
class WebContents;
}
namespace url {
class Origin;
} // namespace url
namespace media_router {
class IssueManager;
class MediaRoutesObserver;
class MediaSinksObserver;
class PresentationConnectionStateObserver;
class RouteRequestResult;
// Commandline flag to disable the default media route providers for tests that
// are sensitive to the presence of sinks e.g. on the local network.
constexpr char kDisableMediaRouteProvidersForTestSwitch[] =
"disable-media-route-providers-for-test";
// Type of callback used in |CreateRoute()| and |JoinRoute()|. Callback is
// invoked when the route request either succeeded or failed. |connection| is
// set depending on whether the MRP chooses to setup the PresentationConnections
// itself.
using MediaRouteResponseCallback =
base::OnceCallback<void(mojom::RoutePresentationConnectionPtr connection,
const RouteRequestResult& result)>;
// An interface for handling resources related to media routing.
// Responsible for registering observers for receiving sink availability
// updates, handling route requests/responses, and operating on routes (e.g.
// posting messages or closing).
// TODO(imcheng): Reduce number of parameters by putting them into structs.
class MediaRouter : public KeyedService {
public:
~MediaRouter() override = default;
// Must be called before invoking any other method.
virtual void Initialize() = 0;
// Creates a media route from |source_id| to |sink_id|.
// |origin| is the origin of requestor's page.
// |web_contents| is the WebContents of the tab in which the request was made.
// |origin| and |web_contents| are used for enforcing same-origin and/or
// same-tab scope for JoinRoute() requests. (e.g., if enforced, the page
// requesting JoinRoute() must have the same origin as the page that requested
// CreateRoute()).
// The caller may pass in nullptr for |web_contents| if tab is not applicable.
// Each callback in |callbacks| is invoked with a response indicating
// success or failure, in the order they are listed.
// If |timeout| is positive, then any un-invoked |callbacks| will be invoked
// with a timeout error after the timeout expires.
virtual void CreateRoute(const MediaSource::Id& source_id,
const MediaSink::Id& sink_id,
const url::Origin& origin,
content::WebContents* web_contents,
MediaRouteResponseCallback callback,
base::TimeDelta timeout) = 0;
// Joins an existing route identified by |presentation_id|.
// |source|: The source to route to the existing route.
// |presentation_id|: Presentation ID of the existing route.
// |origin|, |web_contents|: Origin and WebContents of the join route request.
// Used for validation when enforcing same-origin and/or same-tab scope.
// (See CreateRoute documentation).
// Each callback in |callbacks| is invoked with a response indicating
// success or failure, in the order they are listed.
// If |timeout| is positive, then any un-invoked |callbacks| will be invoked
// with a timeout error after the timeout expires.
virtual void JoinRoute(const MediaSource::Id& source,
const std::string& presentation_id,
const url::Origin& origin,
content::WebContents* web_contents,
MediaRouteResponseCallback callback,
base::TimeDelta timeout) = 0;
// Terminates the media route specified by |route_id|.
virtual void TerminateRoute(const MediaRoute::Id& route_id) = 0;
// Detaches the media route specified by |route_id|. The request might come
// from the page or from an event like navigation or garbage collection.
virtual void DetachRoute(MediaRoute::Id route_id) = 0;
// Posts |message| to a MediaSink connected via MediaRoute with |route_id|.
virtual void SendRouteMessage(const MediaRoute::Id& route_id,
const std::string& message) = 0;
// Sends |data| to a MediaSink connected via MediaRoute with |route_id|.
// This is called for Blob / ArrayBuffer / ArrayBufferView types.
virtual void SendRouteBinaryMessage(
const MediaRoute::Id& route_id,
std::unique_ptr<std::vector<uint8_t>> data) = 0;
// Notifies the Media Router that the user has taken an action involving the
// Media Router. This can be used to perform any initialization that is not
// approriate to be done at construction.
virtual void OnUserGesture() = 0;
// Adds |callback| to listen for state changes for presentation connected to
// |route_id|. The returned subscription is owned by the caller. |callback|
// will be invoked whenever there are state changes, until the caller destroys
// the subscription.
virtual base::CallbackListSubscription
AddPresentationConnectionStateChangedCallback(
const MediaRoute::Id& route_id,
const content::PresentationConnectionStateChangedCallback& callback) = 0;
// Returns the media routes that currently exist. To get notified whenever
// there is a change to the media routes, subclass MediaRoutesObserver.
virtual std::vector<MediaRoute> GetCurrentRoutes() const = 0;
// Returns a controller that sends commands to media within a route, and
// propagates MediaStatus changes.
// Returns a nullptr if no controller can be be found from |route_id|.
virtual std::unique_ptr<media::FlingingController> GetFlingingController(
const MediaRoute::Id& route_id) = 0;
#if !BUILDFLAG(IS_ANDROID)
// Returns a pointer to a controller host that sends media commands related to
// mirroring within a route.
virtual MirroringMediaControllerHost* GetMirroringMediaControllerHost(
const MediaRoute::Id& route_id) = 0;
// Returns the IssueManager owned by the MediaRouter. Guaranteed to be
// non-null.
virtual IssueManager* GetIssueManager() = 0;
// Binds |controller| for sending media commands to a route. The controller
// will notify |observer| whenever there is a change to the status of the
// media. It may invalidate bindings from previous calls to this method.
virtual void GetMediaController(
const MediaRoute::Id& route_id,
mojo::PendingReceiver<mojom::MediaController> controller,
mojo::PendingRemote<mojom::MediaStatusObserver> observer) = 0;
// Returns logs collected from Media Router components.
// Used by chrome://media-router-internals.
virtual base::Value GetLogs() const = 0;
// Returns media router state as a JSON string represented by base::Value.
// Includes known sinks and sink compatibility with media sources.
// Used by chrome://media-router-internals.
virtual base::Value::Dict GetState() const = 0;
// Returns the media route provider state for |provider_id| via |callback|.
// Includes details about routes/sessions owned by the MRP.
// Used by chrome://media-router-internals.
virtual void GetProviderState(
mojom::MediaRouteProviderId provider_id,
mojom::MediaRouteProvider::GetStateCallback callback) const = 0;
// Returns a pointer to LoggerImpl that can be used to add logging messages.
virtual LoggerImpl* GetLogger() = 0;
// Returns the instance of the debugger for this MediaRouter instance.
virtual MediaRouterDebugger& GetDebugger() = 0;
#endif // !BUILDFLAG(IS_ANDROID)
private:
// TODO(https://crbug.com/1198580): remove message observer classes and API.
friend class IssuesObserver;
friend class MediaSinksObserver;
friend class MediaRoutesObserver;
friend class PresentationConnectionStateObserver;
friend class PresentationConnectionMessageObserver;
// The following functions are called by friend Observer classes above.
// Registers |observer| with this MediaRouter. |observer| specifies a media
// source and will receive updates with media sinks that are compatible with
// that source. The initial update may happen synchronously.
// NOTE: This class does not assume ownership of |observer|. Callers must
// manage |observer| and make sure |UnregisterObserver()| is called
// before the observer is destroyed.
// It is invalid to register the same observer more than once and will result
// in undefined behavior.
// If the MRPM Host is not available, the registration request will fail
// immediately.
// The implementation can reject the request to observe in which case it will
// notify the caller by returning |false|.
virtual bool RegisterMediaSinksObserver(MediaSinksObserver* observer) = 0;
// Removes a previously added MediaSinksObserver. |observer| will stop
// receiving further updates.
virtual void UnregisterMediaSinksObserver(MediaSinksObserver* observer) = 0;
// Adds a MediaRoutesObserver to listen for updates on MediaRoutes.
// The initial update may happen synchronously.
// MediaRouter does not own |observer|. |UnregisterMediaRoutesObserver| should
// be called before |observer| is destroyed.
// It is invalid to register the same observer more than once and will result
// in undefined behavior.
virtual void RegisterMediaRoutesObserver(MediaRoutesObserver* observer) = 0;
// Removes a previously added MediaRoutesObserver. |observer| will stop
// receiving further updates.
virtual void UnregisterMediaRoutesObserver(MediaRoutesObserver* observer) = 0;
// Registers |observer| with this MediaRouter. |observer| specifies a media
// route and will receive messages from the MediaSink connected to the
// route. Note that MediaRouter does not own |observer|. |observer| should be
// unregistered before it is destroyed. Registering the same observer more
// than once will result in undefined behavior.
virtual void RegisterPresentationConnectionMessageObserver(
PresentationConnectionMessageObserver* observer) = 0;
// Unregisters a previously registered RouteMessagesObserver. |observer| will
// stop receiving further updates.
virtual void UnregisterPresentationConnectionMessageObserver(
PresentationConnectionMessageObserver* observer) = 0;
};
} // namespace media_router
#endif // COMPONENTS_MEDIA_ROUTER_BROWSER_MEDIA_ROUTER_H_
|