summaryrefslogtreecommitdiff
path: root/chromium/mojo
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2019-05-16 09:59:13 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2019-05-20 10:28:53 +0000
commit6c11fb357ec39bf087b8b632e2b1e375aef1b38b (patch)
treec8315530db18a8ee566521c39ab8a6af4f72bc03 /chromium/mojo
parent3ffaed019d0772e59d6cdb2d0d32fe4834c31f72 (diff)
downloadqtwebengine-chromium-6c11fb357ec39bf087b8b632e2b1e375aef1b38b.tar.gz
BASELINE: Update Chromium to 74.0.3729.159
Change-Id: I8d2497da544c275415aedd94dd25328d555de811 Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
Diffstat (limited to 'chromium/mojo')
-rw-r--r--chromium/mojo/README.md144
-rw-r--r--chromium/mojo/core/channel.cc2
-rw-r--r--chromium/mojo/core/channel.h8
-rw-r--r--chromium/mojo/core/channel_fuchsia.cc130
-rw-r--r--chromium/mojo/core/channel_fuzzer.cc21
-rw-r--r--chromium/mojo/core/channel_posix.cc29
-rw-r--r--chromium/mojo/core/channel_win.cc2
-rw-r--r--chromium/mojo/core/dispatcher.h75
-rw-r--r--chromium/mojo/core/message_pipe_perftest.cc2
-rw-r--r--chromium/mojo/core/message_unittest.cc1
-rw-r--r--chromium/mojo/core/multiprocess_message_pipe_unittest.cc16
-rw-r--r--chromium/mojo/core/node_channel_fuzzer.cc21
-rw-r--r--chromium/mojo/core/node_controller.cc6
-rw-r--r--chromium/mojo/core/platform_handle_in_transit.cc15
-rw-r--r--chromium/mojo/core/platform_handle_in_transit.h20
-rw-r--r--chromium/mojo/core/ports/ports_unittest.cc2
-rw-r--r--chromium/mojo/core/trap_unittest.cc2
-rw-r--r--chromium/mojo/public/c/system/README.md4
-rw-r--r--chromium/mojo/public/c/system/buffer.h10
-rw-r--r--chromium/mojo/public/c/system/data_pipe.h14
-rw-r--r--chromium/mojo/public/c/system/invitation.h16
-rw-r--r--chromium/mojo/public/c/system/macros.h8
-rw-r--r--chromium/mojo/public/c/system/message_pipe.h22
-rw-r--r--chromium/mojo/public/c/system/platform_handle.h23
-rw-r--r--chromium/mojo/public/c/system/quota.h4
-rw-r--r--chromium/mojo/public/c/system/trap.h10
-rw-r--r--chromium/mojo/public/c/system/types.h6
-rw-r--r--chromium/mojo/public/cpp/bindings/BUILD.gn7
-rw-r--r--chromium/mojo/public/cpp/bindings/README.md36
-rw-r--r--chromium/mojo/public/cpp/bindings/call_internal.cc18
-rw-r--r--chromium/mojo/public/cpp/bindings/call_internal.h48
-rw-r--r--chromium/mojo/public/cpp/bindings/clone_traits.h2
-rw-r--r--chromium/mojo/public/cpp/bindings/features.cc4
-rw-r--r--chromium/mojo/public/cpp/bindings/interface_endpoint_client.h14
-rw-r--r--chromium/mojo/public/cpp/bindings/interface_ptr_set.h1
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/connector.cc6
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc20
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/interface_ptr_state.h14
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/interface_serialization.h41
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/message.cc39
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/message_dumper.cc1
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/message_internal.h5
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/native_struct_serialization.cc4
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/scoped_interface_endpoint_handle.cc18
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/test_random_mojo_delays.cc1
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/tracing_helper.h20
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/validation_errors.h2
-rw-r--r--chromium/mojo/public/cpp/bindings/pending_receiver.h79
-rw-r--r--chromium/mojo/public/cpp/bindings/pending_remote.h104
-rw-r--r--chromium/mojo/public/cpp/bindings/receiver.h172
-rw-r--r--chromium/mojo/public/cpp/bindings/remote.h247
-rw-r--r--chromium/mojo/public/cpp/bindings/tests/BUILD.gn2
-rw-r--r--chromium/mojo/public/cpp/bindings/thread_safe_interface_ptr.h33
-rw-r--r--chromium/mojo/public/cpp/bindings/type_converter.h2
-rw-r--r--chromium/mojo/public/cpp/platform/BUILD.gn2
-rw-r--r--chromium/mojo/public/cpp/platform/features.cc19
-rw-r--r--chromium/mojo/public/cpp/platform/features.h23
-rw-r--r--chromium/mojo/public/cpp/platform/platform_handle.cc33
-rw-r--r--chromium/mojo/public/cpp/platform/platform_handle.h53
-rw-r--r--chromium/mojo/public/cpp/platform/socket_utils_posix.cc4
-rw-r--r--chromium/mojo/public/cpp/platform/socket_utils_posix.h5
-rw-r--r--chromium/mojo/public/cpp/system/BUILD.gn1
-rw-r--r--chromium/mojo/public/cpp/system/README.md4
-rw-r--r--chromium/mojo/public/cpp/system/data_pipe.cc54
-rw-r--r--chromium/mojo/public/cpp/system/data_pipe.h28
-rw-r--r--chromium/mojo/public/cpp/system/handle_signal_tracker.cc1
-rw-r--r--chromium/mojo/public/cpp/system/simple_watcher.cc13
-rw-r--r--chromium/mojo/public/cpp/test_support/lib/test_utils.cc1
-rw-r--r--chromium/mojo/public/cpp/test_support/test_utils.h3
-rw-r--r--chromium/mojo/public/interfaces/bindings/native_struct.mojom19
-rw-r--r--chromium/mojo/public/interfaces/bindings/tests/BUILD.gn23
-rw-r--r--chromium/mojo/public/js/BUILD.gn14
-rw-r--r--chromium/mojo/public/js/bindings_lite.js19
-rw-r--r--chromium/mojo/public/js/interface_support.js84
-rw-r--r--chromium/mojo/public/js/lib/codec.js2
-rw-r--r--chromium/mojo/public/js/lib/control_message_proxy.js2
-rw-r--r--chromium/mojo/public/js/mojo_bindings_resources.grd19
-rw-r--r--chromium/mojo/public/tools/bindings/BUILD.gn7
-rw-r--r--chromium/mojo/public/tools/bindings/README.md55
-rw-r--r--chromium/mojo/public/tools/bindings/chromium_bindings_configuration.gni3
-rw-r--r--chromium/mojo/public/tools/bindings/generators/cpp_templates/enum_macros.tmpl25
-rw-r--r--chromium/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl2
-rw-r--r--chromium/mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl2
-rw-r--r--chromium/mojo/public/tools/bindings/generators/cpp_templates/module-forward.h.tmpl195
-rw-r--r--chromium/mojo/public/tools/bindings/generators/cpp_templates/module-import-headers.h.tmpl28
-rw-r--r--chromium/mojo/public/tools/bindings/generators/cpp_templates/module-params-data.h.tmpl80
-rw-r--r--chromium/mojo/public/tools/bindings/generators/cpp_templates/module-shared-internal.h.tmpl12
-rw-r--r--chromium/mojo/public/tools/bindings/generators/cpp_templates/module-shared.cc.tmpl2
-rw-r--r--chromium/mojo/public/tools/bindings/generators/cpp_templates/module-shared.h.tmpl23
-rw-r--r--chromium/mojo/public/tools/bindings/generators/cpp_templates/module-test-utils.cc.tmpl8
-rw-r--r--chromium/mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl3
-rw-r--r--chromium/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl84
-rw-r--r--chromium/mojo/public/tools/bindings/generators/cpp_templates/wrapper_union_class_template_definition.tmpl4
-rw-r--r--chromium/mojo/public/tools/bindings/generators/js_templates/fuzzing.tmpl4
-rw-r--r--chromium/mojo/public/tools/bindings/generators/js_templates/lite/enum_definition.tmpl40
-rw-r--r--chromium/mojo/public/tools/bindings/generators/js_templates/lite/interface_definition.tmpl103
-rw-r--r--chromium/mojo/public/tools/bindings/generators/js_templates/lite/interface_externs.tmpl114
-rw-r--r--chromium/mojo/public/tools/bindings/generators/js_templates/lite/module.externs.tmpl35
-rw-r--r--chromium/mojo/public/tools/bindings/generators/js_templates/lite/module_definition.tmpl22
-rw-r--r--chromium/mojo/public/tools/bindings/generators/js_templates/lite/mojom-lite.js.tmpl5
-rw-r--r--chromium/mojo/public/tools/bindings/generators/js_templates/lite/struct_definition.tmpl25
-rw-r--r--chromium/mojo/public/tools/bindings/generators/js_templates/lite/struct_externs.tmpl25
-rw-r--r--chromium/mojo/public/tools/bindings/generators/js_templates/lite/test/BUILD.gn2
-rw-r--r--chromium/mojo/public/tools/bindings/generators/js_templates/lite/union_definition.tmpl11
-rw-r--r--chromium/mojo/public/tools/bindings/generators/js_templates/lite/union_externs.tmpl12
-rw-r--r--chromium/mojo/public/tools/bindings/generators/js_templates/validation_macros.tmpl5
-rw-r--r--chromium/mojo/public/tools/bindings/generators/mojom_cpp_generator.py40
-rw-r--r--chromium/mojo/public/tools/bindings/generators/mojom_java_generator.py16
-rw-r--r--chromium/mojo/public/tools/bindings/generators/mojom_js_generator.py51
-rw-r--r--chromium/mojo/public/tools/bindings/mojom.gni98
-rw-r--r--chromium/mojo/public/tools/bindings/pylib/mojom/generate/module.py34
-rw-r--r--chromium/mojo/public/tools/bindings/pylib/mojom/generate/pack.py5
-rw-r--r--chromium/mojo/public/tools/bindings/pylib/mojom/generate/translate.py12
-rw-r--r--chromium/mojo/public/tools/bindings/pylib/mojom/parse/lexer.py4
-rw-r--r--chromium/mojo/public/tools/bindings/pylib/mojom/parse/parser.py12
-rw-r--r--chromium/mojo/public/tools/fuzzers/mojo_fuzzer_message_dump.cc3
-rw-r--r--chromium/mojo/public/tools/fuzzers/mojo_parse_message_fuzzer.cc1
-rw-r--r--chromium/mojo/public/tools/fuzzers/mojo_parse_message_proto_fuzzer.cc1
118 files changed, 2311 insertions, 881 deletions
diff --git a/chromium/mojo/README.md b/chromium/mojo/README.md
index b7ce83fbae9..1dfe46eb48a 100644
--- a/chromium/mojo/README.md
+++ b/chromium/mojo/README.md
@@ -4,18 +4,21 @@
## Getting Started With Mojo
-To get started using Mojo in applications which already support it (such as
-Chrome), the fastest path forward will be to look at the bindings documentation
-for your language of choice ([**C++**](#C_Bindings),
-[**JavaScript**](#JavaScript-Bindings), or [**Java**](#Java-Bindings)) as well
-as the documentation for the
-[**Mojom IDL and bindings generator**](/mojo/public/tools/bindings/README.md).
-
-If you're looking for information on creating and/or connecting to services, see
-the top-level [Services documentation](/services/README.md).
-
-For specific details regarding the conversion of old things to new things, check
-out [Converting Legacy Chrome IPC To Mojo](/ipc/README.md).
+To get started using Mojo in Chromium, the fastest path forward will likely be
+to read the Mojo sections of the
+[Intro to Mojo &amp; Services](/docs/mojo_and_services.md) guide.
+
+For more detailed reference material on the most commonly used features of Mojo,
+head directly to the [bindings](#Bindings-APIs) documentation for your language
+of choice or the more general
+[mojom Interface Definition Language (IDL)](/mojo/public/tools/bindings/README.md)
+documentation.
+
+If you're looking for information on creating and/or connecting to services,
+you're in the wrong place! Mojo does not deal with services, it only facilitates
+interface definition, message passing, and other lower-level IPC primitives.
+Instead, you should take a look at some of the other available
+[Mojo &amp; Services](/docs/README.md#Mojo-Services) documentation.
## System Overview
@@ -25,9 +28,10 @@ library with code generation for multiple target languages to facilitate
convenient message passing across arbitrary inter- and intra-process boundaries.
The documentation here is segmented according to the different libraries
-comprising Mojo. The basic hierarchy of features is as follows:
+comprising Mojo. Mojo is divided into cleanly-separated layers with the basic
+hierarchy of subcomponents as follows:
-![Mojo Library Layering: Core on bottom, language bindings on top, public system support APIs in the middle](https://docs.google.com/drawings/d/1RwhzKblXUZw-zhy_KDVobAYprYSqxZzopXTUsbwzDPw/pub?w=570&h=324)
+![Mojo Library Layering: Core on bottom, language bindings on top, public system support APIs in the middle](/docs/images/mojo_stack.png)
## Mojo Core
In order to use any of the more interesting high-level support libraries like
@@ -44,6 +48,9 @@ Mojo support within each process by calling `mojo::core::Init()`. See
This is a reasonable option when you can guarantee that all interconnected
process binaries are linking against precisely the same revision of Mojo Core.
+This includes Chromium itself as well as any developer tools and test
+executables built within the tree.
+
To support other scenarios, use dynamic linking.
### Dynamic Linking
@@ -51,7 +58,7 @@ On some platforms, it's also possible for applications to rely on a
dynamically-linked Mojo Core library (`libmojo_core.so` or `mojo_core.dll`)
instead of statically linking against Mojo Core.
-In order to take advantage of this mechanism, the corresponding library must be
+In order to take advantage of this mechanism, the library's binary must be
present in either:
- The working directory of the application
@@ -60,84 +67,65 @@ present in either:
Instead of calling `mojo::core::Init()` as embedders do, an application using
dynamic Mojo Core instead calls `MojoInitialize()` from the C System API. This
-call will attempt to locate (see above) and load a Mojo Core library to support
-subsequent Mojo API usage within the process.
+call will attempt to locate (see above) and load the Mojo Core library to
+support subsequent Mojo API usage within the process.
-Note that the Mojo Core shared library presents a stable, forward-compatible C
-ABI which can support all current and future versions of the higher-level,
-public (and not binary-stable) System and Bindings APIs.
+Note that the Mojo Core shared library presents a **stable C ABI** designed with
+both forward- and backward-compatibility in mind. Thus old applications will
+work with new versions of the shared library, and new applications can work
+with old versions of the shared library (modulo any dependency on newer
+features, whose absence can be gracefully detected at runtime).
## C System API
Once Mojo is initialized within a process, the public
[**C System API**](/mojo/public/c/system/README.md) is usable on any thread for
-the remainder of the process's lifetime. This is a lightweight API with a
-relatively small, stable, forward-compatible ABI, comprising the total public
-API surface of the Mojo Core library.
+the remainder of the process's lifetime. This encapsulates Mojo Core's stable
+ABI and comprises the total public API surface of the Mojo Core library.
+
+The C System library's only dependency (apart from the system libc and e.g.
+pthreads) is Mojo Core itself. As such, it's possible build a fully-featured
+multiprocess system using only Mojo Core and its exposed C API. It exposes the
+fundamental cross-platform capabilities to create and manipulate Mojo primitives
+like **message pipes**, **data pipes**, and **shared buffers**, as well as APIs
+to help bootstrap connections among processes.
-This API is rarely used directly, but it is the foundation upon which all
-higher-level Mojo APIs are built. It exposes the fundamental capabilities to
-create and interact Mojo primitives like **message pipes**, **data pipes**, and
-**shared buffers**, as well as APIs to help bootstrap connections among
-processes.
+Despite this, it's rare for applications to use the C API directly. Instead this
+API acts as a stable foundation upon which several higher-level and more
+ergonomic Mojo libraries are built.
## Platform Support API
Mojo provides a small collection of abstractions around platform-specific IPC
primitives to facilitate bootstrapping Mojo IPC between two processes. See the
[Platform API](/mojo/public/cpp/platform/README.md) documentation for details.
-## High-Level System APIs
+## Higher-Level System APIs
There is a relatively small, higher-level system API for each supported
language, built upon the low-level C API. Like the C API, direct usage of these
system APIs is rare compared to the bindings APIs, but it is sometimes desirable
or necessary.
-### C++
-The [**C++ System API**](/mojo/public/cpp/system/README.md) provides a layer of
-C++ helper classes and functions to make safe System API usage easier:
-strongly-typed handle scopers, synchronous waiting operations, system handle
-wrapping and unwrapping helpers, common handle operations, and utilities for
-more easily watching handle state changes.
-
-### JavaScript
-The [**JavaScript System API**](/third_party/blink/renderer/core/mojo/README.md)
-exposes the Mojo primitives to JavaScript, covering all basic functionality of the
-low-level C API.
-
-### Java
-The [**Java System API**](/mojo/public/java/system/README.md) provides helper
-classes for working with Mojo primitives, covering all basic functionality of
-the low-level C API.
-
-## High-Level Bindings APIs
-Typically developers do not use raw message pipe I/O directly, but instead
-define some set of interfaces which are used to generate code that resembles
-an idiomatic method-calling interface in the target language of choice. This is
-the bindings layer.
-
-### Mojom IDL and Bindings Generator
-Interfaces are defined using the
-[**Mojom IDL**](/mojo/public/tools/bindings/README.md), which can be fed to the
-[**bindings generator**](/mojo/public/tools/bindings/README.md) to generate code
-in various supported languages. Generated code manages serialization and
-deserialization of messages between interface clients and implementations,
-simplifying the code -- and ultimately hiding the message pipe -- on either side
-of an interface connection.
-
-### C++ Bindings
-By far the most commonly used API defined by Mojo, the
-[**C++ Bindings API**](/mojo/public/cpp/bindings/README.md) exposes a robust set
-of features for interacting with message pipes via generated C++ bindings code,
-including support for sets of related bindings endpoints, associated interfaces,
-nested sync IPC, versioning, bad-message reporting, arbitrary message filter
-injection, and convenient test facilities.
-
-### JavaScript Bindings
-The [**JavaScript Bindings API**](/mojo/public/js/README.md) provides helper
-classes for working with JavaScript code emitted by the bindings generator.
-
-### Java Bindings
-The [**Java Bindings API**](/mojo/public/java/bindings/README.md) provides
-helper classes for working with Java code emitted by the bindings generator.
+These APIs provide wrappers around low-level [system API](#C-System-API)
+concepts, presenting interfaces that are more idiomatic for the target language:
+
+- [**C++ System API**](/mojo/public/cpp/system/README.md)
+- [**JavaScript System API**](/third_party/blink/renderer/core/mojo/README.md)
+- [**Java System API**](/mojo/public/java/system/README.md)
+
+## Bindings APIs
+The [**mojom Interface Definition Language (IDL)**](/mojo/public/tools/bindings/README.md)
+is used to generate interface bindings for various languages to send and receive
+mojom interface messages using Mojo message pipes. The generated code is
+supported by a language-specific bindings API:
+
+- [**C++ Bindings API**](/mojo/public/cpp/bindings/README.md)
+- [**JavaScript Bindings API**](/mojo/public/js/README.md)
+- [**Java Bindings API**](/mojo/public/java/bindings/README.md)
+
+Note that the C++ bindings see the broadest usage in Chromium and are thus
+naturally the most feature-rich, including support for things like
+[associated interfaces](/mojo/public/cpp/bindings/README.md#Associated-Interfaces),
+[synchronous calls](/mojo/public/cpp/bindings/README.md#Synchronous-Calls), and
+[type-mapping](/mojo/public/cpp/bindings/README.md#Type-Mapping).
## FAQ
@@ -162,7 +150,9 @@ Compared to the old IPC in Chrome, making a Mojo call is about 1/3 faster and us
### Can I use in-process message pipes?
Yes, and message pipe usage is identical regardless of whether the pipe actually
-crosses a process boundary -- in fact this detail is intentionally obscured.
+crosses a process boundary -- in fact the location of the other end of a pipe is
+intentionally obscured, in part for the sake of efficiency, and in part to
+discourage tight coupling of application logic to such details.
Message pipes which don't cross a process boundary are efficient: sent messages
are never copied, and a write on one end will synchronously modify the message
diff --git a/chromium/mojo/core/channel.cc b/chromium/mojo/core/channel.cc
index d6ebfa00a09..c641e66f0c9 100644
--- a/chromium/mojo/core/channel.cc
+++ b/chromium/mojo/core/channel.cc
@@ -279,6 +279,8 @@ Channel::MessagePtr Channel::Message::Deserialize(
std::vector<PlatformHandleInTransit> handles(num_handles);
for (size_t i = 0; i < num_handles; i++) {
HANDLE handle = base::win::Uint32ToHandle(message->handles_[i].handle);
+ if (PlatformHandleInTransit::IsPseudoHandle(handle))
+ return nullptr;
if (from_process == base::kNullProcessHandle) {
handles[i] = PlatformHandleInTransit(
PlatformHandle(base::win::ScopedHandle(handle)));
diff --git a/chromium/mojo/core/channel.h b/chromium/mojo/core/channel.h
index 5ab84f2578c..9d0f8fd05ae 100644
--- a/chromium/mojo/core/channel.h
+++ b/chromium/mojo/core/channel.h
@@ -125,12 +125,8 @@ class MOJO_SYSTEM_IMPL_EXPORT Channel
"sizeof(MachPortsExtraHeader) must be 2 bytes");
#elif defined(OS_FUCHSIA)
struct HandleInfoEntry {
- // The FDIO type associated with one or more handles, or zero for handles
- // that do not belong to FDIO.
- uint8_t type;
- // Zero for non-FDIO handles, otherwise the number of handles to consume
- // to generate an FDIO file-descriptor wrapper.
- uint8_t count;
+ // True if the handle represents an FDIO file-descriptor, false otherwise.
+ bool is_file_descriptor;
};
#elif defined(OS_WIN)
struct HandleEntry {
diff --git a/chromium/mojo/core/channel_fuchsia.cc b/chromium/mojo/core/channel_fuchsia.cc
index 0dc6794b046..eb30cb9fef9 100644
--- a/chromium/mojo/core/channel_fuchsia.cc
+++ b/chromium/mojo/core/channel_fuchsia.cc
@@ -4,8 +4,8 @@
#include "mojo/core/channel.h"
+#include <lib/fdio/fd.h>
#include <lib/fdio/limits.h>
-#include <lib/fdio/util.h>
#include <lib/zx/channel.h>
#include <lib/zx/handle.h>
#include <zircon/processargs.h>
@@ -34,94 +34,57 @@ namespace {
const size_t kMaxBatchReadCapacity = 256 * 1024;
-bool UnwrapPlatformHandle(PlatformHandleInTransit handle,
- Channel::Message::HandleInfoEntry* info_out,
- std::vector<PlatformHandleInTransit>* handles_out) {
+bool UnwrapFdioHandle(PlatformHandleInTransit handle,
+ PlatformHandleInTransit* out_handle,
+ Channel::Message::HandleInfoEntry* info) {
DCHECK(handle.handle().is_valid());
if (!handle.handle().is_valid_fd()) {
- *info_out = {0u, 0u};
- handles_out->emplace_back(std::move(handle));
+ info->is_file_descriptor = false;
+ *out_handle = std::move(handle);
return true;
}
- // Each FDIO file descriptor is implemented using one or more native resources
- // and can be un-wrapped into a set of |handle| and |info| pairs, with |info|
- // consisting of an FDIO-defined type & arguments (see zircon/processargs.h).
- //
- // We try to transfer the FD, but if that fails (for example if the file has
- // already been dup()d into another FD) we may need to clone.
- zx_handle_t handles[FDIO_MAX_HANDLES] = {};
- uint32_t info[FDIO_MAX_HANDLES] = {};
- zx_status_t result =
- fdio_transfer_fd(handle.handle().GetFD().get(), 0, handles, info);
- if (result > 0) {
+ // Try to transfer the FD, and if that fails (for example if the file has
+ // already been dup()d into another FD) then fall back to cloning it.
+ zx::handle result;
+ zx_status_t status = fdio_fd_transfer(handle.handle().GetFD().get(),
+ result.reset_and_get_address());
+ if (status == ZX_OK) {
// On success, the fd in |handle| has been transferred and is no longer
// valid. Release from the PlatformHandle to avoid close()ing an invalid
// an invalid handle.
handle.CompleteTransit();
- } else if (result == ZX_ERR_UNAVAILABLE) {
+ } else if (status == ZX_ERR_UNAVAILABLE) {
// No luck, try cloning instead.
- result = fdio_clone_fd(handle.handle().GetFD().get(), 0, handles, info);
+ status = fdio_fd_clone(handle.handle().GetFD().get(),
+ result.reset_and_get_address());
}
- if (result <= 0) {
- ZX_DLOG(ERROR, result) << "fdio_transfer_fd("
+ if (status != ZX_OK) {
+ ZX_DLOG(ERROR, status) << "fdio_fd_clone/transfer("
<< handle.handle().GetFD().get() << ")";
return false;
}
- DCHECK_LE(result, FDIO_MAX_HANDLES);
-
- // We assume here that only the |PA_HND_TYPE| of the |info| really matters,
- // and that that is the same for all the underlying handles.
- *info_out = {PA_HND_TYPE(info[0]), result};
- for (int i = 0; i < result; ++i) {
- DCHECK_EQ(PA_HND_TYPE(info[0]), PA_HND_TYPE(info[i]));
- DCHECK_EQ(0u, PA_HND_SUBTYPE(info[i]));
- handles_out->emplace_back(
- PlatformHandleInTransit(PlatformHandle(zx::handle(handles[i]))));
- }
+ info->is_file_descriptor = true;
+ *out_handle = PlatformHandleInTransit(PlatformHandle(std::move(result)));
return true;
}
-PlatformHandle WrapPlatformHandles(Channel::Message::HandleInfoEntry info,
- base::circular_deque<zx::handle>* handles) {
- PlatformHandle out_handle;
- if (!info.type) {
- out_handle = PlatformHandle(std::move(handles->front()));
- handles->pop_front();
- } else {
- if (info.count > FDIO_MAX_HANDLES)
- return PlatformHandle();
-
- // Fetch the required number of handles from |handles| and set up type info.
- zx_handle_t fd_handles[FDIO_MAX_HANDLES] = {};
- uint32_t fd_infos[FDIO_MAX_HANDLES] = {};
- for (int i = 0; i < info.count; ++i) {
- fd_handles[i] = (*handles)[i].get();
- fd_infos[i] = PA_HND(info.type, 0);
- }
-
- // Try to wrap the handles into an FDIO file descriptor.
- base::ScopedFD out_fd;
- zx_status_t result = fdio_create_fd(fd_handles, fd_infos, info.count,
- base::ScopedFD::Receiver(out_fd).get());
- if (result != ZX_OK) {
- ZX_DLOG(ERROR, result) << "fdio_create_fd";
- return PlatformHandle();
- }
-
- // The handles are owned by FDIO now, so |release()| them before removing
- // the entries from |handles|.
- for (int i = 0; i < info.count; ++i) {
- ignore_result(handles->front().release());
- handles->pop_front();
- }
-
- out_handle = PlatformHandle(std::move(out_fd));
+PlatformHandle WrapFdioHandle(zx::handle handle,
+ Channel::Message::HandleInfoEntry info) {
+ if (!info.is_file_descriptor)
+ return PlatformHandle(std::move(handle));
+
+ base::ScopedFD out_fd;
+ zx_status_t status =
+ fdio_fd_create(handle.release(), base::ScopedFD::Receiver(out_fd).get());
+ if (status != ZX_OK) {
+ ZX_DLOG(ERROR, status) << "fdio_fd_create";
+ return PlatformHandle();
}
- return out_handle;
+ return PlatformHandle(std::move(out_fd));
}
// A view over a Channel::Message object. The write queue uses these since
@@ -164,18 +127,19 @@ class MessageView {
return std::vector<PlatformHandleInTransit>();
// We can only pass Fuchsia handles via IPC, so unwrap any FDIO file-
- // descriptors in |handles_| into the underlying handles, and serialize the
- // metadata, if any, into the extra header.
+ // descriptors in |handles_| into the underlying handles, with metadata in
+ // the extra header to note which belong to FDIO.
auto* handles_info = reinterpret_cast<Channel::Message::HandleInfoEntry*>(
message_->mutable_extra_header());
memset(handles_info, 0, message_->extra_header_size());
- std::vector<PlatformHandleInTransit> in_handles = std::move(handles_);
- handles_.reserve(in_handles.size());
- for (size_t i = 0; i < in_handles.size(); i++) {
- if (!UnwrapPlatformHandle(std::move(in_handles[i]), &handles_info[i],
- &handles_))
+ // Since file descriptors unwrap to a single handle, we can unwrap in-place
+ // in the |handles_| vector.
+ for (size_t i = 0; i < handles_.size(); i++) {
+ if (!UnwrapFdioHandle(std::move(handles_[i]), &handles_[i],
+ &handles_info[i])) {
return std::vector<PlatformHandleInTransit>();
+ }
}
return std::move(handles_);
}
@@ -263,23 +227,17 @@ class ChannelFuchsia : public Channel,
if (handles_info_size > extra_header_size)
return false;
- // Some caller-supplied handles may be FDIO file-descriptors, which were
- // un-wrapped to more than one native platform resource handle for transfer.
- // We may therefore need to expect more than |num_handles| handles to have
- // been accumulated in |incoming_handles_|, based on the handle info.
- size_t num_raw_handles = 0u;
- for (size_t i = 0; i < num_handles; ++i)
- num_raw_handles += handles_info[i].type ? handles_info[i].count : 1;
-
// If there are too few handles then we're not ready yet, so return true
// indicating things are OK, but leave |handles| empty.
- if (incoming_handles_.size() < num_raw_handles)
+ if (incoming_handles_.size() < num_handles)
return true;
handles->reserve(num_handles);
for (size_t i = 0; i < num_handles; ++i) {
- handles->emplace_back(
- WrapPlatformHandles(handles_info[i], &incoming_handles_));
+ handles->emplace_back(WrapFdioHandle(std::move(incoming_handles_.front()),
+ handles_info[i]));
+ DCHECK(handles->back().is_valid());
+ incoming_handles_.pop_front();
}
return true;
}
diff --git a/chromium/mojo/core/channel_fuzzer.cc b/chromium/mojo/core/channel_fuzzer.cc
index b72f9e74ba6..afebf29ebf5 100644
--- a/chromium/mojo/core/channel_fuzzer.cc
+++ b/chromium/mojo/core/channel_fuzzer.cc
@@ -14,6 +14,10 @@
#include "mojo/core/entrypoints.h"
#include "mojo/public/cpp/platform/platform_channel.h"
+#if defined(OS_WIN)
+#include <windows.h>
+#endif
+
using namespace mojo::core;
// A fake delegate for each Channel endpoint. By the time an incoming message
@@ -51,6 +55,23 @@ extern "C" int LLVMFuzzerTestOneInput(const unsigned char* data, size_t size) {
ConnectionParams(channel.TakeLocalEndpoint()),
Channel::HandlePolicy::kRejectHandles,
environment->message_loop.task_runner());
+
+#if defined(OS_WIN)
+ // On Windows, it's important that the receiver behaves like a broker process
+ // receiving messages from a non-broker process. This is because that case can
+ // safely handle invalid HANDLE attachments without crashing. The same is not
+ // true for messages going in the reverse direction (where the non-broker
+ // receiver has to assume that the broker has already duplicated the HANDLE
+ // into the non-broker's process), but fuzzing that direction is not
+ // interesting since a compromised broker process has much bigger problems.
+ //
+ // Note that in order for this hack to work properly, the remote process
+ // handle needs to be a "real" process handle rather than the pseudo-handle
+ // returned by GetCurrentProcessHandle(). Hence the use of OpenProcess().
+ receiver->set_remote_process(mojo::core::ScopedProcessHandle(
+ ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, ::GetCurrentProcessId())));
+#endif
+
receiver->Start();
FakeChannelDelegate sender_delegate;
diff --git a/chromium/mojo/core/channel_posix.cc b/chromium/mojo/core/channel_posix.cc
index 430dbb74054..2ef2a5fcfe3 100644
--- a/chromium/mojo/core/channel_posix.cc
+++ b/chromium/mojo/core/channel_posix.cc
@@ -85,10 +85,17 @@ class MessageView {
handles_ = std::move(handles);
}
+ size_t num_handles_sent() { return num_handles_sent_; }
+
+ void set_num_handles_sent(size_t num_handles_sent) {
+ num_handles_sent_ = num_handles_sent;
+ }
+
private:
Channel::MessagePtr message_;
size_t offset_;
std::vector<PlatformHandleInTransit> handles_;
+ size_t num_handles_sent_ = 0;
DISALLOW_COPY_AND_ASSIGN(MessageView);
};
@@ -514,17 +521,21 @@ class ChannelPosix : public Channel,
return true;
}
size_t bytes_written = 0;
+ std::vector<PlatformHandleInTransit> handles = message_view.TakeHandles();
+ size_t num_handles = handles.size();
+ size_t handles_written = message_view.num_handles_sent();
do {
message_view.advance_data_offset(bytes_written);
ssize_t result;
- std::vector<PlatformHandleInTransit> handles = message_view.TakeHandles();
- if (!handles.empty()) {
+ if (handles_written < num_handles) {
iovec iov = {const_cast<void*>(message_view.data()),
message_view.data_num_bytes()};
- std::vector<base::ScopedFD> fds(handles.size());
- for (size_t i = 0; i < handles.size(); ++i)
- fds[i] = handles[i].TakeHandle().TakeFD();
+ size_t num_handles_to_send =
+ std::min(num_handles - handles_written, kMaxSendmsgHandles);
+ std::vector<base::ScopedFD> fds(num_handles_to_send);
+ for (size_t i = 0; i < num_handles_to_send; ++i)
+ fds[i] = handles[i + handles_written].TakeHandle().TakeFD();
// TODO: Handle lots of handles.
result = SendmsgWithHandles(socket_.get(), &iov, 1, fds);
if (result >= 0) {
@@ -549,11 +560,14 @@ class ChannelPosix : public Channel,
fds_to_close_.emplace_back(std::move(fd));
}
#endif // defined(OS_MACOSX)
+ handles_written += num_handles_to_send;
+ DCHECK_LE(handles_written, num_handles);
+ message_view.set_num_handles_sent(handles_written);
} else {
// Message transmission failed, so pull the FDs back into |handles|
// so they can be held by the Message again.
for (size_t i = 0; i < fds.size(); ++i) {
- handles[i] =
+ handles[i + handles_written] =
PlatformHandleInTransit(PlatformHandle(std::move(fds[i])));
}
}
@@ -591,7 +605,8 @@ class ChannelPosix : public Channel,
}
bytes_written = static_cast<size_t>(result);
- } while (bytes_written < message_view.data_num_bytes());
+ } while (handles_written < num_handles ||
+ bytes_written < message_view.data_num_bytes());
return FlushOutgoingMessagesNoLock();
}
diff --git a/chromium/mojo/core/channel_win.cc b/chromium/mojo/core/channel_win.cc
index 0a2000c2728..a927dbbf98c 100644
--- a/chromium/mojo/core/channel_win.cc
+++ b/chromium/mojo/core/channel_win.cc
@@ -121,6 +121,8 @@ class ChannelWin : public Channel,
for (size_t i = 0; i < num_handles; i++) {
HANDLE handle_value =
base::win::Uint32ToHandle(extra_header_handles[i].handle);
+ if (PlatformHandleInTransit::IsPseudoHandle(handle_value))
+ return false;
if (remote_process().is_valid()) {
// If we know the remote process's handle, we assume it doesn't know
// ours; that means any handle values still belong to that process, and
diff --git a/chromium/mojo/core/dispatcher.h b/chromium/mojo/core/dispatcher.h
index 58cd7a7a39d..be62e70c8e2 100644
--- a/chromium/mojo/core/dispatcher.h
+++ b/chromium/mojo/core/dispatcher.h
@@ -41,8 +41,14 @@ class PlatformSharedMemoryMapping;
using DispatcherVector = std::vector<scoped_refptr<Dispatcher>>;
-// A |Dispatcher| implements Mojo EDK calls that are associated with a
+// A |Dispatcher| implements Mojo core API calls that are associated with a
// particular MojoHandle.
+//
+// Every MojoHandle in the system is an opaque reference to some implementation
+// of this class. See MessagePipeDispatcher, SharedBufferDispatcher,
+// DataPipeConsumerDispatcher, DataPipeProducerDispatcher, WatcherDispatcher
+// (which should really be renamed to TrapDispatcher now), and
+// InvitationDispatcher.
class MOJO_SYSTEM_IMPL_EXPORT Dispatcher
: public base::RefCountedThreadSafe<Dispatcher> {
public:
@@ -75,67 +81,130 @@ class MOJO_SYSTEM_IMPL_EXPORT Dispatcher
///////////// Watcher API ////////////////////
+ // Supports the |MojoAddTrigger()| API if implemented by this Dispatcher.
+ // |dispatcher| is the resolved Dispatcher implementation from the given
+ // MojoHandle to watch. The remaining arguments correspond directly to
+ // arguments on the original |MojoAddTrigger()| API call. See
+ // |MojoAddTrigger()| documentation.
virtual MojoResult WatchDispatcher(scoped_refptr<Dispatcher> dispatcher,
MojoHandleSignals signals,
MojoTriggerCondition condition,
uintptr_t context);
+
+ // Supports the |MojoRemoveTrigger()| API if implemented by this Dispatcher.
+ // Arguments correspond directly to arguments on the original
+ // |MojoRemoveTrigger()| API call. See |MojoRemoveTrigger()| documentation.
virtual MojoResult CancelWatch(uintptr_t context);
+
+ // Supports the |MojoArmTrap()| API if implemented by this Dispatcher.
+ // Arguments correspond directly to arguments on the original |MojoArmTrap()|
+ // API call. See |MojoArmTrap()| documentation.
virtual MojoResult Arm(uint32_t* num_blocking_events,
MojoTrapEvent* blocking_events);
///////////// Message pipe API /////////////
+ // Supports the |MojoWriteMessage()| API if implemented by this Dispatcher.
+ // |message| is the message object referenced by the MojoMessageHandle passed
+ // to the original API call. See |MojoWriteMessage()| documentation.
virtual MojoResult WriteMessage(
std::unique_ptr<ports::UserMessageEvent> message);
+ // Supports the |MojoReadMessage()| API if implemented by this Dispatcher.
+ // If successful, |*message| contains a newly read message object, which will
+ // be yielded to the API caller as an opaque MojoMessageHandle value. See
+ // |MojoReadMessage()| documentation.
virtual MojoResult ReadMessage(
std::unique_ptr<ports::UserMessageEvent>* message);
///////////// Shared buffer API /////////////
+ // Supports the |MojoDuplicateBufferHandle()| API if implemented by this
+ // Dispatcher.
+ //
// |options| may be null. |new_dispatcher| must not be null, but
// |*new_dispatcher| should be null (and will contain the dispatcher for the
// new handle on success).
+ //
+ // See |MojoDuplicateBufferHandle()| documentation.
virtual MojoResult DuplicateBufferHandle(
const MojoDuplicateBufferHandleOptions* options,
scoped_refptr<Dispatcher>* new_dispatcher);
+ // Supports the |MojoMapBuffer()| API if implemented by this Dispatcher.
+ // |offset| and |num_bytes| correspond to arguments given to the original API
+ // call. On success, |*mapping| will contain a memory mapping that Mojo Core
+ // will internally retain until the buffer is unmapped by |MojoUnmapBuffer()|.
+ // See |MojoMapBuffer()| documentation.
virtual MojoResult MapBuffer(
uint64_t offset,
uint64_t num_bytes,
std::unique_ptr<PlatformSharedMemoryMapping>* mapping);
+ // Supports the |MojoGetBufferInfo()| API if implemented by this Dispatcher.
+ // Arguments correspond to the ones given to the original API call. See
+ // |MojoGetBufferInfo()| documentation.
virtual MojoResult GetBufferInfo(MojoSharedBufferInfo* info);
///////////// Data pipe consumer API /////////////
+ // Supports the the |MojoReadData()| API if implemented by this Dispatcher.
+ // Arguments correspond to the ones given to the original API call. See
+ // |MojoReadData()| documentation.
virtual MojoResult ReadData(const MojoReadDataOptions& options,
void* elements,
uint32_t* num_bytes);
+ // Supports the the |MojoBeginReadData()| API if implemented by this
+ // Dispatcher. Arguments correspond to the ones given to the original API
+ // call. See |MojoBeginReadData()| documentation.
virtual MojoResult BeginReadData(const void** buffer,
uint32_t* buffer_num_bytes);
+ // Supports the the |MojoEndReadData()| API if implemented by this Dispatcher.
+ // Arguments correspond to the ones given to the original API call. See
+ // |MojoEndReadData()| documentation.
virtual MojoResult EndReadData(uint32_t num_bytes_read);
///////////// Data pipe producer API /////////////
+ // Supports the the |MojoWriteData()| API if implemented by this Dispatcher.
+ // Arguments correspond to the ones given to the original API call. See
+ // |MojoWriteData()| documentation.
virtual MojoResult WriteData(const void* elements,
uint32_t* num_bytes,
const MojoWriteDataOptions& options);
+ // Supports the the |MojoBeginWriteData()| API if implemented by this
+ // Dispatcher. Arguments correspond to the ones given to the original API
+ // call. See |MojoBeginWriteData()| documentation.
virtual MojoResult BeginWriteData(void** buffer, uint32_t* buffer_num_bytes);
+ // Supports the the |MojoEndWriteData()| API if implemented by this
+ // Dispatcher. Arguments correspond to the ones given to the original API
+ // call. See |MojoEndWriteData()| documentation.
virtual MojoResult EndWriteData(uint32_t num_bytes_written);
- // Invitation API.
+ // Supports the |MojoAttachMessagePipeToInvitation()| API if implemented by
+ // this Dispatcher. Arguments correspond to the ones given to the original API
+ // call. See |MojoAttachMessagePipeToInvitation()| documentation.
virtual MojoResult AttachMessagePipe(base::StringPiece name,
ports::PortRef remote_peer_port);
+
+ // Supports the |MojoExtractMessagePipeFromInvitation()| API if implemented by
+ // this Dispatcher. Arguments correspond to the ones given to the original API
+ // call. See |MojoExtractMessagePipeFromInvitation()| documentation.
virtual MojoResult ExtractMessagePipe(base::StringPiece name,
MojoHandle* message_pipe_handle);
- // Quota API.
+ // Supports the |MojoSetQuota()| API if implemented by this Dispatcher.
+ // Arguments correspond to the ones given to the original API call. See
+ // |MojoSetQuota()| documentation.
virtual MojoResult SetQuota(MojoQuotaType type, uint64_t limit);
+
+ // Supports the |MojoQueryQuota()| API if implemented by this Dispatcher.
+ // Arguments correspond to the ones given to the original API call. See
+ // |MojoQueryQuota()| documentation.
virtual MojoResult QueryQuota(MojoQuotaType type,
uint64_t* limit,
uint64_t* usage);
diff --git a/chromium/mojo/core/message_pipe_perftest.cc b/chromium/mojo/core/message_pipe_perftest.cc
index 93c833a559b..5faffca9b36 100644
--- a/chromium/mojo/core/message_pipe_perftest.cc
+++ b/chromium/mojo/core/message_pipe_perftest.cc
@@ -136,7 +136,7 @@ TEST_F(MessagePipePerfTest, PingPong) {
client_thread.Start();
client_thread.task_runner()->PostTask(
FROM_HERE,
- base::Bind(base::IgnoreResult(&RunPingPongClient), client_handle));
+ base::BindOnce(base::IgnoreResult(&RunPingPongClient), client_handle));
RunPingPongServer(server_handle);
}
diff --git a/chromium/mojo/core/message_unittest.cc b/chromium/mojo/core/message_unittest.cc
index 8f047ac8ebd..48cf664e5eb 100644
--- a/chromium/mojo/core/message_unittest.cc
+++ b/chromium/mojo/core/message_unittest.cc
@@ -7,6 +7,7 @@
#include <utility>
#include <vector>
+#include "base/bind.h"
#include "base/memory/ptr_util.h"
#include "base/numerics/safe_math.h"
#include "base/rand_util.h"
diff --git a/chromium/mojo/core/multiprocess_message_pipe_unittest.cc b/chromium/mojo/core/multiprocess_message_pipe_unittest.cc
index a30f376dd94..ea06608fc21 100644
--- a/chromium/mojo/core/multiprocess_message_pipe_unittest.cc
+++ b/chromium/mojo/core/multiprocess_message_pipe_unittest.cc
@@ -483,13 +483,13 @@ TEST_P(MultiprocessMessagePipeTestWithPipeCount, PlatformHandlePassing) {
// Android multi-process tests are not executing the new process. This is flaky.
#if !defined(OS_ANDROID)
-INSTANTIATE_TEST_CASE_P(PipeCount,
- MultiprocessMessagePipeTestWithPipeCount,
- // TODO(rockot): Enable the 128 and 250 pipe cases when
- // ChannelPosix and ChannelFuchsia have support for
- // sending larger numbers of handles per-message. See
- // kMaxAttachedHandles in channel.cc for details.
- testing::Values(1u, 64u /*, 128u, 250u*/));
+INSTANTIATE_TEST_SUITE_P(PipeCount,
+ MultiprocessMessagePipeTestWithPipeCount,
+ // TODO(rockot): Enable the 128 and 250 pipe cases when
+ // ChannelPosix and ChannelFuchsia have support for
+ // sending larger numbers of handles per-message. See
+ // kMaxAttachedHandles in channel.cc for details.
+ testing::Values(1u, 64u /*, 128u, 250u*/));
#endif
DEFINE_TEST_CLIENT_WITH_PIPE(CheckMessagePipe, MultiprocessMessagePipeTest, h) {
@@ -1335,7 +1335,7 @@ DEFINE_TEST_CLIENT_TEST_WITH_PIPE(BadMessageClient,
EXPECT_EQ("bye", ReadMessage(parent));
}
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
,
MultiprocessMessagePipeTestWithPeerSupport,
testing::Values(test::MojoTestBase::LaunchType::CHILD,
diff --git a/chromium/mojo/core/node_channel_fuzzer.cc b/chromium/mojo/core/node_channel_fuzzer.cc
index c9276098393..aea2ead69a9 100644
--- a/chromium/mojo/core/node_channel_fuzzer.cc
+++ b/chromium/mojo/core/node_channel_fuzzer.cc
@@ -15,6 +15,10 @@
#include "mojo/core/node_channel.h" // nogncheck
#include "mojo/public/cpp/platform/platform_channel.h"
+#if defined(OS_WIN)
+#include <windows.h>
+#endif
+
using namespace mojo::core;
// Implementation of NodeChannel::Delegate which does nothing. All of the
@@ -104,6 +108,23 @@ extern "C" int LLVMFuzzerTestOneInput(const unsigned char* data, size_t size) {
&receiver_delegate, ConnectionParams(channel.TakeLocalEndpoint()),
Channel::HandlePolicy::kRejectHandles,
environment->message_loop.task_runner(), base::DoNothing());
+
+#if defined(OS_WIN)
+ // On Windows, it's important that the receiver behaves like a broker process
+ // receiving messages from a non-broker process. This is because that case can
+ // safely handle invalid HANDLE attachments without crashing. The same is not
+ // true for messages going in the reverse direction (where the non-broker
+ // receiver has to assume that the broker has already duplicated the HANDLE
+ // into the non-broker's process), but fuzzing that direction is not
+ // interesting since a compromised broker process has much bigger problems.
+ //
+ // Note that in order for this hack to work properly, the remote process
+ // handle needs to be a "real" process handle rather than the pseudo-handle
+ // returned by GetCurrentProcessHandle(). Hence the use of OpenProcess().
+ receiver->SetRemoteProcessHandle(mojo::core::ScopedProcessHandle(
+ ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, ::GetCurrentProcessId())));
+#endif
+
receiver->Start();
// We only use a Channel for the sender side, since it allows us to easily
diff --git a/chromium/mojo/core/node_controller.cc b/chromium/mojo/core/node_controller.cc
index 44b8ef341fc..5a796e95b52 100644
--- a/chromium/mojo/core/node_controller.cc
+++ b/chromium/mojo/core/node_controller.cc
@@ -122,7 +122,7 @@ class ThreadDestructionObserver
new ThreadDestructionObserver(callback);
} else {
task_runner->PostTask(FROM_HERE,
- base::Bind(&Create, task_runner, callback));
+ base::BindOnce(&Create, task_runner, callback));
}
}
@@ -1216,8 +1216,8 @@ void NodeController::OnChannelError(const ports::NodeName& from_node,
} else {
io_task_runner_->PostTask(
FROM_HERE,
- base::Bind(&NodeController::OnChannelError, base::Unretained(this),
- from_node, base::RetainedRef(channel)));
+ base::BindOnce(&NodeController::OnChannelError, base::Unretained(this),
+ from_node, base::RetainedRef(channel)));
}
}
diff --git a/chromium/mojo/core/platform_handle_in_transit.cc b/chromium/mojo/core/platform_handle_in_transit.cc
index 7b82f27c34b..9ee60d86c3d 100644
--- a/chromium/mojo/core/platform_handle_in_transit.cc
+++ b/chromium/mojo/core/platform_handle_in_transit.cc
@@ -129,6 +129,21 @@ bool PlatformHandleInTransit::TransferToProcess(
#if defined(OS_WIN)
// static
+bool PlatformHandleInTransit::IsPseudoHandle(HANDLE handle) {
+ // Note that there appears to be no official documentation covering the
+ // existence of specific pseudo handle values. In practice it's clear that
+ // e.g. -1 is the current process, -2 is the current thread, etc. The largest
+ // negative value known to be an issue with DuplicateHandle in the fuzzer is
+ // -12.
+ //
+ // Note that there is virtually no risk of a real handle value falling within
+ // this range and being misclassified as a pseudo handle.
+ constexpr int kMinimumKnownPseudoHandleValue = -12;
+ const auto value = static_cast<int32_t>(reinterpret_cast<uintptr_t>(handle));
+ return value < 0 && value >= kMinimumKnownPseudoHandleValue;
+}
+
+// static
PlatformHandle PlatformHandleInTransit::TakeIncomingRemoteHandle(
HANDLE handle,
base::ProcessHandle owning_process) {
diff --git a/chromium/mojo/core/platform_handle_in_transit.h b/chromium/mojo/core/platform_handle_in_transit.h
index b75a01fbb01..ebe49e262e4 100644
--- a/chromium/mojo/core/platform_handle_in_transit.h
+++ b/chromium/mojo/core/platform_handle_in_transit.h
@@ -62,6 +62,26 @@ class PlatformHandleInTransit {
#if defined(OS_WIN)
HANDLE remote_handle() const { return remote_handle_; }
+ // Indicates whether |handle| is a known pseudo handle value. In a fuzzing
+ // environment we merely simulate IPC, so we end up accepting "remote" handle
+ // values from our own process. This means that unlike in production
+ // scenarios, we may end up successfully calling DuplicateHandle on a fuzzed
+ // pseudo handle value (in production if a remote process sent us a pseudo
+ // handle value, DuplicateHandle would always fail).
+ //
+ // For some reason, a small number of special pseudo handle values always
+ // duplicate to the same real handle value when DUPLICATE_CLOSE_SOURCE is
+ // specified, presumably because the returned handle is closed before it's
+ // even returned. For example, duplicating -10 with DUPLICATE_CLOSE_SOURCE
+ // always yields the handle value 0x50. This ends up interacting poorly with
+ // the rest of Mojo's handle deserialization code and eventually crashes
+ // in ScopedHandleVerifier.
+ //
+ // We avoid the issue by explicitly discarding any known pseudo handle values,
+ // since they are always invalid when received from a remote process anyway
+ // and thus always signal a misbehaving client.
+ static bool IsPseudoHandle(HANDLE handle);
+
// Returns a new local handle, with ownership of |handle| being transferred
// from |owning_process| to the caller.
static PlatformHandle TakeIncomingRemoteHandle(
diff --git a/chromium/mojo/core/ports/ports_unittest.cc b/chromium/mojo/core/ports/ports_unittest.cc
index 3d18bb680fa..e3a2a085723 100644
--- a/chromium/mojo/core/ports/ports_unittest.cc
+++ b/chromium/mojo/core/ports/ports_unittest.cc
@@ -124,7 +124,7 @@ class TestNode : public NodeDelegate {
node_thread_.Start();
node_thread_.task_runner()->PostTask(
FROM_HERE,
- base::Bind(&TestNode::ProcessEvents, base::Unretained(this)));
+ base::BindOnce(&TestNode::ProcessEvents, base::Unretained(this)));
}
void StopWhenIdle() {
diff --git a/chromium/mojo/core/trap_unittest.cc b/chromium/mojo/core/trap_unittest.cc
index 555726f4da6..309e5476ffd 100644
--- a/chromium/mojo/core/trap_unittest.cc
+++ b/chromium/mojo/core/trap_unittest.cc
@@ -511,7 +511,7 @@ TEST_F(TrapTest, TrapDataPipeProducerWritable) {
EXPECT_EQ(MOJO_RESULT_OK, MojoClose(t));
EXPECT_EQ(MOJO_RESULT_OK, MojoClose(producer));
EXPECT_EQ(MOJO_RESULT_OK, MojoClose(consumer));
-};
+}
TEST_F(TrapTest, CloseWatchedDataPipeConsumerHandle) {
constexpr size_t kTestPipeCapacity = 8;
diff --git a/chromium/mojo/public/c/system/README.md b/chromium/mojo/public/c/system/README.md
index ec88e3e6674..1d8b64b5ae7 100644
--- a/chromium/mojo/public/c/system/README.md
+++ b/chromium/mojo/public/c/system/README.md
@@ -43,8 +43,8 @@ user-provided notification handlers may be invoked at any time on arbitrary
threads in the process. It is entirely up to the API user to take appropriate
measures to synchronize operations against other application state.
-The higher level [system](/mojo/README.md#High-Level-System-APIs) and
-[bindings](/mojo/README.md#High-Level-Bindings-APIs) APIs provide helpers to
+The higher-level [system](/mojo/README.md#Higher_Level-System-APIs) and
+[bindings](/mojo/README.md#Bindings-APIs) APIs provide helpers to
simplify Mojo usage in this regard, at the expense of some flexibility.
## Result Codes
diff --git a/chromium/mojo/public/c/system/buffer.h b/chromium/mojo/public/c/system/buffer.h
index 83b198b2a89..677d343cc29 100644
--- a/chromium/mojo/public/c/system/buffer.h
+++ b/chromium/mojo/public/c/system/buffer.h
@@ -31,7 +31,7 @@ struct MOJO_ALIGNAS(8) MojoCreateSharedBufferOptions {
MojoCreateSharedBufferFlags flags;
};
MOJO_STATIC_ASSERT(MOJO_ALIGNOF(int64_t) <= 8, "int64_t has weird alignment");
-MOJO_STATIC_ASSERT(sizeof(MojoCreateSharedBufferOptions) == 8,
+MOJO_STATIC_ASSERT(sizeof(struct MojoCreateSharedBufferOptions) == 8,
"MojoCreateSharedBufferOptions has wrong size");
// Flags passed to |MojoGetBufferInfo()| via |MojoGetBufferInfoOptions|. See
@@ -49,7 +49,7 @@ struct MOJO_ALIGNAS(8) MojoGetBufferInfoOptions {
// See |MojoGetBufferInfoFlags|.
MojoGetBufferInfoFlags flags;
};
-MOJO_STATIC_ASSERT(sizeof(MojoGetBufferInfoOptions) == 8,
+MOJO_STATIC_ASSERT(sizeof(struct MojoGetBufferInfoOptions) == 8,
"MojoSharedBufferOptions has wrong size");
// Structure used to receive information about a shared buffer via
@@ -61,7 +61,7 @@ struct MOJO_ALIGNAS(8) MojoSharedBufferInfo {
// The size of the shared buffer.
uint64_t size;
};
-MOJO_STATIC_ASSERT(sizeof(MojoSharedBufferInfo) == 16,
+MOJO_STATIC_ASSERT(sizeof(struct MojoSharedBufferInfo) == 16,
"MojoSharedBufferInfo has wrong size");
// Flags passed to |MojoDuplicateBufferHandle()| via
@@ -92,7 +92,7 @@ struct MojoDuplicateBufferHandleOptions {
// See |MojoDuplicateBufferHandleFlags|.
MojoDuplicateBufferHandleFlags flags;
};
-MOJO_STATIC_ASSERT(sizeof(MojoDuplicateBufferHandleOptions) == 8,
+MOJO_STATIC_ASSERT(sizeof(struct MojoDuplicateBufferHandleOptions) == 8,
"MojoDuplicateBufferHandleOptions has wrong size");
// Flags passed to |MojoMapBuffer()| via |MojoMapBufferOptions|. See values
@@ -110,7 +110,7 @@ struct MojoMapBufferOptions {
// See |MojoMapBufferFlags|.
MojoMapBufferFlags flags;
};
-MOJO_STATIC_ASSERT(sizeof(MojoMapBufferOptions) == 8,
+MOJO_STATIC_ASSERT(sizeof(struct MojoMapBufferOptions) == 8,
"MojoMapBufferOptions has wrong size");
#ifdef __cplusplus
diff --git a/chromium/mojo/public/c/system/data_pipe.h b/chromium/mojo/public/c/system/data_pipe.h
index c72f55387ad..1a4ca5f385d 100644
--- a/chromium/mojo/public/c/system/data_pipe.h
+++ b/chromium/mojo/public/c/system/data_pipe.h
@@ -41,7 +41,7 @@ struct MOJO_ALIGNAS(8) MojoCreateDataPipeOptions {
uint32_t capacity_num_bytes;
};
MOJO_STATIC_ASSERT(MOJO_ALIGNOF(int64_t) <= 8, "int64_t has weird alignment");
-MOJO_STATIC_ASSERT(sizeof(MojoCreateDataPipeOptions) == 16,
+MOJO_STATIC_ASSERT(sizeof(struct MojoCreateDataPipeOptions) == 16,
"MojoCreateDataPipeOptions has wrong size");
// Flags passed to |MojoWriteData()| via |MojoWriteDataOptions|. See values
@@ -64,7 +64,7 @@ struct MOJO_ALIGNAS(8) MojoWriteDataOptions {
// See |MojoWriteDataFlags|.
MojoWriteDataFlags flags;
};
-MOJO_STATIC_ASSERT(sizeof(MojoWriteDataOptions) == 8,
+MOJO_STATIC_ASSERT(sizeof(struct MojoWriteDataOptions) == 8,
"MojoWriteDataOptions has wrong size");
// Flags passed to |MojoBeginWriteData()| via |MojoBeginWriteDataOptions|. See
@@ -82,7 +82,7 @@ struct MOJO_ALIGNAS(8) MojoBeginWriteDataOptions {
// See |MojoBeginWriteDataFlags|.
MojoBeginWriteDataFlags flags;
};
-MOJO_STATIC_ASSERT(sizeof(MojoBeginWriteDataOptions) == 8,
+MOJO_STATIC_ASSERT(sizeof(struct MojoBeginWriteDataOptions) == 8,
"MojoBeginWriteDataOptions has wrong size");
// Flags passed to |MojoEndWriteData()| via |MojoEndWriteDataOptions|. See
@@ -100,7 +100,7 @@ struct MOJO_ALIGNAS(8) MojoEndWriteDataOptions {
// See |MojoEndWriteDataFlags|.
MojoEndWriteDataFlags flags;
};
-MOJO_STATIC_ASSERT(sizeof(MojoEndWriteDataOptions) == 8,
+MOJO_STATIC_ASSERT(sizeof(struct MojoEndWriteDataOptions) == 8,
"MojoEndWriteDataOptions has wrong size");
// Flags passed to |MojoReadData()| via |MojoReadDataOptions|.
@@ -139,7 +139,7 @@ struct MOJO_ALIGNAS(8) MojoReadDataOptions {
// See |MojoReadDataFlags|.
MojoReadDataFlags flags;
};
-MOJO_STATIC_ASSERT(sizeof(MojoReadDataOptions) == 8,
+MOJO_STATIC_ASSERT(sizeof(struct MojoReadDataOptions) == 8,
"MojoReadDataOptions has wrong size");
// Flags passed to |MojoBeginReadData()| via |MojoBeginReadDataOptions|. See
@@ -157,7 +157,7 @@ struct MOJO_ALIGNAS(8) MojoBeginReadDataOptions {
// See |MojoBeginReadDataFlags|.
MojoBeginReadDataFlags flags;
};
-MOJO_STATIC_ASSERT(sizeof(MojoBeginReadDataOptions) == 8,
+MOJO_STATIC_ASSERT(sizeof(struct MojoBeginReadDataOptions) == 8,
"MojoBeginReadDataOptions has wrong size");
// Flags passed to |MojoEndReadData()| via |MojoEndReadDataOptions|. See
@@ -175,7 +175,7 @@ struct MOJO_ALIGNAS(8) MojoEndReadDataOptions {
// See |MojoEndReadDataFlags|.
MojoEndReadDataFlags flags;
};
-MOJO_STATIC_ASSERT(sizeof(MojoEndReadDataOptions) == 8,
+MOJO_STATIC_ASSERT(sizeof(struct MojoEndReadDataOptions) == 8,
"MojoEndReadDataOptions has wrong size");
#ifdef __cplusplus
diff --git a/chromium/mojo/public/c/system/invitation.h b/chromium/mojo/public/c/system/invitation.h
index eb1a4a80e8e..09909417f5a 100644
--- a/chromium/mojo/public/c/system/invitation.h
+++ b/chromium/mojo/public/c/system/invitation.h
@@ -48,7 +48,7 @@ struct MOJO_ALIGNAS(8) MojoProcessErrorDetails {
// See |MojoProcessErrorFlags|.
MojoProcessErrorFlags flags;
};
-MOJO_STATIC_ASSERT(sizeof(MojoProcessErrorDetails) == 24,
+MOJO_STATIC_ASSERT(sizeof(struct MojoProcessErrorDetails) == 24,
"MojoProcessErrorDetails has wrong size.");
// An opaque process handle value which must be provided when sending an
@@ -63,7 +63,7 @@ struct MOJO_ALIGNAS(8) MojoPlatformProcessHandle {
// POSIX systems, it's a PID.
uint64_t value;
};
-MOJO_STATIC_ASSERT(sizeof(MojoPlatformProcessHandle) == 16,
+MOJO_STATIC_ASSERT(sizeof(struct MojoPlatformProcessHandle) == 16,
"MojoPlatformProcesHandle has wrong size.");
// Enumeration indicating the type of transport over which an invitation will be
@@ -110,7 +110,7 @@ struct MOJO_ALIGNAS(8) MojoInvitationTransportEndpoint {
// descriptor.
MOJO_POINTER_FIELD(const struct MojoPlatformHandle*, platform_handles);
};
-MOJO_STATIC_ASSERT(sizeof(MojoInvitationTransportEndpoint) == 24,
+MOJO_STATIC_ASSERT(sizeof(struct MojoInvitationTransportEndpoint) == 24,
"MojoInvitationTransportEndpoint has wrong size.");
// Flags passed to |MojoCreateInvitation()| via |MojoCreateInvitationOptions|.
@@ -127,7 +127,7 @@ struct MOJO_ALIGNAS(8) MojoCreateInvitationOptions {
// See |MojoCreateInvitationFlags|.
MojoCreateInvitationFlags flags;
};
-MOJO_STATIC_ASSERT(sizeof(MojoCreateInvitationOptions) == 8,
+MOJO_STATIC_ASSERT(sizeof(struct MojoCreateInvitationOptions) == 8,
"MojoCreateInvitationOptions has wrong size");
// Flags passed to |MojoAttachMessagePipeToInvitation()| via
@@ -146,7 +146,7 @@ struct MOJO_ALIGNAS(8) MojoAttachMessagePipeToInvitationOptions {
// See |MojoAttachMessagePipeToInvitationFlags|.
MojoAttachMessagePipeToInvitationFlags flags;
};
-MOJO_STATIC_ASSERT(sizeof(MojoAttachMessagePipeToInvitationOptions) == 8,
+MOJO_STATIC_ASSERT(sizeof(struct MojoAttachMessagePipeToInvitationOptions) == 8,
"MojoAttachMessagePipeToInvitationOptions has wrong size");
// Flags passed to |MojoExtractMessagePipeFromInvitation()| via
@@ -166,7 +166,7 @@ struct MOJO_ALIGNAS(8) MojoExtractMessagePipeFromInvitationOptions {
MojoExtractMessagePipeFromInvitationFlags flags;
};
MOJO_STATIC_ASSERT(
- sizeof(MojoExtractMessagePipeFromInvitationOptions) == 8,
+ sizeof(struct MojoExtractMessagePipeFromInvitationOptions) == 8,
"MojoExtractMessagePipeFromInvitationOptions has wrong size");
// Flags passed to |MojoSendInvitation()| via |MojoSendInvitationOptions|.
@@ -202,7 +202,7 @@ struct MOJO_ALIGNAS(8) MojoSendInvitationOptions {
MOJO_POINTER_FIELD(const char*, isolated_connection_name);
uint32_t isolated_connection_name_length;
};
-MOJO_STATIC_ASSERT(sizeof(MojoSendInvitationOptions) == 24,
+MOJO_STATIC_ASSERT(sizeof(struct MojoSendInvitationOptions) == 24,
"MojoSendInvitationOptions has wrong size");
// Flags passed to |MojoAcceptInvitation()| via |MojoAcceptInvitationOptions|.
@@ -223,7 +223,7 @@ struct MOJO_ALIGNAS(8) MojoAcceptInvitationOptions {
// See |MojoAcceptInvitationFlags|.
MojoAcceptInvitationFlags flags;
};
-MOJO_STATIC_ASSERT(sizeof(MojoAcceptInvitationOptions) == 8,
+MOJO_STATIC_ASSERT(sizeof(struct MojoAcceptInvitationOptions) == 8,
"MojoAcceptInvitationOptions has wrong size");
#ifdef __cplusplus
diff --git a/chromium/mojo/public/c/system/macros.h b/chromium/mojo/public/c/system/macros.h
index 6de4a913de7..7786094e250 100644
--- a/chromium/mojo/public/c/system/macros.h
+++ b/chromium/mojo/public/c/system/macros.h
@@ -8,11 +8,15 @@
#include <stddef.h>
// Assert things at compile time. (|msg| should be a valid identifier name.)
-// This macro is currently C++-only, but we want to use it in the C core.h.
// Use like:
-// MOJO_STATIC_ASSERT(sizeof(Foo) == 12, "Foo has invalid size");
+// MOJO_STATIC_ASSERT(sizeof(struct Foo) == 12, "Foo has invalid size");
#if defined(__cplusplus)
#define MOJO_STATIC_ASSERT(expr, msg) static_assert(expr, msg)
+#elif defined(__clang__)
+// TODO(thakis): Use #include <assert.h> and static_assert() in C11 mode
+// (__STDC_VERSION__>= 201112L) once https://reviews.llvm.org/D17444 made its
+// way into Chromium.
+#define MOJO_STATIC_ASSERT(expr, msg) _Static_assert(expr, msg)
#else
#define MOJO_STATIC_ASSERT(expr, msg)
#endif
diff --git a/chromium/mojo/public/c/system/message_pipe.h b/chromium/mojo/public/c/system/message_pipe.h
index 0f642dd9658..4dcee5f50f5 100644
--- a/chromium/mojo/public/c/system/message_pipe.h
+++ b/chromium/mojo/public/c/system/message_pipe.h
@@ -36,7 +36,7 @@ struct MOJO_ALIGNAS(8) MojoCreateMessagePipeOptions {
MojoCreateMessagePipeFlags flags;
};
MOJO_STATIC_ASSERT(MOJO_ALIGNOF(int64_t) <= 8, "int64_t has weird alignment");
-MOJO_STATIC_ASSERT(sizeof(MojoCreateMessagePipeOptions) == 8,
+MOJO_STATIC_ASSERT(sizeof(struct MojoCreateMessagePipeOptions) == 8,
"MojoCreateMessagePipeOptions has wrong size");
// Flags passed to |MojoWriteMessage()| via |MojoWriteMessageOptions|. See
@@ -54,7 +54,7 @@ struct MOJO_ALIGNAS(8) MojoWriteMessageOptions {
// See |MojoWriteMessageFlags|.
MojoWriteMessageFlags flags;
};
-MOJO_STATIC_ASSERT(sizeof(MojoWriteMessageOptions) == 8,
+MOJO_STATIC_ASSERT(sizeof(struct MojoWriteMessageOptions) == 8,
"MojoWriteMessageOptions has wrong size");
// Flags passed to |MojoReadMessage()| via |MojoReadMessageOptions|. See values
@@ -72,7 +72,7 @@ struct MOJO_ALIGNAS(8) MojoReadMessageOptions {
// See |MojoReadMessageFlags|.
MojoReadMessageFlags flags;
};
-MOJO_STATIC_ASSERT(sizeof(MojoReadMessageOptions) == 8,
+MOJO_STATIC_ASSERT(sizeof(struct MojoReadMessageOptions) == 8,
"MojoReadMessageOptions has wrong size");
// Flags passed to |MojoFuseMessagePipes()| via |MojoFuseMessagePipeOptions|.
@@ -90,7 +90,7 @@ struct MOJO_ALIGNAS(8) MojoFuseMessagePipesOptions {
// See |MojoFuseMessagePipesFlags|.
MojoFuseMessagePipesFlags flags;
};
-MOJO_STATIC_ASSERT(sizeof(MojoFuseMessagePipesOptions) == 8,
+MOJO_STATIC_ASSERT(sizeof(struct MojoFuseMessagePipesOptions) == 8,
"MojoFuseMessagePipesOptions has wrong size");
// Flags passed to |MojoCreateMessage()| via |MojoCreateMessageOptions|.
@@ -107,7 +107,7 @@ struct MOJO_ALIGNAS(8) MojoCreateMessageOptions {
// See |MojoCreateMessageFlags|.
MojoCreateMessageFlags flags;
};
-MOJO_STATIC_ASSERT(sizeof(MojoCreateMessageOptions) == 8,
+MOJO_STATIC_ASSERT(sizeof(struct MojoCreateMessageOptions) == 8,
"MojoCreateMessageOptions has wrong size");
// Flags passed to |MojoSerializeMessage()| via |MojoSerializeMessageOptions|.
@@ -124,7 +124,7 @@ struct MOJO_ALIGNAS(8) MojoSerializeMessageOptions {
// See |MojoSerializeMessageFlags|.
MojoSerializeMessageFlags flags;
};
-MOJO_STATIC_ASSERT(sizeof(MojoSerializeMessageOptions) == 8,
+MOJO_STATIC_ASSERT(sizeof(struct MojoSerializeMessageOptions) == 8,
"MojoSerializeMessageOptions has wrong size");
// Flags passed to |MojoAppendMessageData()| via |MojoAppendMessageDataOptions|.
@@ -146,7 +146,7 @@ struct MOJO_ALIGNAS(8) MojoAppendMessageDataOptions {
// See |MojoAppendMessageDataFlags|.
MojoAppendMessageDataFlags flags;
};
-MOJO_STATIC_ASSERT(sizeof(MojoAppendMessageDataOptions) == 8,
+MOJO_STATIC_ASSERT(sizeof(struct MojoAppendMessageDataOptions) == 8,
"MojoAppendMessageDataOptions has wrong size");
// Flags passed to |MojoGetMessageData()| via |MojoGetMessageDataOptions|.
@@ -167,7 +167,7 @@ struct MOJO_ALIGNAS(8) MojoGetMessageDataOptions {
// See |MojoGetMessageDataFlags|.
MojoGetMessageDataFlags flags;
};
-MOJO_STATIC_ASSERT(sizeof(MojoGetMessageDataOptions) == 8,
+MOJO_STATIC_ASSERT(sizeof(struct MojoGetMessageDataOptions) == 8,
"MojoGetMessageDataOptions has wrong size");
// Flags passed to |MojoSetMessageContext()| via |MojoSetMessageContextOptions|.
@@ -184,7 +184,7 @@ struct MOJO_ALIGNAS(8) MojoSetMessageContextOptions {
// See |MojoSetMessageContextFlags|.
MojoSetMessageContextFlags flags;
};
-MOJO_STATIC_ASSERT(sizeof(MojoSetMessageContextOptions) == 8,
+MOJO_STATIC_ASSERT(sizeof(struct MojoSetMessageContextOptions) == 8,
"MojoSetMessageContextOptions has wrong size");
// Flags passed to |MojoGetMessageContext()| via |MojoGetMessageContextOptions|.
@@ -201,7 +201,7 @@ struct MOJO_ALIGNAS(8) MojoGetMessageContextOptions {
// See |MojoGetMessageContextFlags|.
MojoGetMessageContextFlags flags;
};
-MOJO_STATIC_ASSERT(sizeof(MojoGetMessageContextOptions) == 8,
+MOJO_STATIC_ASSERT(sizeof(struct MojoGetMessageContextOptions) == 8,
"MojoGetMessageContextOptions has wrong size");
// Flags passed to |MojoNotifyBadMessage()| via |MojoNotifyBadMessageOptions|.
@@ -218,7 +218,7 @@ struct MOJO_ALIGNAS(8) MojoNotifyBadMessageOptions {
// See |MojoNotifyBadMessageFlags|.
MojoNotifyBadMessageFlags flags;
};
-MOJO_STATIC_ASSERT(sizeof(MojoNotifyBadMessageOptions) == 8,
+MOJO_STATIC_ASSERT(sizeof(struct MojoNotifyBadMessageOptions) == 8,
"MojoNotifyBadMessageOptions has wrong size");
#ifdef __cplusplus
diff --git a/chromium/mojo/public/c/system/platform_handle.h b/chromium/mojo/public/c/system/platform_handle.h
index 17a1fbdee6a..2055a16ddea 100644
--- a/chromium/mojo/public/c/system/platform_handle.h
+++ b/chromium/mojo/public/c/system/platform_handle.h
@@ -30,8 +30,7 @@ typedef uint32_t MojoPlatformHandleType;
// usable on POSIX host systems (e.g. Android, Linux, Chrome OS, Mac).
#define MOJO_PLATFORM_HANDLE_TYPE_FILE_DESCRIPTOR ((MojoPlatformHandleType)1)
-// The |MojoPlatformHandle| value represents a Mach port right (e.g. a value
-// opaquely of type |mach_port_t|). Only usable on Mac OS X hosts.
+// Deprecated. TYPE_MACH_PORT is equivalent to TYPE_MACH_SEND_RIGHT.
#define MOJO_PLATFORM_HANDLE_TYPE_MACH_PORT ((MojoPlatformHandleType)2)
// The |MojoPlatformHandle| value represents a Windows HANDLE value. Only usable
@@ -42,6 +41,15 @@ typedef uint32_t MojoPlatformHandleType;
// usable on Fuchsia hosts.
#define MOJO_PLATFORM_HANDLE_TYPE_FUCHSIA_HANDLE ((MojoPlatformHandleType)4)
+// The |MojoPlatformHandle| value represents a Mach send right (e.g. a value
+// opaquely of type |mach_port_t|). Only usable on macOS hosts.
+#define MOJO_PLATFORM_HANDLE_TYPE_MACH_SEND_RIGHT \
+ MOJO_PLATFORM_HANDLE_TYPE_MACH_PORT
+
+// The |MojoPlatformHandle| value represents a Mach receive right (e.g. a value
+// opaquely of type |mach_port_t|). Only usable on macOS hosts.
+#define MOJO_PLATFORM_HANDLE_TYPE_MACH_RECEIVE_RIGHT ((MojoPlatformHandleType)5)
+
// |MojoPlatformHandle|: A handle to a native platform object.
//
// |uint32_t struct_size|: The size of this structure. Used for versioning
@@ -67,7 +75,7 @@ struct MOJO_ALIGNAS(8) MojoPlatformHandle {
// treatment of this value by Mojo depends on the value of |type|.
uint64_t value;
};
-MOJO_STATIC_ASSERT(sizeof(MojoPlatformHandle) == 16,
+MOJO_STATIC_ASSERT(sizeof(struct MojoPlatformHandle) == 16,
"MojoPlatformHandle has wrong size");
// Flags passed to |MojoWrapPlatformHandle()| via
@@ -85,7 +93,7 @@ struct MOJO_ALIGNAS(8) MojoWrapPlatformHandleOptions {
// See |MojoWrapPlatformHandleFlags|.
MojoWrapPlatformHandleFlags flags;
};
-MOJO_STATIC_ASSERT(sizeof(MojoWrapPlatformHandleOptions) == 8,
+MOJO_STATIC_ASSERT(sizeof(struct MojoWrapPlatformHandleOptions) == 8,
"MojoWrapPlatformHandleOptions has wrong size");
// Flags passed to |MojoUnwrapPlatformHandle()| via
@@ -103,7 +111,7 @@ struct MOJO_ALIGNAS(8) MojoUnwrapPlatformHandleOptions {
// See |MojoUnwrapPlatformHandleFlags|.
MojoUnwrapPlatformHandleFlags flags;
};
-MOJO_STATIC_ASSERT(sizeof(MojoUnwrapPlatformHandleOptions) == 8,
+MOJO_STATIC_ASSERT(sizeof(struct MojoUnwrapPlatformHandleOptions) == 8,
"MojoUnwrapPlatformHandleOptions has wrong size");
// A GUID value used to identify the shared memory region backing a Mojo shared
@@ -164,7 +172,8 @@ struct MOJO_ALIGNAS(8) MojoWrapPlatformSharedMemoryRegionOptions {
// See |MojoWrapPlatformSharedMemoryRegionFlags|.
MojoWrapPlatformSharedMemoryRegionFlags flags;
};
-MOJO_STATIC_ASSERT(sizeof(MojoWrapPlatformSharedMemoryRegionOptions) == 8,
+MOJO_STATIC_ASSERT(sizeof(struct MojoWrapPlatformSharedMemoryRegionOptions) ==
+ 8,
"MojoWrapPlatformSharedMemoryRegionOptions has wrong size");
// Flags passed to |MojoUnwrapPlatformSharedMemoryRegion()| via
@@ -184,7 +193,7 @@ struct MOJO_ALIGNAS(8) MojoUnwrapPlatformSharedMemoryRegionOptions {
MojoUnwrapPlatformSharedMemoryRegionFlags flags;
};
MOJO_STATIC_ASSERT(
- sizeof(MojoUnwrapPlatformSharedMemoryRegionOptions) == 8,
+ sizeof(struct MojoUnwrapPlatformSharedMemoryRegionOptions) == 8,
"MojoUnwrapPlatformSharedMemoryRegionOptions has wrong size");
// Wraps a native platform handle as a Mojo handle which can be transferred
diff --git a/chromium/mojo/public/c/system/quota.h b/chromium/mojo/public/c/system/quota.h
index 0e4ad3cb722..721c0e1bfdc 100644
--- a/chromium/mojo/public/c/system/quota.h
+++ b/chromium/mojo/public/c/system/quota.h
@@ -25,7 +25,7 @@ struct MOJO_ALIGNAS(8) MojoSetQuotaOptions {
// See |MojoSetQuotaFlags| above.
MojoSetQuotaFlags flags;
};
-MOJO_STATIC_ASSERT(sizeof(MojoSetQuotaOptions) == 8,
+MOJO_STATIC_ASSERT(sizeof(struct MojoSetQuotaOptions) == 8,
"MojoSetQuotaOptions has wrong size.");
// Flags passed to |MojoQueryQuota| via |MojoQueryQuotaOptions|.
@@ -42,7 +42,7 @@ struct MOJO_ALIGNAS(8) MojoQueryQuotaOptions {
// See |MojoQueryQuotaFlags| above.
MojoQueryQuotaFlags flags;
};
-MOJO_STATIC_ASSERT(sizeof(MojoQueryQuotaOptions) == 8,
+MOJO_STATIC_ASSERT(sizeof(struct MojoQueryQuotaOptions) == 8,
"MojoQueryQuotaOptions has wrong size.");
// The maximum value any quota can be set to. Effectively means "no quota".
diff --git a/chromium/mojo/public/c/system/trap.h b/chromium/mojo/public/c/system/trap.h
index c5e718ec131..5c6011bb756 100644
--- a/chromium/mojo/public/c/system/trap.h
+++ b/chromium/mojo/public/c/system/trap.h
@@ -63,7 +63,7 @@ struct MOJO_ALIGNAS(8) MojoTrapEvent {
// time the trap was tripped.
struct MojoHandleSignalsState signals_state;
};
-MOJO_STATIC_ASSERT(sizeof(MojoTrapEvent) == 32,
+MOJO_STATIC_ASSERT(sizeof(struct MojoTrapEvent) == 32,
"MojoTrapEvent has wrong size.");
// Value given to |MojoAddTrigger| to configure what condition should cause it
@@ -103,7 +103,7 @@ struct MOJO_ALIGNAS(8) MojoCreateTrapOptions {
// Flags. Currently unused.
MojoCreateTrapFlags flags;
};
-MOJO_STATIC_ASSERT(sizeof(MojoCreateTrapOptions) == 8,
+MOJO_STATIC_ASSERT(sizeof(struct MojoCreateTrapOptions) == 8,
"MojoCreateTrapOptions has wrong size.");
// Flags passed to |MojoAddTrigger()| via |MojoAddTriggerOptions|.
@@ -123,7 +123,7 @@ struct MOJO_ALIGNAS(8) MojoAddTriggerOptions {
// Flags. Currently unused.
MojoAddTriggerFlags flags;
};
-MOJO_STATIC_ASSERT(sizeof(MojoAddTriggerOptions) == 8,
+MOJO_STATIC_ASSERT(sizeof(struct MojoAddTriggerOptions) == 8,
"MojoAddTriggerOptions has wrong size.");
// Flags passed to |MojoRemoveTrigger()| via |MojoRemoveTriggerOptions|.
@@ -143,7 +143,7 @@ struct MOJO_ALIGNAS(8) MojoRemoveTriggerOptions {
// Flags. Currently unused.
MojoRemoveTriggerFlags flags;
};
-MOJO_STATIC_ASSERT(sizeof(MojoRemoveTriggerOptions) == 8,
+MOJO_STATIC_ASSERT(sizeof(struct MojoRemoveTriggerOptions) == 8,
"MojoRemoveTriggerOptions has wrong size.");
// Flags passed to |MojoArmTrap()| via |MojoArmTrapOptions|.
@@ -163,7 +163,7 @@ struct MOJO_ALIGNAS(8) MojoArmTrapOptions {
// Flags. Currently unused.
MojoArmTrapFlags flags;
};
-MOJO_STATIC_ASSERT(sizeof(MojoArmTrapOptions) == 8,
+MOJO_STATIC_ASSERT(sizeof(struct MojoArmTrapOptions) == 8,
"MojoArmTrapOptions has wrong size.");
#ifdef __cplusplus
diff --git a/chromium/mojo/public/c/system/types.h b/chromium/mojo/public/c/system/types.h
index 55756028f05..cee529f1dac 100644
--- a/chromium/mojo/public/c/system/types.h
+++ b/chromium/mojo/public/c/system/types.h
@@ -164,7 +164,7 @@ struct MOJO_ALIGNAS(8) MojoInitializeOptions {
MOJO_POINTER_FIELD(const char*, mojo_core_path);
uint32_t mojo_core_path_length;
};
-MOJO_STATIC_ASSERT(sizeof(MojoInitializeOptions) == 24,
+MOJO_STATIC_ASSERT(sizeof(struct MojoInitializeOptions) == 24,
"MojoInitializeOptions has wrong size");
// Flags passed to |MojoShutdown()| via |MojoShutdownOptions|.
@@ -181,7 +181,7 @@ struct MOJO_ALIGNAS(8) MojoShutdownOptions {
// See |MojoShutdownFlags|.
MojoShutdownFlags flags;
};
-MOJO_STATIC_ASSERT(sizeof(MojoShutdownOptions) == 8,
+MOJO_STATIC_ASSERT(sizeof(struct MojoShutdownOptions) == 8,
"MojoShutdownOptions has wrong size");
// |MojoHandleSignals|: Used to specify signals that can be watched for on a
@@ -240,7 +240,7 @@ struct MOJO_ALIGNAS(4) MojoHandleSignalsState {
MojoHandleSignals satisfied_signals;
MojoHandleSignals satisfiable_signals;
};
-MOJO_STATIC_ASSERT(sizeof(MojoHandleSignalsState) == 8,
+MOJO_STATIC_ASSERT(sizeof(struct MojoHandleSignalsState) == 8,
"MojoHandleSignalsState has wrong size");
// TODO(https://crbug.com/819046): Remove these aliases.
diff --git a/chromium/mojo/public/cpp/bindings/BUILD.gn b/chromium/mojo/public/cpp/bindings/BUILD.gn
index 379d5813307..52082de79a6 100644
--- a/chromium/mojo/public/cpp/bindings/BUILD.gn
+++ b/chromium/mojo/public/cpp/bindings/BUILD.gn
@@ -70,6 +70,7 @@ component("bindings_base") {
"lib/serialization_util.h",
"lib/string_serialization.h",
"lib/template_util.h",
+ "lib/tracing_helper.h",
"lib/unserialized_message_context.cc",
"lib/unserialized_message_context.h",
"lib/validate_params.h",
@@ -119,6 +120,8 @@ component("bindings") {
"associated_interface_request.h",
"binding.h",
"binding_set.h",
+ "call_internal.cc",
+ "call_internal.h",
"callback_helpers.h",
"connection_error_callback.h",
"connector.h",
@@ -161,10 +164,14 @@ component("bindings") {
"lib/task_runner_helper.cc",
"lib/task_runner_helper.h",
"native_enum.h",
+ "pending_receiver.h",
+ "pending_remote.h",
"pipe_control_message_handler.h",
"pipe_control_message_handler_delegate.h",
"pipe_control_message_proxy.h",
"raw_ptr_impl_ref_traits.h",
+ "receiver.h",
+ "remote.h",
"sequence_local_sync_event_watcher.h",
"strong_associated_binding.h",
"strong_binding.h",
diff --git a/chromium/mojo/public/cpp/bindings/README.md b/chromium/mojo/public/cpp/bindings/README.md
index 07d4e350351..75ef5a7702a 100644
--- a/chromium/mojo/public/cpp/bindings/README.md
+++ b/chromium/mojo/public/cpp/bindings/README.md
@@ -17,7 +17,7 @@ snippets. For a detailed API references please consult the headers in
[//mojo/public/cpp/bindings](https://cs.chromium.org/chromium/src/mojo/public/cpp/bindings/README.md).
For a simplified guide targeted at Chromium developers, see [this
-link](/docs/mojo_guide.md).
+link](/docs/mojo_and_services.md).
## Getting Started
@@ -153,7 +153,7 @@ routed to some implementation which will **bind** it. The `InterfaceRequest<T>`
doesn't actually *do* anything other than hold onto a pipe endpoint and carry
useful compile-time type information.
-![Diagram illustrating InterfacePtr and InterfaceRequest on either end of a message pipe](https://docs.google.com/drawings/d/1_Ocprq7EGgTKcSE_WlOn_RBfXcr5C3FJyIbWhwzwNX8/pub?w=608&h=100)
+![Diagram illustrating InterfacePtr and InterfaceRequest on either end of a message pipe](/docs/images/mojo_pipe.png)
So how do we create a strongly-typed message pipe?
@@ -211,7 +211,7 @@ logger->Log("Hello!");
This actually writes a `Log` message to the pipe.
-![Diagram illustrating a message traveling on a pipe from LoggerPtr to LoggerRequest](https://docs.google.com/drawings/d/11vnOpNP3UBLlWg4KplQuIU3r_e1XqwDFETD-O_bV-2w/pub?w=635&h=112)
+![Diagram illustrating a message traveling on a pipe from LoggerPtr to LoggerRequest](/docs/images/mojo_message.png)
But as mentioned above, `InterfaceRequest` *doesn't actually do anything*, so
that message will just sit on the pipe forever. We need a way to read messages
@@ -278,7 +278,7 @@ motion by the above line of code:
3. The `Log` message is read and deserialized, causing the `Binding` to invoke
the `Logger::Log` implementation on its bound `LoggerImpl`.
-![Diagram illustrating the progression of binding a request, reading a pending message, and dispatching it](https://docs.google.com/drawings/d/1F2VvfoOINGuNibomqeEU8KekYCtxYVFC00146CFGGQY/pub?w=550&h=500)
+![Diagram illustrating the progression of binding a request, reading a pending message, and dispatching it](/docs/images/mojo_binding_and_dispatch.png)
As a result, our implementation will eventually log the client's `"Hello!"`
message via `LOG(ERROR)`.
@@ -1261,8 +1261,7 @@ sync method call? It continues to process incoming sync request messages
messages and sync response messages that don’t match the ongoing sync
call.
-![Diagram illustrating sync call flow](
-https://docs.google.com/a/google.com/drawings/d/e/2PACX-1vRvsmrmZBszFl_OX9AhCn2Cqwx63K0GC7cYrDNPoRYRuHzxS30OZ4ygMBpeU_cThuQY2lYZkYpvSCdM/pub?w=960&h=560)
+![Diagram illustrating sync call flow](/docs/images/mojo_sync_call_flow.png)
Please note that sync response messages that don’t match the ongoing
sync call cannot re-enter. That is because they correspond to sync calls
@@ -1274,8 +1273,7 @@ while the stack unwinds.
Please note that the re-entrancy behavior doesn’t prevent deadlocks
involving async calls. You need to avoid call sequences such as:
-![Diagram illustrating a sync call deadlock](
-https://docs.google.com/a/google.com/drawings/d/e/2PACX-1vTBl5XPA8K-kVPt0oByMNSSoxpCKh1p2_atIDR9Me4xGfa6nf0fNAKkJ-Hg5utllY5ghXtoS1haHL6d/pub?w=960&h=480)
+![Diagram illustrating a sync call deadlock](/docs/images/mojo_sync_call_deadlock.png)
### Read more
@@ -1373,10 +1371,10 @@ some less common requirements. See
In order to define the mapping for `gfx::Rect`, we want the following
`StructTraits` specialization, which we'll define in
-`//ui/gfx/geometry/mojo/geometry_struct_traits.h`:
+`//ui/gfx/geometry/mojo/geometry_mojom_traits.h`:
``` cpp
-#include "mojo/public/cpp/bindings/struct_traits.h"
+#include "mojo/public/cpp/bindings/mojom_traits.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/mojo/geometry.mojom.h"
@@ -1396,10 +1394,10 @@ class StructTraits<gfx::mojom::RectDataView, gfx::Rect> {
} // namespace mojo
```
-And in `//ui/gfx/geometry/mojo/geometry_struct_traits.cc`:
+And in `//ui/gfx/geometry/mojo/geometry_mojom_traits.cc`:
``` cpp
-#include "ui/gfx/geometry/mojo/geometry_struct_traits.h"
+#include "ui/gfx/geometry/mojo/geometry_mojom_traits.h"
namespace mojo {
@@ -1467,10 +1465,10 @@ Let's place this `geometry.typemap` file alongside our Mojom file:
mojom = "//ui/gfx/geometry/mojo/geometry.mojom"
os_whitelist = [ "android" ]
public_headers = [ "//ui/gfx/geometry/rect.h" ]
-traits_headers = [ "//ui/gfx/geometry/mojo/geometry_struct_traits.h" ]
+traits_headers = [ "//ui/gfx/geometry/mojo/geometry_mojom_traits.h" ]
sources = [
- "//ui/gfx/geometry/mojo/geometry_struct_traits.cc",
- "//ui/gfx/geometry/mojo/geometry_struct_traits.h",
+ "//ui/gfx/geometry/mojo/geometry_mojom_traits.cc",
+ "//ui/gfx/geometry/mojo/geometry_mojom_traits.h",
]
public_deps = [ "//ui/gfx/geometry" ]
type_mappings = [
@@ -1491,9 +1489,9 @@ Let's look at each of the variables above:
here.
* `traits_headers`: Headers which contain the relevant `StructTraits`
specialization(s) for any type mappings described by this file.
-* `sources`: Any implementation sources and headers needed for the
- `StructTraits` definition. These sources are compiled directly into the
- generated C++ bindings target for a `mojom` file applying this typemap.
+* `sources`: Any implementation sources needed for the `StructTraits`
+ definition. These sources are compiled directly into the generated C++
+ bindings target for a `mojom` file applying this typemap.
* `public_deps`: Target dependencies exposed by the `public_headers` and
`traits_headers`.
* `deps`: Target dependencies exposed by `sources` but not already covered by
@@ -1795,7 +1793,7 @@ inline bool IsKnownEnumValue(Department value);
### Using Mojo Bindings in Chrome
-See [Converting Legacy Chrome IPC To Mojo](/ipc/README.md).
+See [Converting Legacy Chrome IPC To Mojo](/docs/mojo_ipc_conversion.md).
### Additional Documentation
diff --git a/chromium/mojo/public/cpp/bindings/call_internal.cc b/chromium/mojo/public/cpp/bindings/call_internal.cc
new file mode 100644
index 00000000000..8e4e57eeea2
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/call_internal.cc
@@ -0,0 +1,18 @@
+// Copyright 2019 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 "mojo/public/cpp/bindings/call_internal.h"
+
+namespace mojo {
+namespace internal {
+
+CallProxyWrapperBase::CallProxyWrapperBase(void* proxy) : proxy_(proxy) {}
+
+CallProxyWrapperBase::CallProxyWrapperBase(CallProxyWrapperBase&& other)
+ : proxy_(other.proxy_) {}
+
+CallProxyWrapperBase::~CallProxyWrapperBase() = default;
+
+} // namespace internal
+} // namespace mojo
diff --git a/chromium/mojo/public/cpp/bindings/call_internal.h b/chromium/mojo/public/cpp/bindings/call_internal.h
new file mode 100644
index 00000000000..ddefd8eb28a
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/call_internal.h
@@ -0,0 +1,48 @@
+// Copyright 2019 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.
+
+#ifndef MOJO_PUBLIC_CPP_BINDINGS_CALL_INTERNAL_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_CALL_INTERNAL_H_
+
+#include <utility>
+
+#include "base/component_export.h"
+#include "base/macros.h"
+
+namespace mojo {
+namespace internal {
+
+// Base class for temporary objects returned by |Remote<T>::rpc()|. This
+// provides pass-through access to the passed calling proxy.
+class COMPONENT_EXPORT(MOJO_CPP_BINDINGS) CallProxyWrapperBase {
+ public:
+ explicit CallProxyWrapperBase(void* proxy);
+ CallProxyWrapperBase(CallProxyWrapperBase&& other);
+ ~CallProxyWrapperBase();
+
+ void* proxy() const { return proxy_; }
+
+ private:
+ void* proxy_;
+
+ DISALLOW_COPY_AND_ASSIGN(CallProxyWrapperBase);
+};
+
+template <typename T>
+class CallProxyWrapper : public CallProxyWrapperBase {
+ public:
+ explicit CallProxyWrapper(T* proxy) : CallProxyWrapperBase(proxy) {}
+ CallProxyWrapper(CallProxyWrapper&& other)
+ : CallProxyWrapperBase(std::move(other)) {}
+
+ T* operator->() const { return static_cast<T*>(proxy()); }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(CallProxyWrapper);
+};
+
+} // namespace internal
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_CALL_INTERNAL_H_
diff --git a/chromium/mojo/public/cpp/bindings/clone_traits.h b/chromium/mojo/public/cpp/bindings/clone_traits.h
index e7e0a14cf02..604bfffb361 100644
--- a/chromium/mojo/public/cpp/bindings/clone_traits.h
+++ b/chromium/mojo/public/cpp/bindings/clone_traits.h
@@ -79,7 +79,7 @@ struct CloneTraits<base::flat_map<K, V>, false> {
template <typename T>
T Clone(const T& input) {
return CloneTraits<T>::Clone(input);
-};
+}
} // namespace mojo
diff --git a/chromium/mojo/public/cpp/bindings/features.cc b/chromium/mojo/public/cpp/bindings/features.cc
index 36c00d9952c..9026ba7f20b 100644
--- a/chromium/mojo/public/cpp/bindings/features.cc
+++ b/chromium/mojo/public/cpp/bindings/features.cc
@@ -19,10 +19,8 @@ namespace features {
// regress in performance due to high-priority messages seeing increased
// latency. Ideally we'd address these cases by giving the affected bindings
// higher-priority TaskRunners.
-//
-// TODO(https://crbug.com/866708): Enable this by default after M73 branch.
const base::Feature kTaskPerMessage{"MojoTaskPerMessage",
- base::FEATURE_DISABLED_BY_DEFAULT};
+ base::FEATURE_ENABLED_BY_DEFAULT};
} // namespace features
} // namespace mojo
diff --git a/chromium/mojo/public/cpp/bindings/interface_endpoint_client.h b/chromium/mojo/public/cpp/bindings/interface_endpoint_client.h
index 7ba91262d7a..0d24ae29364 100644
--- a/chromium/mojo/public/cpp/bindings/interface_endpoint_client.h
+++ b/chromium/mojo/public/cpp/bindings/interface_endpoint_client.h
@@ -14,6 +14,7 @@
#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/component_export.h"
+#include "base/location.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
@@ -115,6 +116,12 @@ class COMPONENT_EXPORT(MOJO_CPP_BINDINGS) InterfaceEndpointClient
void FlushForTesting();
void FlushAsyncForTesting(base::OnceClosure callback);
+#if DCHECK_IS_ON()
+ void SetNextCallLocation(const base::Location& location) {
+ next_call_location_ = location;
+ }
+#endif
+
private:
// Maps from the id of a response to the MessageReceiver that handles the
// response.
@@ -184,6 +191,13 @@ class COMPONENT_EXPORT(MOJO_CPP_BINDINGS) InterfaceEndpointClient
internal::ControlMessageProxy control_message_proxy_;
internal::ControlMessageHandler control_message_handler_;
+#if DCHECK_IS_ON()
+ // The code location of the the most recent call into a method on this
+ // interface endpoint. This is set *after* the call but *before* any message
+ // is actually transmitted for it.
+ base::Location next_call_location_;
+#endif
+
SEQUENCE_CHECKER(sequence_checker_);
base::WeakPtrFactory<InterfaceEndpointClient> weak_ptr_factory_;
diff --git a/chromium/mojo/public/cpp/bindings/interface_ptr_set.h b/chromium/mojo/public/cpp/bindings/interface_ptr_set.h
index 17f90b1e7f9..8130785bdae 100644
--- a/chromium/mojo/public/cpp/bindings/interface_ptr_set.h
+++ b/chromium/mojo/public/cpp/bindings/interface_ptr_set.h
@@ -8,6 +8,7 @@
#include <map>
#include <utility>
+#include "base/bind.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/stl_util.h"
diff --git a/chromium/mojo/public/cpp/bindings/lib/connector.cc b/chromium/mojo/public/cpp/bindings/lib/connector.cc
index 641e3c4ac9c..4f73c98ebdc 100644
--- a/chromium/mojo/public/cpp/bindings/lib/connector.cc
+++ b/chromium/mojo/public/cpp/bindings/lib/connector.cc
@@ -19,6 +19,7 @@
#include "base/trace_event/trace_event.h"
#include "mojo/public/cpp/bindings/features.h"
#include "mojo/public/cpp/bindings/lib/may_auto_lock.h"
+#include "mojo/public/cpp/bindings/lib/tracing_helper.h"
#include "mojo/public/cpp/bindings/mojo_buildflags.h"
#include "mojo/public/cpp/bindings/sync_handle_watcher.h"
#include "mojo/public/cpp/system/wait.h"
@@ -457,7 +458,7 @@ void Connector::WaitToReadMore() {
// no longer be met, we signal the error asynchronously to avoid reentry.
task_runner_->PostTask(
FROM_HERE,
- base::Bind(&Connector::OnWatcherHandleReady, weak_self_, rv));
+ base::BindOnce(&Connector::OnWatcherHandleReady, weak_self_, rv));
} else {
handle_watcher_->ArmOrNotify();
}
@@ -512,6 +513,9 @@ bool Connector::DispatchMessage(Message message) {
incoming_serialization_mode_);
}
+ TRACE_EVENT_WITH_FLOW0(
+ TRACE_DISABLED_BY_DEFAULT("toplevel.flow"), "mojo::Message Receive",
+ MANGLE_MESSAGE_ID(message.header()->trace_id), TRACE_EVENT_FLAG_FLOW_IN);
#if !BUILDFLAG(MOJO_TRACE_ENABLED)
// This emits just full class name, and is inferior to mojo tracing.
TRACE_EVENT0("mojom", heap_profiler_tag_);
diff --git a/chromium/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc b/chromium/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc
index 4e6108d3373..f9318db6451 100644
--- a/chromium/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc
+++ b/chromium/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc
@@ -61,8 +61,8 @@ class ResponderThunk : public MessageReceiverWithStatus {
}
} else {
task_runner_->PostTask(
- FROM_HERE,
- base::Bind(&InterfaceEndpointClient::RaiseError, endpoint_client_));
+ FROM_HERE, base::BindOnce(&InterfaceEndpointClient::RaiseError,
+ endpoint_client_));
}
}
}
@@ -239,6 +239,11 @@ bool InterfaceEndpointClient::Accept(Message* message) {
InitControllerIfNecessary();
+#if DCHECK_IS_ON()
+ // TODO(https://crbug.com/695289): Send |next_call_location_| in a control
+ // message before calling |SendMessage()| below.
+#endif
+
return controller_->SendMessage(message);
}
@@ -265,6 +270,11 @@ bool InterfaceEndpointClient::AcceptWithResponder(
message->set_request_id(request_id);
+#if DCHECK_IS_ON()
+ // TODO(https://crbug.com/695289): Send |next_call_location_| in a control
+ // message before calling |SendMessage()| below.
+#endif
+
bool is_sync = message->has_flag(Message::kFlagIsSync);
if (!controller_->SendMessage(message))
return false;
@@ -368,9 +378,9 @@ void InterfaceEndpointClient::OnAssociationEvent(
} else if (event ==
ScopedInterfaceEndpointHandle::PEER_CLOSED_BEFORE_ASSOCIATION) {
task_runner_->PostTask(FROM_HERE,
- base::Bind(&InterfaceEndpointClient::NotifyError,
- weak_ptr_factory_.GetWeakPtr(),
- handle_.disconnect_reason()));
+ base::BindOnce(&InterfaceEndpointClient::NotifyError,
+ weak_ptr_factory_.GetWeakPtr(),
+ handle_.disconnect_reason()));
}
}
diff --git a/chromium/mojo/public/cpp/bindings/lib/interface_ptr_state.h b/chromium/mojo/public/cpp/bindings/lib/interface_ptr_state.h
index 980b68ab981..9ed2102fa84 100644
--- a/chromium/mojo/public/cpp/bindings/lib/interface_ptr_state.h
+++ b/chromium/mojo/public/cpp/bindings/lib/interface_ptr_state.h
@@ -15,6 +15,7 @@
#include "base/bind.h"
#include "base/callback_forward.h"
#include "base/component_export.h"
+#include "base/location.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
@@ -59,6 +60,12 @@ class COMPONENT_EXPORT(MOJO_CPP_BINDINGS) InterfacePtrStateBase {
return endpoint_client_ && endpoint_client_->has_pending_responders();
}
+#if DCHECK_IS_ON()
+ void SetNextCallLocation(const base::Location& location) {
+ endpoint_client_->SetNextCallLocation(location);
+ }
+#endif
+
protected:
InterfaceEndpointClient* endpoint_client() const {
return endpoint_client_.get();
@@ -116,6 +123,13 @@ class InterfacePtrState : public InterfacePtrStateBase {
return proxy_.get();
}
+ void SetNextCallLocation(const base::Location& location) {
+#if DCHECK_IS_ON()
+ ConfigureProxyIfNecessary();
+ InterfacePtrStateBase::SetNextCallLocation(location);
+#endif
+ }
+
void QueryVersion(const base::Callback<void(uint32_t)>& callback) {
ConfigureProxyIfNecessary();
InterfacePtrStateBase::QueryVersion(callback);
diff --git a/chromium/mojo/public/cpp/bindings/lib/interface_serialization.h b/chromium/mojo/public/cpp/bindings/lib/interface_serialization.h
index 00954de2610..498308a3108 100644
--- a/chromium/mojo/public/cpp/bindings/lib/interface_serialization.h
+++ b/chromium/mojo/public/cpp/bindings/lib/interface_serialization.h
@@ -16,6 +16,8 @@
#include "mojo/public/cpp/bindings/lib/bindings_internal.h"
#include "mojo/public/cpp/bindings/lib/serialization_context.h"
#include "mojo/public/cpp/bindings/lib/serialization_forward.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/system/handle.h"
#include "mojo/public/cpp/system/message_pipe.h"
@@ -115,6 +117,26 @@ struct Serializer<InterfacePtrDataView<Base>, InterfacePtrInfo<T>> {
};
template <typename Base, typename T>
+struct Serializer<InterfacePtrDataView<Base>, PendingRemote<T>> {
+ static_assert(std::is_base_of<Base, T>::value, "Interface type mismatch.");
+
+ static void Serialize(PendingRemote<T>& input,
+ Interface_Data* output,
+ SerializationContext* context) {
+ context->AddInterfaceInfo(input.TakePipe(), input.version(), output);
+ }
+
+ static bool Deserialize(Interface_Data* input,
+ PendingRemote<T>* output,
+ SerializationContext* context) {
+ *output = PendingRemote<T>(
+ context->TakeHandleAs<mojo::MessagePipeHandle>(input->handle),
+ input->version);
+ return true;
+ }
+};
+
+template <typename Base, typename T>
struct Serializer<InterfaceRequestDataView<Base>, InterfaceRequest<T>> {
static_assert(std::is_base_of<Base, T>::value, "Interface type mismatch.");
@@ -133,6 +155,25 @@ struct Serializer<InterfaceRequestDataView<Base>, InterfaceRequest<T>> {
}
};
+template <typename Base, typename T>
+struct Serializer<InterfaceRequestDataView<Base>, PendingReceiver<T>> {
+ static_assert(std::is_base_of<Base, T>::value, "Interface type mismatch.");
+
+ static void Serialize(PendingReceiver<T>& input,
+ Handle_Data* output,
+ SerializationContext* context) {
+ context->AddHandle(ScopedHandle::From(input.TakePipe()), output);
+ }
+
+ static bool Deserialize(Handle_Data* input,
+ PendingReceiver<T>* output,
+ SerializationContext* context) {
+ *output =
+ PendingReceiver<T>(context->TakeHandleAs<MessagePipeHandle>(*input));
+ return true;
+ }
+};
+
} // namespace internal
} // namespace mojo
diff --git a/chromium/mojo/public/cpp/bindings/lib/message.cc b/chromium/mojo/public/cpp/bindings/lib/message.cc
index 12f1a822166..fa28aa4e51e 100644
--- a/chromium/mojo/public/cpp/bindings/lib/message.cc
+++ b/chromium/mojo/public/cpp/bindings/lib/message.cc
@@ -9,6 +9,7 @@
#include <stdlib.h>
#include <algorithm>
+#include <atomic>
#include <utility>
#include "base/bind.h"
@@ -17,8 +18,10 @@
#include "base/numerics/safe_math.h"
#include "base/strings/stringprintf.h"
#include "base/threading/sequence_local_storage_slot.h"
+#include "base/trace_event/trace_event.h"
#include "mojo/public/cpp/bindings/associated_group_controller.h"
#include "mojo/public/cpp/bindings/lib/array_internal.h"
+#include "mojo/public/cpp/bindings/lib/tracing_helper.h"
#include "mojo/public/cpp/bindings/lib/unserialized_message_context.h"
namespace mojo {
@@ -43,8 +46,22 @@ void AllocateHeaderFromBuffer(internal::Buffer* buffer, HeaderType** header) {
(*header)->num_bytes = sizeof(HeaderType);
}
+uint32_t GetTraceId(void* object) {
+ // |object| is a pointer to some object, which we are going to use as
+ // a hopefully unique id for this message.
+ // Additionally xor it with a counter to protect against the situations when
+ // a new object is allocated with the same address.
+ // The counter alone is not sufficient because we also have to deal with
+ // different processes, and the counter is only process-unique.
+ static std::atomic<int> counter{0};
+ uint64_t value = reinterpret_cast<intptr_t>(object);
+ return static_cast<uint32_t>(counter.fetch_add(1, std::memory_order_relaxed) ^
+ (value >> 32) ^ ((value << 32) >> 32));
+}
+
void WriteMessageHeader(uint32_t name,
uint32_t flags,
+ uint32_t trace_id,
size_t payload_interface_id_count,
internal::Buffer* payload_buffer) {
if (payload_interface_id_count > 0) {
@@ -54,6 +71,7 @@ void WriteMessageHeader(uint32_t name,
header->version = 2;
header->name = name;
header->flags = flags;
+ header->trace_id = trace_id;
// The payload immediately follows the header.
header->payload.Set(header + 1);
} else if (flags &
@@ -64,22 +82,29 @@ void WriteMessageHeader(uint32_t name,
header->version = 1;
header->name = name;
header->flags = flags;
+ header->trace_id = trace_id;
} else {
internal::MessageHeader* header;
AllocateHeaderFromBuffer(payload_buffer, &header);
header->version = 0;
header->name = name;
header->flags = flags;
+ header->trace_id = trace_id;
}
}
void CreateSerializedMessageObject(uint32_t name,
uint32_t flags,
+ uint32_t trace_id,
size_t payload_size,
size_t payload_interface_id_count,
std::vector<ScopedHandle>* handles,
ScopedMessageHandle* out_handle,
internal::Buffer* out_buffer) {
+ TRACE_EVENT_WITH_FLOW0(TRACE_DISABLED_BY_DEFAULT("toplevel.flow"),
+ "mojo::Message Send", MANGLE_MESSAGE_ID(trace_id),
+ TRACE_EVENT_FLAG_FLOW_OUT);
+
ScopedMessageHandle handle;
MojoResult rv = mojo::CreateMessage(&handle);
DCHECK_EQ(MOJO_RESULT_OK, rv);
@@ -109,7 +134,8 @@ void CreateSerializedMessageObject(uint32_t name,
// Make sure we zero the memory first!
memset(payload_buffer.data(), 0, total_size);
- WriteMessageHeader(name, flags, payload_interface_id_count, &payload_buffer);
+ WriteMessageHeader(name, flags, trace_id, payload_interface_id_count,
+ &payload_buffer);
*out_handle = std::move(handle);
*out_buffer = std::move(payload_buffer);
@@ -119,6 +145,12 @@ void SerializeUnserializedContext(MojoMessageHandle message,
uintptr_t context_value) {
auto* context =
reinterpret_cast<internal::UnserializedMessageContext*>(context_value);
+ uint32_t trace_id = GetTraceId(context);
+
+ TRACE_EVENT_WITH_FLOW0(TRACE_DISABLED_BY_DEFAULT("toplevel.flow"),
+ "mojo::Message Send", MANGLE_MESSAGE_ID(trace_id),
+ TRACE_EVENT_FLAG_FLOW_OUT);
+
void* buffer;
uint32_t buffer_size;
MojoResult attach_result = MojoAppendMessageData(
@@ -129,7 +161,8 @@ void SerializeUnserializedContext(MojoMessageHandle message,
internal::Buffer payload_buffer(MessageHandle(message), 0, buffer,
buffer_size);
WriteMessageHeader(context->message_name(), context->message_flags(),
- 0 /* payload_interface_id_count */, &payload_buffer);
+ trace_id, 0 /* payload_interface_id_count */,
+ &payload_buffer);
// We need to copy additional header data which may have been set after
// message construction, as this codepath may be reached at some arbitrary
@@ -202,7 +235,7 @@ Message::Message(uint32_t name,
size_t payload_size,
size_t payload_interface_id_count,
std::vector<ScopedHandle>* handles) {
- CreateSerializedMessageObject(name, flags, payload_size,
+ CreateSerializedMessageObject(name, flags, GetTraceId(this), payload_size,
payload_interface_id_count, handles, &handle_,
&payload_buffer_);
transferable_ = true;
diff --git a/chromium/mojo/public/cpp/bindings/lib/message_dumper.cc b/chromium/mojo/public/cpp/bindings/lib/message_dumper.cc
index ea05aa1a9bb..3f912c4a65b 100644
--- a/chromium/mojo/public/cpp/bindings/lib/message_dumper.cc
+++ b/chromium/mojo/public/cpp/bindings/lib/message_dumper.cc
@@ -4,6 +4,7 @@
#include "mojo/public/cpp/bindings/message_dumper.h"
+#include "base/bind.h"
#include "base/files/file.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
diff --git a/chromium/mojo/public/cpp/bindings/lib/message_internal.h b/chromium/mojo/public/cpp/bindings/lib/message_internal.h
index 40539e27aaa..93850c6b135 100644
--- a/chromium/mojo/public/cpp/bindings/lib/message_internal.h
+++ b/chromium/mojo/public/cpp/bindings/lib/message_internal.h
@@ -33,8 +33,9 @@ struct MessageHeader : internal::StructHeader {
uint32_t name;
// 0 or either of the enum values defined above.
uint32_t flags;
- // Unused padding to make the struct size a multiple of 8 bytes.
- uint32_t padding;
+ // A unique (hopefully) id for a message. Used in tracing to match trace
+ // events for sending and receiving a message.
+ uint32_t trace_id;
};
static_assert(sizeof(MessageHeader) == 24, "Bad sizeof(MessageHeader)");
diff --git a/chromium/mojo/public/cpp/bindings/lib/native_struct_serialization.cc b/chromium/mojo/public/cpp/bindings/lib/native_struct_serialization.cc
index 283080089ff..5eedd5ba967 100644
--- a/chromium/mojo/public/cpp/bindings/lib/native_struct_serialization.cc
+++ b/chromium/mojo/public/cpp/bindings/lib/native_struct_serialization.cc
@@ -90,7 +90,7 @@ void UnmappedNativeStructSerializerImpl::SerializeMessageContents(
internal::Serializer<ScopedHandle, ScopedHandle>::Serialize(
handle, &handle_writer->the_handle, context);
handle_writer->type = static_cast<int32_t>(
- mojo::ConvertTo<native::SerializedHandle::Type>(attachment->GetType()));
+ mojo::ConvertTo<native::SerializedHandleType>(attachment->GetType()));
handles_writer.data()->at(i).Set(handle_writer.data());
}
writer->data()->handles.Set(handles_writer.data());
@@ -115,7 +115,7 @@ bool UnmappedNativeStructSerializerImpl::DeserializeMessageAttachments(
auto attachment = IPC::MessageAttachment::CreateFromMojoHandle(
std::move(handle),
mojo::ConvertTo<IPC::MessageAttachment::Type>(
- static_cast<native::SerializedHandle::Type>(handle_data->type)));
+ static_cast<native::SerializedHandleType>(handle_data->type)));
message->attachment_set()->AddAttachment(std::move(attachment));
}
return true;
diff --git a/chromium/mojo/public/cpp/bindings/lib/scoped_interface_endpoint_handle.cc b/chromium/mojo/public/cpp/bindings/lib/scoped_interface_endpoint_handle.cc
index 2e5559ce0d4..9ccae37b223 100644
--- a/chromium/mojo/public/cpp/bindings/lib/scoped_interface_endpoint_handle.cc
+++ b/chromium/mojo/public/cpp/bindings/lib/scoped_interface_endpoint_handle.cc
@@ -108,13 +108,13 @@ class ScopedInterfaceEndpointHandle::State
if (!pending_association_) {
runner_->PostTask(
FROM_HERE,
- base::Bind(
+ base::BindOnce(
&ScopedInterfaceEndpointHandle::State::RunAssociationEventHandler,
this, runner_, ASSOCIATED));
} else if (!peer_state_) {
runner_->PostTask(
FROM_HERE,
- base::Bind(
+ base::BindOnce(
&ScopedInterfaceEndpointHandle::State::RunAssociationEventHandler,
this, runner_, PEER_CLOSED_BEFORE_ASSOCIATION));
}
@@ -196,10 +196,10 @@ class ScopedInterfaceEndpointHandle::State
handler = std::move(association_event_handler_);
runner_ = nullptr;
} else {
- runner_->PostTask(FROM_HERE,
- base::Bind(&ScopedInterfaceEndpointHandle::State::
- RunAssociationEventHandler,
- this, runner_, ASSOCIATED));
+ runner_->PostTask(
+ FROM_HERE, base::BindOnce(&ScopedInterfaceEndpointHandle::State::
+ RunAssociationEventHandler,
+ this, runner_, ASSOCIATED));
}
}
}
@@ -234,9 +234,9 @@ class ScopedInterfaceEndpointHandle::State
} else {
runner_->PostTask(
FROM_HERE,
- base::Bind(&ScopedInterfaceEndpointHandle::State::
- RunAssociationEventHandler,
- this, runner_, PEER_CLOSED_BEFORE_ASSOCIATION));
+ base::BindOnce(&ScopedInterfaceEndpointHandle::State::
+ RunAssociationEventHandler,
+ this, runner_, PEER_CLOSED_BEFORE_ASSOCIATION));
}
}
}
diff --git a/chromium/mojo/public/cpp/bindings/lib/test_random_mojo_delays.cc b/chromium/mojo/public/cpp/bindings/lib/test_random_mojo_delays.cc
index 861aa99b9e5..18e4aec2d04 100644
--- a/chromium/mojo/public/cpp/bindings/lib/test_random_mojo_delays.cc
+++ b/chromium/mojo/public/cpp/bindings/lib/test_random_mojo_delays.cc
@@ -4,6 +4,7 @@
#include <list>
+#include "base/bind.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/no_destructor.h"
diff --git a/chromium/mojo/public/cpp/bindings/lib/tracing_helper.h b/chromium/mojo/public/cpp/bindings/lib/tracing_helper.h
new file mode 100644
index 00000000000..ebc5cc27e85
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/lib/tracing_helper.h
@@ -0,0 +1,20 @@
+// Copyright 2019 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.
+
+#ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_TRACING_HELPER_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_LIB_TRACING_HELPER_H_
+
+#define MANGLE_MESSAGE_ID(id) (id ^ ::mojo::internal::kMojoMessageMangleMask)
+
+namespace mojo {
+namespace internal {
+
+// Mojo message id is 32-bit, but for tracing we ensure that mojo messages
+// don't collide with other trace events.
+constexpr uint64_t kMojoMessageMangleMask = 0x655b2a8e8efdf27f;
+
+} // namespace internal
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_TRACING_HELPER_H_
diff --git a/chromium/mojo/public/cpp/bindings/lib/validation_errors.h b/chromium/mojo/public/cpp/bindings/lib/validation_errors.h
index e48e37c6b62..9967e584f0f 100644
--- a/chromium/mojo/public/cpp/bindings/lib/validation_errors.h
+++ b/chromium/mojo/public/cpp/bindings/lib/validation_errors.h
@@ -166,6 +166,6 @@ class COMPONENT_EXPORT(MOJO_CPP_BINDINGS_BASE)
DLOG_IF(FATAL, (condition) && !ReportSerializationWarning(error)) \
<< "The outgoing message will trigger " \
<< ValidationErrorToString(error) << " at the receiving side (" \
- << description << ").";
+ << description << ")."
#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_VALIDATION_ERRORS_H_
diff --git a/chromium/mojo/public/cpp/bindings/pending_receiver.h b/chromium/mojo/public/cpp/bindings/pending_receiver.h
new file mode 100644
index 00000000000..342d077ab21
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/pending_receiver.h
@@ -0,0 +1,79 @@
+// Copyright 2019 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.
+
+#ifndef MOJO_PUBLIC_CPP_BINDINGS_PENDING_RECEIVER_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_PENDING_RECEIVER_H_
+
+#include <utility>
+
+#include "base/macros.h"
+#include "mojo/public/cpp/system/message_pipe.h"
+
+namespace mojo {
+
+// A PendingReceiver receives and accumulates a queue of incoming Interface
+// method calls made by a single corresponding Remote. PendingReceiver instances
+// may be freely moved to another thread/sequence, or even transferred to
+// another process via a Mojo interface call (see pending_receiver<T> syntax in
+// mojom IDL).
+//
+// This object should eventually be consumed to bind a Receiver, which will then
+// begin dispatching any queued and future incoming method calls to a local
+// implementation of Interface. See Receiver documentation for more details.
+//
+// NOTE: This object is essentially semantic sugar wrapping a message pipe
+// handle that is expected to receive Interface messages from a Remote. As such,
+// consumers who know what they're doing (i.e. who are confident about what lies
+// on the other end of a pipe) may freely convert between a PendingReceiver and
+// a raw message pipe handle.
+template <typename Interface>
+class PendingReceiver {
+ public:
+ // Constructs an invalid PendingReceiver. This object is not entangled with
+ // any Remote and cannot be used to bind a Receiver.
+ //
+ // A valid PendingReceiver is commonly obtained by calling
+ // |Remote::BindNewReceiver()| on an existing unbound Remote instance or less
+ // commonly by calling calling |PendingRemote::MakeReceiver()| on an existing
+ // but invalid PendingRemote instance.
+ PendingReceiver() = default;
+ PendingReceiver(PendingReceiver&&) noexcept = default;
+
+ // Constructs a valid PendingReceiver from a valid raw message pipe handle.
+ explicit PendingReceiver(ScopedMessagePipeHandle pipe)
+ : pipe_(std::move(pipe)) {
+ DCHECK(pipe_.is_valid());
+ }
+
+ ~PendingReceiver() = default;
+
+ PendingReceiver& operator=(PendingReceiver&&) noexcept = default;
+
+ // Indicates whether the PendingReceiver is valid, meaning it can ne used to
+ // bind a Receiver that wants to begin dispatching method calls made by the
+ // entangled Remote.
+ bool is_valid() const { return pipe_.is_valid(); }
+
+ // Resets this PendingReceiver to an invalid state. If it was entangled with a
+ // Remote or PendingRemote, that object remains in a valid state and will
+ // eventually detect that its receiver is gone. Any calls it makes will
+ // effectively be dropped.
+ void reset() { pipe_.reset(); }
+
+ // Takes ownership of this PendingReceiver's message pipe handle. After this
+ // call, the PendingReceiver is no longer in a valid state and can no longer
+ // be used to bind a Receiver.
+ ScopedMessagePipeHandle TakePipe() WARN_UNUSED_RESULT {
+ return std::move(pipe_);
+ }
+
+ private:
+ ScopedMessagePipeHandle pipe_;
+
+ DISALLOW_COPY_AND_ASSIGN(PendingReceiver);
+};
+
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_PENDING_RECEIVER_H_
diff --git a/chromium/mojo/public/cpp/bindings/pending_remote.h b/chromium/mojo/public/cpp/bindings/pending_remote.h
new file mode 100644
index 00000000000..cf37734e61b
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/pending_remote.h
@@ -0,0 +1,104 @@
+// Copyright 2019 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.
+
+#ifndef MOJO_PUBLIC_CPP_BINDINGS_PENDING_REMOTE_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_PENDING_REMOTE_H_
+
+#include <cstdint>
+#include <utility>
+
+#include "base/compiler_specific.h"
+#include "base/logging.h"
+#include "base/macros.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "mojo/public/cpp/system/message_pipe.h"
+
+namespace mojo {
+
+// A valid PendingRemote is entangled with exactly one Receiver or
+// PendingReceiver, and can be consumed to bind a Remote in order to begin
+// issuing method calls to that receiver. See Remote documentation for more
+// details.
+//
+// PendingRemote instances may be freely moved to another thread/sequence, or
+// even transferred to another process via a Mojo interface call (see
+// pending_remote<T> syntax in mojom IDL).
+//
+// NOTE: This object is essentially semantic sugar wrapping a raw message pipe
+// handle that is expected to send Interface messages of a specified version
+// (typically 0) to a Receiver. As such, consumers who know what they're doing
+// (i.e. who are confident about what lies on the other side of a pipe) may
+// freely convert between a PendingRemote and a 2-tuple of
+// [raw message pipe handle, expected interface version number].
+template <typename Interface>
+class PendingRemote {
+ public:
+ // Constructs an invalid PendingRemote. This object is not entangled with any
+ // receiver and cannot be used to bind a Remote.
+ //
+ // A valid PendingRemote is typically obtained by calling
+ // |Receiver::BindNewRemote()| on an existing unbound Receiver instance.
+ //
+ // To simultaneously create a valid PendingRemote and an entangled
+ // PendingReceiver for rarer cases where both objects need to be passed
+ // elsewhere, use the |MakeReceiver()| method defined below.
+ PendingRemote() = default;
+ PendingRemote(PendingRemote&&) noexcept = default;
+
+ // Constructs a valid PendingRemote over a valid raw message pipe handle and
+ // expected interface version number.
+ PendingRemote(ScopedMessagePipeHandle pipe, uint32_t version)
+ : pipe_(std::move(pipe)), version_(version) {
+ DCHECK(pipe_.is_valid());
+ }
+
+ ~PendingRemote() = default;
+
+ PendingRemote& operator=(PendingRemote&&) noexcept = default;
+
+ // Indicates whether the PendingRemote is valid, meaning it can be used to
+ // bind a Remote that wants to begin issuing method calls to be dispatched by
+ // the entangled Receiver.
+ bool is_valid() const { return pipe_.is_valid(); }
+
+ // Resets this PendingRemote to an invalid state. If it was entangled with a
+ // Receiver or PendingReceiver, that object remains in a valid state and will
+ // eventually detect that its remote caller is gone.
+ void reset() {
+ pipe_.reset();
+ version_ = 0;
+ }
+
+ // Takes ownership of this PendingRemote's message pipe handle. After this
+ // call, the PendingRemote is no longer in a valid state and can no longer be
+ // used to bind a Remote.
+ ScopedMessagePipeHandle TakePipe() WARN_UNUSED_RESULT {
+ version_ = 0;
+ return std::move(pipe_);
+ }
+
+ // The version of the interface this Remote is assuming when making method
+ // calls. For the most common case of unversioned mojom interfaces, this is
+ // always zero.
+ uint32_t version() const { return version_; }
+
+ // Creates a new PendingReceiver and entangles this PendingRemote with it.
+ // May only be called on an invalid PendingRemote.
+ PendingReceiver<Interface> MakeReceiver() WARN_UNUSED_RESULT {
+ DCHECK(!is_valid()) << "PendingRemote already has a receiver";
+ MessagePipe pipe;
+ pipe_ = std::move(pipe.handle0);
+ return PendingReceiver<Interface>(std::move(pipe.handle1));
+ }
+
+ private:
+ ScopedMessagePipeHandle pipe_;
+ uint32_t version_ = 0;
+
+ DISALLOW_COPY_AND_ASSIGN(PendingRemote);
+};
+
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_PENDING_REMOTE_H_
diff --git a/chromium/mojo/public/cpp/bindings/receiver.h b/chromium/mojo/public/cpp/bindings/receiver.h
new file mode 100644
index 00000000000..e97d0aafa02
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/receiver.h
@@ -0,0 +1,172 @@
+// Copyright 2019 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.
+
+#ifndef MOJO_PUBLIC_CPP_BINDINGS_RECEIVER_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_RECEIVER_H_
+
+#include <utility>
+
+#include "base/compiler_specific.h"
+#include "base/logging.h"
+#include "base/macros.h"
+#include "base/memory/scoped_refptr.h"
+#include "base/sequenced_task_runner.h"
+#include "mojo/public/cpp/bindings/interface_request.h"
+#include "mojo/public/cpp/bindings/lib/binding_state.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
+#include "mojo/public/cpp/bindings/raw_ptr_impl_ref_traits.h"
+#include "mojo/public/cpp/bindings/receiver.h"
+#include "mojo/public/cpp/system/message_pipe.h"
+
+namespace mojo {
+
+// A Receiver is used to receive and dispatch Interface method calls to a local
+// implementation of Interface. Every Receiver object is permanently linked to
+// an implementation of Interface at construction time. The Receiver begins
+// receiving and scheduling method calls to the implementation once it becomes
+// bound by consuming a PendingReceiver, either at construction time or by
+// calling |Bind()|.
+//
+// Receiver is NOT thread- or sequence- safe and must be used from a single
+// (but otherwise arbitrary) sequence. All bound Receiver objects are associated
+// with a base::SequencedTaskRunner which the Receiver uses exclusively to
+// schedule incoming method calls and disconnection notifications.
+//
+// IMPORTANT: In the name of memory safety, Interface method calls and
+// disconnection notifications scheduled by a Receiver object will NEVER run
+// beyond the lifetime of the Receiver object.
+template <typename Interface,
+ typename ImplRefTraits = RawPtrImplRefTraits<Interface>>
+class Receiver {
+ public:
+ // Typically (and by default) a Receiver uses a raw pointer to reference its
+ // linked Interface implementation object, because typically that
+ // implementation object owns the Receiver. An alternative |ImplRefTraits| may
+ // be provided as a second Receiver template argument in order to use a
+ // different reference type.
+ using ImplPointerType = typename ImplRefTraits::PointerType;
+
+ // Constructs an unbound Receiver linked to |impl| for the duration of the
+ // Receive's lifetime. The Receiver can be bound later by calling |Bind()| or
+ // |BindNewRemote()|. An unbound Receiver does not schedule any asynchronous
+ // tasks.
+ explicit Receiver(ImplPointerType impl) : internal_state_(std::move(impl)) {}
+
+ // Constructs a bound Receiver by consuming |pending_receiver|. The Receiver
+ // is permanently linked to |impl| and will schedule incoming |impl| method
+ // and disconnection notifications on the default SequencedTaskRunner (i.e.
+ // base::SequencedTaskRunnerHandle::Get() at construction time).
+ Receiver(ImplPointerType impl, PendingReceiver<Interface> pending_receiver)
+ : Receiver(std::move(impl), std::move(pending_receiver), nullptr) {}
+
+ // Similar to above but the constructed Receiver schedules all tasks via
+ // |task_runner| instead of the default SequencedTaskRunner. |task_runner|
+ // must run tasks on the same sequence that owns this Receiver.
+ Receiver(ImplPointerType impl,
+ PendingReceiver<Interface> pending_receiver,
+ scoped_refptr<base::SequencedTaskRunner> task_runner)
+ : internal_state_(std::move(impl)) {
+ Bind(std::move(pending_receiver), std::move(task_runner));
+ }
+
+ ~Receiver() = default;
+
+ // Indicates whether this Receiver is bound, meaning it may continue to
+ // receive Interface method calls from a remote caller.
+ //
+ // NOTE: A Receiver is NEVER passively unbound. The only way for it to become
+ // unbound is to explicitly call |reset()| or |Unbind()|.
+ bool is_bound() const { return internal_state_.is_bound(); }
+
+ // Sets a OnceClosure to be invoked if this Receiver is cut off from its
+ // Remote (or PendingRemote). This can happen if the corresponding Remote (or
+ // unconsumed PendingRemote) has been destroyed, or if the Remote sends a
+ // malformed message. Must only be called on a bound Receiver object, and only
+ // remains set as long as the Receiver is both bound and connected.
+ //
+ // If ever invoked, |handler| will be scheduled asynchronously on the
+ // Receiver's bound SequencedTaskRunner.
+ void set_disconnect_handler(base::OnceClosure handler) {
+ internal_state_.set_connection_error_handler(std::move(handler));
+ }
+
+ // Resets this Receiver to an unbound state. An unbound Receiver will NEVER
+ // schedule method calls or disconnection notifications, and any pending tasks
+ // which were scheduled prior to unbinding are effectively cancelled.
+ void reset() { internal_state_.Close(); }
+
+ // Binds this Receiver, connecting it to a new PendingRemote which is
+ // returned for transmission elsewhere (typically to a Remote who will consume
+ // it to start making calls).
+ //
+ // The Receiver will schedule incoming |impl| method calls and disconnection
+ // notifications on the default SequencedTaskRunner (i.e.
+ // base::SequencedTaskRunnerHandle::Get() at the time of this call). Must only
+ // be called on an unbound Receiver.
+ PendingRemote<Interface> BindNewRemote() WARN_UNUSED_RESULT {
+ return BindNewRemote(nullptr);
+ }
+
+ // Like above, but the Receiver will schedule incoming |impl| method calls and
+ // disconnection notifications on |task_runner| rather than on the default
+ // SequencedTaskRunner. Must only be called on an unbound Receiver.
+ // |task_runner| must run tasks on the same sequence that owns this Receiver.
+ PendingRemote<Interface> BindNewRemote(
+ scoped_refptr<base::SequencedTaskRunner> task_runner) WARN_UNUSED_RESULT {
+ DCHECK(!is_bound()) << "Receiver is already bound";
+ PendingRemote<Interface> remote;
+ Bind(remote.MakeReceiver(), std::move(task_runner));
+ return remote;
+ }
+
+ // Binds this Receiver by consuming |pending_receiver|, which must be valid.
+ // Must only be called on an unbound Receiver.
+ //
+ // The newly bound Receiver will schedule incoming |impl| method calls and
+ // disconnection notifications on the default SequencedTaskRunner (i.e.
+ // base::SequencedTaskRunnerHandle::Get() at the time of this call).
+ void Bind(PendingReceiver<Interface> pending_receiver) {
+ DCHECK(pending_receiver.is_valid());
+ Bind(std::move(pending_receiver), nullptr);
+ }
+
+ // Like above, but the newly bound Receiver will schedule incoming |impl|
+ // method calls and disconnection notifications on |task_runner| instead of
+ // the default SequencedTaskRunner. Must only be called on an unbound
+ // Receiver. |task_runner| must run tasks on the same sequence that owns this
+ // Receiver.
+ void Bind(PendingReceiver<Interface> pending_receiver,
+ scoped_refptr<base::SequencedTaskRunner> task_runner) {
+ internal_state_.Bind(pending_receiver.TakePipe(), std::move(task_runner));
+ }
+
+ // Unbinds this Receiver, preventing any further |impl| method calls or
+ // disconnection notifications from being scheduled by it. Any such tasks that
+ // were scheduled prior to unbinding are effectively cancelled.
+ //
+ // Returns a PendingReceiver which remains connected to this receiver's
+ // Remote and which may be transferred elsewhere and consumed by another
+ // Receiver. Any messages received but not actually dispatched by this
+ // Receiver remain intact within the returned PendingReceiver and can be
+ // dispatched by whomever binds with it later.
+ //
+ // Note that a Receiver should not be unbound while there are still living
+ // response callbacks that haven't been invoked, as once the Receiver is
+ // unbound those response callbacks are no longer valid and the Remote will
+ // never be able to receive its expected responses.
+ PendingReceiver<Interface> Unbind() {
+ CHECK(!internal_state_.HasAssociatedInterfaces());
+ return PendingReceiver<Interface>(
+ internal_state_.Unbind().PassMessagePipe());
+ }
+
+ private:
+ internal::BindingState<Interface, ImplRefTraits> internal_state_;
+
+ DISALLOW_COPY_AND_ASSIGN(Receiver);
+};
+
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_RECEIVER_H_
diff --git a/chromium/mojo/public/cpp/bindings/remote.h b/chromium/mojo/public/cpp/bindings/remote.h
new file mode 100644
index 00000000000..eeb7d9334de
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/remote.h
@@ -0,0 +1,247 @@
+// Copyright 2019 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.
+
+#ifndef MOJO_PUBLIC_CPP_BINDINGS_REMOTE_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_REMOTE_H_
+
+#include <cstdint>
+#include <utility>
+
+#include "base/callback_forward.h"
+#include "base/compiler_specific.h"
+#include "base/location.h"
+#include "base/logging.h"
+#include "base/macros.h"
+#include "base/memory/scoped_refptr.h"
+#include "base/sequenced_task_runner.h"
+#include "mojo/public/cpp/bindings/call_internal.h"
+#include "mojo/public/cpp/bindings/interface_ptr_info.h"
+#include "mojo/public/cpp/bindings/lib/interface_ptr_state.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
+#include "mojo/public/cpp/bindings/receiver.h"
+#include "mojo/public/cpp/system/message_pipe.h"
+
+namespace mojo {
+
+// A Remote is used to issue Interface method calls to a single connected
+// Receiver or PendingReceiver. The Remote must be bound in order to issue those
+// method calls, and it becomes bound by consuming a PendingRemote either at
+// construction time or by calling |Bind()|.
+//
+// Remote is NOT thread- or sequence-safe and must be used on a single
+// (but otherwise arbitrary) sequence. All bound Remote objects are associated
+// with a base::SequenceTaskRunner which the Remote uses exclusively to schedule
+// response callbacks and disconnection notifications.
+//
+// The most common ways to bind a Remote are to consume to a PendingRemote
+// received via some IPC, or to call |BindNewReceiver()| and send the returned
+// PendingReceiver somewhere useful (i.e., to a remote Receiver who will consume
+// it). For example:
+//
+// mojo::Remote<mojom::Widget> widget;
+// widget_factory->CreateWidget(widget.BindNewReceiver());
+// widget.rpc(FROM_HERE)->Click();
+//
+// IMPORTANT: There are some things to be aware of regarding Interface method
+// calls as they relate to Remote object lifetime:
+//
+// - Interface method calls issued immediately before the destruction of a
+// Remote ARE guaranteed to be transmitted to the remote's receiver as long
+// as the receiver itself remains alive, either as a Receiver or a
+// PendingReceiver.
+//
+// - In the name of memory safety, Interface method response callbacks (and in
+// general ANY tasks which can be scheduled by a Remote) will NEVER
+// be dispatched beyond the lifetime of the Remote object. As such, if
+// you make a call and you need its reply, you must keep the Remote alive
+// until the reply is received.
+template <typename Interface>
+class Remote {
+ public:
+ // Constructs an unbound Remote. This object cannot issue Interface method
+ // calls and does not schedule any tasks.
+ Remote() = default;
+ Remote(Remote&& other) noexcept {
+ internal_state_.Swap(&other.internal_state_);
+ }
+
+ // Constructs a new Remote which is bound from |pending_remote| and which
+ // schedules response callbacks and disconnection notifications on the default
+ // SequencedTaskRunner (i.e., base::SequencedTaskRunnerHandle::Get() at
+ // construction time).
+ explicit Remote(PendingRemote<Interface> pending_remote)
+ : Remote(std::move(pending_remote), nullptr) {}
+
+ // Constructs a new Remote which is bound from |pending_remote| and which
+ // schedules response callbacks and disconnection notifications on
+ // |task_runner|. |task_runner| must run tasks on the same sequence that owns
+ // this Remote.
+ Remote(PendingRemote<Interface> pending_remote,
+ scoped_refptr<base::SequencedTaskRunner> task_runner) {
+ DCHECK(pending_remote.is_valid());
+ Bind(std::move(pending_remote), std::move(task_runner));
+ }
+
+ ~Remote() = default;
+
+ // Issue a method call to the remote implementation of Interface. If the
+ // remote end is still a PendingReceiver, the call will be queued within that
+ // object. If the remote end is bound to a live Receiver, the call will
+ // eventually be dispatched in the order it was received.
+ //
+ // If the Remote is no longer connected because the receiver has been
+ // destroyed, the call will be dropped.
+ internal::CallProxyWrapper<Interface> rpc(const base::Location& from_here) {
+ internal_state_.SetNextCallLocation(from_here);
+ return internal::CallProxyWrapper<Interface>(internal_state_.instance());
+ }
+
+ // Exposes access to callable Interface methods directed at this Remote's
+ // receiver. Must only be called on a bound Remote.
+ //
+ // Direct use of this accessor is discouraged and callers should prefer to use
+ // |rpc()| instead when making remote calls. Using |rpc()| can provide
+ // useful call-site attribution in DCHECK-enabled builds and makes IPC call
+ // sites easier to grok.
+ typename Interface::Proxy_* get() const {
+ DCHECK(is_bound())
+ << "Cannot issue Interface method calls on an unbound Remote";
+ return internal_state_.instance();
+ }
+
+ // Shorthand form of |get()|. See above.
+ //
+ // TODO(https://crbug.com/934883): Figure out whether to disallow use of this
+ // operator in certain environments.
+ typename Interface::Proxy_* operator->() const { return get(); }
+
+ // Indicates whether this Remote is bound and thus can issue Interface method
+ // calls via e.g. |rpc()|.
+ //
+ // NOTE: The state of being "bound" should not be confused with the state of
+ // being "connected" (see |is_connected()| below). A Remote is NEVER passively
+ // unbound and the only way for it to become unbound is to explicitly call
+ // |reset()| or |Unbind()|. As such, unless you make explicit calls to those
+ // methods, it is always safe to assume that a Remote you've bound will remain
+ // bound and callable.
+ bool is_bound() const { return internal_state_.is_bound(); }
+
+ // Indicates whether this Remote is connected to a receiver. Must only be
+ // called on a bound Remote. If this returns |true|, method calls made by this
+ // Remote may eventually end up at the connected receiver (though it's of
+ // course possible for this call to race with disconnection). If this returns
+ // |false| however, all future Interface method calls on this Remote will be
+ // silently dropped.
+ //
+ // A bound Remote becomes disconnected automatically either when its receiver
+ // is destroyed, or when it receives a malformed or otherwise unexpected
+ // response message from the receiver.
+ //
+ // NOTE: The state of being "bound" should not be confused with the state of
+ // being "connected". See |is_bound()| above.
+ bool is_connected() const {
+ DCHECK(is_bound());
+ return !internal_state_.encountered_error();
+ }
+
+ // Sets a Closure to be invoked if this Remote is cut off from its receiver.
+ // This can happen if the corresponding Receiver (or unconsumed
+ // PendingReceiver) is destroyed, or if the Receiver sends a malformed or
+ // otherwise unexpected response message to this Remote. Must only be called
+ // on a bound Remote object, and only remains set as long as the Remote is
+ // both bound and connected.
+ //
+ // If invoked at all, |handler| will be scheduled asynchronously using the
+ // Remote's bound SequencedTaskRunner.
+ void set_disconnect_handler(base::OnceClosure handler) {
+ if (is_connected())
+ internal_state_.set_connection_error_handler(std::move(handler));
+ }
+
+ // Resets this Remote to an unbound state. To reset the Remote and recover an
+ // PendingRemote that can be bound again later, use |Unbind()| instead.
+ void reset() {
+ State doomed_state;
+ internal_state_.Swap(&doomed_state);
+ }
+
+ // Binds this Remote, connecting it to a new PendingReceiver which is
+ // returned for transmission to some Receiver which can bind it. The Remote
+ // will schedule any response callbacks or disconnection notifications on the
+ // default SequencedTaskRunner (i.e. base::SequencedTaskRunnerHandle::Get() at
+ // the time of this call). Must only be called on an unbound Remote.
+ PendingReceiver<Interface> BindNewReceiver() WARN_UNUSED_RESULT {
+ return BindNewReceiver(nullptr);
+ }
+
+ // Like above, but the Remote will schedule response callbacks and
+ // disconnection notifications on |task_runner| instead of the default
+ // SequencedTaskRunner. |task_runner| must run tasks on the same sequence that
+ // owns this Remote.
+ PendingReceiver<Interface> BindNewReceiver(
+ scoped_refptr<base::SequencedTaskRunner> task_runner) WARN_UNUSED_RESULT {
+ MessagePipe pipe;
+ Bind(PendingRemote<Interface>(std::move(pipe.handle0), 0),
+ std::move(task_runner));
+ return PendingReceiver<Interface>(std::move(pipe.handle1));
+ }
+
+ // Binds this Remote by consuming |pending_remote|, which must be valid. The
+ // Remote will schedule any response callbacks or disconnection notifications
+ // on the default SequencedTaskRunner (i.e.
+ // base::SequencedTaskRunnerHandle::Get() at the time of this call). Must only
+ // be called on an unbound Remote.
+ void Bind(PendingRemote<Interface> pending_remote) {
+ DCHECK(pending_remote.is_valid());
+ Bind(std::move(pending_remote), nullptr);
+ }
+
+ // Like above, but the Remote will schedule response callbacks and
+ // disconnection notifications on |task_runner| instead of the default
+ // SequencedTaskRunner. Must only be called on an unbound Remote.
+ // |task_runner| must run tasks on the same sequence that owns this Remote.
+ void Bind(PendingRemote<Interface> pending_remote,
+ scoped_refptr<base::SequencedTaskRunner> task_runner) {
+ DCHECK(!is_bound()) << "Remote is already bound";
+ internal_state_.Bind(InterfacePtrInfo<Interface>(pending_remote.TakePipe(),
+ pending_remote.version()),
+ std::move(task_runner));
+
+ // Force the internal state to configure its proxy. Unlike InterfacePtr we
+ // do not use Remote in transit, so binding to a pipe handle can also imply
+ // binding to a SequencedTaskRunner and observing pipe handle state. This
+ // allows for e.g. |is_connected()| to be a more reliable API than
+ // |InterfacePtr::encountered_error()|.
+ ignore_result(internal_state_.instance());
+ }
+
+ // Unbinds this Remote, rendering it unable to issue further Interface method
+ // calls. Returns a PendingRemote which may be passed across threads or
+ // processes and consumed by another Remote elsewhere.
+ //
+ // Note that it is an error (the bad, crashy kind of error) to attempt to
+ // |Unbind()| a Remote which is awaiting one or more responses to previously
+ // issued Interface method calls. Calling this method should only be
+ // considered in cases where satisfaction of that constraint can be proven.
+ //
+ // Must only be called on a bound Remote.
+ PendingRemote<Interface> Unbind() WARN_UNUSED_RESULT {
+ DCHECK(is_bound());
+ CHECK(!internal_state_.has_unbound_callbacks());
+ State state;
+ internal_state_.Swap(&state);
+ InterfacePtrInfo<Interface> info = state.PassInterface();
+ return PendingRemote<Interface>(info.PassHandle(), info.version());
+ }
+
+ private:
+ using State = internal::InterfacePtrState<Interface>;
+ mutable State internal_state_;
+
+ DISALLOW_COPY_AND_ASSIGN(Remote);
+};
+
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_REMOTE_H_
diff --git a/chromium/mojo/public/cpp/bindings/tests/BUILD.gn b/chromium/mojo/public/cpp/bindings/tests/BUILD.gn
index dd9db3ec5d3..a73a8736b50 100644
--- a/chromium/mojo/public/cpp/bindings/tests/BUILD.gn
+++ b/chromium/mojo/public/cpp/bindings/tests/BUILD.gn
@@ -30,6 +30,7 @@ source_set("tests") {
"message_queue.h",
"multiplex_router_unittest.cc",
"native_struct_unittest.cc",
+ "new_endpoint_types_unittest.cc",
"report_bad_message_unittest.cc",
"request_response_unittest.cc",
"router_test_util.cc",
@@ -54,6 +55,7 @@ source_set("tests") {
"//mojo/public/cpp/bindings",
"//mojo/public/cpp/system",
"//mojo/public/cpp/test_support:test_utils",
+ "//mojo/public/interfaces/bindings/tests:other_test_interfaces",
"//mojo/public/interfaces/bindings/tests:test_associated_interfaces",
"//mojo/public/interfaces/bindings/tests:test_export_component",
"//mojo/public/interfaces/bindings/tests:test_export_component2",
diff --git a/chromium/mojo/public/cpp/bindings/thread_safe_interface_ptr.h b/chromium/mojo/public/cpp/bindings/thread_safe_interface_ptr.h
index 0a5c7f6f433..17c29b09065 100644
--- a/chromium/mojo/public/cpp/bindings/thread_safe_interface_ptr.h
+++ b/chromium/mojo/public/cpp/bindings/thread_safe_interface_ptr.h
@@ -7,6 +7,7 @@
#include <memory>
+#include "base/bind.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/memory/ref_counted.h"
@@ -97,7 +98,7 @@ class ThreadSafeForwarder : public MessageReceiverWithResponder {
associated_group_.GetController());
}
task_runner_->PostTask(FROM_HERE,
- base::Bind(forward_, base::Passed(message)));
+ base::BindOnce(forward_, base::Passed(message)));
return true;
}
@@ -117,8 +118,9 @@ class ThreadSafeForwarder : public MessageReceiverWithResponder {
auto reply_forwarder =
std::make_unique<ForwardToCallingThread>(std::move(responder));
task_runner_->PostTask(
- FROM_HERE, base::Bind(forward_with_responder_, base::Passed(message),
- base::Passed(&reply_forwarder)));
+ FROM_HERE,
+ base::BindOnce(forward_with_responder_, base::Passed(message),
+ std::move(reply_forwarder)));
return true;
}
@@ -136,8 +138,9 @@ class ThreadSafeForwarder : public MessageReceiverWithResponder {
auto response = base::MakeRefCounted<SyncResponseInfo>();
auto response_signaler = std::make_unique<SyncResponseSignaler>(response);
task_runner_->PostTask(
- FROM_HERE, base::Bind(forward_with_responder_, base::Passed(message),
- base::Passed(&response_signaler)));
+ FROM_HERE,
+ base::BindOnce(forward_with_responder_, base::Passed(message),
+ std::move(response_signaler)));
// Save the pending SyncResponseInfo so that if the sync call deletes
// |this|, we can signal the completion of the call to return from
@@ -229,9 +232,9 @@ class ThreadSafeForwarder : public MessageReceiverWithResponder {
// deleted.
caller_task_runner_->PostTask(
FROM_HERE,
- base::Bind(&ForwardToCallingThread::CallAcceptAndDeleteResponder,
- base::Passed(std::move(responder_)),
- base::Passed(std::move(*message))));
+ base::BindOnce(&ForwardToCallingThread::CallAcceptAndDeleteResponder,
+ base::Passed(std::move(responder_)),
+ base::Passed(std::move(*message))));
return true;
}
@@ -318,8 +321,8 @@ class ThreadSafeInterfacePtrBase
void BindOnTaskRunner(AssociatedInterfacePtrInfo<InterfaceType> ptr_info) {
associated_group_ = AssociatedGroup(ptr_info.handle());
- task_runner_->PostTask(FROM_HERE, base::Bind(&PtrWrapper::Bind, this,
- base::Passed(&ptr_info)));
+ task_runner_->PostTask(FROM_HERE, base::BindOnce(&PtrWrapper::Bind, this,
+ std::move(ptr_info)));
}
void BindOnTaskRunner(InterfacePtrInfo<InterfaceType> ptr_info) {
@@ -330,8 +333,8 @@ class ThreadSafeInterfacePtrBase
// the interface pointer on the |task_runner_|. Therefore, MultiplexRouter
// should be able to be created on a sequence different than the one that
// it is supposed to listen on. crbug.com/682334
- task_runner_->PostTask(FROM_HERE, base::Bind(&PtrWrapper::Bind, this,
- base::Passed(&ptr_info)));
+ task_runner_->PostTask(FROM_HERE, base::BindOnce(&PtrWrapper::Bind, this,
+ std::move(ptr_info)));
}
std::unique_ptr<ThreadSafeForwarder<InterfaceType>> CreateForwarder() {
@@ -365,9 +368,9 @@ class ThreadSafeInterfacePtrBase
if (!task_runner_->RunsTasksInCurrentSequence()) {
// NOTE: This is only called when there are no more references to
// |this|, so binding it unretained is both safe and necessary.
- task_runner_->PostTask(FROM_HERE,
- base::Bind(&PtrWrapper::DeleteOnCorrectThread,
- base::Unretained(this)));
+ task_runner_->PostTask(
+ FROM_HERE, base::BindOnce(&PtrWrapper::DeleteOnCorrectThread,
+ base::Unretained(this)));
} else {
delete this;
}
diff --git a/chromium/mojo/public/cpp/bindings/type_converter.h b/chromium/mojo/public/cpp/bindings/type_converter.h
index 395eeb4ffee..c0e5b99b888 100644
--- a/chromium/mojo/public/cpp/bindings/type_converter.h
+++ b/chromium/mojo/public/cpp/bindings/type_converter.h
@@ -109,7 +109,7 @@ struct TypeConverter<std::vector<T>, Container> {
template <typename T, typename U>
inline T ConvertTo(const U& obj) {
return TypeConverter<T, U>::Convert(obj);
-};
+}
} // namespace mojo
diff --git a/chromium/mojo/public/cpp/platform/BUILD.gn b/chromium/mojo/public/cpp/platform/BUILD.gn
index 6fbc9aeebfc..c20f95bb6d7 100644
--- a/chromium/mojo/public/cpp/platform/BUILD.gn
+++ b/chromium/mojo/public/cpp/platform/BUILD.gn
@@ -8,6 +8,7 @@ component("platform") {
output_name = "mojo_cpp_platform"
public = [
+ "features.h",
"platform_channel.h",
"platform_channel_endpoint.h",
"platform_channel_server_endpoint.h",
@@ -15,6 +16,7 @@ component("platform") {
]
sources = [
+ "features.cc",
"named_platform_channel_win.cc",
"platform_channel.cc",
"platform_channel_endpoint.cc",
diff --git a/chromium/mojo/public/cpp/platform/features.cc b/chromium/mojo/public/cpp/platform/features.cc
new file mode 100644
index 00000000000..79bdd62c41f
--- /dev/null
+++ b/chromium/mojo/public/cpp/platform/features.cc
@@ -0,0 +1,19 @@
+// Copyright 2019 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 "mojo/public/cpp/platform/features.h"
+
+namespace mojo {
+namespace features {
+
+#if defined(OS_MACOSX) && !defined(OS_IOS)
+// Enables the ChannelMac implementation, which uses Mach IPC as the underlying
+// transport mechanism for PlatformChannel. Otherwise, macOS defaults to using
+// ChannelPosix.
+const base::Feature kMojoChannelMac{"MojoChannelMac",
+ base::FEATURE_DISABLED_BY_DEFAULT};
+#endif
+
+} // namespace features
+} // namespace mojo
diff --git a/chromium/mojo/public/cpp/platform/features.h b/chromium/mojo/public/cpp/platform/features.h
new file mode 100644
index 00000000000..0ab2980e588
--- /dev/null
+++ b/chromium/mojo/public/cpp/platform/features.h
@@ -0,0 +1,23 @@
+// Copyright 2019 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.
+
+#ifndef MOJO_PUBLIC_CPP_PLATFORM_FEATURES_H_
+#define MOJO_PUBLIC_CPP_PLATFORM_FEATURES_H_
+
+#include "base/component_export.h"
+#include "base/feature_list.h"
+#include "build/build_config.h"
+
+namespace mojo {
+namespace features {
+
+#if defined(OS_MACOSX) && !defined(OS_IOS)
+COMPONENT_EXPORT(MOJO_CPP_PLATFORM)
+extern const base::Feature kMojoChannelMac;
+#endif
+
+} // namespace features
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_PLATFORM_FEATURES_H_
diff --git a/chromium/mojo/public/cpp/platform/platform_handle.cc b/chromium/mojo/public/cpp/platform/platform_handle.cc
index 106fe48e4cd..735f7c13f90 100644
--- a/chromium/mojo/public/cpp/platform/platform_handle.cc
+++ b/chromium/mojo/public/cpp/platform/platform_handle.cc
@@ -95,7 +95,9 @@ PlatformHandle::PlatformHandle(zx::handle handle)
: type_(Type::kHandle), handle_(std::move(handle)) {}
#elif defined(OS_MACOSX) && !defined(OS_IOS)
PlatformHandle::PlatformHandle(base::mac::ScopedMachSendRight mach_port)
- : type_(Type::kMachPort), mach_port_(std::move(mach_port)) {}
+ : type_(Type::kMachSend), mach_send_(std::move(mach_port)) {}
+PlatformHandle::PlatformHandle(base::mac::ScopedMachReceiveRight mach_port)
+ : type_(Type::kMachReceive), mach_receive_(std::move(mach_port)) {}
#endif
#if defined(OS_POSIX) || defined(OS_FUCHSIA)
@@ -118,7 +120,8 @@ PlatformHandle& PlatformHandle::operator=(PlatformHandle&& other) {
#elif defined(OS_FUCHSIA)
handle_ = std::move(other.handle_);
#elif defined(OS_MACOSX) && !defined(OS_IOS)
- mach_port_ = std::move(other.mach_port_);
+ mach_send_ = std::move(other.mach_send_);
+ mach_receive_ = std::move(other.mach_receive_);
#endif
#if defined(OS_POSIX) || defined(OS_FUCHSIA)
@@ -152,10 +155,14 @@ void PlatformHandle::ToMojoPlatformHandle(PlatformHandle handle,
break;
}
#elif defined(OS_MACOSX) && !defined(OS_IOS)
- if (handle.is_mach_port()) {
- out_handle->type = MOJO_PLATFORM_HANDLE_TYPE_MACH_PORT;
+ if (handle.is_mach_send()) {
+ out_handle->type = MOJO_PLATFORM_HANDLE_TYPE_MACH_SEND_RIGHT;
+ out_handle->value = static_cast<uint64_t>(handle.ReleaseMachSendRight());
+ break;
+ } else if (handle.is_mach_receive()) {
+ out_handle->type = MOJO_PLATFORM_HANDLE_TYPE_MACH_RECEIVE_RIGHT;
out_handle->value =
- static_cast<uint64_t>(handle.TakeMachPort().release());
+ static_cast<uint64_t>(handle.ReleaseMachReceiveRight());
break;
}
#endif
@@ -188,9 +195,12 @@ PlatformHandle PlatformHandle::FromMojoPlatformHandle(
if (handle->type == MOJO_PLATFORM_HANDLE_TYPE_FUCHSIA_HANDLE)
return PlatformHandle(zx::handle(handle->value));
#elif defined(OS_MACOSX) && !defined(OS_IOS)
- if (handle->type == MOJO_PLATFORM_HANDLE_TYPE_MACH_PORT) {
+ if (handle->type == MOJO_PLATFORM_HANDLE_TYPE_MACH_SEND_RIGHT) {
return PlatformHandle(base::mac::ScopedMachSendRight(
static_cast<mach_port_t>(handle->value)));
+ } else if (handle->type == MOJO_PLATFORM_HANDLE_TYPE_MACH_RECEIVE_RIGHT) {
+ return PlatformHandle(base::mac::ScopedMachReceiveRight(
+ static_cast<mach_port_t>(handle->value)));
}
#endif
@@ -209,7 +219,8 @@ void PlatformHandle::reset() {
#elif defined(OS_FUCHSIA)
handle_.reset();
#elif defined(OS_MACOSX) && !defined(OS_IOS)
- mach_port_.reset();
+ mach_send_.reset();
+ mach_receive_.reset();
#endif
#if defined(OS_POSIX) || defined(OS_FUCHSIA)
@@ -225,7 +236,8 @@ void PlatformHandle::release() {
#elif defined(OS_FUCHSIA)
ignore_result(handle_.release());
#elif defined(OS_MACOSX) && !defined(OS_IOS)
- ignore_result(mach_port_.release());
+ ignore_result(mach_send_.release());
+ ignore_result(mach_receive_.release());
#endif
#if defined(OS_POSIX) || defined(OS_FUCHSIA)
@@ -241,8 +253,9 @@ PlatformHandle PlatformHandle::Clone() const {
return PlatformHandle(CloneHandle(handle_));
return PlatformHandle(CloneFD(fd_));
#elif defined(OS_MACOSX) && !defined(OS_IOS)
- if (is_valid_mach_port())
- return PlatformHandle(CloneMachPort(mach_port_));
+ if (is_valid_mach_send())
+ return PlatformHandle(CloneMachPort(mach_send_));
+ CHECK(!is_valid_mach_receive()) << "Cannot clone Mach receive rights";
return PlatformHandle(CloneFD(fd_));
#elif defined(OS_POSIX)
return PlatformHandle(CloneFD(fd_));
diff --git a/chromium/mojo/public/cpp/platform/platform_handle.h b/chromium/mojo/public/cpp/platform/platform_handle.h
index 22ea774f56a..a6ac190f4cc 100644
--- a/chromium/mojo/public/cpp/platform/platform_handle.h
+++ b/chromium/mojo/public/cpp/platform/platform_handle.h
@@ -47,6 +47,8 @@ class COMPONENT_EXPORT(MOJO_CPP_PLATFORM) PlatformHandle {
kHandle,
#elif defined(OS_MACOSX) && !defined(OS_IOS)
kMachPort,
+ kMachSend = kMachPort,
+ kMachReceive,
#endif
#if defined(OS_POSIX) || defined(OS_FUCHSIA)
kFd,
@@ -62,6 +64,7 @@ class COMPONENT_EXPORT(MOJO_CPP_PLATFORM) PlatformHandle {
explicit PlatformHandle(zx::handle handle);
#elif defined(OS_MACOSX) && !defined(OS_IOS)
explicit PlatformHandle(base::mac::ScopedMachSendRight mach_port);
+ explicit PlatformHandle(base::mac::ScopedMachReceiveRight mach_port);
#endif
#if defined(OS_POSIX) || defined(OS_FUCHSIA)
@@ -129,20 +132,47 @@ class COMPONENT_EXPORT(MOJO_CPP_PLATFORM) PlatformHandle {
}
#elif defined(OS_MACOSX) && !defined(OS_IOS)
bool is_valid() const { return is_valid_fd() || is_valid_mach_port(); }
- bool is_valid_mach_port() const { return mach_port_.is_valid(); }
- bool is_mach_port() const { return type_ == Type::kMachPort; }
- const base::mac::ScopedMachSendRight& GetMachPort() const {
- return mach_port_;
+ bool is_valid_mach_port() const {
+ return is_valid_mach_send() || is_valid_mach_receive();
+ }
+
+ bool is_valid_mach_send() const { return mach_send_.is_valid(); }
+ bool is_mach_send() const { return type_ == Type::kMachSend; }
+ const base::mac::ScopedMachSendRight& GetMachSendRight() const {
+ return mach_send_;
}
- base::mac::ScopedMachSendRight TakeMachPort() {
- if (type_ == Type::kMachPort)
+ base::mac::ScopedMachSendRight TakeMachSendRight() {
+ if (type_ == Type::kMachSend)
type_ = Type::kNone;
- return std::move(mach_port_);
+ return std::move(mach_send_);
}
- mach_port_t ReleaseMachPort() WARN_UNUSED_RESULT {
- if (type_ == Type::kMachPort)
+ mach_port_t ReleaseMachSendRight() WARN_UNUSED_RESULT {
+ return TakeMachSendRight().release();
+ }
+
+ bool is_valid_mach_receive() const { return mach_receive_.is_valid(); }
+ bool is_mach_receive() const { return type_ == Type::kMachReceive; }
+ const base::mac::ScopedMachReceiveRight& GetMachReceiveRight() const {
+ return mach_receive_;
+ }
+ base::mac::ScopedMachReceiveRight TakeMachReceiveRight() {
+ if (type_ == Type::kMachReceive)
type_ = Type::kNone;
- return mach_port_.release();
+ return std::move(mach_receive_);
+ }
+ mach_port_t ReleaseMachReceiveRight() WARN_UNUSED_RESULT {
+ return TakeMachReceiveRight().release();
+ }
+
+ // The following Mach port methods are deprecated. Use the ones above
+ // instead.
+ bool is_mach_port() const { return type_ == Type::kMachPort; }
+ const base::mac::ScopedMachSendRight& GetMachPort() const {
+ return GetMachSendRight();
+ }
+ base::mac::ScopedMachSendRight TakeMachPort() { return TakeMachSendRight(); }
+ mach_port_t ReleaseMachPort() WARN_UNUSED_RESULT {
+ return ReleaseMachSendRight();
}
#elif defined(OS_POSIX)
bool is_valid() const { return is_valid_fd(); }
@@ -174,7 +204,8 @@ class COMPONENT_EXPORT(MOJO_CPP_PLATFORM) PlatformHandle {
#elif defined(OS_FUCHSIA)
zx::handle handle_;
#elif defined(OS_MACOSX) && !defined(OS_IOS)
- base::mac::ScopedMachSendRight mach_port_;
+ base::mac::ScopedMachSendRight mach_send_;
+ base::mac::ScopedMachReceiveRight mach_receive_;
#endif
#if defined(OS_POSIX) || defined(OS_FUCHSIA)
diff --git a/chromium/mojo/public/cpp/platform/socket_utils_posix.cc b/chromium/mojo/public/cpp/platform/socket_utils_posix.cc
index 4bbdcb754bb..6199a36a69e 100644
--- a/chromium/mojo/public/cpp/platform/socket_utils_posix.cc
+++ b/chromium/mojo/public/cpp/platform/socket_utils_posix.cc
@@ -73,8 +73,6 @@ constexpr int kSendmsgFlags = 0;
constexpr int kSendmsgFlags = MSG_NOSIGNAL;
#endif
-constexpr size_t kMaxSendmsgHandles = 128;
-
} // namespace
ssize_t SocketWrite(base::PlatformFile socket,
@@ -107,7 +105,7 @@ ssize_t SendmsgWithHandles(base::PlatformFile socket,
DCHECK(iov);
DCHECK_GT(num_iov, 0u);
DCHECK(!descriptors.empty());
- DCHECK_LE(descriptors.size(), kMaxSendmsgHandles);
+ CHECK_LE(descriptors.size(), kMaxSendmsgHandles);
char cmsg_buf[CMSG_SPACE(kMaxSendmsgHandles * sizeof(int))];
struct msghdr msg = {};
diff --git a/chromium/mojo/public/cpp/platform/socket_utils_posix.h b/chromium/mojo/public/cpp/platform/socket_utils_posix.h
index e512f1bc807..30082484d56 100644
--- a/chromium/mojo/public/cpp/platform/socket_utils_posix.h
+++ b/chromium/mojo/public/cpp/platform/socket_utils_posix.h
@@ -18,6 +18,11 @@ struct iovec; // Declared in <sys/uio.h>
namespace mojo {
+// There is an upper bound of number of handles on what is supported across
+// various OS implementations of sendmsg(). This value was chosen because it
+// should be safe across all supported platforms.
+constexpr size_t kMaxSendmsgHandles = 128;
+
// NOTE: Functions declared here really don't belong in Mojo, but they exist to
// support code which used to rely on internal parts of the Mojo implementation
// and there wasn't a much better home for them. Consider moving them to
diff --git a/chromium/mojo/public/cpp/system/BUILD.gn b/chromium/mojo/public/cpp/system/BUILD.gn
index 07fc688f41e..01b62788fbe 100644
--- a/chromium/mojo/public/cpp/system/BUILD.gn
+++ b/chromium/mojo/public/cpp/system/BUILD.gn
@@ -26,6 +26,7 @@ component("system") {
"buffer.cc",
"buffer.h",
"core.h",
+ "data_pipe.cc",
"data_pipe.h",
"data_pipe_drainer.cc",
"data_pipe_drainer.h",
diff --git a/chromium/mojo/public/cpp/system/README.md b/chromium/mojo/public/cpp/system/README.md
index abc722ce9ad..60ef3f7a356 100644
--- a/chromium/mojo/public/cpp/system/README.md
+++ b/chromium/mojo/public/cpp/system/README.md
@@ -367,9 +367,7 @@ wait_set.AddHandle(b.handle0.get(), MOJO_HANDLE_SIGNAL_READABLE);
wait_set.AddEvent(&timeout_event);
// Ensure the Wait() lasts no more than 5 seconds.
-bg_thread->task_runner()->PostDelayedTask(
- FROM_HERE,
- base::Bind([](base::WaitableEvent* e) { e->Signal(); }, &timeout_event);
+bg_thread->task_runner()->PostDelayedTask(FROM_HERE, base::BindOnce([](base::WaitableEvent* e) { e->Signal(); }, &timeout_event);
base::TimeDelta::FromSeconds(5));
base::WaitableEvent* ready_event = nullptr;
diff --git a/chromium/mojo/public/cpp/system/data_pipe.cc b/chromium/mojo/public/cpp/system/data_pipe.cc
new file mode 100644
index 00000000000..8fe5ed7c88b
--- /dev/null
+++ b/chromium/mojo/public/cpp/system/data_pipe.cc
@@ -0,0 +1,54 @@
+// Copyright 2019 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 "mojo/public/cpp/system/data_pipe.h"
+
+namespace mojo {
+
+namespace {
+
+NOINLINE void CrashMojoResourceExhausted() {
+ LOG(FATAL)
+ << "Failed to create data pipe due to MOJO_RESULT_RESOURCE_EXHAUSTED.";
+}
+
+void CrashIfResultNotOk(MojoResult result) {
+ if (LIKELY(result == MOJO_RESULT_OK))
+ return;
+
+ // Include some extra information for resource exhausted failures.
+ if (result == MOJO_RESULT_RESOURCE_EXHAUSTED)
+ CrashMojoResourceExhausted();
+
+ LOG(FATAL) << "Failed to create data pipe; result=" << result;
+}
+
+} // namespace
+
+DataPipe::DataPipe() {
+ MojoResult result =
+ CreateDataPipe(nullptr, &producer_handle, &consumer_handle);
+ CrashIfResultNotOk(result);
+}
+
+DataPipe::DataPipe(uint32_t capacity_num_bytes) {
+ MojoCreateDataPipeOptions options;
+ options.struct_size = sizeof(MojoCreateDataPipeOptions);
+ options.flags = MOJO_CREATE_DATA_PIPE_FLAG_NONE;
+ options.element_num_bytes = 1;
+ options.capacity_num_bytes = capacity_num_bytes;
+ MojoResult result =
+ CreateDataPipe(&options, &producer_handle, &consumer_handle);
+ CrashIfResultNotOk(result);
+}
+
+DataPipe::DataPipe(const MojoCreateDataPipeOptions& options) {
+ MojoResult result =
+ CreateDataPipe(&options, &producer_handle, &consumer_handle);
+ CrashIfResultNotOk(result);
+}
+
+DataPipe::~DataPipe() {}
+
+} // namespace mojo
diff --git a/chromium/mojo/public/cpp/system/data_pipe.h b/chromium/mojo/public/cpp/system/data_pipe.h
index c810ed490a2..205af858aee 100644
--- a/chromium/mojo/public/cpp/system/data_pipe.h
+++ b/chromium/mojo/public/cpp/system/data_pipe.h
@@ -141,7 +141,7 @@ inline MojoResult CreateDataPipe(
// TODO(vtl): Make an even more friendly version? (Maybe templatized for a
// particular type instead of some "element"? Maybe functions that take
// vectors?)
-class DataPipe {
+class MOJO_CPP_SYSTEM_EXPORT DataPipe {
public:
DataPipe();
explicit DataPipe(uint32_t capacity_num_bytes);
@@ -152,32 +152,6 @@ class DataPipe {
ScopedDataPipeConsumerHandle consumer_handle;
};
-inline DataPipe::DataPipe() {
- MojoResult result =
- CreateDataPipe(nullptr, &producer_handle, &consumer_handle);
- CHECK_EQ(MOJO_RESULT_OK, result);
-}
-
-inline DataPipe::DataPipe(uint32_t capacity_num_bytes) {
- MojoCreateDataPipeOptions options;
- options.struct_size = sizeof(MojoCreateDataPipeOptions);
- options.flags = MOJO_CREATE_DATA_PIPE_FLAG_NONE;
- options.element_num_bytes = 1;
- options.capacity_num_bytes = capacity_num_bytes;
- MojoResult result =
- CreateDataPipe(&options, &producer_handle, &consumer_handle);
- CHECK_EQ(MOJO_RESULT_OK, result);
-}
-
-inline DataPipe::DataPipe(const MojoCreateDataPipeOptions& options) {
- MojoResult result =
- CreateDataPipe(&options, &producer_handle, &consumer_handle);
- CHECK_EQ(MOJO_RESULT_OK, result);
-}
-
-inline DataPipe::~DataPipe() {
-}
-
} // namespace mojo
#endif // MOJO_PUBLIC_CPP_SYSTEM_DATA_PIPE_H_
diff --git a/chromium/mojo/public/cpp/system/handle_signal_tracker.cc b/chromium/mojo/public/cpp/system/handle_signal_tracker.cc
index 85672ca7f6e..53fe5d70e0d 100644
--- a/chromium/mojo/public/cpp/system/handle_signal_tracker.cc
+++ b/chromium/mojo/public/cpp/system/handle_signal_tracker.cc
@@ -4,6 +4,7 @@
#include "mojo/public/cpp/system/handle_signal_tracker.h"
+#include "base/bind.h"
#include "base/synchronization/lock.h"
#include "mojo/public/cpp/system/handle_signals_state.h"
diff --git a/chromium/mojo/public/cpp/system/simple_watcher.cc b/chromium/mojo/public/cpp/system/simple_watcher.cc
index c692de32ce3..5905b02c247 100644
--- a/chromium/mojo/public/cpp/system/simple_watcher.cc
+++ b/chromium/mojo/public/cpp/system/simple_watcher.cc
@@ -11,6 +11,7 @@
#include "base/synchronization/lock.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/trace_event/heap_profiler.h"
+#include "base/trace_event/trace_event.h"
#include "mojo/public/c/system/trap.h"
namespace mojo {
@@ -117,8 +118,8 @@ class SimpleWatcher::Context : public base::RefCountedThreadSafe<Context> {
weak_watcher_->OnHandleReady(watch_id_, result, state);
} else {
task_runner_->PostTask(
- FROM_HERE, base::Bind(&SimpleWatcher::OnHandleReady, weak_watcher_,
- watch_id_, result, state));
+ FROM_HERE, base::BindOnce(&SimpleWatcher::OnHandleReady,
+ weak_watcher_, watch_id_, result, state));
}
}
@@ -257,8 +258,8 @@ void SimpleWatcher::ArmOrNotify() {
DCHECK_EQ(MOJO_RESULT_FAILED_PRECONDITION, rv);
task_runner_->PostTask(
FROM_HERE,
- base::Bind(&SimpleWatcher::OnHandleReady, weak_factory_.GetWeakPtr(),
- watch_id_, ready_result, ready_state));
+ base::BindOnce(&SimpleWatcher::OnHandleReady, weak_factory_.GetWeakPtr(),
+ watch_id_, ready_result, ready_state));
}
void SimpleWatcher::OnHandleReady(int watch_id,
@@ -283,6 +284,10 @@ void SimpleWatcher::OnHandleReady(int watch_id,
// NOTE: It's legal for |callback| to delete |this|.
if (!callback.is_null()) {
TRACE_HEAP_PROFILER_API_SCOPED_TASK_EXECUTION event(heap_profiler_tag_);
+ // Lot of janks caused are grouped to OnHandleReady tasks. This trace event helps identify the
+ // cause of janks. It is ok to pass |heap_profiler_tag_| here since it is a string literal.
+ // TODO(927206): Consider renaming |heap_profiler_tag_|.
+ TRACE_EVENT0("toplevel", heap_profiler_tag_);
base::WeakPtr<SimpleWatcher> weak_self = weak_factory_.GetWeakPtr();
callback.Run(result, state);
diff --git a/chromium/mojo/public/cpp/test_support/lib/test_utils.cc b/chromium/mojo/public/cpp/test_support/lib/test_utils.cc
index 10a899e33bd..99e7f708bf2 100644
--- a/chromium/mojo/public/cpp/test_support/lib/test_utils.cc
+++ b/chromium/mojo/public/cpp/test_support/lib/test_utils.cc
@@ -9,6 +9,7 @@
#include <vector>
+#include "base/bind.h"
#include "mojo/core/embedder/embedder.h"
#include "mojo/public/cpp/system/core.h"
#include "mojo/public/cpp/system/wait.h"
diff --git a/chromium/mojo/public/cpp/test_support/test_utils.h b/chromium/mojo/public/cpp/test_support/test_utils.h
index 54651c5d41e..790df113b89 100644
--- a/chromium/mojo/public/cpp/test_support/test_utils.h
+++ b/chromium/mojo/public/cpp/test_support/test_utils.h
@@ -64,6 +64,9 @@ class BadMessageObserver {
// Waits for the bad message and returns the error string.
std::string WaitForBadMessage();
+ // Returns true iff a bad message was already received.
+ bool got_bad_message() const { return got_bad_message_; }
+
private:
void OnReportBadMessage(const std::string& message);
diff --git a/chromium/mojo/public/interfaces/bindings/native_struct.mojom b/chromium/mojo/public/interfaces/bindings/native_struct.mojom
index f2e869cf620..c6a285293c3 100644
--- a/chromium/mojo/public/interfaces/bindings/native_struct.mojom
+++ b/chromium/mojo/public/interfaces/bindings/native_struct.mojom
@@ -5,18 +5,17 @@
[JavaPackage="org.chromium.mojo.native_types"]
module mojo.native;
+enum SerializedHandleType {
+ MOJO_HANDLE,
+ PLATFORM_FILE,
+ WIN_HANDLE,
+ MACH_PORT,
+ FUCHSIA_HANDLE,
+};
+
struct SerializedHandle {
handle the_handle;
-
- enum Type {
- MOJO_HANDLE,
- PLATFORM_FILE,
- WIN_HANDLE,
- MACH_PORT,
- FUCHSIA_HANDLE,
- };
-
- Type type;
+ SerializedHandleType type;
};
[CustomSerializer]
diff --git a/chromium/mojo/public/interfaces/bindings/tests/BUILD.gn b/chromium/mojo/public/interfaces/bindings/tests/BUILD.gn
index 0cfecb841c9..1309315189b 100644
--- a/chromium/mojo/public/interfaces/bindings/tests/BUILD.gn
+++ b/chromium/mojo/public/interfaces/bindings/tests/BUILD.gn
@@ -484,3 +484,26 @@ mojom("echo") {
"echo_import/echo_import.mojom",
]
}
+
+# These could probably be merged with "test_interfaces" at some point.
+mojom("other_test_interfaces") {
+ testonly = true
+ sources = [
+ "new_endpoint_types.test-mojom",
+ ]
+}
+
+# Ensure that some target forces JS and Java bindings generation when all
+# targets are built. This provides a basic generation smoke test for new
+# endpoint types in mojom.
+group("test_generation") {
+ testonly = true
+ deps = [
+ ":other_test_interfaces",
+ ":other_test_interfaces_js",
+ ]
+
+ if (is_android) {
+ deps += [ ":other_test_interfaces_java" ]
+ }
+}
diff --git a/chromium/mojo/public/js/BUILD.gn b/chromium/mojo/public/js/BUILD.gn
index 6a607c046f4..b27019dde25 100644
--- a/chromium/mojo/public/js/BUILD.gn
+++ b/chromium/mojo/public/js/BUILD.gn
@@ -60,14 +60,14 @@ bindings_lite_sources = [
bindings_lite_compiled_file = "$target_gen_dir/mojo_bindings_lite.js"
-if (enable_mojom_closure_compile) {
- js_library("bindings_lite_sources") {
- sources = [ "compile_preamble.js" ] + bindings_lite_sources
- deps = [
- "//mojo/public/interfaces/bindings:bindings_js_library_for_compile",
- ]
- }
+js_library("bindings_lite_sources") {
+ sources = [ "compile_preamble.js" ] + bindings_lite_sources
+ deps = [
+ "//mojo/public/interfaces/bindings:bindings_js_library_for_compile",
+ ]
+}
+if (enable_mojom_closure_compile || closure_compile) {
js_binary("bindings_lite") {
outputs = [
bindings_lite_compiled_file,
diff --git a/chromium/mojo/public/js/bindings_lite.js b/chromium/mojo/public/js/bindings_lite.js
index 0ffa69adad1..c7fd65834b2 100644
--- a/chromium/mojo/public/js/bindings_lite.js
+++ b/chromium/mojo/public/js/bindings_lite.js
@@ -400,13 +400,11 @@ mojo.internal.Encoder = class {
}
encodeString(offset, value) {
- if (!mojo.internal.Message.textEncoder)
- mojo.internal.Message.textEncoder = new TextEncoder('utf-8');
if (typeof value !== 'string')
throw new Error('Unxpected non-string value for string field.');
this.encodeArray(
{elementType: mojo.internal.Uint8}, offset,
- mojo.internal.Message.textEncoder.encode(value));
+ mojo.internal.Encoder.stringToUtf8Bytes(value));
}
encodeOffset(offset, absoluteOffset) {
@@ -556,10 +554,20 @@ mojo.internal.Encoder = class {
field['type'].$.encode(
value[tag], unionEncoder, offset + 8, 0, field['nullable']);
}
+
+ /**
+ * @param {string} value
+ * @return {!Uint8Array}
+ */
+ static stringToUtf8Bytes(value) {
+ if (!mojo.internal.Encoder.textEncoder)
+ mojo.internal.Encoder.textEncoder = new TextEncoder('utf-8');
+ return mojo.internal.Encoder.textEncoder.encode(value);
+ }
};
/** @type {TextEncoder} */
-mojo.internal.Message.textEncoder = null;
+mojo.internal.Encoder.textEncoder = null;
/**
* Helps decode incoming messages. Decoders may be created recursively to
@@ -1161,7 +1169,8 @@ mojo.internal.String = {
},
computePayloadSize: function(value, nullable) {
return mojo.internal.computeTotalArraySize(
- {elementType: mojo.internal.Uint8}, value);
+ {elementType: mojo.internal.Uint8},
+ mojo.internal.Encoder.stringToUtf8Bytes(value));
},
arrayElementSize: nullable => 8,
isValidObjectKeyType: true,
diff --git a/chromium/mojo/public/js/interface_support.js b/chromium/mojo/public/js/interface_support.js
index fcb4662b010..9e36eb1fbb0 100644
--- a/chromium/mojo/public/js/interface_support.js
+++ b/chromium/mojo/public/js/interface_support.js
@@ -3,7 +3,8 @@
// found in the LICENSE file.
'use strict';
-goog.require('mojo.interfaceControl');
+goog.require('mojo.interfaceControl.kRunMessageId');
+goog.require('mojo.interfaceControl.RunResponseMessageParamsSpec');
goog.require('mojo.internal');
goog.provide('mojo.internal.interfaceSupport');
@@ -27,7 +28,7 @@ mojo.internal.interfaceSupport.ControlMessageHandler = class {
mojo.internal.serializeAndSendMessage(
this.handle_, mojo.interfaceControl.kRunMessageId, requestId,
mojo.internal.kMessageFlagExpectsResponse,
- mojo.interfaceControl.RunMessageParams.$, {'input': input});
+ mojo.interfaceControl.RunMessageParamsSpec.$, {'input': input});
this.pendingFlushResolvers_.set(requestId, resolve);
});
}
@@ -47,12 +48,13 @@ mojo.internal.interfaceSupport.ControlMessageHandler = class {
handleRunRequest_(requestId, decoder) {
const input = decoder.decodeStructInline(
- mojo.interfaceControl.RunMessageParams.$.$.structSpec)['input'];
+ mojo.interfaceControl.RunMessageParamsSpec.$.$.structSpec)['input'];
if (input.hasOwnProperty('flushForTesting')) {
mojo.internal.serializeAndSendMessage(
this.handle_, mojo.interfaceControl.kRunMessageId, requestId,
mojo.internal.kMessageFlagIsResponse,
- mojo.interfaceControl.RunResponseMessageParams.$, {'output': null});
+ mojo.interfaceControl.RunResponseMessageParamsSpec.$,
+ {'output': null});
return true;
}
@@ -151,19 +153,24 @@ mojo.internal.interfaceSupport.ConnectionErrorEventRouter = class {
* Generic helper used to implement all generated proxy classes. Knows how to
* serialize requests and deserialize their replies, both according to
* declarative message structure specs.
+ * @template T
* @export
*/
mojo.internal.interfaceSupport.InterfaceProxyBase = class {
/**
+ * @param {!function(new:T, !MojoHandle)} requestType
* @param {MojoHandle=} opt_handle The message pipe handle to use as a proxy
* endpoint. If null, this object must be bound with bindHandle before
* it can be used to send any messages.
* @public
*/
- constructor(opt_handle) {
+ constructor(requestType, opt_handle) {
/** @public {?MojoHandle} */
this.handle = null;
+ /** @private {!function(new:T, !MojoHandle)} */
+ this.requestType_ = requestType;
+
/** @private {?mojo.internal.interfaceSupport.HandleReader} */
this.reader_ = null;
@@ -187,6 +194,15 @@ mojo.internal.interfaceSupport.InterfaceProxyBase = class {
}
/**
+ * @return {!T}
+ */
+ createRequest() {
+ let {handle0, handle1} = Mojo.createMessagePipe();
+ this.bindHandle(handle0);
+ return new this.requestType_(handle1);
+ }
+
+ /**
* @param {!MojoHandle} handle
* @export
*/
@@ -213,6 +229,11 @@ mojo.internal.interfaceSupport.InterfaceProxyBase = class {
this.reader_.stop();
}
+ /** @export */
+ close() {
+ this.cleanupAndFlushPendingResponses_('Message pipe closed.');
+ }
+
/**
* @return {!mojo.internal.interfaceSupport.ConnectionErrorEventRouter}
* @export
@@ -232,12 +253,12 @@ mojo.internal.interfaceSupport.InterfaceProxyBase = class {
sendMessage(ordinal, paramStruct, responseStruct, args) {
if (!this.handle) {
throw new Error(
- 'Attempting to use an unbound proxy. Try createRequest() first.')
+ 'Attempting to use an unbound proxy. Try $.createRequest() first.')
}
// The pipe has already been closed, so just drop the message.
if (!this.reader_ || this.reader_.isStopped())
- return Promise.reject();
+ return Promise.reject(new Error('The pipe has already been closed.'));
const requestId = this.nextRequestId_++;
const value = {};
@@ -305,16 +326,63 @@ mojo.internal.interfaceSupport.InterfaceProxyBase = class {
* @private
*/
onError_(opt_reason) {
+ this.cleanupAndFlushPendingResponses_(opt_reason);
+ this.connectionErrorEventRouter_.dispatchErrorEvent();
+ }
+
+ /**
+ * @param {string=} opt_reason
+ * @private
+ */
+ cleanupAndFlushPendingResponses_(opt_reason) {
this.reader_.stopAndCloseHandle();
this.reader_ = null;
for (const id of this.pendingResponses_.keys())
this.pendingResponses_.get(id).reject(new Error(opt_reason));
this.pendingResponses_ = new Map;
- this.connectionErrorEventRouter_.dispatchErrorEvent();
}
};
/**
+ * Wrapper around mojo.internal.interfaceSupport.InterfaceProxyBase that
+ * exposes the subset of InterfaceProxyBase's method that users are allowed
+ * to use.
+ * @template T
+ * @export
+ */
+mojo.internal.interfaceSupport.InterfaceProxyBaseWrapper = class {
+ /**
+ * @param {!mojo.internal.interfaceSupport.InterfaceProxyBase<T>} proxy
+ * @public
+ */
+ constructor(proxy) {
+ /** @private {!mojo.internal.interfaceSupport.InterfaceProxyBase<T>} */
+ this.proxy_ = proxy;
+ }
+
+ /**
+ * @return {!T}
+ * @export
+ */
+ createRequest() {
+ return this.proxy_.createRequest();
+ }
+
+ /** @export */
+ close() {
+ this.proxy_.close();
+ }
+
+ /**
+ * @return {!Promise}
+ * @export
+ */
+ flushForTesting() {
+ return this.proxy_.flushForTesting();
+ }
+}
+
+/**
* Helper used by generated EventRouter types to dispatch incoming interface
* messages as Event-like things.
* @export
diff --git a/chromium/mojo/public/js/lib/codec.js b/chromium/mojo/public/js/lib/codec.js
index 2bb7b8ae47c..85f7047812d 100644
--- a/chromium/mojo/public/js/lib/codec.js
+++ b/chromium/mojo/public/js/lib/codec.js
@@ -349,7 +349,7 @@
if (cls === PackedBool) {
var byte = 0;
- for (i = 0; i < numberOfElements; ++i) {
+ for (let i = 0; i < numberOfElements; ++i) {
if (val[i])
byte |= (1 << i % 8);
if (i % 8 === 7 || i == numberOfElements - 1) {
diff --git a/chromium/mojo/public/js/lib/control_message_proxy.js b/chromium/mojo/public/js/lib/control_message_proxy.js
index c8447cded15..1993aefef28 100644
--- a/chromium/mojo/public/js/lib/control_message_proxy.js
+++ b/chromium/mojo/public/js/lib/control_message_proxy.js
@@ -54,7 +54,7 @@
* Accepts the response message from the receiver and decodes the message
* struct to RunResponseMessageParams.
*
- * @param {Router} receiver.
+ * @param {Router} receiver
* @param {RunMessageParams} runMessageParams to be sent via a message.
* @return {Promise} that resolves to a RunResponseMessageParams.
*/
diff --git a/chromium/mojo/public/js/mojo_bindings_resources.grd b/chromium/mojo/public/js/mojo_bindings_resources.grd
index 57f2a9bdf75..deddde08110 100644
--- a/chromium/mojo/public/js/mojo_bindings_resources.grd
+++ b/chromium/mojo/public/js/mojo_bindings_resources.grd
@@ -23,9 +23,24 @@
use_base_dir="false"
type="BINDATA"
compress="gzip" />
+ <include name="IDR_MOJO_BIG_BUFFER_MOJOM_LITE_JS"
+ file="${root_gen_dir}/mojo/public/mojom/base/big_buffer.mojom-lite.js"
+ use_base_dir="false"
+ type="BINDATA"
+ compress="gzip" />
+ <include name="IDR_MOJO_FILE_MOJOM_LITE_JS"
+ file="${root_gen_dir}/mojo/public/mojom/base/file.mojom-lite.js"
+ use_base_dir="false"
+ type="BINDATA"
+ compress="gzip" />
+ <include name="IDR_MOJO_STRING16_MOJOM_LITE_JS"
+ file="${root_gen_dir}/mojo/public/mojom/base/string16.mojom-lite.js"
+ use_base_dir="false"
+ type="BINDATA"
+ compress="gzip" />
<if expr="is_win or is_macosx or is_linux">
- <include name="IDR_MOJO_TIME_MOJOM_JS"
- file="${root_gen_dir}/mojo/public/mojom/base/time.mojom.js"
+ <include name="IDR_MOJO_TIME_MOJOM_LITE_JS"
+ file="${root_gen_dir}/mojo/public/mojom/base/time.mojom-lite.js"
use_base_dir="false"
type="BINDATA"
compress="gzip" />
diff --git a/chromium/mojo/public/tools/bindings/BUILD.gn b/chromium/mojo/public/tools/bindings/BUILD.gn
index de558a617fa..c0a5b6fbd60 100644
--- a/chromium/mojo/public/tools/bindings/BUILD.gn
+++ b/chromium/mojo/public/tools/bindings/BUILD.gn
@@ -17,6 +17,9 @@ action("precompile_templates") {
"$mojom_generator_root/generators/cpp_templates/interface_request_validator_declaration.tmpl",
"$mojom_generator_root/generators/cpp_templates/interface_response_validator_declaration.tmpl",
"$mojom_generator_root/generators/cpp_templates/interface_stub_declaration.tmpl",
+ "$mojom_generator_root/generators/cpp_templates/module-forward.h.tmpl",
+ "$mojom_generator_root/generators/cpp_templates/module-import-headers.h.tmpl",
+ "$mojom_generator_root/generators/cpp_templates/module-params-data.h.tmpl",
"$mojom_generator_root/generators/cpp_templates/module-shared-internal.h.tmpl",
"$mojom_generator_root/generators/cpp_templates/module-shared-message-ids.h.tmpl",
"$mojom_generator_root/generators/cpp_templates/module-shared.cc.tmpl",
@@ -67,14 +70,10 @@ action("precompile_templates") {
"$mojom_generator_root/generators/js_templates/interface_definition.tmpl",
"$mojom_generator_root/generators/js_templates/lite/enum_definition.tmpl",
"$mojom_generator_root/generators/js_templates/lite/interface_definition.tmpl",
- "$mojom_generator_root/generators/js_templates/lite/interface_externs.tmpl",
- "$mojom_generator_root/generators/js_templates/lite/module.externs.tmpl",
"$mojom_generator_root/generators/js_templates/lite/module_definition.tmpl",
"$mojom_generator_root/generators/js_templates/lite/mojom-lite.js.tmpl",
"$mojom_generator_root/generators/js_templates/lite/struct_definition.tmpl",
- "$mojom_generator_root/generators/js_templates/lite/struct_externs.tmpl",
"$mojom_generator_root/generators/js_templates/lite/union_definition.tmpl",
- "$mojom_generator_root/generators/js_templates/lite/union_externs.tmpl",
"$mojom_generator_root/generators/js_templates/module.amd.tmpl",
"$mojom_generator_root/generators/js_templates/module_definition.tmpl",
"$mojom_generator_root/generators/js_templates/struct_definition.tmpl",
diff --git a/chromium/mojo/public/tools/bindings/README.md b/chromium/mojo/public/tools/bindings/README.md
index 76c6f321ee6..29694594715 100644
--- a/chromium/mojo/public/tools/bindings/README.md
+++ b/chromium/mojo/public/tools/bindings/README.md
@@ -1,18 +1,18 @@
-# Mojom IDL and Bindings Generator
+# Mojom Interface Definition Language (IDL)
This document is a subset of the [Mojo documentation](/mojo/README.md).
[TOC]
## Overview
-Mojom is the IDL for Mojo bindings interfaces. Given a `.mojom` file, the
+Mojom is the IDL for Mojo interfaces. Given a `.mojom` file, the
[bindings
-generator](https://cs.chromium.org/chromium/src/mojo/public/tools/bindings/)
-outputs bindings for all supported languages: **C++**, **JavaScript**, and
+generator](https://cs.chromium.org/chromium/src/mojo/public/tools/bindings/) can
+output bindings for any supported language: **C++**, **JavaScript**, or
**Java**.
For a trivial example consider the following hypothetical Mojom file we write to
-`//services/widget/public/interfaces/frobinator.mojom`:
+`//services/widget/public/mojom/frobinator.mojom`:
```
module widget.mojom;
@@ -25,15 +25,15 @@ interface Frobinator {
This defines a single [interface](#Interfaces) named `Frobinator` in a
[module](#Modules) named `widget.mojom` (and thus fully qualified in Mojom as
`widget.mojom.Frobinator`.) Note that many interfaces and/or other types of
-definitions may be included in a single Mojom file.
+definitions (structs, enums, *etc.*) may be included in a single Mojom file.
If we add a corresponding GN target to
-`//services/widget/public/interfaces/BUILD.gn`:
+`//services/widget/public/mojom/BUILD.gn`:
```
import("mojo/public/tools/bindings/mojom.gni")
-mojom("interfaces") {
+mojom("mojom") {
sources = [
"frobinator.mojom",
]
@@ -43,22 +43,32 @@ mojom("interfaces") {
and then build this target:
```
-ninja -C out/r services/widget/public/interfaces
+ninja -C out/r services/widget/public/mojom
```
we'll find several generated sources in our output directory:
```
-out/r/gen/services/widget/public/interfaces/frobinator.mojom.cc
-out/r/gen/services/widget/public/interfaces/frobinator.mojom.h
-out/r/gen/services/widget/public/interfaces/frobinator.mojom.js
-out/r/gen/services/widget/public/interfaces/frobinator.mojom.srcjar
-...
+out/r/gen/services/widget/public/mojom/frobinator.mojom.cc
+out/r/gen/services/widget/public/mojom/frobinator.mojom.h
+out/r/gen/services/widget/public/mojom/frobinator.mojom-shared.h
+etc...
```
Each of these generated source modules includes a set of definitions
-representing the Mojom contents within the target language. For more details
-regarding the generated outputs please see
+representing the Mojom contents in C++. You can also build or depend on suffixed
+target names to get bindings for other languages. For example,
+
+```
+ninja -C out/r services/widget/public/mojom:mojom_js
+ninja -C out/r services/widget/public/mojom:mojom_java
+```
+
+would generate JavaScript and Java bindings respectively, in the same generated
+output directory.
+
+For more details regarding the generated
+outputs please see
[documentation for individual target languages](#Generated-Code-For-Target-Languages).
## Mojom Syntax
@@ -136,7 +146,7 @@ If your Mojom references definitions from other Mojom files, you must **import**
those files. Import syntax is as follows:
```
-import "services/widget/public/interfaces/frobinator.mojom";
+import "services/widget/public/mojom/frobinator.mojom";
```
Import paths are always relative to the top-level directory.
@@ -386,8 +396,9 @@ interesting attributes supported today.
: The `Native` attribute may be specified for an empty struct declaration to
provide a nominal bridge between Mojo IPC and legacy `IPC::ParamTraits` or
`IPC_STRUCT_TRAITS*` macros.
- See [Using Legacy IPC Traits](/ipc/README.md#Using-Legacy-IPC-Traits) for
- more details. Note support for this attribute is strictly limited to C++
+ See
+ [Repurposing Legacy IPC Traits](/docs/mojo_ipc_conversion.md#repurposing-and-invocations)
+ for more details. Note support for this attribute is strictly limited to C++
bindings generation.
**`[MinVersion=N]`**
@@ -493,7 +504,7 @@ relative ordering guarantees among them. Associated interfaces are useful when
one interface needs to guarantee strict FIFO ordering with respect to one or
more other interfaces, as they allow interfaces to share a single pipe.
-Currenly associated interfaces are only supported in generated C++ bindings.
+Currently associated interfaces are only supported in generated C++ bindings.
See the documentation for
[C++ Associated Interfaces](/mojo/public/cpp/bindings/README.md#Associated-Interfaces).
@@ -688,7 +699,7 @@ ModuleStatement = AttributeSection "module" Identifier ";"
ImportStatement = "import" StringLiteral ";"
Definition = Struct Union Interface Enum Const
-AttributeSection = "[" AttributeList "]"
+AttributeSection = <empty> | "[" AttributeList "]"
AttributeList = <empty> | NonEmptyAttributeList
NonEmptyAttributeList = Attribute
| Attribute "," NonEmptyAttributeList
@@ -702,7 +713,7 @@ StructBody = <empty>
| StructBody Const
| StructBody Enum
| StructBody StructField
-StructField = AttributeSection TypeSpec Name Orginal Default ";"
+StructField = AttributeSection TypeSpec Name Ordinal Default ";"
Union = AttributeSection "union" Name "{" UnionBody "}" ";"
UnionBody = <empty> | UnionBody UnionField
diff --git a/chromium/mojo/public/tools/bindings/chromium_bindings_configuration.gni b/chromium/mojo/public/tools/bindings/chromium_bindings_configuration.gni
index 00a4b1e4adc..6cd039ea3c8 100644
--- a/chromium/mojo/public/tools/bindings/chromium_bindings_configuration.gni
+++ b/chromium/mojo/public/tools/bindings/chromium_bindings_configuration.gni
@@ -8,7 +8,7 @@ _typemap_imports = [
"//chrome/common/importer/typemaps.gni",
"//chrome/common/media_router/mojo/typemaps.gni",
"//chrome/typemaps.gni",
- "//chromecast/common/mojom/typemaps.gni",
+ "//chromecast/typemaps.gni",
"//chromeos/typemaps.gni",
"//chromeos/components/multidevice/mojom/typemaps.gni",
"//chromeos/services/secure_channel/public/mojom/typemaps.gni",
@@ -38,6 +38,7 @@ _typemap_imports = [
"//services/proxy_resolver/public/cpp/typemaps.gni",
"//services/resource_coordinator/public/cpp/typemaps.gni",
"//services/service_manager/public/cpp/typemaps.gni",
+ "//services/tracing/public/mojom/typemaps.gni",
"//services/ws/public/mojom/ime/typemaps.gni",
"//services/viz/privileged/cpp/typemaps.gni",
"//services/viz/privileged/interfaces/compositing/typemaps.gni",
diff --git a/chromium/mojo/public/tools/bindings/generators/cpp_templates/enum_macros.tmpl b/chromium/mojo/public/tools/bindings/generators/cpp_templates/enum_macros.tmpl
index f783cabfbdb..f353ac79a08 100644
--- a/chromium/mojo/public/tools/bindings/generators/cpp_templates/enum_macros.tmpl
+++ b/chromium/mojo/public/tools/bindings/generators/cpp_templates/enum_macros.tmpl
@@ -2,8 +2,14 @@
Macro for enum definition, and the declaration of associated functions.
---#}
+{%- macro enum_forward(enum) %}
+{%- set enum_name = enum|get_name_for_kind(flatten_nested_kind=True) %}
+enum class {{enum_name}} : int32_t;
+{%- endmacro %}
+
{%- macro enum_decl(enum, export_attribute) %}
{%- set enum_name = enum|get_name_for_kind(flatten_nested_kind=True) %}
+
enum class {{enum_name}} : int32_t {
{%- for field in enum.fields %}
{%- if field.value %}
@@ -116,11 +122,6 @@ struct {{hash_fn_name}} {
};
template <>
-struct DefaultHash<{{enum_name}}> {
- using Hash = {{hash_fn_name}};
-};
-
-template <>
struct HashTraits<{{enum_name}}>
: public GenericHashTraits<{{enum_name}}> {
static_assert({{empty_value_unused}},
@@ -140,3 +141,17 @@ struct HashTraits<{{enum_name}}>
};
} // namespace WTF
{%- endmacro %}
+
+{%- macro enum_hash_blink_forward(enum) %}
+{%- set enum_name = enum|get_qualified_name_for_kind(
+ flatten_nested_kind=True, include_variant=False) %}
+{%- set hash_fn_name = enum|wtf_hash_fn_name_for_enum %}
+namespace WTF {
+struct {{hash_fn_name}};
+
+template <>
+struct DefaultHash<{{enum_name}}> {
+ using Hash = {{hash_fn_name}};
+};
+} // namespace WTF
+{%- endmacro %}
diff --git a/chromium/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl b/chromium/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl
index 12e67cbe0fc..b60b926045f 100644
--- a/chromium/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl
+++ b/chromium/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl
@@ -31,7 +31,7 @@ std::move(p_{{param.name}})
{%- endmacro %}
{#--- Begin #}
-const char {{class_name}}::Name_[] = "{{namespace}}.{{class_name}}";
+const char {{class_name}}::Name_[] = "{{module_namespace}}.{{class_name}}";
{#--- Constants #}
{%- for constant in interface.constants %}
diff --git a/chromium/mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl b/chromium/mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl
index 687eea8409d..42d4ad1270f 100644
--- a/chromium/mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl
+++ b/chromium/mojo/public/tools/bindings/generators/cpp_templates/interface_proxy_declaration.tmpl
@@ -2,6 +2,8 @@
class {{export_attribute}} {{interface.name}}Proxy
: public {{interface.name}} {
public:
+ using InterfaceType = {{interface.name}};
+
explicit {{interface.name}}Proxy(mojo::MessageReceiverWithResponder* receiver);
{%- for method in interface.methods %}
diff --git a/chromium/mojo/public/tools/bindings/generators/cpp_templates/module-forward.h.tmpl b/chromium/mojo/public/tools/bindings/generators/cpp_templates/module-forward.h.tmpl
new file mode 100644
index 00000000000..a14d5112656
--- /dev/null
+++ b/chromium/mojo/public/tools/bindings/generators/cpp_templates/module-forward.h.tmpl
@@ -0,0 +1,195 @@
+// Copyright 2019 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.
+
+{%- if variant -%}
+{%- set variant_path = "%s-%s"|format(module.path, variant) -%}
+{%- else -%}
+{%- set variant_path = module.path -%}
+{%- endif -%}
+
+{%- set header_guard = "%s_FORWARD_H_"|format(
+ variant_path|upper|replace("/","_")|replace(".","_")|
+ replace("-", "_")) %}
+
+{%- macro namespace_begin() %}
+{%- for namespace in namespaces_as_array %}
+namespace {{namespace}} {
+{%- endfor %}
+{%- if variant %}
+namespace {{variant}} {
+{%- endif %}
+{%- endmacro %}
+
+{%- macro namespace_end() %}
+{%- if variant %}
+} // namespace {{variant}}
+{%- endif %}
+{%- for namespace in namespaces_as_array|reverse %}
+} // namespace {{namespace}}
+{%- endfor %}
+{%- endmacro %}
+
+#ifndef {{header_guard}}
+#define {{header_guard}}
+
+#include "mojo/public/cpp/bindings/struct_ptr.h"
+
+{% if not disallow_interfaces -%}
+#include "mojo/public/cpp/bindings/associated_interface_ptr.h"
+#include "mojo/public/cpp/bindings/associated_interface_ptr_info.h"
+#include "mojo/public/cpp/bindings/associated_interface_request.h"
+#include "mojo/public/cpp/bindings/interface_ptr.h"
+#include "mojo/public/cpp/bindings/interface_request.h"
+#include "mojo/public/cpp/bindings/lib/control_message_handler.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
+#include "mojo/public/cpp/bindings/raw_ptr_impl_ref_traits.h"
+#include "mojo/public/cpp/bindings/thread_safe_interface_ptr.h"
+{%- if for_blink %}
+#include "third_party/blink/renderer/platform/mojo/revocable_interface_ptr.h"
+{%- endif %}
+{%- endif %}
+
+{% if not disallow_native_types %}
+#include "mojo/public/cpp/bindings/lib/native_enum_serialization.h"
+#include "mojo/public/cpp/bindings/lib/native_struct_serialization.h"
+{%- endif %}
+
+{%- if export_header %}
+#include "{{export_header}}"
+{%- endif %}
+
+{%- if variant %}
+{%- for namespace in namespaces_as_array %}
+namespace {{namespace}} {
+{%- endfor %}
+
+{%- from "enum_macros.tmpl" import enum_forward%}
+{%- for enum in all_enums %}
+{%- if enum|is_native_only_kind %}
+using {{enum|get_name_for_kind(flatten_nested_kind=True)}} = mojo::NativeEnum;
+{%- else %}
+{{enum_forward(enum)}}
+{%- endif %}
+{%- endfor %}
+
+{%- for namespace in namespaces_as_array %}
+} // namespace {{namespace}}
+{%- endfor %}
+{%- endif %}
+
+{#--- WTF enum hashing #}
+{%- from "enum_macros.tmpl" import enum_hash_blink_forward%}
+{%- if for_blink %}
+{%- if all_enums %}
+#include "third_party/blink/renderer/platform/wtf/hash_functions.h"
+{%- endif %}
+
+{%- for enum in all_enums %}
+{%- if not enum|is_native_only_kind %}
+{{enum_hash_blink_forward(enum)}}
+{%- endif %}
+{%- endfor %}
+{%- endif %}
+
+{{namespace_begin()}}
+
+{#- These are non-variant header only. #}
+{%- if not variant %}
+
+{#--- Struct Forward Declarations -#}
+{%- for struct in structs %}
+{%- if struct|is_native_only_kind %}
+using {{struct.name}}DataView = mojo::native::NativeStructDataView;
+{%- else %}
+class {{struct.name}}DataView;
+{%- endif %}
+{% endfor %}
+
+{#--- Union Forward Declarations -#}
+{%- for union in unions %}
+class {{union.name}}DataView;
+{%- endfor %}
+
+{#--- Enums #}
+{%- from "enum_macros.tmpl" import enum_forward%}
+{%- for enum in all_enums %}
+{%- if enum|is_native_only_kind %}
+using {{enum|get_name_for_kind(flatten_nested_kind=True)}} = mojo::NativeEnum;
+{%- else %}
+{{enum_forward(enum)}}
+{%- endif %}
+{%- endfor %}
+
+{%- endif %}
+
+{#--- Enums #}
+{%- if variant %}
+{%- for enum in enums %}
+using {{enum.name}} = {{enum.name}}; // Alias for definition in the parent namespace.
+{%- endfor %}
+{%- endif %}
+
+{#--- Constants #}
+{%- for constant in module.constants %}
+{{constant|format_constant_declaration}};
+{%- endfor %}
+
+{#--- Struct Forward Declarations -#}
+{% for struct in structs %}
+{%- if struct|is_native_only_kind %}
+using {{struct.name}} = mojo::native::NativeStruct;
+using {{struct.name}}Ptr = mojo::native::NativeStructPtr;
+{%- else %}
+class {{struct.name}};
+{%- if struct|should_inline %}
+using {{struct.name}}Ptr = mojo::InlinedStructPtr<{{struct.name}}>;
+{%- else %}
+using {{struct.name}}Ptr = mojo::StructPtr<{{struct.name}}>;
+{%- endif %}
+{%- endif %}
+{% endfor %}
+
+{#--- Union Forward Declarations -#}
+{% for union in unions %}
+class {{union.name}};
+{% if union|should_inline_union %}
+typedef mojo::InlinedStructPtr<{{union.name}}> {{union.name}}Ptr;
+{% else %}
+typedef mojo::StructPtr<{{union.name}}> {{union.name}}Ptr;
+{% endif %}
+{%- endfor %}
+
+
+{#--- Interface Forward Declarations -#}
+{% for interface in interfaces %}
+class {{interface.name}};
+using {{interface.name}}Ptr = mojo::InterfacePtr<{{interface.name}}>;
+{%- if for_blink %}
+using Revocable{{interface.name}}Ptr = ::blink::RevocableInterfacePtr<{{interface.name}}>;
+{%- endif %}
+using {{interface.name}}PtrInfo = mojo::InterfacePtrInfo<{{interface.name}}>;
+using ThreadSafe{{interface.name}}Ptr =
+ mojo::ThreadSafeInterfacePtr<{{interface.name}}>;
+using {{interface.name}}Request = mojo::InterfaceRequest<{{interface.name}}>;
+using {{interface.name}}AssociatedPtr =
+ mojo::AssociatedInterfacePtr<{{interface.name}}>;
+using ThreadSafe{{interface.name}}AssociatedPtr =
+ mojo::ThreadSafeAssociatedInterfacePtr<{{interface.name}}>;
+using {{interface.name}}AssociatedPtrInfo =
+ mojo::AssociatedInterfacePtrInfo<{{interface.name}}>;
+using {{interface.name}}AssociatedRequest =
+ mojo::AssociatedInterfaceRequest<{{interface.name}}>;
+{% endfor %}
+
+
+{{namespace_end()}}
+
+{#- TODO(tikuta): Use forward declaration of native enum/struct here. #}
+
+{%- for header in extra_public_headers %}
+#include "{{header}}"
+{%- endfor %}
+
+#endif // {{header_guard}}
diff --git a/chromium/mojo/public/tools/bindings/generators/cpp_templates/module-import-headers.h.tmpl b/chromium/mojo/public/tools/bindings/generators/cpp_templates/module-import-headers.h.tmpl
new file mode 100644
index 00000000000..928ad1a3a0e
--- /dev/null
+++ b/chromium/mojo/public/tools/bindings/generators/cpp_templates/module-import-headers.h.tmpl
@@ -0,0 +1,28 @@
+// Copyright 2019 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.
+
+{%- if variant -%}
+{%- set variant_path = "%s-%s"|format(module.path, variant) -%}
+{%- else -%}
+{%- set variant_path = module.path -%}
+{%- endif -%}
+
+{%- set header_guard = "%s_IMPORT_HEADERS_H_"|format(
+ variant_path|upper|replace("/","_")|replace(".","_")|
+ replace("-", "_")) %}
+
+#ifndef {{header_guard}}
+#define {{header_guard}}
+
+{%- for import in imports %}
+{%- if variant %}
+#include "{{"%s-%s.h"|format(import.path, variant)}}"
+#include "{{"%s-%s-import-headers.h"|format(import.path, variant)}}"
+{%- else %}
+#include "{{import.path}}.h"
+#include "{{import.path}}-import-headers.h"
+{%- endif %}
+{%- endfor %}
+
+#endif // {{header_guard}}
diff --git a/chromium/mojo/public/tools/bindings/generators/cpp_templates/module-params-data.h.tmpl b/chromium/mojo/public/tools/bindings/generators/cpp_templates/module-params-data.h.tmpl
new file mode 100644
index 00000000000..92cbffe605a
--- /dev/null
+++ b/chromium/mojo/public/tools/bindings/generators/cpp_templates/module-params-data.h.tmpl
@@ -0,0 +1,80 @@
+// Copyright 2019 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.
+
+{%- set header_guard = "%s_PARAMS_DATA_H_"|format(
+ module.path|upper|replace("/","_")|replace(".","_")|
+ replace("-", "_")) %}
+
+#ifndef {{header_guard}}
+#define {{header_guard}}
+
+#include "base/logging.h"
+#include "base/macros.h"
+#include "mojo/public/cpp/bindings/lib/bindings_internal.h"
+#include "mojo/public/cpp/bindings/lib/buffer.h"
+#include "mojo/public/cpp/bindings/lib/validation_context.h"
+
+#if defined(__clang__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunused-private-field"
+#elif defined(_MSC_VER)
+#pragma warning(push)
+#pragma warning(disable:4056)
+#pragma warning(disable:4065)
+#pragma warning(disable:4756)
+#endif
+
+{%- for namespace in namespaces_as_array %}
+namespace {{namespace}} {
+{%- endfor %}
+namespace internal {
+
+{#--- Interface parameter definitions #}
+{%- for interface in interfaces %}
+{%- for method in interface.methods %}
+{%- set struct = method.param_struct %}
+{% include "struct_declaration.tmpl" %}
+{%- if method.response_parameters != None %}
+{%- set struct = method.response_param_struct %}
+{% include "struct_declaration.tmpl" %}
+{%- endif %}
+{%- endfor %}
+{%- endfor %}
+
+} // namespace internal
+
+{#--- Interface parameter definitions #}
+{%- for interface in interfaces %}
+{%- for method in interface.methods %}
+{%- set struct = method.param_struct %}
+{% include "struct_data_view_declaration.tmpl" %}
+{%- if method.response_parameters != None %}
+{%- set struct = method.response_param_struct %}
+{% include "struct_data_view_declaration.tmpl" %}
+{%- endif %}
+{%- endfor %}
+{%- endfor %}
+
+{%- for interface in interfaces %}
+{%- for method in interface.methods %}
+{%- set struct = method.param_struct %}
+{% include "struct_data_view_definition.tmpl" %}
+{%- if method.response_parameters != None %}
+{%- set struct = method.response_param_struct %}
+{% include "struct_data_view_definition.tmpl" %}
+{%- endif %}
+{%- endfor %}
+{%- endfor %}
+
+{%- for namespace in namespaces_as_array|reverse %}
+} // namespace {{namespace}}
+{%- endfor %}
+
+#if defined(__clang__)
+#pragma clang diagnostic pop
+#elif defined(_MSC_VER)
+#pragma warning(pop)
+#endif
+
+#endif // {{header_guard}}
diff --git a/chromium/mojo/public/tools/bindings/generators/cpp_templates/module-shared-internal.h.tmpl b/chromium/mojo/public/tools/bindings/generators/cpp_templates/module-shared-internal.h.tmpl
index e32f43bf554..f6ee8a61f3e 100644
--- a/chromium/mojo/public/tools/bindings/generators/cpp_templates/module-shared-internal.h.tmpl
+++ b/chromium/mojo/public/tools/bindings/generators/cpp_templates/module-shared-internal.h.tmpl
@@ -78,18 +78,6 @@ using {{enum|get_name_for_kind(flatten_nested_kind=True)}}_Data =
{%- endif %}
{%- endfor %}
-{#--- Interface parameter definitions #}
-{%- for interface in interfaces %}
-{%- for method in interface.methods %}
-{%- set struct = method.param_struct %}
-{% include "struct_declaration.tmpl" %}
-{%- if method.response_parameters != None %}
-{%- set struct = method.response_param_struct %}
-{% include "struct_declaration.tmpl" %}
-{%- endif %}
-{%- endfor %}
-{%- endfor %}
-
#pragma pack(pop)
} // namespace internal
diff --git a/chromium/mojo/public/tools/bindings/generators/cpp_templates/module-shared.cc.tmpl b/chromium/mojo/public/tools/bindings/generators/cpp_templates/module-shared.cc.tmpl
index c1a12f34b66..9742f85564a 100644
--- a/chromium/mojo/public/tools/bindings/generators/cpp_templates/module-shared.cc.tmpl
+++ b/chromium/mojo/public/tools/bindings/generators/cpp_templates/module-shared.cc.tmpl
@@ -18,6 +18,8 @@
#include "mojo/public/cpp/bindings/lib/validation_errors.h"
#include "mojo/public/cpp/bindings/lib/validation_util.h"
+#include "{{module.path}}-params-data.h"
+
{%- for header in extra_traits_headers %}
#include "{{header}}"
{%- endfor %}
diff --git a/chromium/mojo/public/tools/bindings/generators/cpp_templates/module-shared.h.tmpl b/chromium/mojo/public/tools/bindings/generators/cpp_templates/module-shared.h.tmpl
index 017f06d04c7..0c2e6e4492a 100644
--- a/chromium/mojo/public/tools/bindings/generators/cpp_templates/module-shared.h.tmpl
+++ b/chromium/mojo/public/tools/bindings/generators/cpp_templates/module-shared.h.tmpl
@@ -140,18 +140,6 @@ using {{interface.name}}AssociatedRequestDataView =
{%- endif %}
{%- endfor %}
-{#--- Interface parameter definitions #}
-{%- for interface in interfaces %}
-{%- for method in interface.methods %}
-{%- set struct = method.param_struct %}
-{% include "struct_data_view_declaration.tmpl" %}
-{%- if method.response_parameters != None %}
-{%- set struct = method.response_param_struct %}
-{% include "struct_data_view_declaration.tmpl" %}
-{%- endif %}
-{%- endfor %}
-{%- endfor %}
-
{#--- Unions #}
{%- for union in unions %}
{% include "union_data_view_declaration.tmpl" %}
@@ -203,17 +191,6 @@ namespace mojo {
{%- endif %}
{%- endfor %}
-{%- for interface in interfaces %}
-{%- for method in interface.methods %}
-{%- set struct = method.param_struct %}
-{% include "struct_data_view_definition.tmpl" %}
-{%- if method.response_parameters != None %}
-{%- set struct = method.response_param_struct %}
-{% include "struct_data_view_definition.tmpl" %}
-{%- endif %}
-{%- endfor %}
-{%- endfor %}
-
{%- for union in unions %}
{% include "union_data_view_definition.tmpl" %}
{%- endfor %}
diff --git a/chromium/mojo/public/tools/bindings/generators/cpp_templates/module-test-utils.cc.tmpl b/chromium/mojo/public/tools/bindings/generators/cpp_templates/module-test-utils.cc.tmpl
index a7ea114add4..93e620fb0f0 100644
--- a/chromium/mojo/public/tools/bindings/generators/cpp_templates/module-test-utils.cc.tmpl
+++ b/chromium/mojo/public/tools/bindings/generators/cpp_templates/module-test-utils.cc.tmpl
@@ -52,6 +52,14 @@ namespace {{variant}} {
#include "mojo/public/cpp/bindings/lib/wtf_serialization.h"
{%- endif %}
+{%- for import in imports %}
+{%- if variant %}
+#include "{{"%s-%s.h"|format(import.path, variant)}}"
+{%- else %}
+#include "{{import.path}}.h"
+{%- endif %}
+{%- endfor %}
+
{# This is include guard for jumbo build. #}
#ifndef {{header_guard_for_jumbo}}
#define {{header_guard_for_jumbo}}
diff --git a/chromium/mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl b/chromium/mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl
index 467f2b8e1dc..f6f1388acd5 100644
--- a/chromium/mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl
+++ b/chromium/mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl
@@ -38,8 +38,11 @@
#include "mojo/public/cpp/bindings/lib/validation_errors.h"
#include "mojo/public/interfaces/bindings/interface_control_messages.mojom.h"
+#include "{{module.path}}-params-data.h"
#include "{{module.path}}-shared-message-ids.h"
+#include "{{variant_path}}-import-headers.h"
+
{%- if for_blink %}
#include "mojo/public/cpp/bindings/lib/wtf_serialization.h"
{%- endif %}
diff --git a/chromium/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl b/chromium/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl
index 1537b1c828a..b4f2a452191 100644
--- a/chromium/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl
+++ b/chromium/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl
@@ -54,13 +54,35 @@ namespace {{variant}} {
#include "mojo/public/cpp/bindings/struct_traits.h"
#include "mojo/public/cpp/bindings/union_traits.h"
#include "{{module.path}}-shared.h"
+#include "{{variant_path}}-forward.h"
+
+{#- Imported struct and union types must be fully defined if used in this
+ mojom. #}
+{%- set import_definition_header = namespace(need=false) %}
+{%- for struct in structs %}
+{%- for field in struct.fields %}
+{%- if field.kind|is_object_kind or field.kind|is_union_kind %}
+{%- set import_definition_header.need = true %}
+{%- endif %}
+{%- endfor %}
+{%- endfor %}
+
{%- for import in imports %}
-{%- if variant %}
+{%- if import_definition_header.need %}
+{%- if variant %}
#include "{{"%s-%s.h"|format(import.path, variant)}}"
-{%- else %}
+{%- else %}
#include "{{import.path}}.h"
+{%- endif %}
+{%- else %}
+{%- if variant %}
+#include "{{"%s-%s-forward.h"|format(import.path, variant)}}"
+{%- else %}
+#include "{{import.path}}-forward.h"
+{%- endif %}
{%- endif %}
{%- endfor %}
+
{%- if not for_blink %}
#include <string>
#include <vector>
@@ -113,64 +135,6 @@ namespace {{variant}} {
{{namespace_begin()}}
-{#--- Enums #}
-{%- if variant %}
-{%- for enum in enums %}
-using {{enum.name}} = {{enum.name}}; // Alias for definition in the parent namespace.
-{%- endfor %}
-{%- endif %}
-
-{#--- Constants #}
-{%- for constant in module.constants %}
-{{constant|format_constant_declaration}};
-{%- endfor %}
-
-{#--- Interface Forward Declarations -#}
-{% for interface in interfaces %}
-class {{interface.name}};
-using {{interface.name}}Ptr = mojo::InterfacePtr<{{interface.name}}>;
-{%- if for_blink %}
-using Revocable{{interface.name}}Ptr = ::blink::RevocableInterfacePtr<{{interface.name}}>;
-{%- endif %}
-using {{interface.name}}PtrInfo = mojo::InterfacePtrInfo<{{interface.name}}>;
-using ThreadSafe{{interface.name}}Ptr =
- mojo::ThreadSafeInterfacePtr<{{interface.name}}>;
-using {{interface.name}}Request = mojo::InterfaceRequest<{{interface.name}}>;
-using {{interface.name}}AssociatedPtr =
- mojo::AssociatedInterfacePtr<{{interface.name}}>;
-using ThreadSafe{{interface.name}}AssociatedPtr =
- mojo::ThreadSafeAssociatedInterfacePtr<{{interface.name}}>;
-using {{interface.name}}AssociatedPtrInfo =
- mojo::AssociatedInterfacePtrInfo<{{interface.name}}>;
-using {{interface.name}}AssociatedRequest =
- mojo::AssociatedInterfaceRequest<{{interface.name}}>;
-{% endfor %}
-
-{#--- Struct Forward Declarations -#}
-{% for struct in structs %}
-{%- if struct|is_native_only_kind %}
-using {{struct.name}} = mojo::native::NativeStruct;
-using {{struct.name}}Ptr = mojo::native::NativeStructPtr;
-{%- else %}
-class {{struct.name}};
-{%- if struct|should_inline %}
-using {{struct.name}}Ptr = mojo::InlinedStructPtr<{{struct.name}}>;
-{%- else %}
-using {{struct.name}}Ptr = mojo::StructPtr<{{struct.name}}>;
-{%- endif %}
-{%- endif %}
-{% endfor %}
-
-{#--- Union Forward Declarations -#}
-{% for union in unions %}
-class {{union.name}};
-{% if union|should_inline_union %}
-typedef mojo::InlinedStructPtr<{{union.name}}> {{union.name}}Ptr;
-{% else %}
-typedef mojo::StructPtr<{{union.name}}> {{union.name}}Ptr;
-{% endif %}
-{%- endfor %}
-
{#--- Interfaces -#}
{% for interface in interfaces %}
{% include "interface_declaration.tmpl" %}
diff --git a/chromium/mojo/public/tools/bindings/generators/cpp_templates/wrapper_union_class_template_definition.tmpl b/chromium/mojo/public/tools/bindings/generators/cpp_templates/wrapper_union_class_template_definition.tmpl
index a29a1b7f552..ec3343820da 100644
--- a/chromium/mojo/public/tools/bindings/generators/cpp_templates/wrapper_union_class_template_definition.tmpl
+++ b/chromium/mojo/public/tools/bindings/generators/cpp_templates/wrapper_union_class_template_definition.tmpl
@@ -14,7 +14,7 @@ template <typename UnionPtrType>
{%- endif %}
break;
{%- endfor %}
- };
+ }
return rv;
}
@@ -35,7 +35,7 @@ bool {{union.name}}::Equals(const T& other) const {
return mojo::Equals(data_.{{field.name}}, other.data_.{{field.name}});
{%- endif %}
{%- endfor %}
- };
+ }
return false;
}
diff --git a/chromium/mojo/public/tools/bindings/generators/js_templates/fuzzing.tmpl b/chromium/mojo/public/tools/bindings/generators/js_templates/fuzzing.tmpl
index a91260ed9ac..e8a7460fe1c 100644
--- a/chromium/mojo/public/tools/bindings/generators/js_templates/fuzzing.tmpl
+++ b/chromium/mojo/public/tools/bindings/generators/js_templates/fuzzing.tmpl
@@ -95,10 +95,12 @@ idx = {{name}}.setHandlesInternal_(handles, idx)
{%- endmacro -%}
{%- macro generate_or_mutate_interface(obj, operation, kind, name) -%}
-{%- if kind|is_interface_request_kind -%}
+{%- if kind|is_interface_request_kind or kind|is_pending_receiver_kind -%}
{{build_call(obj, operation, 'InterfaceRequest', name, '"' ~ kind.kind.module.namespace ~ '.' ~ kind.kind.name ~ '"', kind.is_nullable|to_js_boolean)}}
{%- elif kind|is_interface_kind -%}
{{build_call(obj, operation, 'Interface', name, '"' ~ kind.module.namespace ~ '.' ~ kind.name ~ '"', kind.is_nullable|to_js_boolean)}}
+{%- elif kind|is_pending_remote_kind -%}
+{{build_call(obj, operation, 'Interface', name, '"' ~ kind.kind.module.namespace ~ '.' ~ kind.kind.name ~ '"', kind.is_nullable|to_js_boolean)}}
{%- elif kind|is_associated_interface_request_kind -%}
{{build_call(obj, operation, 'AssociatedInterfaceRequest', name, '"' ~ kind.kind.module.namespace ~ '.' ~ kind.kind.name ~ '"', kind.is_nullable|to_js_boolean)}}
{%- elif kind|is_associated_interface_kind -%}
diff --git a/chromium/mojo/public/tools/bindings/generators/js_templates/lite/enum_definition.tmpl b/chromium/mojo/public/tools/bindings/generators/js_templates/lite/enum_definition.tmpl
index 2b8d4b2ab74..b6f1293d96d 100644
--- a/chromium/mojo/public/tools/bindings/generators/js_templates/lite/enum_definition.tmpl
+++ b/chromium/mojo/public/tools/bindings/generators/js_templates/lite/enum_definition.tmpl
@@ -1,26 +1,42 @@
-{%- macro enum_def(enum_name, enum) -%}
+{%- macro enum_def(enum_spec_parent, enum_parent, enum) -%}
{# TODO: Less generic enum annotations would be nice. We do it this way because
the bindings generator is still too stupid to generate the right integral
constants directly. #}
+{% if generate_closure_exports -%}
+goog.provide('{{enum_spec_parent}}.{{enum.name}}Spec');
+{%- endif %}
/**
- * @const {!Object}
+ * @const { {$: !mojo.internal.MojomType} }
* @export
*/
-{{enum_name}} = { $: mojo.internal.Enum() };
+{{enum_spec_parent}}.{{enum.name}}Spec = { $: mojo.internal.Enum() };
+
+/**
+ * @enum {number}
+ * @export
+ */
+{{enum_parent}}.{{enum.name}} = {
+ {# Set up the enum here, but fill out the values later. #}
{%- for field in enum.fields %}
-{%- if field.value %}
-{{enum_name}}.{{field.name}} = {{field.value|expression_to_text_lite}};
-{%- elif loop.first %}
-{{enum_name}}.{{field.name}} = 0;
-{%- else %}
-{{enum_name}}.{{field.name}} = {{enum_name}}.{{enum.fields[loop.index0 - 1].name}} + 1;
-{%- endif %}
+ {{field.name}}: 0,
{%- endfor %}
{%- if enum.min_value is not none %}
-{{enum_name}}.MIN_VALUE = {{enum.min_value}};
+ MIN_VALUE: {{enum.min_value}},
{%- endif %}
{%- if enum.max_value is not none %}
-{{enum_name}}.MAX_VALUE = {{enum.max_value}};
+ MAX_VALUE: {{enum.max_value}},
{%- endif %}
+};
+{%- for field in enum.fields %}
+{# Suppress type checks since we're assigning number into an enum. #}
+/** @suppress {checkTypes} */
+{%- if field.value %}
+{{enum_parent}}.{{enum.name}}.{{field.name}} = {{field.value|expression_to_text_lite}};
+{%- elif loop.first %}
+{{enum_parent}}.{{enum.name}}.{{field.name}} = 0;
+{%- else %}
+{{enum_parent}}.{{enum.name}}.{{field.name}} = {{enum_parent}}.{{enum.name}}.{{enum.fields[loop.index0 - 1].name}} + 1;
+{%- endif %}
+{%- endfor %}
{%- endmacro %}
diff --git a/chromium/mojo/public/tools/bindings/generators/js_templates/lite/interface_definition.tmpl b/chromium/mojo/public/tools/bindings/generators/js_templates/lite/interface_definition.tmpl
index 1dbd4fcb64e..874b97ff4ba 100644
--- a/chromium/mojo/public/tools/bindings/generators/js_templates/lite/interface_definition.tmpl
+++ b/chromium/mojo/public/tools/bindings/generators/js_templates/lite/interface_definition.tmpl
@@ -1,3 +1,22 @@
+{% macro generateMethodAnnotation(method) %}
+ /**
+{%- for param in method.parameters %}
+ * @param { {{param.kind|lite_closure_type_with_nullability}} } {{param.name|sanitize_identifier}}
+{%- endfor -%}
+{%- if method.response_parameters != None %}
+{%- if method.response_parameters|length == 0 %}
+ * @return {Promise}
+{%- else %}
+ * @return {Promise<{
+{%- for response_parameter in method.response_parameters %}
+ {{response_parameter.name}}: {{response_parameter.kind|lite_closure_type_with_nullability}},
+{%- endfor %}
+ * }>}
+{%- endif %}
+{%- endif %}
+ */
+{% endmacro %}
+
/** @export */
{{module.namespace}}.{{interface.name}}Request = class {
/** @param {!MojoHandle} handle */
@@ -11,14 +30,7 @@
/** @interface */
{{module.namespace}}.{{interface.name}}Interface = class {
{%- for method in interface.methods %}
- /**
-{%- for param in method.parameters %}
- * @param { {{param.kind|lite_closure_param_type}} } {{param.name|sanitize_identifier}}
-{%- endfor -%}
-{%- if method.response_parameters != None %}
- * @return {Promise}
-{%- endif %}
- */
+ {{generateMethodAnnotation(method)}}
{{method.name}}(
{%- for param in method.parameters -%}
{{param.name|sanitize_identifier}}{% if not loop.last %}, {% endif %}
@@ -28,41 +40,35 @@
};
{%- endif %}
-/** @implements { {{module.namespace}}.{{interface.name}}Interface } */
+/**
+ * @export
+ * @implements { {{module.namespace}}.{{interface.name}}Interface }
+ */
{{module.namespace}}.{{interface.name}}Proxy = class {
/** @param {MojoHandle=} opt_handle */
constructor(opt_handle) {
- /** @private {!mojo.internal.interfaceSupport.InterfaceProxyBase} */
+ /**
+ * @private {!mojo.internal.interfaceSupport.InterfaceProxyBase<!{{module.namespace}}.{{interface.name}}Request>}
+ */
this.proxy =
- new mojo.internal.interfaceSupport.InterfaceProxyBase(opt_handle);
+ new mojo.internal.interfaceSupport.InterfaceProxyBase(
+ {{module.namespace}}.{{interface.name}}Request,
+ opt_handle);
+
+ /**
+ * @public {!mojo.internal.interfaceSupport.InterfaceProxyBaseWrapper<!{{module.namespace}}.{{interface.name}}Request>}
+ */
+ this.$ = new mojo.internal.interfaceSupport.InterfaceProxyBaseWrapper(this.proxy);
/** @public {!mojo.internal.interfaceSupport.ConnectionErrorEventRouter} */
this.onConnectionError = this.proxy.getConnectionErrorEventRouter();
}
- /**
- * @return {!{{module.namespace}}.{{interface.name}}Request}
- * @export
- */
- createRequest() {
- let {handle0, handle1} = Mojo.createMessagePipe();
- this.proxy.bindHandle(handle0);
- return new {{module.namespace}}.{{interface.name}}Request(handle1);
- }
-
{%- for method in interface.methods -%}
{%- set interface_message_id =
interface.mojom_name ~ "_" ~ method.mojom_name %}
- /**
-{%- for param in method.parameters %}
- * @param { {{param.kind|lite_closure_param_type}} } {{param.name|sanitize_identifier}}
-{%- endfor -%}
-{%- if method.response_parameters != None %}
- * @return {Promise}
-{%- endif %}
- * @export
- */
+ {{generateMethodAnnotation(method)}}
{{method.name}}(
{%- for param in method.parameters %}
{{param.name}}{%- if not loop.last %},{% endif %}
@@ -73,9 +79,9 @@
this.proxy.sendMessage(
{%- endif %}
{{method.ordinal}},
- {{module.namespace}}.{{interface_message_id}}_Params.$,
+ {{module.namespace}}.{{interface_message_id}}_ParamsSpec.$,
{%- if method.response_parameters != None %}
- {{module.namespace}}.{{interface_message_id}}_ResponseParams.$,
+ {{module.namespace}}.{{interface_message_id}}_ResponseParamsSpec.$,
{%- else %}
null,
{%- endif %}
@@ -86,15 +92,6 @@
]);
}
{%- endfor %}
-
-
- /**
- * @return {!Promise}
- * @export
- */
- flushForTesting() {
- return this.proxy.flushForTesting();
- }
};
/**
@@ -115,9 +112,9 @@
interface.mojom_name ~ "_" ~ method.mojom_name %}
this.target_.registerHandler(
{{method.ordinal}},
- {{module.namespace}}.{{interface_message_id}}_Params.$,
+ {{module.namespace}}.{{interface_message_id}}_ParamsSpec.$,
{%- if method.response_parameters != None %}
- {{module.namespace}}.{{interface_message_id}}_ResponseParams.$,
+ {{module.namespace}}.{{interface_message_id}}_ResponseParamsSpec.$,
{%- else %}
null,
{%- endif %}
@@ -147,7 +144,7 @@
static getProxy() {
let proxy = new {{module.namespace}}.{{interface.name}}Proxy;
Mojo.bindInterface('{{mojom_namespace}}.{{interface.name}}',
- proxy.createRequest().handle);
+ proxy.$.createRequest().handle);
return proxy;
}
@@ -160,15 +157,16 @@
*/
createProxy() {
let proxy = new {{module.namespace}}.{{interface.name}}Proxy;
- this.target_.bindHandle(proxy.createRequest().handle);
+ this.target_.bindHandle(proxy.$.createRequest().handle);
return proxy;
}
};
{#--- Enums #}
-{% from "lite/enum_definition.tmpl" import enum_def %}
+{% from "lite/enum_definition.tmpl" import enum_def with context %}
{%- for enum in interface.enums %}
-{{ enum_def("%s.%s.%s"|format(module.namespace, interface.name, enum.name),
+{{ enum_def("%s.%sSpec"|format(module.namespace, interface.name),
+ "%s.%s"|format(module.namespace, interface.name),
enum) }}
{%- endfor %}
@@ -194,15 +192,18 @@
{% for method in interface.methods %}
{%- set interface_message_id =
interface.mojom_name ~ "_" ~ method.mojom_name %}
- /** @public {!mojo.internal.interfaceSupport.InterfaceCallbackTarget} */
+ /**
+ * @export {!mojo.internal.interfaceSupport.InterfaceCallbackTarget}
+ */
this.{{method.name}} =
new mojo.internal.interfaceSupport.InterfaceCallbackTarget(
this.router_);
+
this.target_.registerHandler(
{{method.ordinal}},
- {{module.namespace}}.{{interface_message_id}}_Params.$,
+ {{module.namespace}}.{{interface_message_id}}_ParamsSpec.$,
{%- if method.response_parameters != None %}
- {{module.namespace}}.{{interface_message_id}}_ResponseParams.$,
+ {{module.namespace}}.{{interface_message_id}}_ResponseParamsSpec.$,
this.{{method.name}}.createTargetHandler(true /* expectsResponse */));
{%- else %}
null,
@@ -239,7 +240,7 @@
*/
createProxy() {
let proxy = new {{module.namespace}}.{{interface.name}}Proxy;
- this.target_.bindHandle(proxy.createRequest().handle);
+ this.target_.bindHandle(proxy.$.createRequest().handle);
return proxy;
}
diff --git a/chromium/mojo/public/tools/bindings/generators/js_templates/lite/interface_externs.tmpl b/chromium/mojo/public/tools/bindings/generators/js_templates/lite/interface_externs.tmpl
deleted file mode 100644
index 813684e60cc..00000000000
--- a/chromium/mojo/public/tools/bindings/generators/js_templates/lite/interface_externs.tmpl
+++ /dev/null
@@ -1,114 +0,0 @@
-{# Note that goog.provide is understood by the Closure Compiler even if the
- Closure base library is unavailable. See https://crbug.com/898692 #}
-goog.provide('{{module.namespace}}.{{interface.name}}');
-goog.provide('{{module.namespace}}.{{interface.name}}Interface');
-goog.provide('{{module.namespace}}.{{interface.name}}Request');
-goog.provide('{{module.namespace}}.{{interface.name}}Proxy');
-goog.provide('{{module.namespace}}.{{interface.name}}CallbackRouter');
-
-{% macro generateInterfaceClassBody() -%}
-{%- for method in interface.methods %}
- /**
-{%- for parameter in method.parameters %}
- * @param { {{parameter.kind|lite_closure_type_with_nullability}} } {{parameter.name|sanitize_identifier}}
-{%- endfor -%}
-{%- if method.response_parameters != None %}
-{%- if method.response_parameters|length == 0 %}
- * @return {Promise}
-{%- else %}
- * @return {Promise<{
-{%- for response_parameter in method.response_parameters %}
- {{response_parameter.name}}: {{response_parameter.kind|lite_closure_type_with_nullability}},
-{%- endfor %}
- * }>}
-{%- endif %}
-{%- endif %}
- */
- {{method.name}}(
-{%- for parameter in method.parameters -%}
-{{parameter.name|sanitize_identifier}}{% if not loop.last %}, {% endif %}
-{%- endfor -%}
-) {}
-{%- endfor %}
-{%- endmacro %}
-
-/** @interface */
-{{module.namespace}}.{{interface.name}}Interface = class {
-{{ generateInterfaceClassBody() }}
-};
-
-{{module.namespace}}.{{interface.name}}Request = class {
- /** @param {!MojoHandle} handle */
- constructor(handle) {}
-};
-
-/** @implements { {{module.namespace}}.{{interface.name}}Interface } */
-{{module.namespace}}.{{interface.name}}Proxy = class {
- constructor() {
- /** @public {!mojo.internal.ConnectionErrorEventRouter} */
- this.onConnectionError;
- }
-{{ generateInterfaceClassBody() }}
-
- /**
- * @return {!{{module.namespace}}.{{interface.name}}Request}
- */
- createRequest() {}
-};
-
-{{module.namespace}}.{{interface.name}} = class {
- /** @param {!{{module.namespace}}.{{interface.name}}Interface} impl */
- constructor(impl) {}
-
- /**
- * @param {!MojoHandle} handle
- */
- bindHandle(handle) {}
-
- /**
- * @return {!{{module.namespace}}.{{interface.name}}Proxy }
- */
- static getProxy() {}
-
- /**
- * @return {!{{module.namespace}}.{{interface.name}}Proxy }
- */
- createProxy() {}
-};
-
-/** @const {!string} */
-{{module.namespace}}.{{interface.name}}.$interfaceName;
-
-{{module.namespace}}.{{interface.name}}CallbackRouter = class {
- constructor() {
-{%- for method in interface.methods %}
- /** @public {!mojo.internal.InterfaceCallbackTarget} */
- this.{{method.name}};
-{%- endfor %}
- }
-
- /**
- * @param {!MojoHandle} handle
- */
- bindHandle(handle) {}
-
- /**
- * @return {!{{module.namespace}}.{{interface.name}}Proxy }
- */
- createProxy() {}
-
- /**
- * @param {number} id An ID returned by a prior call to addListener.
- * @return {boolean} True iff the identified listener was found and removed.
- */
- removeListener(id) {}
-};
-
-{#--- Enum definitions #}
-{% for enum in interface.enums %}
-/** @enum {number} */
-{{module.namespace}}.{{interface.name}}.{{enum.name}} = {};
-{%- for field in enum.fields %}
-{{module.namespace}}.{{interface.name}}.{{enum.name}}.{{field.name}};
-{%- endfor %}
-{%- endfor %}
diff --git a/chromium/mojo/public/tools/bindings/generators/js_templates/lite/module.externs.tmpl b/chromium/mojo/public/tools/bindings/generators/js_templates/lite/module.externs.tmpl
deleted file mode 100644
index 4e1d2355138..00000000000
--- a/chromium/mojo/public/tools/bindings/generators/js_templates/lite/module.externs.tmpl
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2018 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.
-
-{# Note that goog.provide is understood by the Closure Compiler even if the
- Closure base library is unavailable. See https://crbug.com/898692 #}
-{#--- Constant definitions #}
-{%- for constant in module.constants %}
-/** @type { {{constant.kind|closure_type_with_nullability }} } */
-goog.provide('{{module.namespace}}.{{constant.name}}');
-{%- endfor %}
-
-{#--- Enum definitions #}
-{% for enum in enums %}
-/** @enum {number} */
-{{module.namespace}}.{{enum.name}} = {};
-{%- for field in enum.fields %}
-{{module.namespace}}.{{enum.name}}.{{field.name}};
-{%- endfor %}
-{%- endfor %}
-
-{#--- Interface definitions #}
-{%- for interface in interfaces -%}
-{%- include "lite/interface_externs.tmpl" %}
-{% endfor -%}
-
-{#--- Struct definitions #}
-{%- for struct in structs -%}
-{%- include "lite/struct_externs.tmpl" %}
-{% endfor -%}
-
-{#--- Union definitions #}
-{%- for union in unions -%}
-{%- include "lite/union_externs.tmpl" %}
-{% endfor -%}
diff --git a/chromium/mojo/public/tools/bindings/generators/js_templates/lite/module_definition.tmpl b/chromium/mojo/public/tools/bindings/generators/js_templates/lite/module_definition.tmpl
index a6cdc1824b7..e8124d4a865 100644
--- a/chromium/mojo/public/tools/bindings/generators/js_templates/lite/module_definition.tmpl
+++ b/chromium/mojo/public/tools/bindings/generators/js_templates/lite/module_definition.tmpl
@@ -1,5 +1,9 @@
{#--- Constants #}
{%- for constant in module.constants %}
+{% if generate_closure_exports -%}
+goog.provide('{{module.namespace}}.{{constant.name}}');
+
+{%- endif %}
/**
* @const { {{constant.kind|lite_closure_type_with_nullability}} }
* @export
@@ -9,9 +13,9 @@
{%- endfor %}
{#--- Enums #}
-{% from "lite/enum_definition.tmpl" import enum_def %}
+{% from "lite/enum_definition.tmpl" import enum_def with context %}
{%- for enum in enums %}
-{{enum_def("%s.%s"|format(module.namespace, enum.name), enum)}}
+{{enum_def(module.namespace, module.namespace, enum)}}
{% endfor %}
{#--- Interface definitions #}
@@ -24,19 +28,25 @@
# mojo.internal.Struct and mojo.internal.Union will fix-up the object
# appropriately, and we don't want Closure to complain. #}
{% for struct in structs %}
+{% if generate_closure_exports -%}
+goog.provide('{{module.namespace}}.{{struct.name}}Spec');
+{%- endif %}
/**
- * @const {!Object}
+ * @const { {$:!mojo.internal.MojomType}}
* @export
*/
-{{module.namespace}}.{{struct.name}} =
+{{module.namespace}}.{{struct.name}}Spec =
{ $: /** @type {!mojo.internal.MojomType} */ ({}) };
{% endfor %}
{%- for union in unions %}
+{% if generate_closure_exports -%}
+goog.provide('{{module.namespace}}.{{union.name}}Spec');
+{%- endif %}
/**
- * @const {!Object}
+ * @const { {$:!mojo.internal.MojomType} }
* @export
*/
-{{module.namespace}}.{{union.name}} =
+{{module.namespace}}.{{union.name}}Spec =
{ $: /** @type {!mojo.internal.MojomType} */ ({}) };
{% endfor %}
diff --git a/chromium/mojo/public/tools/bindings/generators/js_templates/lite/mojom-lite.js.tmpl b/chromium/mojo/public/tools/bindings/generators/js_templates/lite/mojom-lite.js.tmpl
index 44463228700..b9b2e32e0aa 100644
--- a/chromium/mojo/public/tools/bindings/generators/js_templates/lite/mojom-lite.js.tmpl
+++ b/chromium/mojo/public/tools/bindings/generators/js_templates/lite/mojom-lite.js.tmpl
@@ -8,11 +8,6 @@ goog.require('mojo.internal');
{%- if interfaces %}
goog.require('mojo.internal.interfaceSupport');
{%- endif %}
-
-{% for import in imports -%}
-goog.require('{{import.namespace}}');
-{% endfor %}
-goog.provide('{{module.namespace}}');
{% endif %}
mojo.internal.exportModule('{{module.namespace}}');
diff --git a/chromium/mojo/public/tools/bindings/generators/js_templates/lite/struct_definition.tmpl b/chromium/mojo/public/tools/bindings/generators/js_templates/lite/struct_definition.tmpl
index 60163e74d07..fa6bd2e71b3 100644
--- a/chromium/mojo/public/tools/bindings/generators/js_templates/lite/struct_definition.tmpl
+++ b/chromium/mojo/public/tools/bindings/generators/js_templates/lite/struct_definition.tmpl
@@ -7,13 +7,14 @@
{{constant.value|expression_to_text_lite}};
{% endfor %}
-{%- from "lite/enum_definition.tmpl" import enum_def %}
+{%- from "lite/enum_definition.tmpl" import enum_def with context %}
{% for enum in struct.enums %}
-{{enum_def("%s.%s.%s"|format(module.namespace, struct.name, enum.name), enum)}}
+{{enum_def("%s.%sSpec"|format(module.namespace, struct.name),
+ "%s.%s"|format(module.namespace, struct.name), enum)}}
{% endfor %}
mojo.internal.Struct(
- {{module.namespace}}.{{struct.name}}.$,
+ {{module.namespace}}.{{struct.name}}Spec.$,
'{{struct.name}}',
{{struct.packed|payload_size}},
[
@@ -31,3 +32,21 @@ mojo.internal.Struct(
{%- endif %}
{%- endfor %}
]);
+
+{% if generate_closure_exports -%}
+goog.provide('{{module.namespace}}.{{struct.name}}');
+
+{% if struct.packed.packed_fields %}
+/**
+ * @typedef { {
+{%- for packed_field in struct.packed.packed_fields %}
+ * {{packed_field.field.name}}: {{packed_field.field.kind|lite_closure_field_type}},
+{%- endfor %}
+ * } }
+ */
+{% else %}
+/** @typedef {Object} */
+{% endif %}
+{{module.namespace}}.{{struct.name}};
+
+{%- endif %}
diff --git a/chromium/mojo/public/tools/bindings/generators/js_templates/lite/struct_externs.tmpl b/chromium/mojo/public/tools/bindings/generators/js_templates/lite/struct_externs.tmpl
deleted file mode 100644
index cc22de47d30..00000000000
--- a/chromium/mojo/public/tools/bindings/generators/js_templates/lite/struct_externs.tmpl
+++ /dev/null
@@ -1,25 +0,0 @@
-{# Note that goog.provide is understood by the Closure Compiler even if the
- Closure base library is unavailable. See https://crbug.com/898692 #}
-goog.provide('{{module.namespace}}.{{struct.name}}');
-
-{% if struct.packed.packed_fields %}
-/**
- * @typedef { {
-{%- for packed_field in struct.packed.packed_fields %}
- * {{packed_field.field.name}}: {{packed_field.field.kind|lite_closure_field_type}},
-{%- endfor %}
- * } }
- */
-{% else %}
-/** @typedef {Object} */
-{% endif %}
-{{module.namespace}}.{{struct.name}};
-
-{#--- Enum definitions #}
-{% for enum in struct.enums %}
-/** @enum {number} */
-{{module.namespace}}.{{struct.name}}.{{enum.name}} = {};
-{%- for field in enum.fields %}
-{{module.namespace}}.{{struct.name}}.{{enum.name}}.{{field.name}};
-{%- endfor %}
-{%- endfor %}
diff --git a/chromium/mojo/public/tools/bindings/generators/js_templates/lite/test/BUILD.gn b/chromium/mojo/public/tools/bindings/generators/js_templates/lite/test/BUILD.gn
index 671f91e309f..ec085c5f674 100644
--- a/chromium/mojo/public/tools/bindings/generators/js_templates/lite/test/BUILD.gn
+++ b/chromium/mojo/public/tools/bindings/generators/js_templates/lite/test/BUILD.gn
@@ -20,6 +20,6 @@ js_type_check("closure_compile") {
js_library("test") {
deps = [
- ":mojo_bindings_js_externs",
+ ":mojo_bindings_js_library_for_compile",
]
}
diff --git a/chromium/mojo/public/tools/bindings/generators/js_templates/lite/union_definition.tmpl b/chromium/mojo/public/tools/bindings/generators/js_templates/lite/union_definition.tmpl
index 0b8a6307b0c..ee637012d2b 100644
--- a/chromium/mojo/public/tools/bindings/generators/js_templates/lite/union_definition.tmpl
+++ b/chromium/mojo/public/tools/bindings/generators/js_templates/lite/union_definition.tmpl
@@ -1,6 +1,6 @@
mojo.internal.Union(
- {{module.namespace}}.{{union.name}}.$, '{{union.name}}',
+ {{module.namespace}}.{{union.name}}Spec.$, '{{union.name}}',
{
{%- for field in union.fields %}
'{{field.name}}': {
@@ -12,3 +12,12 @@ mojo.internal.Union(
},
{%- endfor %}
});
+
+/**
+ * @typedef { {
+{%- for field in union.fields %}
+ * {{field.name}}: ({{field.kind|lite_closure_type_with_nullability}}|undefined),
+{%- endfor %}
+ * } }
+ */
+{{module.namespace}}.{{union.name}};
diff --git a/chromium/mojo/public/tools/bindings/generators/js_templates/lite/union_externs.tmpl b/chromium/mojo/public/tools/bindings/generators/js_templates/lite/union_externs.tmpl
deleted file mode 100644
index 732cf630ce2..00000000000
--- a/chromium/mojo/public/tools/bindings/generators/js_templates/lite/union_externs.tmpl
+++ /dev/null
@@ -1,12 +0,0 @@
-{# Note that goog.provide is understood by the Closure Compiler even if the
- Closure base library is unavailable. See https://crbug.com/898692 #}
-goog.provide('{{module.namespace}}.{{union.name}}');
-
-{{module.namespace}}.{{union.name}} = class {
- constructor() {
-{%- for field in fields %}
- /** @type { {{field.kind|lite_closure_type_with_nullability}} } */
- this.{{field.name}};
-{%- endfor %}
- }
-};
diff --git a/chromium/mojo/public/tools/bindings/generators/js_templates/validation_macros.tmpl b/chromium/mojo/public/tools/bindings/generators/js_templates/validation_macros.tmpl
index 0e9b89315c2..de19055e4ae 100644
--- a/chromium/mojo/public/tools/bindings/generators/js_templates/validation_macros.tmpl
+++ b/chromium/mojo/public/tools/bindings/generators/js_templates/validation_macros.tmpl
@@ -20,11 +20,12 @@ err = messageValidator.validateStructPointer({{offset}}, {{field|validate_struct
// validate {{name}}
err = messageValidator.validateMapPointer({{offset}}, {{field|validate_map_params}});
{{_check_err()}}
-{%- elif field.kind|is_interface_kind %}
+{%- elif field.kind|is_interface_kind or field.kind|is_pending_remote_kind %}
// validate {{name}}
err = messageValidator.validateInterface({{offset}}, {{field|validate_nullable_params}});
{{_check_err()}}
-{%- elif field.kind|is_interface_request_kind %}
+{%- elif field.kind|is_interface_request_kind or
+ field.kind|is_pending_receiver_kind %}
// validate {{name}}
err = messageValidator.validateInterfaceRequest({{offset}}, {{field|validate_nullable_params}})
{{_check_err()}}
diff --git a/chromium/mojo/public/tools/bindings/generators/mojom_cpp_generator.py b/chromium/mojo/public/tools/bindings/generators/mojom_cpp_generator.py
index 8c5dd88756a..2e6e20a78c9 100644
--- a/chromium/mojo/public/tools/bindings/generators/mojom_cpp_generator.py
+++ b/chromium/mojo/public/tools/bindings/generators/mojom_cpp_generator.py
@@ -224,7 +224,9 @@ class Generator(generator.Generator):
mojom.IsAnyHandleKind(kind) or
mojom.IsInterfaceKind(kind) or
mojom.IsInterfaceRequestKind(kind) or
- mojom.IsAssociatedKind(kind)):
+ mojom.IsAssociatedKind(kind) or
+ mojom.IsPendingRemoteKind(kind) or
+ mojom.IsPendingReceiverKind(kind)):
pass
elif mojom.IsArrayKind(kind):
AddKind(kind.kind)
@@ -302,7 +304,7 @@ class Generator(generator.Generator):
"interfaces": self.module.interfaces,
"kinds": self.module.kinds,
"module": self.module,
- "namespace": self.module.namespace,
+ "module_namespace": self.module.namespace,
"namespaces_as_array": NamespaceToArray(self.module.namespace),
"structs": self.module.structs,
"support_lazy_serialization": self.support_lazy_serialization,
@@ -376,10 +378,18 @@ class Generator(generator.Generator):
def _GenerateModuleHeader(self):
return self._GetJinjaExports()
+ @UseJinja("module-forward.h.tmpl")
+ def _GenerateModuleForwardHeader(self):
+ return self._GetJinjaExports()
+
@UseJinja("module.cc.tmpl")
def _GenerateModuleSource(self):
return self._GetJinjaExports()
+ @UseJinja("module-import-headers.h.tmpl")
+ def _GenerateModuleImportHeadersHeader(self):
+ return self._GetJinjaExports()
+
@UseJinja("module-shared.h.tmpl")
def _GenerateModuleSharedHeader(self):
return self._GetJinjaExports()
@@ -404,6 +414,10 @@ class Generator(generator.Generator):
def _GenerateModuleTestUtilsSource(self):
return self._GetJinjaExports()
+ @UseJinja("module-params-data.h.tmpl")
+ def _GenerateModuleParamsDataHeader(self):
+ return self._GetJinjaExports()
+
def GenerateFiles(self, args):
self.module.Stylize(generator.Stylizer())
@@ -418,12 +432,18 @@ class Generator(generator.Generator):
"%s-shared-internal.h" % self.module.path)
self.Write(self._GenerateModuleSharedSource(),
"%s-shared.cc" % self.module.path)
+ self.Write(self._GenerateModuleParamsDataHeader(),
+ "%s-params-data.h" % self.module.path)
else:
suffix = "-%s" % self.variant if self.variant else ""
self.Write(self._GenerateModuleHeader(),
"%s%s.h" % (self.module.path, suffix))
+ self.Write(self._GenerateModuleForwardHeader(),
+ "%s%s-forward.h" % (self.module.path, suffix))
self.Write(self._GenerateModuleSource(),
"%s%s.cc" % (self.module.path, suffix))
+ self.Write(self._GenerateModuleImportHeadersHeader(),
+ "%s%s-import-headers.h" % (self.module.path, suffix))
self.Write(self._GenerateModuleTestUtilsHeader(),
"%s%s-test-utils.h" % (self.module.path, suffix))
self.Write(self._GenerateModuleTestUtilsSource(),
@@ -567,6 +587,12 @@ class Generator(generator.Generator):
if mojom.IsInterfaceRequestKind(kind):
return "%sRequest" % self._GetNameForKind(
kind.kind, add_same_module_namespaces=add_same_module_namespaces)
+ if mojom.IsPendingRemoteKind(kind):
+ return "mojo::PendingRemote<%s>" % self._GetNameForKind(
+ kind.kind, add_same_module_namespaces=add_same_module_namespaces)
+ if mojom.IsPendingReceiverKind(kind):
+ return "mojo::PendingReceiver<%s>" % self._GetNameForKind(
+ kind.kind, add_same_module_namespaces=add_same_module_namespaces)
if mojom.IsAssociatedInterfaceKind(kind):
return "%sAssociatedPtrInfo" % self._GetNameForKind(
kind.kind, add_same_module_namespaces=add_same_module_namespaces)
@@ -653,9 +679,9 @@ class Generator(generator.Generator):
return ("mojo::internal::Pointer<mojo::internal::Map_Data<%s, %s>>" %
(self._GetCppFieldType(kind.key_kind),
self._GetCppFieldType(kind.value_kind)))
- if mojom.IsInterfaceKind(kind):
+ if mojom.IsInterfaceKind(kind) or mojom.IsPendingRemoteKind(kind):
return "mojo::internal::Interface_Data"
- if mojom.IsInterfaceRequestKind(kind):
+ if mojom.IsInterfaceRequestKind(kind) or mojom.IsPendingReceiverKind(kind):
return "mojo::internal::Handle_Data"
if mojom.IsAssociatedInterfaceKind(kind):
return "mojo::internal::AssociatedInterface_Data"
@@ -871,6 +897,12 @@ class Generator(generator.Generator):
return "%sPtrDataView" % _GetName(kind)
if mojom.IsInterfaceRequestKind(kind):
return "%sRequestDataView" % _GetName(kind.kind)
+ if mojom.IsPendingRemoteKind(kind):
+ return ("mojo::InterfacePtrDataView<%sInterfaceBase>" %
+ _GetName(kind.kind))
+ if mojom.IsPendingReceiverKind(kind):
+ return ("mojo::InterfaceRequestDataView<%sInterfaceBase>" %
+ _GetName(kind.kind))
if mojom.IsAssociatedInterfaceKind(kind):
return "%sAssociatedPtrInfoDataView" % _GetName(kind.kind)
if mojom.IsAssociatedInterfaceRequestKind(kind):
diff --git a/chromium/mojo/public/tools/bindings/generators/mojom_java_generator.py b/chromium/mojo/public/tools/bindings/generators/mojom_java_generator.py
index 0f2b6181825..8097af35ffc 100644
--- a/chromium/mojo/public/tools/bindings/generators/mojom_java_generator.py
+++ b/chromium/mojo/public/tools/bindings/generators/mojom_java_generator.py
@@ -134,7 +134,9 @@ def GetNameForElement(element):
if name in _java_reserved_types:
return name + '_'
return name
- if mojom.IsInterfaceRequestKind(element) or mojom.IsAssociatedKind(element):
+ if (mojom.IsInterfaceRequestKind(element) or
+ mojom.IsAssociatedKind(element) or mojom.IsPendingRemoteKind(element) or
+ mojom.IsPendingReceiverKind(element)):
return GetNameForElement(element.kind)
if isinstance(element, (mojom.Method,
mojom.Parameter,
@@ -199,8 +201,12 @@ def AppendEncodeDecodeParams(initial_params, context, kind, bit):
params.append(GetArrayExpectedLength(kind))
if mojom.IsInterfaceKind(kind):
params.append('%s.MANAGER' % GetJavaType(context, kind))
+ if mojom.IsPendingRemoteKind(kind):
+ params.append('%s.MANAGER' % GetJavaType(context, kind.kind))
if mojom.IsArrayKind(kind) and mojom.IsInterfaceKind(kind.kind):
params.append('%s.MANAGER' % GetJavaType(context, kind.kind))
+ if mojom.IsArrayKind(kind) and mojom.IsPendingRemoteKind(kind.kind):
+ params.append('%s.MANAGER' % GetJavaType(context, kind.kind.kind))
return params
@@ -211,9 +217,9 @@ def DecodeMethod(context, kind, offset, bit):
return _DecodeMethodName(kind.kind) + 's'
if mojom.IsEnumKind(kind):
return _DecodeMethodName(mojom.INT32)
- if mojom.IsInterfaceRequestKind(kind):
+ if mojom.IsInterfaceRequestKind(kind) or mojom.IsPendingReceiverKind(kind):
return 'readInterfaceRequest'
- if mojom.IsInterfaceKind(kind):
+ if mojom.IsInterfaceKind(kind) or mojom.IsPendingRemoteKind(kind):
return 'readServiceInterface'
if mojom.IsAssociatedInterfaceRequestKind(kind):
return 'readAssociatedInterfaceRequestNotSupported'
@@ -271,7 +277,9 @@ def GetJavaType(context, kind, boxed=False, with_generics=True):
mojom.IsInterfaceKind(kind) or
mojom.IsUnionKind(kind)):
return GetNameForKind(context, kind)
- if mojom.IsInterfaceRequestKind(kind):
+ if mojom.IsPendingRemoteKind(kind):
+ return GetNameForKind(context, kind.kind)
+ if mojom.IsInterfaceRequestKind(kind) or mojom.IsPendingReceiverKind(kind):
return ('org.chromium.mojo.bindings.InterfaceRequest<%s>' %
GetNameForKind(context, kind.kind))
if mojom.IsAssociatedInterfaceKind(kind):
diff --git a/chromium/mojo/public/tools/bindings/generators/mojom_js_generator.py b/chromium/mojo/public/tools/bindings/generators/mojom_js_generator.py
index 54891417344..bc8bc63a39f 100644
--- a/chromium/mojo/public/tools/bindings/generators/mojom_js_generator.py
+++ b/chromium/mojo/public/tools/bindings/generators/mojom_js_generator.py
@@ -289,7 +289,9 @@ class Generator(generator.Generator):
"is_any_handle_kind": mojom.IsAnyHandleKind,
"is_any_interface_kind": mojom.IsAnyInterfaceKind,
"is_interface_kind": mojom.IsInterfaceKind,
+ "is_pending_remote_kind": mojom.IsPendingRemoteKind,
"is_interface_request_kind": mojom.IsInterfaceRequestKind,
+ "is_pending_receiver_kind": mojom.IsPendingReceiverKind,
"is_map_kind": mojom.IsMapKind,
"is_object_kind": mojom.IsObjectKind,
"is_reference_kind": mojom.IsReferenceKind,
@@ -341,10 +343,6 @@ class Generator(generator.Generator):
def _GenerateLiteBindingsForCompile(self):
return self._GetParameters(for_compile=True)
- @UseJinja("lite/module.externs.tmpl")
- def _GenerateLiteExterns(self):
- return self._GetParameters()
-
def GenerateFiles(self, args):
if self.variant:
raise Exception("Variants not supported in JavaScript bindings.")
@@ -362,8 +360,6 @@ class Generator(generator.Generator):
self.Write(self._GenerateLiteBindings(), "%s-lite.js" % self.module.path)
self.Write(self._GenerateLiteBindingsForCompile(),
"%s-lite-for-compile.js" % self.module.path)
- self.Write(self._GenerateLiteExterns(),
- "%s-lite.externs.js" % self.module.path)
def _SetUniqueNameForImports(self):
used_names = set()
@@ -387,6 +383,8 @@ class Generator(generator.Generator):
return _kind_to_closure_type[kind]
if mojom.IsInterfaceKind(kind):
return kind.module.namespace + "." + kind.name + "Ptr"
+ if mojom.IsPendingRemoteKind(kind):
+ return kind.kind.module.namespace + "." + kind.kind.name + "Ptr"
if (mojom.IsStructKind(kind) or
mojom.IsEnumKind(kind)):
return kind.module.namespace + "." + kind.name
@@ -398,7 +396,7 @@ class Generator(generator.Generator):
if mojom.IsMapKind(kind):
return "Map<%s, %s>" % (
self._ClosureType(kind.key_kind), self._ClosureType(kind.value_kind))
- if mojom.IsInterfaceRequestKind(kind):
+ if mojom.IsInterfaceRequestKind(kind) or mojom.IsPendingReceiverKind(kind):
return "mojo.InterfaceRequest"
# TODO(calamity): Support associated interfaces properly.
if mojom.IsAssociatedInterfaceKind(kind):
@@ -432,7 +430,8 @@ class Generator(generator.Generator):
self._LiteClosureTypeWithNullability(kind.key_kind),
self._LiteClosureTypeWithNullability(kind.value_kind))
- if mojom.IsAssociatedKind(kind) or mojom.IsInterfaceRequestKind(kind):
+ if (mojom.IsAssociatedKind(kind) or mojom.IsInterfaceRequestKind(kind) or
+ mojom.IsPendingRemoteKind(kind) or mojom.IsPendingReceiverKind(kind)):
named_kind = kind.kind
else:
named_kind = kind
@@ -448,9 +447,9 @@ class Generator(generator.Generator):
if (mojom.IsStructKind(kind) or mojom.IsUnionKind(kind) or
mojom.IsEnumKind(kind)):
return name
- if mojom.IsInterfaceKind(kind):
+ if mojom.IsInterfaceKind(kind) or mojom.IsPendingRemoteKind(kind):
return name + "Proxy"
- if mojom.IsInterfaceRequestKind(kind):
+ if mojom.IsInterfaceRequestKind(kind) or mojom.IsPendingReceiverKind(kind):
return name + "Request"
# TODO(calamity): Support associated interfaces properly.
if mojom.IsAssociatedInterfaceKind(kind):
@@ -523,7 +522,8 @@ class Generator(generator.Generator):
self._LiteJavaScriptType(kind.value_kind),
"true" if mojom.IsNullableKind(kind.value_kind) else "false")
- if mojom.IsAssociatedKind(kind) or mojom.IsInterfaceRequestKind(kind):
+ if (mojom.IsAssociatedKind(kind) or mojom.IsInterfaceRequestKind(kind) or
+ mojom.IsPendingRemoteKind(kind) or mojom.IsPendingReceiverKind(kind)):
named_kind = kind.kind
else:
named_kind = kind
@@ -532,19 +532,20 @@ class Generator(generator.Generator):
if named_kind.module:
name.append(named_kind.module.namespace)
if named_kind.parent_kind:
- name.append(named_kind.parent_kind.name)
+ name.append(named_kind.parent_kind.name + "Spec")
name.append(named_kind.name)
name = ".".join(name)
if (mojom.IsStructKind(kind) or mojom.IsUnionKind(kind) or
mojom.IsEnumKind(kind)):
- return "%s.$" % name
- if mojom.IsInterfaceKind(kind):
+ return "%sSpec.$" % name
+ if mojom.IsInterfaceKind(kind) or mojom.IsPendingRemoteKind(kind):
return "mojo.internal.InterfaceProxy(%sProxy)" % name
- if mojom.IsInterfaceRequestKind(kind):
+ if mojom.IsInterfaceRequestKind(kind) or mojom.IsPendingReceiverKind(kind):
return "mojo.internal.InterfaceRequest(%sRequest)" % name
if mojom.IsAssociatedInterfaceKind(kind):
- return "mojo.internal.AssociatedInterfaceProxy(%sAssociatedProxy)" % (
+ # TODO(rockot): Implement associated interfaces.
+ return "mojo.internal.AssociatedInterfaceProxy(%sProxy)" % (
name)
if mojom.IsAssociatedInterfaceRequestKind(kind):
return "mojo.internal.AssociatedInterfaceRequest(%s)" % name
@@ -569,7 +570,10 @@ class Generator(generator.Generator):
return "null"
if mojom.IsInterfaceKind(field.kind):
return "new %sPtr()" % self._JavaScriptType(field.kind)
- if mojom.IsInterfaceRequestKind(field.kind):
+ if mojom.IsPendingRemoteKind(field.kind):
+ return "new %sPtr()" % self._JavaScriptType(field.kind.kind)
+ if (mojom.IsInterfaceRequestKind(field.kind) or
+ mojom.IsPendingReceiverKind(field.kind)):
return "new bindings.InterfaceRequest()"
if mojom.IsAssociatedInterfaceKind(field.kind):
return "new associatedBindings.AssociatedInterfacePtrInfo()"
@@ -584,7 +588,7 @@ class Generator(generator.Generator):
if mojom.IsStructKind(field.kind):
assert field.default == "default"
return "null";
- return self._ExpressionToText(field.default)
+ return self._ExpressionToTextLite(field.default)
if field.kind in mojom.PRIMITIVES:
return _kind_to_javascript_default_value[field.kind]
if mojom.IsEnumKind(field.kind):
@@ -610,7 +614,11 @@ class Generator(generator.Generator):
return "new codec.%s(%sPtr)" % (
"NullableInterface" if mojom.IsNullableKind(kind) else "Interface",
self._JavaScriptType(kind))
- if mojom.IsInterfaceRequestKind(kind):
+ if mojom.IsPendingRemoteKind(kind):
+ return "new codec.%s(%sPtr)" % (
+ "NullableInterface" if mojom.IsNullableKind(kind) else "Interface",
+ self._JavaScriptType(kind.kind))
+ if mojom.IsInterfaceRequestKind(kind) or mojom.IsPendingReceiverKind(kind):
return "codec.%s" % (
"NullableInterfaceRequest" if mojom.IsNullableKind(kind)
else "InterfaceRequest")
@@ -776,12 +784,15 @@ class Generator(generator.Generator):
return result
def _FuzzHandleName(self, kind):
- if mojom.IsInterfaceRequestKind(kind):
+ if mojom.IsInterfaceRequestKind(kind) or mojom.IsPendingReceiverKind(kind):
return '{0}.{1}Request'.format(kind.kind.module.namespace,
kind.kind.name)
elif mojom.IsInterfaceKind(kind):
return '{0}.{1}Ptr'.format(kind.module.namespace,
kind.name)
+ elif mojom.IsPendingRemoteKind(kind):
+ return '{0}.{1}Ptr'.format(kind.kind.module.namespace,
+ kind.kind.name)
elif mojom.IsAssociatedInterfaceRequestKind(kind):
return '{0}.{1}AssociatedRequest'.format(kind.kind.module.namespace,
kind.kind.name)
diff --git a/chromium/mojo/public/tools/bindings/mojom.gni b/chromium/mojo/public/tools/bindings/mojom.gni
index 4fe4e4b65b3..ac896c8dea2 100644
--- a/chromium/mojo/public/tools/bindings/mojom.gni
+++ b/chromium/mojo/public/tools/bindings/mojom.gni
@@ -13,6 +13,7 @@ import("//ui/webui/webui_features.gni")
# Chrome builds. Ideally we could create some generic knobs here that could be
# flipped elsewhere though.
import("//build/config/chrome_build.gni")
+import("//build/config/chromecast_build.gni")
import("//build/config/nacl/config.gni")
import("//components/nacl/features.gni")
import("//third_party/jinja2/jinja2.gni")
@@ -56,7 +57,7 @@ declare_args() {
# check |target_os| explicitly, as it's consistent across all toolchains.
enable_scrambled_message_ids =
enable_mojom_message_id_scrambling &&
- (is_mac || is_win || (is_linux && !is_chromeos) ||
+ (is_mac || is_win || (is_linux && !is_chromeos && !is_chromecast) ||
((enable_nacl || is_nacl || is_nacl_nonsfi) && target_os != "chromeos"))
mojom_generator_root = "//mojo/public/tools/bindings"
@@ -207,6 +208,17 @@ if (enable_mojom_typemapping) {
# cpp_only (optional)
# If set to true, only the C++ bindings targets will be generated.
#
+# NOTE: If the global |enable_ipc_fuzzer| build arg is true, JS bindings
+# will still be generated even when |cpp_only| is set to |true|, unless
+# you also set |enable_fuzzing| to |false| in your mojom target.
+#
+# enable_fuzzing (optional)
+# Enables generation of fuzzing sources for the target if the global build
+# arg |enable_ipc_fuzzer| is also set to |true|. Defaults to |true|. If
+# fuzzing generation is enabled for a target, the target will always
+# generate JS bindings even if |cpp_only| is set to |true|. See note
+# above.
+#
# support_lazy_serialization (optional)
# If set to |true|, generated C++ bindings will effectively prefer to
# transmit messages in an unserialized form when going between endpoints
@@ -407,6 +419,10 @@ template("mojom") {
write_file("$target_gen_dir/$target_name.deps_sources_list", deps_sources)
+ generate_fuzzing = enable_ipc_fuzzer && (!defined(invoker.enable_fuzzing) ||
+ invoker.enable_fuzzing) &&
+ (!defined(invoker.testonly) || !invoker.testonly)
+
if (defined(invoker.sources)) {
parser_target_name = "${target_name}__parser"
enabled_features = []
@@ -617,6 +633,7 @@ template("mojom") {
}
generator_shared_cpp_outputs = [
+ "{{source_gen_dir}}/{{source_file_part}}-params-data.h",
"{{source_gen_dir}}/{{source_file_part}}-shared-internal.h",
"{{source_gen_dir}}/{{source_file_part}}-shared.cc",
"{{source_gen_dir}}/{{source_file_part}}-shared.h",
@@ -638,6 +655,7 @@ template("mojom") {
foreach(source, invoker.sources) {
filelist += [ rebase_path("$source", root_build_dir) ]
outputs += [
+ "$target_gen_dir/$source-params-data.h",
"$target_gen_dir/$source-shared-internal.h",
"$target_gen_dir/$source-shared.cc",
"$target_gen_dir/$source-shared.h",
@@ -673,19 +691,16 @@ template("mojom") {
testonly = invoker.testonly
}
deps = []
+ public_deps = []
if (defined(invoker.sources)) {
sources =
process_file_template(invoker.sources, generator_shared_cpp_outputs)
- deps += [ ":$generator_shared_target_name" ]
+ public_deps += [ ":$generator_shared_target_name" ]
}
if (require_full_cpp_deps) {
- public_deps = [
- "//mojo/public/cpp/bindings",
- ]
+ public_deps += [ "//mojo/public/cpp/bindings" ]
} else {
- public_deps = [
- "//mojo/public/cpp/bindings:bindings_base",
- ]
+ public_deps += [ "//mojo/public/cpp/bindings:bindings_base" ]
}
foreach(d, all_deps) {
# Resolve the name, so that a target //mojo/something becomes
@@ -752,10 +767,12 @@ template("mojom") {
variant_dash_suffix = "-${variant}"
}
generator_cpp_outputs += [
- "{{source_gen_dir}}/{{source_file_part}}${variant_dash_suffix}.cc",
- "{{source_gen_dir}}/{{source_file_part}}${variant_dash_suffix}.h",
+ "{{source_gen_dir}}/{{source_file_part}}${variant_dash_suffix}-forward.h",
+ "{{source_gen_dir}}/{{source_file_part}}${variant_dash_suffix}-import-headers.h",
"{{source_gen_dir}}/{{source_file_part}}${variant_dash_suffix}-test-utils.cc",
"{{source_gen_dir}}/{{source_file_part}}${variant_dash_suffix}-test-utils.h",
+ "{{source_gen_dir}}/{{source_file_part}}${variant_dash_suffix}.cc",
+ "{{source_gen_dir}}/{{source_file_part}}${variant_dash_suffix}.h",
]
enabled_sources = []
if (defined(bindings_configuration.blacklist)) {
@@ -828,10 +845,12 @@ template("mojom") {
foreach(source, invoker.sources) {
filelist += [ rebase_path("$source", root_build_dir) ]
outputs += [
- "$target_gen_dir/${source}${variant_dash_suffix}.cc",
- "$target_gen_dir/${source}${variant_dash_suffix}.h",
+ "$target_gen_dir/${source}${variant_dash_suffix}-forward.h",
+ "$target_gen_dir/${source}${variant_dash_suffix}-import-headers.h",
"$target_gen_dir/${source}${variant_dash_suffix}-test-utils.cc",
"$target_gen_dir/${source}${variant_dash_suffix}-test-utils.h",
+ "$target_gen_dir/${source}${variant_dash_suffix}.cc",
+ "$target_gen_dir/${source}${variant_dash_suffix}.h",
]
}
@@ -1088,7 +1107,7 @@ template("mojom") {
public_deps += [ "//mojo/public/cpp/bindings:wtf_support" ]
}
- if (enable_ipc_fuzzer) {
+ if (generate_fuzzing) {
# Generate JS bindings by default if IPC fuzzer is enabled.
public_deps += [ ":$js_data_deps_target_name" ]
}
@@ -1187,7 +1206,7 @@ template("mojom") {
}
}
- if (enable_ipc_fuzzer || !defined(invoker.cpp_only) || !invoker.cpp_only) {
+ if (generate_fuzzing || !defined(invoker.cpp_only) || !invoker.cpp_only) {
if (defined(invoker.sources)) {
generator_js_target_name = "${target_name}_js__generator"
generator_js_lite_outputs =
@@ -1215,7 +1234,6 @@ template("mojom") {
"$target_gen_dir/$source.externs.js",
"$target_gen_dir/$source-lite.js",
"$target_gen_dir/$source-lite-for-compile.js",
- "$target_gen_dir/$source-lite.externs.js",
]
}
@@ -1234,7 +1252,7 @@ template("mojom") {
args += message_scrambling_args
}
- if (enable_ipc_fuzzer) {
+ if (generate_fuzzing) {
args += [ "--generate_fuzzing" ]
}
}
@@ -1289,48 +1307,30 @@ template("mojom") {
}
}
- if (enable_mojom_closure_compile) {
- js_library_for_compile_target_name =
- "${target_name}_js_library_for_compile"
- if (defined(invoker.sources)) {
- generator_js_lite_for_compile_outputs =
- [ "{{source_gen_dir}}/{{source_file_part}}-lite-for-compile.js" ]
- js_library(js_library_for_compile_target_name) {
- extra_public_deps = [ ":$generator_js_target_name" ]
- sources = process_file_template(invoker.sources,
- generator_js_lite_for_compile_outputs)
-
- deps = []
- foreach(d, all_deps) {
- full_name = get_label_info(d, "label_no_toolchain")
- deps += [ "${full_name}_js_library_for_compile" ]
- }
- }
- } else {
- group(js_library_for_compile_target_name) {
- }
- }
- }
-
- js_externs_target_suffix = "_js_externs"
- js_externs_target_name = "${target_name}${js_externs_target_suffix}"
+ js_library_for_compile_target_name = "${target_name}_js_library_for_compile"
if (defined(invoker.sources)) {
- js_library(js_externs_target_name) {
- sources = []
+ generator_js_lite_for_compile_outputs =
+ [ "{{source_gen_dir}}/{{source_file_part}}-lite-for-compile.js" ]
+ js_library(js_library_for_compile_target_name) {
extra_public_deps = [ ":$generator_js_target_name" ]
- externs_list = [ "${externs_path}/mojo.js" ]
- externs_list += process_file_template(
- invoker.sources,
- [ "{{source_gen_dir}}/{{source_file_part}}-lite.externs.js" ])
+ sources = process_file_template(invoker.sources,
+ generator_js_lite_for_compile_outputs)
+ externs_list = [
+ "${externs_path}/mojo_core.js",
+ "${externs_path}/pending.js",
+ ]
deps = []
+ if (!defined(invoker.disallow_native_types)) {
+ deps += [ "//mojo/public/js:bindings_lite_sources" ]
+ }
foreach(d, all_deps) {
full_name = get_label_info(d, "label_no_toolchain")
- deps += [ "${full_name}${js_externs_target_suffix}" ]
+ deps += [ "${full_name}_js_library_for_compile" ]
}
}
} else {
- group(js_externs_target_name) {
+ group(js_library_for_compile_target_name) {
}
}
}
diff --git a/chromium/mojo/public/tools/bindings/pylib/mojom/generate/module.py b/chromium/mojo/public/tools/bindings/pylib/mojom/generate/module.py
index db45e3344f1..79264a0d23a 100644
--- a/chromium/mojo/public/tools/bindings/pylib/mojom/generate/module.py
+++ b/chromium/mojo/public/tools/bindings/pylib/mojom/generate/module.py
@@ -490,6 +490,30 @@ class Map(ReferenceKind):
return GenericRepr(self, {'key_kind': True, 'value_kind': True})
+class PendingRemote(ReferenceKind):
+ ReferenceKind.AddSharedProperty('kind')
+
+ def __init__(self, kind=None):
+ if not isinstance(kind, Interface):
+ raise Exception(
+ 'pending_remote<T> requires T to be an interface type. Got %r' %
+ kind.spec)
+ ReferenceKind.__init__(self, 'rmt:' + kind.spec)
+ self.kind = kind
+
+
+class PendingReceiver(ReferenceKind):
+ ReferenceKind.AddSharedProperty('kind')
+
+ def __init__(self, kind=None):
+ if not isinstance(kind, Interface):
+ raise Exception(
+ 'pending_receiver<T> requires T to be an interface type. Got %r' %
+ kind.spec)
+ ReferenceKind.__init__(self, 'rcv:' + kind.spec)
+ self.kind = kind
+
+
class InterfaceRequest(ReferenceKind):
ReferenceKind.AddSharedProperty('kind')
@@ -838,6 +862,13 @@ def IsInterfaceRequestKind(kind):
def IsAssociatedInterfaceRequestKind(kind):
return isinstance(kind, AssociatedInterfaceRequest)
+def IsPendingRemoteKind(kind):
+ return isinstance(kind, PendingRemote)
+
+
+def IsPendingReceiverKind(kind):
+ return isinstance(kind, PendingReceiver)
+
def IsEnumKind(kind):
return isinstance(kind, Enum)
@@ -875,7 +906,8 @@ def IsAnyHandleKind(kind):
def IsAnyInterfaceKind(kind):
return (IsInterfaceKind(kind) or IsInterfaceRequestKind(kind) or
- IsAssociatedKind(kind))
+ IsAssociatedKind(kind) or IsPendingRemoteKind(kind) or
+ IsPendingReceiverKind(kind))
def IsAnyHandleOrInterfaceKind(kind):
diff --git a/chromium/mojo/public/tools/bindings/pylib/mojom/generate/pack.py b/chromium/mojo/public/tools/bindings/pylib/mojom/generate/pack.py
index e4204a017db..9187364d1e2 100644
--- a/chromium/mojo/public/tools/bindings/pylib/mojom/generate/pack.py
+++ b/chromium/mojo/public/tools/bindings/pylib/mojom/generate/pack.py
@@ -44,11 +44,12 @@ class PackedField(object):
@classmethod
def GetSizeForKind(cls, kind):
if isinstance(kind, (mojom.Array, mojom.Map, mojom.Struct,
- mojom.Interface, mojom.AssociatedInterface)):
+ mojom.Interface, mojom.AssociatedInterface,
+ mojom.PendingRemote)):
return 8
if isinstance(kind, mojom.Union):
return 16
- if isinstance(kind, mojom.InterfaceRequest):
+ if isinstance(kind, (mojom.InterfaceRequest, mojom.PendingReceiver)):
kind = mojom.MSGPIPE
if isinstance(kind, mojom.AssociatedInterfaceRequest):
return 4
diff --git a/chromium/mojo/public/tools/bindings/pylib/mojom/generate/translate.py b/chromium/mojo/public/tools/bindings/pylib/mojom/generate/translate.py
index 94fe2a6a523..cdc9d0e7c42 100644
--- a/chromium/mojo/public/tools/bindings/pylib/mojom/generate/translate.py
+++ b/chromium/mojo/public/tools/bindings/pylib/mojom/generate/translate.py
@@ -69,7 +69,7 @@ def _MapKind(kind):
base_kind = _MapKind(kind[0:-1])
# NOTE: This doesn't rule out enum types. Those will be detected later, when
# cross-reference is established.
- reference_kinds = ('m', 's', 'h', 'a', 'r', 'x', 'asso')
+ reference_kinds = ('m', 's', 'h', 'a', 'r', 'x', 'asso', 'rmt', 'rcv')
if re.split('[^a-z]', base_kind, 1)[0] not in reference_kinds:
raise Exception(
'A type (spec "%s") cannot be made nullable' % base_kind)
@@ -87,6 +87,12 @@ def _MapKind(kind):
if kind.startswith('asso<'):
assert kind.endswith('>')
return 'asso:' + _MapKind(kind[5:-1])
+ if kind.startswith('rmt<'):
+ assert kind.endswith('>')
+ return 'rmt:' + _MapKind(kind[4:-1])
+ if kind.startswith('rcv<'):
+ assert kind.endswith('>')
+ return 'rcv:' + _MapKind(kind[4:-1])
if kind in map_to_kind:
return map_to_kind[kind]
return 'x:' + kind
@@ -202,6 +208,10 @@ def _Kind(kinds, spec, scope):
kind = mojom.Array(_Kind(kinds, spec[colon+1:], scope), length)
elif spec.startswith('r:'):
kind = mojom.InterfaceRequest(_Kind(kinds, spec[2:], scope))
+ elif spec.startswith('rmt:'):
+ kind = mojom.PendingRemote(_Kind(kinds, spec[4:], scope))
+ elif spec.startswith('rcv:'):
+ kind = mojom.PendingReceiver(_Kind(kinds, spec[4:], scope))
elif spec.startswith('m['):
# Isolate the two types from their brackets.
diff --git a/chromium/mojo/public/tools/bindings/pylib/mojom/parse/lexer.py b/chromium/mojo/public/tools/bindings/pylib/mojom/parse/lexer.py
index 06354b1d85e..9a30d33a2df 100644
--- a/chromium/mojo/public/tools/bindings/pylib/mojom/parse/lexer.py
+++ b/chromium/mojo/public/tools/bindings/pylib/mojom/parse/lexer.py
@@ -65,7 +65,9 @@ class Lexer(object):
'DEFAULT',
'ARRAY',
'MAP',
- 'ASSOCIATED'
+ 'ASSOCIATED',
+ 'PENDING_REMOTE',
+ 'PENDING_RECEIVER'
)
keyword_map = {}
diff --git a/chromium/mojo/public/tools/bindings/pylib/mojom/parse/parser.py b/chromium/mojo/public/tools/bindings/pylib/mojom/parse/parser.py
index b9f10dce9e3..d49612749df 100644
--- a/chromium/mojo/public/tools/bindings/pylib/mojom/parse/parser.py
+++ b/chromium/mojo/public/tools/bindings/pylib/mojom/parse/parser.py
@@ -271,7 +271,9 @@ class Parser(object):
p[0] = p[1]
def p_basictypename(self, p):
- """basictypename : identifier
+ """basictypename : remotetype
+ | receivertype
+ | identifier
| ASSOCIATED identifier
| handletype"""
if len(p) == 2:
@@ -279,6 +281,14 @@ class Parser(object):
else:
p[0] = "asso<" + p[2] + ">"
+ def p_remotetype(self, p):
+ """remotetype : PENDING_REMOTE LANGLE identifier RANGLE"""
+ p[0] = "rmt<%s>" % p[3]
+
+ def p_receivertype(self, p):
+ """receivertype : PENDING_RECEIVER LANGLE identifier RANGLE"""
+ p[0] = "rcv<%s>" % p[3]
+
def p_handletype(self, p):
"""handletype : HANDLE
| HANDLE LANGLE NAME RANGLE"""
diff --git a/chromium/mojo/public/tools/fuzzers/mojo_fuzzer_message_dump.cc b/chromium/mojo/public/tools/fuzzers/mojo_fuzzer_message_dump.cc
index dad4fd897b7..3cc657cf04c 100644
--- a/chromium/mojo/public/tools/fuzzers/mojo_fuzzer_message_dump.cc
+++ b/chromium/mojo/public/tools/fuzzers/mojo_fuzzer_message_dump.cc
@@ -5,6 +5,7 @@
#include <stddef.h>
#include <stdint.h>
+#include "base/bind.h"
#include "base/containers/flat_map.h"
#include "base/files/file.h"
#include "base/message_loop/message_loop.h"
@@ -44,7 +45,7 @@ class MessageDumper : public mojo::MessageReceiver {
bool Accept(mojo::Message* message) override {
base::FilePath path = directory_.Append(FILE_PATH_LITERAL("message_") +
- base::IntToString(count_++) +
+ base::NumberToString(count_++) +
FILE_PATH_LITERAL(".mojomsg"));
base::File file(path,
diff --git a/chromium/mojo/public/tools/fuzzers/mojo_parse_message_fuzzer.cc b/chromium/mojo/public/tools/fuzzers/mojo_parse_message_fuzzer.cc
index 0357271c11f..28ff521a4ee 100644
--- a/chromium/mojo/public/tools/fuzzers/mojo_parse_message_fuzzer.cc
+++ b/chromium/mojo/public/tools/fuzzers/mojo_parse_message_fuzzer.cc
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "base/bind.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/task/task_scheduler/task_scheduler.h"
diff --git a/chromium/mojo/public/tools/fuzzers/mojo_parse_message_proto_fuzzer.cc b/chromium/mojo/public/tools/fuzzers/mojo_parse_message_proto_fuzzer.cc
index f16e228db16..d6b5e9684cd 100644
--- a/chromium/mojo/public/tools/fuzzers/mojo_parse_message_proto_fuzzer.cc
+++ b/chromium/mojo/public/tools/fuzzers/mojo_parse_message_proto_fuzzer.cc
@@ -5,6 +5,7 @@
// Implementation of a proto version of mojo_parse_message_fuzzer that sends
// multiple messages per run.
+#include "base/bind.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/task/task_scheduler/task_scheduler.h"