chromium/components/cast_receiver/README.md

# Introduction

This component provides the shared Cast receiver implementation that is used by
various embedders throughout Chromium. It is planned to be used for WebEngine,
Chromecast hardware, and others.

# Usage

The specifics of integrating this component with an existing Chromium embedder
are described below. The canonical implementation of this component can be found
at
[`//chromecast/cast_core`](https://source.chromium.org/chromium/chromium/src/+/main:chromecast/cast_core/).
For specific usages of the below described APIs, see its
[RuntimeServiceImpl](https://source.chromium.org/chromium/chromium/src/+/main:chromecast/cast_core/runtime/browser/runtime_service_impl.h;l=33)
and
[RuntimeApplicationServiceImpl](https://source.chromium.org/chromium/chromium/src/+/main:chromecast/cast_core/runtime/browser/runtime_application_service_impl.h)
classes, which use this component to implement a
[`gRPC`-defined service](https://source.chromium.org/chromium/chromium/src/+/main:third_party/cast_core/public/src/proto/runtime/runtime_service.proto).

## Integration With Existing Code

Integration with an existing Chromium embedder is relateively easy, with only
a small number of integration points required:

### Browser-Side Integration

Browser-side integration has two parts:

#### Permissions Management

The
[`Permissions Manager`](https://source.chromium.org/chromium/chromium/src/+/main:components/cast_receiver/browser/public/permissions_manager.h)
is used to define the
[permissions](https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/public/common/permissions/permission_utils.h;drc=b8524150039182faf7988e9478a9eff89728ac03;l=23)
that can be used by a given application. It is integrated into an existing
Chromium embedder by
[calling into](https://source.chromium.org/chromium/chromium/src/+/main:chromecast/browser/cast_permission_manager.cc;l=104)
the
[PermissionsManager::GetPermissionsStatus()](https://source.chromium.org/chromium/chromium/src/+/main:components/cast_receiver/browser/public/permissions_manager.h;l=37)
function from the embedder's implementation of
[`content::PermissionControllerDelegate::GetPermissionStatus()`](https://source.chromium.org/chromium/chromium/src/+/main:content/public/browser/permission_controller_delegate.h;l=75).

#### Runtime Hooks

The remaining integration is done by creating an instance of the
[`ContentBrowserClientMixins` class](https://source.chromium.org/chromium/chromium/src/+/main:components/cast_receiver/browser/public/content_browser_client_mixins.h;l=45)
in the `ContentBrowserClient` implementation for this embedder. For instance,
this is
[currently done](https://source.chromium.org/chromium/chromium/src/+/main:chromecast/cast_core/runtime/browser/cast_runtime_content_browser_client.cc;l=54)
in the Cast Core implementation. From there, the `OnWebContentsCreated()` and
`CreateURLLoaderThrottles()` functions must be called from the
`ContentBrowserClient` functions of the same name.

The embedder may additionally call `AddApplicationStateObserver()` or
`AddStreamingResolutionObserver()` to subscribe to state change events for the
runtime.

### Renderer-Side Integration

Renderer side integration is done very similarly to the runtime hooks for the
browser-side integration as described above. Specifically, from the embedder's
`ContentRendererClient` implementation, an instance of
`ContentRendererClientMixins` must be
[created](https://source.chromium.org/chromium/chromium/src/+/main:components/cast_receiver/renderer/public/content_renderer_client_mixins.h;l=34)
as is
[currently done](https://source.chromium.org/chromium/chromium/src/+/main:chromecast/renderer/cast_content_renderer_client.cc;l=88)
in the Cast Core implementation. Then, the functions of this calls must all be
called from the appropriate `ContentRendererClient` functions as outlined in the
class's documentation.

## Running Applications

### Lifetime of an Application

Once the above integration is done, applications can be created by first
[creating an instance](https://source.chromium.org/chromium/chromium/src/+/main:components/cast_receiver/browser/public/content_browser_client_mixins.h;l=88)
of `RuntimeApplicationDispatcher` using the
`ContentBrowserClientMixins::CreateApplicationDispatcher()` function, then
calling
[`CreateApplication()`](https://source.chromium.org/chromium/chromium/src/+/main:components/cast_receiver/browser/public/runtime_application_dispatcher.h;l=36)
and providing
[basic information about the application](https://source.chromium.org/chromium/chromium/src/+/main:components/cast_receiver/browser/public/application_config.h)
(such as application id, requested permissions, etc). Note that this requires a
template parameter of a type implementing the
[`EmbedderApplication` interface](https://source.chromium.org/chromium/chromium/src/+/main:components/cast_receiver/browser/public/embedder_application.h;l=29).

After creation, an application will always exist in one of the following
lifetime states, transitioning between them using functions defined in the
[`RuntimeApplication` interface](https://source.chromium.org/chromium/chromium/src/+/main:components/cast_receiver/browser/public/runtime_application.h;l=19):

1. _Created_: In this state, the `RuntimeApplication` object has been created,
but nothing else has been done.
2. _Loaded_: In this state, information pertaining to the application has been
provided (e.g. any platform-specific application info), and is considered to
have started "running", but no content should be displayed on the screen.
3. _Launched_: The application has been displayed on the screen, and the user
may interact with it.
4. _Stopped_: The application is no longer running and should not be displayed.

It is expected that the application will be _loaded_ immediately after being
_created_, and then _launched_ shortly after.

When the application is to be destroyed, this can be done through calling
`RuntimeApplicationDispatcher::DestroyApplication()`.

### Embedder-Specific Application Details

Implementing
[`EmbedderApplication`](https://source.chromium.org/chromium/chromium/src/+/main:components/cast_receiver/browser/public/embedder_application.h;l=29)
is where the majority of the embedder's work is located. Doing so requires the
following:

- Callbacks to inform the embedder's infrastructure of application state changes
(`NotifyApplicationStarted()`, `NotifyApplicationStopped()`, and
`NotifyMediaPlaybackChanged()`).
- Accessors to the application-specific data for displaying its contents
(`GetWebContents()` and `GetAllBindings()`).
- Embedder-specific controls for the underlying application
 (`GetMessagePortService()` and `GetContentWindowControls()`).
- Other optional overloads that may be needed depending on the embedder's
infrastructure.

Implementing this type therefore requires at minimum implementations of the
following two embedder-specific classes:
- `ContentWindowControls`: Used for controlling the UX Window associated with
this application.
- `MessagePortService`: A wrapper around message port functionality, used to
handle communication with services outside of this component.

### Connecting Runtime Applications and Embedder Applications

When
[creating an instance](https://source.chromium.org/chromium/chromium/src/+/main:components/cast_receiver/browser/public/runtime_application_dispatcher.h;l=28)
of `EmbedderApplication` through `RuntimeApplicationDispatcher`, an instance of
[`RuntimeApplication`](https://source.chromium.org/chromium/chromium/src/+/main:components/cast_receiver/browser/public/runtime_application.h;l=19)
is provided, which can be used for control of this application. Specifically:

- Application Lifetime can be controlled through the `Load()`, `Launch()`, and
`Stop()` functions.
- Application State can be controlled with the `SetMediaBlocking()`,
`SetVisibility()`, `SetTouchInputEnabled()`, and `SetUrlRewriteRules()`
functions.

A pointer to this instance of `EmbedderApplication` will also be provided to the
`RuntimeApplicaiton`, which will use the callbacks and controls as described
previously throughout the application's lifetime.

# Architecture

## Code Structure

The top-level object with which the embedder will interact is the
`ContentBrowserClientMixins` class which will be used to
[create](https://source.chromium.org/chromium/chromium/src/+/main:components/cast_receiver/browser/public/content_browser_client_mixins.h;l=88)
a `RuntimeApplicationDispatcher` instance. That instance will
[create](https://source.chromium.org/chromium/chromium/src/+/main:components/cast_receiver/browser/public/runtime_application_dispatcher.h;l=36)
`RuntimeApplications` instances, either `StreamingRuntimeApplication` or
`WebRuntimeApplication` instances, and then
[wrap them](https://source.chromium.org/chromium/chromium/src/+/main:components/cast_receiver/browser/runtime_application_dispatcher_impl.h;l=86;drc=790df4d5983e38ad1d1d00fbc10ef941070eed24)
in an `EmbedderApplication` instance using a factory provided by the embedder.
The `EmbedderApplication` instance will control the `RuntimeApplication` with
the following
[commands](https://source.chromium.org/chromium/chromium/src/+/main:components/cast_receiver/browser/public/runtime_application_dispatcher.h):

*   `Load()`
*   `Launch()`
*   `Stop()`

Additionally, the `RuntimeApplication`
[exposes](https://source.chromium.org/chromium/chromium/src/+/main:components/cast_receiver/browser/public/runtime_application.h;drc=12be03159fe22cd4ef291e9561762531c2589539)
a number of accessors and ways to set properties of the application, such as
enabling or disabling touch input. The `EmbedderApplication`
[exposes](https://source.chromium.org/chromium/chromium/src/+/main:components/cast_receiver/browser/public/embedder_application.h;drc=12be03159fe22cd4ef291e9561762531c2589539)
functions to supply embedder-specific types or commands, such as:

*   `GetAllBindings()`
*   `GetMessagePortService()`
*   `GetContentWindowControls()`
*   `GetStreamingConfigManager()`

Additionally, it exposes functions by which it may be informed of state changes
in the `RuntimeApplication` instance it owns.

![cast_receiver code structure](/docs/images/cast_receiver_code_structure.png "cast_receiver code structure")


## Common Scenarios

In each of the following diagrams, blue boxes are used to represent
embedder-specific infrastructure, while white boxes are part of the component.

This component supports two types of applications: Web Applications and
Streaming Applications. Much of the infrastructure for these two application
types is shared, but the differences are substantial enough that each will be
discussed independently.

### Web Applications

Web Applications are used for hosting the majority of applications for a Cast
receiver. At a high level, the flow for using a Web Application is:

1. [Create](https://source.chromium.org/chromium/chromium/src/+/main:components/cast_receiver/browser/public/content_browser_client_mixins.h;l=45;drc=12be03159fe22cd4ef291e9561762531c2589539)
a new `ContentBrowserClientMixins` instance in the embedder-specific
`ContentBrowserClient` implementation, and then use that instance to
[create](https://source.chromium.org/chromium/chromium/src/+/main:components/cast_receiver/browser/public/content_browser_client_mixins.h;l=88;drc=12be03159fe22cd4ef291e9561762531c2589539)
a `RuntimeApplicationDispatcher`.
2. Use the `RuntimeApplicationDispatcher` to
[create](https://source.chromium.org/chromium/chromium/src/+/main:components/cast_receiver/browser/public/runtime_application_dispatcher.h;l=36;drc=1bcc6d9e4af49c462d3b2bee9f00db757084d262)
a `WebRuntimeApplication` instance, which will then be used to
[create](https://source.chromium.org/chromium/chromium/src/+/main:components/cast_receiver/browser/runtime_application_dispatcher_impl.h;l=86;drc=790df4d5983e38ad1d1d00fbc10ef941070eed24) an instance of the embedder-specific `EmbedderApplication` type.
3. Call `Load()` on the `RuntimeApplication` instance, and wait for its
callback.
4. Call `SetUrlRewriteRules()` on the `RuntimeApplication`. This may be called
at any time, but is expected to be called at least once before the `Launch()`
command if such rules are required for the application’s functionality.
5. Call `Launch()` on the `RuntimeApplication` instance, and wait for its
callback. Various `EmbedderApplication` functions will be called to create the
necessary resources.
6. Once the application is no longer needed, close it with `StopApplication()`
and then
[destroy](https://source.chromium.org/chromium/chromium/src/+/main:components/cast_receiver/browser/public/runtime_application_dispatcher.h;l=48;drc=1bcc6d9e4af49c462d3b2bee9f00db757084d262)
the application with the `RuntimeApplicationDispatcher` after the
`StopApplication()`’s callback returns.

![Web Application code flow](/docs/images/cast_receiver_webruntimeapplication_flow.png "WebRuntimeApplication structure")

### Streaming

Streaming Applications are used to support the Cast streaming and remoting
scenarios by making use of the `cast_streaming` component

1. [Create](https://source.chromium.org/chromium/chromium/src/+/main:components/cast_receiver/browser/public/content_browser_client_mixins.h;l=45;drc=12be03159fe22cd4ef291e9561762531c2589539)
a new `ContentBrowserClientMixins` instance in the embedder-specific
`ContentBrowserClient` implementation, and then use that instance to
[create](https://source.chromium.org/chromium/chromium/src/+/main:components/cast_receiver/browser/public/content_browser_client_mixins.h;l=88;drc=12be03159fe22cd4ef291e9561762531c2589539)
a `RuntimeApplicationDispatcher`.
2. Use the `RuntimeApplicationDispatcher` to
[create](https://source.chromium.org/chromium/chromium/src/+/main:components/cast_receiver/browser/public/runtime_application_dispatcher.h;l=36;drc=1bcc6d9e4af49c462d3b2bee9f00db757084d262)
a `StreamingRuntimeApplication` instance, which will then be used to
[create](https://source.chromium.org/chromium/chromium/src/+/main:components/cast_receiver/browser/runtime_application_dispatcher_impl.h;l=86;drc=790df4d5983e38ad1d1d00fbc10ef941070eed24)
an instance of the embedder-specific `EmbedderApplication` type.
3. Call `Load()` on the `RuntimeApplication` instance, and wait for its
callback.
4. Call `Launch()` on the `RuntimeApplication` instance, and wait for its
callback. Various `EmbedderApplication` functions will be called to create the
necessary resources, which will be used to start the `cast_streaming` component.
Each of the following is
[expected](https://source.chromium.org/chromium/chromium/src/+/main:components/cast_receiver/browser/streaming_controller_base.cc;l=88;drc=790df4d5983e38ad1d1d00fbc10ef941070eed24)
to occur for the streaming session to successfully begin, but the order may
vary:
    1. Calling of `StartPlaybackAsync()`, which will be called as part of the
    `Launch()` command before its callback is called.
    2. The `WebContents` instance associated with this application, as returned
    by `EmbedderApplication::GetWebContents()`,
    [loads](https://source.chromium.org/chromium/chromium/src/+/main:components/cast_receiver/browser/streaming_controller_base.cc;l=46)
    the page used for displaying the streaming session.
    3. The configuration to use for streaming is returned by the
    embedder-specific `ConfigurationManager` as
    [provided](https://source.chromium.org/chromium/chromium/src/+/main:components/cast_receiver/browser/public/streaming_config_manager.h;l=25;drc=576992499f3c1488c8f86feafb3a65aee426f784)
    by `EmbedderApplication::GetStreamingConfigManager()`.
5. Once streaming has started and a connection has been formed with the Cast
sender device, a `OnStreamingResolutionChanged()`
[event](https://source.chromium.org/chromium/chromium/src/+/main:components/cast_receiver/browser/public/streaming_resolution_observer.h;l=29)
will be fired.
6. Streaming may be stopped by the embedder as with Web applications.
Alternatively, if the session is
[ended](https://source.chromium.org/chromium/chromium/src/+/main:components/cast_streaming/browser/public/receiver_session.h;l=49;drc=7eb26cecf3a3c92e25c68b8ca4f0fc467ea89af7)
by the remote device, a `NotifyApplicationStopped()` event will be fired to the
`EmbedderApplication`, at which point the application should be
[destroyed](https://source.chromium.org/chromium/chromium/src/+/main:components/cast_receiver/browser/public/runtime_application_dispatcher.h;l=48;drc=1bcc6d9e4af49c462d3b2bee9f00db757084d262)
by the `RuntimeApplicationDispatcher`.

![Streaming Application code flow](/docs/images/cast_receiver_streamingruntimeapplication_flow.png "StreamingRuntimeApplication structure")

# Known Issues and Limitations

- TODO(crbug.com/1405480): DRM is not supported.