chromium/third_party/blink/public/common/messaging/web_message_port.h

// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef THIRD_PARTY_BLINK_PUBLIC_COMMON_MESSAGING_WEB_MESSAGE_PORT_H_
#define THIRD_PARTY_BLINK_PUBLIC_COMMON_MESSAGING_WEB_MESSAGE_PORT_H_

#include <string>
#include <utility>

#include "base/memory/raw_ptr.h"
#include "base/task/sequenced_task_runner.h"
#include "mojo/public/cpp/bindings/connector.h"
#include "mojo/public/cpp/bindings/message.h"
#include "third_party/blink/public/common/common_export.h"
#include "third_party/blink/public/common/messaging/message_port_descriptor.h"

namespace blink {

// Defines a WebMessagePort, which is used by embedders to send and receive
// messages to and from Javascript content. This is a simplified version of the
// full MessagePort concept implemented by renderer/core/messaging/message_port.
// It is a lightweight wrapper of a Mojo message pipe, and provides
// functionality for sending and receiving messages that consist of text content
// and a vector of ports, automatically handling the message serialization and
// formatting. Note the Mojo pipe is bound in SINGLE_THREADED_SEND mode. If you
// need to send more complex message types then refer to transferable_message.*
// and string_message_codec.*.
//
// Intended embedder usage is as follows:
//
//  // Create a pair of ports. The two ends of the pipe are conjugates of each
//  // other.
//  std::pair<WebMessagePort, WebMessagePort> ports =
//      WebMessagePort::CreatePair();
//
//  // Keep one end for ourselves.
//  MessageReceiverImpl receiver;  // Implements MessageReceiver.
//  auto embedder_port = std::move(ports.first);
//  embedder_port.SetReceiver(&receiver, task_runner);
//
//  // Send the other end of the pipe to a WebContents. This will arrive in the
//  // main frame of that WebContents. See
//  // content/browser/public/message_port_provider.h for the API that allows
//  // this injection.
//  std::vector<MessagePortDescriptor> ports;
//  ports.emplace_back(ports.second.PassPort());
//  MessagePortProvider::PostMessageToFrame(
//      web_contents, ..., std::move(ports));
//
//  // The web contents can now talk back to us via |embedder_port|, and we can
//  // talk back directly to it over that same pipe.
//
// Note that some embedders provide "PostMessageToFrame" functions directly on
// their wrapped WebContents equivalents (Android and Cast, for example). Also
// note that for Android embedders, there are equivalent Java interfaces defined
// in org.chromium.content_public.browser.
//
// This is a move-only type, which makes it (almost) impossible to try to send a
// port across itself (which is illegal). This doesn't explicitly prevent you
// from sending a port's conjugate port to its conjugate, but note that the
// underlying impl will close the pipe with an error if you do that.
//
// This object is not thread safe, and is intended to be used from a single
// sequence. The sequence from which it is used does not have to be the same
// sequence that the bound receiver uses.
//
// Further note that a WebMessagePort is not "reusable". That is, once it has
// been bound via SetReceiver, it is no longer transmittable (can't be passed as
// a port in part of a Message). This is enforced via runtime CHECKs.
class BLINK_COMMON_EXPORT WebMessagePort : public mojo::MessageReceiver {};

// A very simple message format. This is a subset of a TransferableMessage, as
// many of the fields in the full message type aren't appropriate for messages
// originating from the embedder.
struct BLINK_COMMON_EXPORT WebMessagePort::Message {};

// Interface to be implemented by receivers.
class BLINK_COMMON_EXPORT WebMessagePort::MessageReceiver {};

}  // namespace blink

#endif  // THIRD_PARTY_BLINK_PUBLIC_COMMON_MESSAGING_WEB_MESSAGE_PORT_H_