Commit a9f1291a authored by Daniel Cheng's avatar Daniel Cheng Committed by Commit Bot

[blink][mojo] Add ToCrossVariantMojoType helper

This eliminates the need to crack a mojo::Receiver/mojo::Remote into a
message pipe and a handle to convert between Blink and non-Blink
variants. This CL also includes a cleanup pass for the remaining uses of
PassPipe() and PassHandle(), migrating them to either std::move()
directly if possible, or use the new ToCrossVariantMojoType helper if
applicable.

Bug: 1059157
Change-Id: Id389d69ba32c17ce76942f16ca2b5b4fd26aab18
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2556565
Commit-Queue: Daniel Cheng <dcheng@chromium.org>
Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Cr-Commit-Position: refs/heads/master@{#830936}
parent 96bf7ce4
......@@ -3,25 +3,30 @@
// found in the LICENSE file.
//
// This header defines utilities for converting between Mojo interface variant
// types. This is useful for maintaining type safety when message pipes need to
// be passed across the Blink public API boundary.
// 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();
//
// // CrossVariantMojoReceiver and CrossVariantMojoRemote may created from
// // any interface variant. Note the use of the unrelated *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 common to all
// // variants of a Mojo interface and is useful for implementing type safety
// // checks such as this one.
// web_local_frame_client->PassGoatTeleporter(
// ToCrossVariantMojoRemote(std::move(cross_variant_remote)));
// // `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
......@@ -30,12 +35,17 @@
//
// 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) {
// mojo::PendingRemote<blink::mojom::GoatTeleporter> remote =
// cross_variant_remote
// .PassAsPendingRemote<blink::mojom::GoatTeleporter>();
// // 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
......@@ -55,7 +65,8 @@
namespace blink {
// Non-associated helpers
// Helpers for passing a variant-less non-associated interface across the Blink
// public API.
template <typename Interface>
class CrossVariantMojoReceiver {
......@@ -122,7 +133,8 @@ class CrossVariantMojoRemote {
mojo::ScopedMessagePipeHandle pipe_;
};
// Associated helpers
// Helpers for passing a variant-less associated interface across the Blink
// public API.
template <typename Interface>
class CrossVariantMojoAssociatedReceiver {
......@@ -197,10 +209,40 @@ class CrossVariantMojoAssociatedRemote {
mojo::ScopedInterfaceEndpointHandle handle_;
};
// 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) {
return blink::CrossVariantMojoReceiver<typename VariantBase::Base_>(
std::move(in));
}
template <typename VariantBase>
auto ToCrossVariantMojoType(mojo::PendingRemote<VariantBase>&& in) {
return blink::CrossVariantMojoRemote<typename VariantBase::Base_>(
std::move(in));
}
template <typename VariantBase>
auto ToCrossVariantMojoType(mojo::PendingAssociatedReceiver<VariantBase>&& in) {
return blink::CrossVariantMojoAssociatedReceiver<typename VariantBase::Base_>(
std::move(in));
}
template <typename VariantBase>
auto ToCrossVariantMojoType(mojo::PendingAssociatedRemote<VariantBase>&& in) {
return blink::CrossVariantMojoAssociatedRemote<typename VariantBase::Base_>(
std::move(in));
}
} // namespace blink
namespace mojo {
// Template specializations so //mojo understands how to convert between
// Pending{Associated,}{Receiver,Remote} and the cross-variant types.
template <typename CrossVariantBase>
struct PendingReceiverConverter<
blink::CrossVariantMojoReceiver<CrossVariantBase>> {
......
......@@ -136,11 +136,8 @@ void ApplicationCacheHostForFrame::SetSubresourceFactory(
mojo::PendingRemote<network::mojom::blink::URLLoaderFactory>
url_loader_factory) {
auto pending_factories = std::make_unique<PendingURLLoaderFactoryBundle>();
// |PassPipe()| invalidates all state, so capture |version()| first.
uint32_t version = url_loader_factory.version();
pending_factories->pending_appcache_factory() =
mojo::PendingRemote<network::mojom::URLLoaderFactory>(
url_loader_factory.PassPipe(), version);
ToCrossVariantMojoType(std::move(url_loader_factory));
local_frame_->Client()->UpdateSubresourceFactory(
std::move(pending_factories));
}
......
......@@ -8,14 +8,14 @@
#include "mojo/public/cpp/base/big_buffer.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "third_party/blink/public/mojom/blob/blob.mojom-blink.h"
#include "third_party/blink/public/platform/cross_variant_mojo_util.h"
#include "third_party/blink/public/web/web_dom_message_event.h"
#include "third_party/blink/renderer/core/events/message_event.h"
#include "third_party/blink/renderer/core/frame/user_activation.h"
#include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h"
#include "third_party/blink/renderer/platform/blob/blob_data.h"
#include "third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.h"
#include "third_party/blink/public/web/web_dom_message_event.h"
namespace blink {
// static
......@@ -51,9 +51,7 @@ BlinkTransferableMessage BlinkTransferableMessage::FromMessageEvent(
blob.value->Uuid(),
BlobDataHandle::Create(blob.value->Uuid(), blob.value->GetType(),
blob.value->size(),
mojo::PendingRemote<mojom::blink::Blob>(
blob.value->CloneBlobRemote().PassPipe(),
mojom::blink::Blob::Version_)));
blob.value->CloneBlobRemote()));
}
// Stream channels.
......@@ -112,11 +110,7 @@ BlinkTransferableMessage BlinkTransferableMessage::FromMessageEvent(
// Native file system transfer tokens.
for (auto& token : serialized_script_value->NativeFileSystemTokens()) {
uint32_t token_version = token.version();
mojo::PendingRemote<mojom::blink::NativeFileSystemTransferToken>
converted_token(token.PassPipe(), token_version);
result.message->NativeFileSystemTokens().push_back(
std::move(converted_token));
result.message->NativeFileSystemTokens().push_back(std::move(token));
}
return result;
......@@ -132,11 +126,9 @@ BlinkTransferableMessage BlinkTransferableMessage::FromTransferableMessage(
for (auto& blob : message.blobs) {
result.message->BlobDataHandles().Set(
String::FromUTF8(blob->uuid),
BlobDataHandle::Create(
String::FromUTF8(blob->uuid), String::FromUTF8(blob->content_type),
blob->size,
mojo::PendingRemote<mojom::blink::Blob>(blob->blob.PassPipe(),
mojom::Blob::Version_)));
BlobDataHandle::Create(String::FromUTF8(blob->uuid),
String::FromUTF8(blob->content_type), blob->size,
ToCrossVariantMojoType(std::move(blob->blob))));
}
if (message.sender_origin) {
result.sender_origin =
......@@ -199,12 +191,9 @@ BlinkTransferableMessage BlinkTransferableMessage::FromTransferableMessage(
// Convert the PendingRemote<NativeFileSystemTransferToken> from the
// blink::mojom namespace to the blink::mojom::blink namespace.
for (auto& native_file_system_token : message.native_file_system_tokens) {
uint32_t token_version = native_file_system_token.version();
mojo::PendingRemote<mojom::blink::NativeFileSystemTransferToken>
converted_token(native_file_system_token.PassPipe(), token_version);
for (auto& token : message.native_file_system_tokens) {
result.message->NativeFileSystemTokens().push_back(
std::move(converted_token));
ToCrossVariantMojoType(std::move(token)));
}
return result;
}
......
......@@ -134,12 +134,9 @@ void SharedWorkerClientHolder::Connect(
connector_->Connect(
std::move(info), std::move(client),
worker->GetExecutionContext()->IsSecureContext()
? mojom::SharedWorkerCreationContextType::kSecure
: mojom::SharedWorkerCreationContextType::kNonsecure,
port.ReleaseHandle(),
mojo::PendingRemote<mojom::blink::BlobURLToken>(
blob_url_token.PassPipe(), mojom::blink::BlobURLToken::Version_),
client_ukm_source_id);
? mojom::blink::SharedWorkerCreationContextType::kSecure
: mojom::blink::SharedWorkerCreationContextType::kNonsecure,
port.ReleaseHandle(), std::move(blob_url_token), client_ukm_source_id);
}
void SharedWorkerClientHolder::Trace(Visitor* visitor) const {
......
......@@ -31,6 +31,7 @@
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "services/metrics/public/cpp/mojo_ukm_recorder.h"
#include "third_party/blink/public/common/thread_safe_browser_interface_broker_proxy.h"
#include "third_party/blink/public/mojom/browser_interface_broker.mojom-blink.h"
#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/web_url_request.h"
......@@ -563,10 +564,9 @@ WorkerGlobalScope::WorkerGlobalScope(
// once all worker types provide a valid
// |creation_params->browser_interface_broker|.
if (creation_params->browser_interface_broker.is_valid()) {
auto pipe = creation_params->browser_interface_broker.PassPipe();
browser_interface_broker_proxy_.Bind(
mojo::PendingRemote<blink::mojom::BrowserInterfaceBroker>(
std::move(pipe), blink::mojom::BrowserInterfaceBroker::Version_),
ToCrossVariantMojoType(
std::move(creation_params->browser_interface_broker)),
GetTaskRunner(TaskType::kInternalDefault));
}
......
......@@ -10,6 +10,7 @@
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "services/device/public/cpp/test/fake_sensor_and_provider.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/cross_variant_mojo_util.h"
#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/platform_event_controller.h"
......@@ -84,9 +85,7 @@ class DeviceMotionEventPumpTest : public testing::Test {
auto* motion_pump =
MakeGarbageCollected<DeviceMotionEventPump>(page_holder_->GetFrame());
motion_pump->SetSensorProviderForTesting(
mojo::PendingRemote<device::mojom::blink::SensorProvider>(
sensor_provider.PassPipe(),
device::mojom::SensorProvider::Version_));
ToCrossVariantMojoType(std::move(sensor_provider)));
controller_ = MakeGarbageCollected<MockDeviceMotionController>(
motion_pump, *page_holder_->GetFrame().DomWindow());
......
......@@ -10,6 +10,7 @@
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "services/device/public/cpp/test/fake_sensor_and_provider.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/cross_variant_mojo_util.h"
#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/platform_event_controller.h"
......@@ -90,14 +91,12 @@ class DeviceOrientationEventPumpTest : public testing::Test {
void SetUp() override {
page_holder_ = std::make_unique<DummyPageHolder>();
mojo::PendingRemote<device::mojom::SensorProvider> sensor_provider;
sensor_provider_.Bind(sensor_provider.InitWithNewPipeAndPassReceiver());
mojo::PendingRemote<device::mojom::blink::SensorProvider> sensor_provider;
sensor_provider_.Bind(ToCrossVariantMojoType(
sensor_provider.InitWithNewPipeAndPassReceiver()));
auto* orientation_pump = MakeGarbageCollected<DeviceOrientationEventPump>(
page_holder_->GetFrame(), false /* absolute */);
orientation_pump->SetSensorProviderForTesting(
mojo::PendingRemote<device::mojom::blink::SensorProvider>(
sensor_provider.PassPipe(),
device::mojom::SensorProvider::Version_));
orientation_pump->SetSensorProviderForTesting(std::move(sensor_provider));
controller_ = MakeGarbageCollected<MockDeviceOrientationController>(
orientation_pump, *page_holder_->GetFrame().DomWindow());
......@@ -497,15 +496,14 @@ class DeviceAbsoluteOrientationEventPumpTest : public testing::Test {
void SetUp() override {
page_holder_ = std::make_unique<DummyPageHolder>();
mojo::PendingRemote<device::mojom::SensorProvider> sensor_provider;
sensor_provider_.Bind(sensor_provider.InitWithNewPipeAndPassReceiver());
mojo::PendingRemote<device::mojom::blink::SensorProvider> sensor_provider;
sensor_provider_.Bind(ToCrossVariantMojoType(
sensor_provider.InitWithNewPipeAndPassReceiver()));
auto* absolute_orientation_pump =
MakeGarbageCollected<DeviceOrientationEventPump>(
page_holder_->GetFrame(), true /* absolute */);
absolute_orientation_pump->SetSensorProviderForTesting(
mojo::PendingRemote<device::mojom::blink::SensorProvider>(
sensor_provider.PassPipe(),
device::mojom::SensorProvider::Version_));
std::move(sensor_provider));
controller_ = MakeGarbageCollected<MockDeviceOrientationController>(
absolute_orientation_pump, *page_holder_->GetFrame().DomWindow());
......
......@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/modules/service_worker/cross_origin_resource_policy_checker.h"
#include "services/network/public/cpp/cross_origin_resource_policy.h"
#include "third_party/blink/public/platform/cross_variant_mojo_util.h"
#include "third_party/blink/renderer/core/fetch/response.h"
namespace blink {
......@@ -15,11 +16,7 @@ CrossOriginResourcePolicyChecker::CrossOriginResourcePolicyChecker(
network::mojom::blink::CrossOriginEmbedderPolicyReporter> reporter)
: policy_(std::move(policy)) {
if (reporter) {
mojo::PendingRemote<network::mojom::CrossOriginEmbedderPolicyReporter>
pending_reporter_non_blink{
reporter.PassPipe(),
network::mojom::CrossOriginEmbedderPolicyReporter::Version_};
reporter_.Bind(std::move(pending_reporter_non_blink));
reporter_.Bind(ToCrossVariantMojoType(std::move(reporter)));
}
}
......
......@@ -58,10 +58,7 @@ StructTraits<blink::mojom::FetchAPIRequestBodyDataView,
out->length = element.optional_blob_data_handle_->size();
mojo::Remote<blink::mojom::blink::Blob> blob_remote(
mojo::PendingRemote<blink::mojom::blink::Blob>(
element.optional_blob_data_handle_->CloneBlobRemote()
.PassPipe(),
blink::mojom::blink::Blob::Version_));
element.optional_blob_data_handle_->CloneBlobRemote());
blob_remote->AsDataPipeGetter(
out->data_pipe_getter.InitWithNewPipeAndPassReceiver());
break;
......
......@@ -23,6 +23,7 @@
#include "third_party/blink/public/mojom/blob/blob.mojom.h"
#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink.h"
#include "third_party/blink/public/mojom/loader/resource_load_info.mojom-shared.h"
#include "third_party/blink/public/platform/cross_variant_mojo_util.h"
#include "third_party/blink/public/platform/file_path_conversion.h"
#include "third_party/blink/public/platform/url_conversion.h"
#include "third_party/blink/public/platform/web_string.h"
......@@ -216,26 +217,23 @@ void PopulateResourceRequestBody(const EncodedFormData& src,
break;
case FormDataElement::kEncodedBlob: {
DCHECK(element.optional_blob_data_handle_);
mojo::Remote<mojom::Blob> blob_remote(mojo::PendingRemote<mojom::Blob>(
element.optional_blob_data_handle_->CloneBlobRemote().PassPipe(),
mojom::Blob::Version_));
mojo::PendingRemote<network::mojom::DataPipeGetter>
mojo::Remote<mojom::blink::Blob> blob_remote(
element.optional_blob_data_handle_->CloneBlobRemote());
mojo::PendingRemote<network::mojom::blink::DataPipeGetter>
data_pipe_getter_remote;
blob_remote->AsDataPipeGetter(
data_pipe_getter_remote.InitWithNewPipeAndPassReceiver());
dest->AppendDataPipe(std::move(data_pipe_getter_remote));
dest->AppendDataPipe(
ToCrossVariantMojoType(std::move(data_pipe_getter_remote)));
break;
}
case FormDataElement::kDataPipe: {
// Convert network::mojom::blink::DataPipeGetter to
// network::mojom::DataPipeGetter through a raw message pipe.
mojo::PendingRemote<network::mojom::blink::DataPipeGetter>
pending_data_pipe_getter;
element.data_pipe_getter_->GetDataPipeGetter()->Clone(
pending_data_pipe_getter.InitWithNewPipeAndPassReceiver());
dest->AppendDataPipe(
mojo::PendingRemote<network::mojom::DataPipeGetter>(
pending_data_pipe_getter.PassPipe(), 0u));
ToCrossVariantMojoType(std::move(pending_data_pipe_getter)));
break;
}
}
......@@ -363,9 +361,8 @@ void PopulateResourceRequest(const ResourceRequestHead& src,
mojo::PendingRemote<network::mojom::blink::ChunkedDataPipeGetter>
stream_body = src_body.TakeStreamBody();
dest->request_body = base::MakeRefCounted<network::ResourceRequestBody>();
mojo::PendingRemote<network::mojom::ChunkedDataPipeGetter>
network_stream_body(stream_body.PassPipe(), 0u);
dest->request_body->SetToReadOnceStream(std::move(network_stream_body));
dest->request_body->SetToReadOnceStream(
ToCrossVariantMojoType(std::move(stream_body)));
dest->request_body->SetAllowHTTP1ForStreamingUpload(
src.AllowHTTP1ForStreamingUpload());
}
......
......@@ -16,6 +16,7 @@
#include "third_party/blink/public/mojom/blob/blob_registry.mojom-blink.h"
#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink.h"
#include "third_party/blink/public/mojom/loader/resource_load_info.mojom-blink.h"
#include "third_party/blink/public/platform/cross_variant_mojo_util.h"
#include "third_party/blink/public/platform/file_path_conversion.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/web_data.h"
......@@ -148,24 +149,19 @@ scoped_refptr<network::ResourceRequestBody> GetRequestBodyForWebHTTPBody(
case HTTPBodyElementType::kTypeBlob: {
DCHECK(element.optional_blob);
mojo::Remote<mojom::blink::Blob> blob_remote(
mojo::PendingRemote<mojom::blink::Blob>(
std::move(element.optional_blob)));
std::move(element.optional_blob));
mojo::PendingRemote<network::mojom::blink::DataPipeGetter>
data_pipe_getter_remote;
blob_remote->AsDataPipeGetter(
data_pipe_getter_remote.InitWithNewPipeAndPassReceiver());
request_body->AppendDataPipe(
mojo::PendingRemote<network::mojom::DataPipeGetter>(
data_pipe_getter_remote.PassPipe(), 0u));
ToCrossVariantMojoType(std::move(data_pipe_getter_remote)));
break;
}
case HTTPBodyElementType::kTypeDataPipe: {
// Convert the raw message pipe to
// mojo::Remote<network::mojom::DataPipeGetter> data_pipe_getter.
mojo::Remote<network::mojom::blink::DataPipeGetter> data_pipe_getter(
mojo::PendingRemote<network::mojom::blink::DataPipeGetter>(
std::move(element.data_pipe_getter)));
std::move(element.data_pipe_getter));
// Set the cloned DataPipeGetter to the output |request_body|, while
// keeping the original message pipe back in the input |httpBody|. This
......@@ -175,8 +171,7 @@ scoped_refptr<network::ResourceRequestBody> GetRequestBodyForWebHTTPBody(
cloned_getter;
data_pipe_getter->Clone(cloned_getter.InitWithNewPipeAndPassReceiver());
request_body->AppendDataPipe(
mojo::PendingRemote<network::mojom::DataPipeGetter>(
cloned_getter.PassPipe(), 0u));
ToCrossVariantMojoType(std::move(cloned_getter)));
element.data_pipe_getter = data_pipe_getter.Unbind();
break;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment