Commit 8d7f9750 authored by Kevin Marshall's avatar Kevin Marshall Committed by Commit Bot

[bindings] Add type checking annotations to NamedMessagePortConnector.

Adds annotations and a check-only js_binary() target to provide
static typechecking assurances for NamedMessagePortConnector's JS.

Bug: 159646269
Change-Id: I8340e4ef8ca291431a26dccef642745625e36911
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2458811
Commit-Queue: Kevin Marshall <kmarshall@chromium.org>
Reviewed-by: default avatarWez <wez@chromium.org>
Auto-Submit: Kevin Marshall <kmarshall@chromium.org>
Cr-Commit-Position: refs/heads/master@{#821805}
parent b75749e7
......@@ -2,6 +2,7 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//third_party/closure_compiler/compile_js.gni")
import("//tools/grit/grit_rule.gni")
source_set("named_message_port_connector") {
......@@ -21,6 +22,7 @@ source_set("named_message_port_connector") {
grit("resources") {
source = "named_message_port_connector_resources.grd"
deps = [ ":js_type_check" ]
outputs = [
"grit/named_message_port_connector_resources.h",
"named_message_port_connector_resources.pak",
......@@ -29,3 +31,9 @@ grit("resources") {
# Allow GRIT to assign IDs using its default set of base IDs.
resource_ids = ""
}
js_binary("js_type_check") {
sources = [ "named_message_port_connector.js" ]
checks_only = true
closure_flags = strict_error_checking_closure_args
}
......@@ -4,34 +4,48 @@
'use strict';
if (!cast) {
if (!window['cast']) {
/**
* @const
*/
// eslint-disable-next-line no-var
var cast = new Object;
}
if (!cast.__platform__) {
cast.__platform__ = new Object;
if (!cast['__platform__']) {
/**
* @const
*/
cast.__platform__ = {};
}
// Creates named HTML5 MessagePorts that are connected to native code.
cast.__platform__.PortConnector = new class {
constructor() {
/** @private {MessagePort} */
this.controlPort_ = null;
// A map of ports waiting to be published to the controlPort_, keyed by
// string IDs.
/** @private {Object<string, MessagePort>} */
this.pendingPorts_ = {};
/** @private */
this.listener = this.onMessageEvent.bind(this);
window.addEventListener(
'message', this.listener,
true // Let the listener handle events before they hit the DOM tree.
);
}
// Returns a MessagePort whose channel will be passed to the native code.
// The channel can be used immediately after construction. Outgoing messages
// will be automatically buffered until the connection is established.
/**
* Returns a MessagePort whose channel will be passed to the native code.
* The channel can be used immediately after construction. Outgoing messages
* will be automatically buffered until the connection is established.
* @param {string} id The ID of the port being registered.
* @return {MessagePort}
*/
bind(id) {
const channel = new MessageChannel();
if (this.controlPort_) {
......@@ -43,33 +57,43 @@ cast.__platform__.PortConnector = new class {
return channel.port1;
}
/**
* Sends a MessagePort to the remote NamedMessagePortConnector.
* @param {string} portId The name of the port to send over the control port.
* @param {MessagePort} port The port being sent.
*/
sendPort(portId, port) {
this.controlPort_.postMessage(portId, [port]);
}
// Receives a control port from native code.
onMessageEvent(e) {
/**
* Handles frame message events to receive a connection "control port" from
* native code.
* @param {Event} messageEvent
*/
onMessageEvent(messageEvent) {
// Only process window.onmessage events which are intended for this class.
if (e.data != 'cast.master.connect') {
if (messageEvent.data != 'cast.master.connect') {
return;
}
if (e.ports.length != 1) {
if (messageEvent.ports.length != 1) {
console.error(
'Expected only one MessagePort, got ' + e.ports.length + ' instead.');
for (const i in e.ports) {
e.ports[i].close();
'Expected only one MessagePort, got ' + messageEvent.ports.length +
' instead.');
for (const port of messageEvent.ports) {
port.close();
}
return;
}
this.controlPort_ = e.ports[0];
this.controlPort_ = messageEvent.ports[0];
for (const portId in this.pendingPorts_) {
this.sendPort(portId, this.pendingPorts_[portId]);
}
this.pendingPorts_ = null;
e.stopPropagation();
messageEvent.stopPropagation();
// No need to receive more onmessage events.
window.removeEventListener('message', this.listener);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment