ludus/out/goog/net/xpc/nativemessagingtransport.js
2023-11-16 13:22:15 -05:00

258 lines
12 KiB
JavaScript

/*TRANSPILED*//*
Copyright The Closure Library Authors.
SPDX-License-Identifier: Apache-2.0
*/
'use strict';
goog.provide("goog.net.xpc.NativeMessagingTransport");
goog.require("goog.Timer");
goog.require("goog.asserts");
goog.require("goog.async.Deferred");
goog.require("goog.dispose");
goog.require("goog.events");
goog.require("goog.events.EventHandler");
goog.require("goog.log");
goog.require("goog.net.xpc");
goog.require("goog.net.xpc.CrossPageChannelRole");
goog.require("goog.net.xpc.Transport");
goog.require("goog.net.xpc.TransportTypes");
goog.requireType("goog.dom.DomHelper");
goog.requireType("goog.events.BrowserEvent");
goog.requireType("goog.net.xpc.CrossPageChannel");
goog.net.xpc.NativeMessagingTransport = function(channel, peerHostname, opt_domHelper, opt_oneSidedHandshake, opt_protocolVersion) {
goog.net.xpc.NativeMessagingTransport.base(this, "constructor", opt_domHelper);
this.channel_ = channel;
this.protocolVersion_ = opt_protocolVersion || 2;
goog.asserts.assert(this.protocolVersion_ >= 1);
goog.asserts.assert(this.protocolVersion_ <= 2);
this.peerHostname_ = peerHostname || "*";
this.eventHandler_ = new goog.events.EventHandler(this);
this.maybeAttemptToConnectTimer_ = new goog.Timer(100, this.getWindow());
this.oneSidedHandshake_ = !!opt_oneSidedHandshake;
this.setupAckReceived_ = new goog.async.Deferred();
this.setupAckSent_ = new goog.async.Deferred();
this.connected_ = new goog.async.Deferred();
this.endpointId_ = goog.net.xpc.getRandomString(10);
this.peerEndpointId_ = null;
if (this.oneSidedHandshake_) {
if (this.channel_.getRole() == goog.net.xpc.CrossPageChannelRole.INNER) {
this.connected_.awaitDeferred(this.setupAckReceived_);
} else {
this.connected_.awaitDeferred(this.setupAckSent_);
}
} else {
this.connected_.awaitDeferred(this.setupAckReceived_);
if (this.protocolVersion_ == 2) {
this.connected_.awaitDeferred(this.setupAckSent_);
}
}
this.connected_.addCallback(this.notifyConnected_, this);
this.connected_.callback(true);
this.eventHandler_.listen(this.maybeAttemptToConnectTimer_, goog.Timer.TICK, this.maybeAttemptToConnect_);
goog.log.info(goog.net.xpc.logger, "NativeMessagingTransport created. " + "protocolVersion\x3d" + this.protocolVersion_ + ", oneSidedHandshake\x3d" + this.oneSidedHandshake_ + ", role\x3d" + this.channel_.getRole());
};
goog.inherits(goog.net.xpc.NativeMessagingTransport, goog.net.xpc.Transport);
goog.net.xpc.NativeMessagingTransport.CONNECTION_DELAY_MS_ = 200;
goog.net.xpc.NativeMessagingTransport.prototype.peerProtocolVersion_ = null;
goog.net.xpc.NativeMessagingTransport.prototype.initialized_ = false;
goog.net.xpc.NativeMessagingTransport.prototype.transportType = goog.net.xpc.TransportTypes.NATIVE_MESSAGING;
goog.net.xpc.NativeMessagingTransport.MESSAGE_DELIMITER_ = ",";
goog.net.xpc.NativeMessagingTransport.activeCount_ = {};
goog.net.xpc.NativeMessagingTransport.prototype.sendTimerId_ = 0;
goog.net.xpc.NativeMessagingTransport.prototype.couldPeerVersionBe_ = function(version) {
return this.peerProtocolVersion_ == null || this.peerProtocolVersion_ == version;
};
goog.net.xpc.NativeMessagingTransport.initialize_ = function(listenWindow) {
const uid = goog.getUid(listenWindow);
let value = goog.net.xpc.NativeMessagingTransport.activeCount_[uid];
if (typeof value !== "number") {
value = 0;
}
if (value == 0) {
goog.events.listen(listenWindow.postMessage ? listenWindow : listenWindow.document, "message", goog.net.xpc.NativeMessagingTransport.messageReceived_, false, goog.net.xpc.NativeMessagingTransport);
}
goog.net.xpc.NativeMessagingTransport.activeCount_[uid] = value + 1;
};
goog.net.xpc.NativeMessagingTransport.messageReceived_ = function(msgEvt) {
const data = msgEvt.getBrowserEvent().data;
if (typeof data !== "string") {
return false;
}
const headDelim = data.indexOf("|");
const serviceDelim = data.indexOf(":");
if (headDelim == -1 || serviceDelim == -1) {
return false;
}
const channelName = data.substring(0, headDelim);
const service = data.substring(headDelim + 1, serviceDelim);
const payload = data.substring(serviceDelim + 1);
goog.log.fine(goog.net.xpc.logger, "messageReceived: channel\x3d" + channelName + ", service\x3d" + service + ", payload\x3d" + payload);
const allChannels = goog.module.get("goog.net.xpc.CrossPageChannel").channels;
const channel = allChannels[channelName];
if (channel) {
channel.xpcDeliver(service, payload, msgEvt.getBrowserEvent().origin);
return true;
}
const transportMessageType = goog.net.xpc.NativeMessagingTransport.parseTransportPayload_(payload)[0];
for (let staleChannelName in allChannels) {
const staleChannel = allChannels[staleChannelName];
if (staleChannel.getRole() == goog.net.xpc.CrossPageChannelRole.INNER && !staleChannel.isConnected() && service == goog.net.xpc.TRANSPORT_SERVICE && (transportMessageType == goog.net.xpc.SETUP || transportMessageType == goog.net.xpc.SETUP_NTPV2) && staleChannel.isMessageOriginAcceptable(msgEvt.getBrowserEvent().origin)) {
staleChannel.updateChannelNameAndCatalog(channelName);
staleChannel.xpcDeliver(service, payload);
return true;
}
}
goog.log.info(goog.net.xpc.logger, 'channel name mismatch; message ignored"');
return false;
};
goog.net.xpc.NativeMessagingTransport.prototype.transportServiceHandler = function(payload) {
const transportParts = goog.net.xpc.NativeMessagingTransport.parseTransportPayload_(payload);
const transportMessageType = transportParts[0];
const peerEndpointId = transportParts[1];
switch(transportMessageType) {
case goog.net.xpc.SETUP_ACK:
this.setPeerProtocolVersion_(1);
if (!this.setupAckReceived_.hasFired()) {
this.setupAckReceived_.callback(true);
}
break;
case goog.net.xpc.SETUP_ACK_NTPV2:
if (this.protocolVersion_ == 2) {
this.setPeerProtocolVersion_(2);
if (!this.setupAckReceived_.hasFired()) {
this.setupAckReceived_.callback(true);
}
}
break;
case goog.net.xpc.SETUP:
this.setPeerProtocolVersion_(1);
this.sendSetupAckMessage_(1);
break;
case goog.net.xpc.SETUP_NTPV2:
if (this.protocolVersion_ == 2) {
const prevPeerProtocolVersion = this.peerProtocolVersion_;
this.setPeerProtocolVersion_(2);
this.sendSetupAckMessage_(2);
if ((prevPeerProtocolVersion == 1 || this.peerEndpointId_ != null) && this.peerEndpointId_ != peerEndpointId) {
goog.log.info(goog.net.xpc.logger, "Sending SETUP and changing peer ID to: " + peerEndpointId);
this.sendSetupMessage_();
}
this.peerEndpointId_ = peerEndpointId;
}
break;
}
};
goog.net.xpc.NativeMessagingTransport.prototype.sendSetupMessage_ = function() {
goog.asserts.assert(!(this.protocolVersion_ == 1 && this.peerProtocolVersion_ == 2));
if (this.protocolVersion_ == 2 && this.couldPeerVersionBe_(2)) {
let payload = goog.net.xpc.SETUP_NTPV2;
payload += goog.net.xpc.NativeMessagingTransport.MESSAGE_DELIMITER_;
payload += this.endpointId_;
this.send(goog.net.xpc.TRANSPORT_SERVICE, payload);
}
if (this.couldPeerVersionBe_(1)) {
this.send(goog.net.xpc.TRANSPORT_SERVICE, goog.net.xpc.SETUP);
}
};
goog.net.xpc.NativeMessagingTransport.prototype.sendSetupAckMessage_ = function(protocolVersion) {
goog.asserts.assert(this.protocolVersion_ != 1 || protocolVersion != 2, "Shouldn't try to send a v2 setup ack in v1 mode.");
if (this.protocolVersion_ == 2 && this.couldPeerVersionBe_(2) && protocolVersion == 2) {
this.send(goog.net.xpc.TRANSPORT_SERVICE, goog.net.xpc.SETUP_ACK_NTPV2);
} else if (this.couldPeerVersionBe_(1) && protocolVersion == 1) {
this.send(goog.net.xpc.TRANSPORT_SERVICE, goog.net.xpc.SETUP_ACK);
} else {
return;
}
if (!this.setupAckSent_.hasFired()) {
this.setupAckSent_.callback(true);
}
};
goog.net.xpc.NativeMessagingTransport.prototype.setPeerProtocolVersion_ = function(version) {
if (version > this.peerProtocolVersion_) {
this.peerProtocolVersion_ = version;
}
if (this.peerProtocolVersion_ == 1) {
if (!this.setupAckSent_.hasFired() && !this.oneSidedHandshake_) {
this.setupAckSent_.callback(true);
}
this.peerEndpointId_ = null;
}
};
goog.net.xpc.NativeMessagingTransport.prototype.connect = function() {
goog.net.xpc.NativeMessagingTransport.initialize_(this.getWindow());
this.initialized_ = true;
this.maybeAttemptToConnect_();
};
goog.net.xpc.NativeMessagingTransport.prototype.maybeAttemptToConnect_ = function() {
const outerFrame = this.channel_.getRole() == goog.net.xpc.CrossPageChannelRole.OUTER;
if (this.oneSidedHandshake_ && outerFrame || this.channel_.isConnected() || this.isDisposed()) {
this.maybeAttemptToConnectTimer_.stop();
return;
}
this.maybeAttemptToConnectTimer_.start();
this.sendSetupMessage_();
};
goog.net.xpc.NativeMessagingTransport.prototype.send = function(service, payload) {
const win = this.channel_.getPeerWindowObject();
if (!win) {
goog.log.fine(goog.net.xpc.logger, "send(): window not ready");
return;
}
this.send = function(service, payload) {
const transport = this;
const channelName = this.channel_.name;
const sendFunctor = function() {
transport.sendTimerId_ = 0;
try {
const obj = win.postMessage ? win : win.document;
if (!obj.postMessage) {
goog.log.warning(goog.net.xpc.logger, "Peer window had no postMessage function.");
return;
}
obj.postMessage(channelName + "|" + service + ":" + payload, transport.peerHostname_);
goog.log.fine(goog.net.xpc.logger, "send(): service\x3d" + service + " payload\x3d" + payload + " to hostname\x3d" + transport.peerHostname_);
} catch (error) {
goog.log.warning(goog.net.xpc.logger, "Error performing postMessage, ignoring.", error);
}
};
this.sendTimerId_ = goog.Timer.callOnce(sendFunctor, 0);
};
this.send(service, payload);
};
goog.net.xpc.NativeMessagingTransport.prototype.notifyConnected_ = function() {
const delay = this.protocolVersion_ == 1 || this.peerProtocolVersion_ == 1 ? goog.net.xpc.NativeMessagingTransport.CONNECTION_DELAY_MS_ : undefined;
this.channel_.notifyConnected(delay);
};
goog.net.xpc.NativeMessagingTransport.prototype.disposeInternal = function() {
if (this.initialized_) {
const listenWindow = this.getWindow();
const uid = goog.getUid(listenWindow);
const value = goog.net.xpc.NativeMessagingTransport.activeCount_[uid];
goog.net.xpc.NativeMessagingTransport.activeCount_[uid] = value - 1;
if (value == 1) {
goog.events.unlisten(listenWindow.postMessage ? listenWindow : listenWindow.document, "message", goog.net.xpc.NativeMessagingTransport.messageReceived_, false, goog.net.xpc.NativeMessagingTransport);
}
}
if (this.sendTimerId_) {
goog.Timer.clear(this.sendTimerId_);
this.sendTimerId_ = 0;
}
goog.dispose(this.eventHandler_);
delete this.eventHandler_;
goog.dispose(this.maybeAttemptToConnectTimer_);
delete this.maybeAttemptToConnectTimer_;
this.setupAckReceived_.cancel();
delete this.setupAckReceived_;
this.setupAckSent_.cancel();
delete this.setupAckSent_;
this.connected_.cancel();
delete this.connected_;
delete this.send;
goog.net.xpc.NativeMessagingTransport.base(this, "disposeInternal");
};
goog.net.xpc.NativeMessagingTransport.parseTransportPayload_ = function(payload) {
const transportParts = payload.split(goog.net.xpc.NativeMessagingTransport.MESSAGE_DELIMITER_);
transportParts[1] = transportParts[1] || null;
return transportParts;
};