// 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_