123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187 |
- // Copyright 2021 The Chromium 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 "components/cast/message_port/blink_message_port_adapter.h"
- #include "base/callback.h"
- #include "base/memory/raw_ptr.h"
- #include "components/cast/message_port/cast/message_port_cast.h"
- #include "components/cast/message_port/platform_message_port.h"
- namespace cast_api_bindings {
- namespace {
- // MessagePortAdapters are used to adapt between two different implementations
- // of cast_api_bindings::MessagePort.
- //
- // PostMessageWithTransferables flow including adaptation:
- //+---+ +-------+ +---------+ +---------+ +-------+ +---+
- //| A | | PortA | | AdptrA | | AdptrB | | PortB | | B |
- //+---+ +-------+ +---------+ +---------+ +-------+ +---+
- // | Post | | | | |
- // |---------->| | | | |
- // | | OnMsg | | | |
- // | |------------>| | | |
- // | | | Adapt Ports | | |
- // | | |-----------| | | |
- // | | |<----------| | | |
- // | | | Post | | |
- // | | |----------------->| | |
- // | | | | OnMsg | |
- // | | | |----------->| |
- // | | | | | OnMsg |
- // | | | | |-------->|
- //
- // Error flow including deletion, for example when OnMessage fails
- // | | | | | false |
- // | | | | |<--------|
- // | | | | OnErr | |
- // | | | |<-----------| |
- // | | | delete | | |
- // | | |<-----------------| | |
- // | | delete | | | |
- // | |<------------| | | |
- // | OnErr | | | | |
- // |<----------| | | | |
- // | | | | delete | |
- // | | | |------| | |
- // | | | |<-----| | |
- class MessagePortAdapter : public MessagePort::Receiver {
- public:
- using CreatePairRepeatingCallback =
- base::RepeatingCallback<void(std::unique_ptr<MessagePort>*,
- std::unique_ptr<MessagePort>*)>;
- // PortType is used to track whether the held port represents a client or a
- // server port. Clients must respect client and server semantics because some
- // platforms have asymmetric port implementations.
- enum class PortType {
- CLIENT = 1,
- SERVER = 2,
- };
- // Two MessagePortAdapters are used to adapt between their respective
- // |port|s. Some implementations are directional, so |port_type| is used
- // determine how the |create_pair| function should be invoked when
- // adapting transferred ports. The adapter pair manages its own lifetime
- // and is destroyed on error.
- MessagePortAdapter(std::unique_ptr<MessagePort> port,
- PortType port_type,
- CreatePairRepeatingCallback create_pair_cb)
- : port_(std::move(port)),
- port_type_(port_type),
- create_pair_cb_(create_pair_cb) {
- DCHECK(port_);
- port_->SetReceiver(this);
- }
- ~MessagePortAdapter() override = default;
- MessagePortAdapter(const MessagePortAdapter&) = delete;
- MessagePortAdapter(MessagePortAdapter&&) = delete;
- // Pairs the port with a |peer|. Their lifetimes will be the same.
- void SetPeer(MessagePortAdapter* peer) {
- DCHECK(peer);
- peer_ = peer;
- }
- // Invokes |create_pair_|, which should create a new pair of ports with the
- // same type as |port_|.
- void CreatePair(std::unique_ptr<MessagePort>* client,
- std::unique_ptr<MessagePort>* server) {
- create_pair_cb_.Run(client, server);
- }
- private:
- // MessagePort::Receiver implementation:
- void OnPipeError() override {
- DCHECK(peer_);
- // Ports are closed on error; when an error occurs, destroy the adapters.
- delete peer_;
- delete this;
- }
- bool OnMessage(base::StringPiece message,
- std::vector<std::unique_ptr<MessagePort>> ports) override {
- DCHECK(peer_);
- std::vector<std::unique_ptr<MessagePort>> transferables;
- // Because we are adapting port types, an adapter to the peer's type is
- // needed for each transferred port.
- for (auto& port : ports) {
- // The incoming |port| is the same kind of port as |this|.
- MessagePortAdapter* incoming =
- new MessagePortAdapter(std::move(port), port_type_, create_pair_cb_);
- // The outgoing port is the same kind of port as |peer_|.
- std::unique_ptr<MessagePort> client;
- std::unique_ptr<MessagePort> server;
- peer_->CreatePair(&client, &server);
- // If |incoming| is a client port adapter, it will be talking to a
- // |server| of the port type of the |peer_|, and vice versa.
- MessagePortAdapter* outgoing = new MessagePortAdapter(
- incoming->port_type_ == PortType::CLIENT ? std::move(server)
- : std::move(client),
- peer_->port_type_, peer_->create_pair_cb_);
- // Connect the adapters together.
- incoming->SetPeer(outgoing);
- outgoing->SetPeer(incoming);
- // If |incoming| is a client port adapter, the |client| port of the
- // |peer_| type will be transferred, and vice versa.
- // |server| of the port type of the |peer_|, and vice versa.
- transferables.push_back(port_type_ == PortType::CLIENT
- ? std::move(client)
- : std::move(server));
- }
- return peer_->port_->PostMessageWithTransferables(message,
- std::move(transferables));
- }
- std::unique_ptr<MessagePort> port_;
- raw_ptr<MessagePortAdapter> peer_ = nullptr;
- const PortType port_type_;
- const CreatePairRepeatingCallback create_pair_cb_;
- };
- } // namespace
- // static
- std::unique_ptr<MessagePort>
- BlinkMessagePortAdapter::ToClientPlatformMessagePort(
- blink::WebMessagePort&& client) {
- MessagePortAdapter* blink =
- new MessagePortAdapter(MessagePortCast::Create(std::move(client)),
- MessagePortAdapter::PortType::CLIENT,
- base::BindRepeating(&MessagePortCast::CreatePair));
- std::unique_ptr<MessagePort> adapted_client;
- std::unique_ptr<MessagePort> server;
- CreatePlatformMessagePortPair(&adapted_client, &server);
- MessagePortAdapter* platform = new MessagePortAdapter(
- std::move(server), MessagePortAdapter::PortType::SERVER,
- base::BindRepeating(&CreatePlatformMessagePortPair));
- blink->SetPeer(platform);
- platform->SetPeer(blink);
- return adapted_client;
- }
- // static
- blink::WebMessagePort BlinkMessagePortAdapter::FromServerPlatformMessagePort(
- std::unique_ptr<MessagePort> server) {
- MessagePortAdapter* platform = new MessagePortAdapter(
- std::move(server), MessagePortAdapter::PortType::SERVER,
- base::BindRepeating(&CreatePlatformMessagePortPair));
- std::unique_ptr<MessagePort> client;
- std::unique_ptr<MessagePort> adapted_server;
- MessagePortCast::CreatePair(&client, &adapted_server);
- MessagePortAdapter* blink = new MessagePortAdapter(
- std::move(client), MessagePortAdapter::PortType::CLIENT,
- base::BindRepeating(&MessagePortCast::CreatePair));
- blink->SetPeer(platform);
- platform->SetPeer(blink);
- return MessagePortCast::FromMessagePort(adapted_server.get())->TakePort();
- }
- } // namespace cast_api_bindings
|