chromium/third_party/blink/public/platform/cross_variant_mojo_util.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.
//
// This header defines utilities for converting between Mojo interface variant
// types. Any code that needs to convert interface endpoints between
// blink::mojom::MyInterface and blink::mojom::blink::MyInterface (such as the
// Blink public API) should use these helpers to eliminate boilerplate code and
// improve type safety.
//
// Background: Mojo generates two C++ interface classes for a given interface:
// one using STL types and another using Blink's WTF types. The two are not
// related to each other in any way. Converting between them previously meant
// decomposing an interface endpoint into an untyped ScopedMessagePipeHandle,
// with only comments to document the interface type.
//
// Example conversion from the Blink variant into a cross-variant handle:
//
// namespace blink {
//
// void WebLocalFrameImpl::PassGoatTeleporter() {
//   // The fully-qualified type of the Blink variant is
//   // blink::mojom::blink::GoatTeleporter.
//   mojo::PendingRemote<mojom::blink::GoatTeleporter> remote =
//       ProcureGoatTeleporter();
//
//   // `PassGoatTeleporter()`'s argument is a `CrossVariantMojoRemote<>`; see
//   // below example for the other part of this example.
//   web_local_frame_client->PassGoatTeleporter(std::move(remote)));
// }
//
// }  // namespace blink
//
// Example conversion from a cross-variant handle into the regular variant:
//
// namespace content {
//
//   // Note the use of the *InterfaceBase class as the cross-variant handle's
//   // template parameter. This is an empty helper class defined by the
//   // .mojom-shared.h header that is shared as a nested type alias by all
//   // generated C++ interface class variants. The cross-variant types key off
//   // this shared type to provide type safety.
// void RenderFrameImpl::PassGoatTeleporter(
//     blink::CrossVariantMojoRemote<GoatTeleporterInterfaceBase>
//     cross_variant_remote) {
//   // Non-Blink code uses the regular variant, so the `SetGoatTeleporter`
//   // argument has  type `blink::mojom::GoatTeleporter`.
//   frame_host_remote_->SetGoatTeleporter(std::move(cross_variant_remote));
// }
//
// }  // namespace content

#ifndef THIRD_PARTY_BLINK_PUBLIC_PLATFORM_CROSS_VARIANT_MOJO_UTIL_H_
#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_CROSS_VARIANT_MOJO_UTIL_H_

#include <type_traits>
#include <utility>

#include "mojo/public/cpp/bindings/pending_associated_receiver.h"
#include "mojo/public/cpp/bindings/pending_associated_remote.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h"
#include "mojo/public/cpp/system/message_pipe.h"

namespace blink {

// Helpers for passing a variant-less non-associated interface across the Blink
// public API.

template <typename Interface>
class CrossVariantMojoReceiver {};

template <typename Interface>
class CrossVariantMojoRemote {};

// Helpers for passing a variant-less associated interface across the Blink
// public API.

template <typename Interface>
class CrossVariantMojoAssociatedReceiver {};

template <typename Interface>
class CrossVariantMojoAssociatedRemote {};

// The `ToCrossVariantMojoType` helpers are more convenient to use when there
// isn't already an explicit CrossVariant{Associated,}{Receiver,Remote} type,
// e.g. Blink code already has the Blink interface variant but wants to share
// common code that requires the regular interface variant.
template <typename VariantBase>
auto ToCrossVariantMojoType(mojo::PendingReceiver<VariantBase>&& in) {}

template <typename VariantBase>
auto ToCrossVariantMojoType(mojo::PendingRemote<VariantBase>&& in) {}

template <typename VariantBase>
auto ToCrossVariantMojoType(mojo::PendingAssociatedReceiver<VariantBase>&& in) {}

template <typename VariantBase>
auto ToCrossVariantMojoType(mojo::PendingAssociatedRemote<VariantBase>&& in) {}

}  // namespace blink

namespace mojo {

// Template specializations so //mojo understands how to convert between
// Pending{Associated,}{Receiver,Remote} and the cross-variant types.
PendingReceiverConverter<blink::CrossVariantMojoReceiver<CrossVariantBase>>;

PendingRemoteConverter<blink::CrossVariantMojoRemote<CrossVariantBase>>;

PendingAssociatedReceiverConverter<blink::CrossVariantMojoAssociatedReceiver<CrossVariantBase>>;

PendingAssociatedRemoteConverter<blink::CrossVariantMojoAssociatedRemote<CrossVariantBase>>;

}  // namespace mojo

#endif  // THIRD_PARTY_BLINK_PUBLIC_PLATFORM_CROSS_VARIANT_MOJO_UTIL_H_