| Index: mojo/public/js/lib/interface_endpoint_handle.js
|
| diff --git a/mojo/public/js/lib/interface_endpoint_handle.js b/mojo/public/js/lib/interface_endpoint_handle.js
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..f48b89ba85c71a372fd8d03c119a578fa8425cc8
|
| --- /dev/null
|
| +++ b/mojo/public/js/lib/interface_endpoint_handle.js
|
| @@ -0,0 +1,158 @@
|
| +// Copyright 2017 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.
|
| +
|
| +define("mojo/public/js/lib/interface_endpoint_handle", [
|
| + "mojo/public/js/interface_types",
|
| + "timer",
|
| +], function(types, timer) {
|
| +
|
| + var AssociationEvent = {
|
| + // The interface has been associated with a message pipe.
|
| + ASSOCIATED: 'associated',
|
| + // The peer of this object has been closed before association.
|
| + PEER_CLOSED_BEFORE_ASSOCIATION: 'peer_closed_before_association'
|
| + };
|
| +
|
| + function State(interfaceId, associatedGroupController) {
|
| + if (interfaceId === undefined) {
|
| + interfaceId = types.kInvalidInterfaceId;
|
| + }
|
| +
|
| + this.interfaceId = interfaceId;
|
| + this.associatedGroupController = associatedGroupController;
|
| + this.pendingAssociation = false;
|
| + this.disconnectReason = null;
|
| + this.peerState_ = null;
|
| + this.associationEventHandler_ = null;
|
| + }
|
| +
|
| + State.prototype.initPendingState = function(peer) {
|
| + this.pendingAssociation = true;
|
| + this.peerState_ = peer;
|
| + };
|
| +
|
| + State.prototype.isValid = function() {
|
| + return this.pendingAssociation ||
|
| + types.isValidInterfaceId(this.interfaceId);
|
| + };
|
| +
|
| + State.prototype.close = function(disconnectReason) {
|
| + var cachedGroupController;
|
| + var cachedPeerState;
|
| + var cachedId = types.kInvalidInterfaceId;
|
| +
|
| + if (!this.pendingAssociation) {
|
| + if (types.isValidInterfaceId(this.interfaceId)) {
|
| + cachedGroupController = this.associatedGroupController;
|
| + this.associatedGroupController = null;
|
| + cachedId = this.interfaceId;
|
| + this.interfaceId = types.kInvalidInterfaceId;
|
| + }
|
| + } else {
|
| + this.pendingAssociation = false;
|
| + cachedPeerState = this.peerState_;
|
| + this.peerState_ = null;
|
| + }
|
| +
|
| + if (cachedGroupController) {
|
| + cachedGroupController.closeEndpointHandle(cachedId,
|
| + disconnectReason);
|
| + } else if (cachedPeerState) {
|
| + cachedPeerState.onPeerClosedBeforeAssociation(disconnectReason);
|
| + }
|
| + };
|
| +
|
| + State.prototype.runAssociationEventHandler = function(associationEvent) {
|
| + if (this.associationEventHandler_) {
|
| + var handler = this.associationEventHandler_;
|
| + this.associationEventHandler_ = null;
|
| + handler(associationEvent);
|
| + }
|
| + };
|
| +
|
| + State.prototype.setAssociationEventHandler = function(handler) {
|
| + if (!this.pendingAssociation &&
|
| + !types.isValidInterfaceId(this.interfaceId)) {
|
| + return;
|
| + }
|
| +
|
| + if (!handler) {
|
| + this.associationEventHandler_ = null;
|
| + return;
|
| + }
|
| +
|
| + this.associationEventHandler_ = handler;
|
| + if (!this.pendingAssociation) {
|
| + timer.createOneShot(0, this.runAssociationEventHandler.bind(this,
|
| + AssociationEvent.ASSOCIATED));
|
| + } else if (!this.peerState_) {
|
| + timer.createOneShot(0, this.runAssociationEventHandler.bind(this,
|
| + AssociationEvent.PEER_CLOSED_BEFORE_ASSOCIATION));
|
| + }
|
| + };
|
| +
|
| + State.prototype.onAssociated = function(interfaceId,
|
| + associatedGroupController) {
|
| + if (!this.pendingAssociation) {
|
| + return;
|
| + }
|
| +
|
| + this.pendingAssociation = false;
|
| + this.peerState_ = null;
|
| + this.interfaceId = interfaceId;
|
| + this.associatedGroupController = associatedGroupController;
|
| + this.runAssociationEventHandler(AssociationEvent.ASSOCIATED);
|
| + };
|
| +
|
| + State.prototype.onPeerClosedBeforeAssociation = function(disconnectReason) {
|
| + if (!this.pendingAssociation) {
|
| + return;
|
| + }
|
| +
|
| + this.peerState_ = null;
|
| + this.disconnectReason = disconnectReason;
|
| +
|
| + this.runAssociationEventHandler(
|
| + AssociationEvent.PEER_CLOSED_BEFORE_ASSOCIATION);
|
| + };
|
| +
|
| + function InterfaceEndpointHandle(interfaceId, associatedGroupController) {
|
| + this.state_ = new State(interfaceId, associatedGroupController);
|
| + }
|
| +
|
| + InterfaceEndpointHandle.prototype.isValid = function() {
|
| + return this.state_.isValid();
|
| + };
|
| +
|
| + InterfaceEndpointHandle.prototype.pendingAssociation = function() {
|
| + return this.state_.pendingAssociation;
|
| + };
|
| +
|
| + InterfaceEndpointHandle.prototype.id = function() {
|
| + return this.state_.interfaceId;
|
| + };
|
| +
|
| + InterfaceEndpointHandle.prototype.groupController = function() {
|
| + return this.state_.associatedGroupController;
|
| + };
|
| +
|
| + InterfaceEndpointHandle.prototype.disconnectReason = function() {
|
| + return this.state_.disconnectReason;
|
| + };
|
| +
|
| + InterfaceEndpointHandle.prototype.setAssociationEventHandler = function(
|
| + handler) {
|
| + this.state_.setAssociationEventHandler(handler);
|
| + };
|
| +
|
| + InterfaceEndpointHandle.prototype.reset = function(reason) {
|
| + this.state_.close(reason);
|
| + this.state_ = new State();
|
| + };
|
| +
|
| + var exports = {};
|
| + exports.InterfaceEndpointHandle = InterfaceEndpointHandle;
|
| +
|
| + return exports;
|
| +});
|
|
|