1*635a8641SAndroid Build Coastguard Worker// Copyright 2014 The Chromium Authors. All rights reserved. 2*635a8641SAndroid Build Coastguard Worker// Use of this source code is governed by a BSD-style license that can be 3*635a8641SAndroid Build Coastguard Worker// found in the LICENSE file. 4*635a8641SAndroid Build Coastguard Worker 5*635a8641SAndroid Build Coastguard Worker(function() { 6*635a8641SAndroid Build Coastguard Worker var internal = mojo.internal; 7*635a8641SAndroid Build Coastguard Worker 8*635a8641SAndroid Build Coastguard Worker /** 9*635a8641SAndroid Build Coastguard Worker * The state of |endpoint|. If both the endpoint and its peer have been 10*635a8641SAndroid Build Coastguard Worker * closed, removes it from |endpoints_|. 11*635a8641SAndroid Build Coastguard Worker * @enum {string} 12*635a8641SAndroid Build Coastguard Worker */ 13*635a8641SAndroid Build Coastguard Worker var EndpointStateUpdateType = { 14*635a8641SAndroid Build Coastguard Worker ENDPOINT_CLOSED: 'endpoint_closed', 15*635a8641SAndroid Build Coastguard Worker PEER_ENDPOINT_CLOSED: 'peer_endpoint_closed' 16*635a8641SAndroid Build Coastguard Worker }; 17*635a8641SAndroid Build Coastguard Worker 18*635a8641SAndroid Build Coastguard Worker function check(condition, output) { 19*635a8641SAndroid Build Coastguard Worker if (!condition) { 20*635a8641SAndroid Build Coastguard Worker // testharness.js does not rethrow errors so the error stack needs to be 21*635a8641SAndroid Build Coastguard Worker // included as a string in the error we throw for debugging layout tests. 22*635a8641SAndroid Build Coastguard Worker throw new Error((new Error()).stack); 23*635a8641SAndroid Build Coastguard Worker } 24*635a8641SAndroid Build Coastguard Worker } 25*635a8641SAndroid Build Coastguard Worker 26*635a8641SAndroid Build Coastguard Worker function InterfaceEndpoint(router, interfaceId) { 27*635a8641SAndroid Build Coastguard Worker this.router_ = router; 28*635a8641SAndroid Build Coastguard Worker this.id = interfaceId; 29*635a8641SAndroid Build Coastguard Worker this.closed = false; 30*635a8641SAndroid Build Coastguard Worker this.peerClosed = false; 31*635a8641SAndroid Build Coastguard Worker this.handleCreated = false; 32*635a8641SAndroid Build Coastguard Worker this.disconnectReason = null; 33*635a8641SAndroid Build Coastguard Worker this.client = null; 34*635a8641SAndroid Build Coastguard Worker } 35*635a8641SAndroid Build Coastguard Worker 36*635a8641SAndroid Build Coastguard Worker InterfaceEndpoint.prototype.sendMessage = function(message) { 37*635a8641SAndroid Build Coastguard Worker message.setInterfaceId(this.id); 38*635a8641SAndroid Build Coastguard Worker return this.router_.connector_.accept(message); 39*635a8641SAndroid Build Coastguard Worker }; 40*635a8641SAndroid Build Coastguard Worker 41*635a8641SAndroid Build Coastguard Worker function Router(handle, setInterfaceIdNamespaceBit) { 42*635a8641SAndroid Build Coastguard Worker if (!(handle instanceof MojoHandle)) { 43*635a8641SAndroid Build Coastguard Worker throw new Error("Router constructor: Not a handle"); 44*635a8641SAndroid Build Coastguard Worker } 45*635a8641SAndroid Build Coastguard Worker if (setInterfaceIdNamespaceBit === undefined) { 46*635a8641SAndroid Build Coastguard Worker setInterfaceIdNamespaceBit = false; 47*635a8641SAndroid Build Coastguard Worker } 48*635a8641SAndroid Build Coastguard Worker 49*635a8641SAndroid Build Coastguard Worker this.connector_ = new internal.Connector(handle); 50*635a8641SAndroid Build Coastguard Worker 51*635a8641SAndroid Build Coastguard Worker this.connector_.setIncomingReceiver({ 52*635a8641SAndroid Build Coastguard Worker accept: this.accept.bind(this), 53*635a8641SAndroid Build Coastguard Worker }); 54*635a8641SAndroid Build Coastguard Worker this.connector_.setErrorHandler({ 55*635a8641SAndroid Build Coastguard Worker onError: this.onPipeConnectionError.bind(this), 56*635a8641SAndroid Build Coastguard Worker }); 57*635a8641SAndroid Build Coastguard Worker 58*635a8641SAndroid Build Coastguard Worker this.setInterfaceIdNamespaceBit_ = setInterfaceIdNamespaceBit; 59*635a8641SAndroid Build Coastguard Worker // |cachedMessageData| caches infomation about a message, so it can be 60*635a8641SAndroid Build Coastguard Worker // processed later if a client is not yet attached to the target endpoint. 61*635a8641SAndroid Build Coastguard Worker this.cachedMessageData = null; 62*635a8641SAndroid Build Coastguard Worker this.controlMessageHandler_ = new internal.PipeControlMessageHandler(this); 63*635a8641SAndroid Build Coastguard Worker this.controlMessageProxy_ = 64*635a8641SAndroid Build Coastguard Worker new internal.PipeControlMessageProxy(this.connector_); 65*635a8641SAndroid Build Coastguard Worker this.nextInterfaceIdValue_ = 1; 66*635a8641SAndroid Build Coastguard Worker this.encounteredError_ = false; 67*635a8641SAndroid Build Coastguard Worker this.endpoints_ = new Map(); 68*635a8641SAndroid Build Coastguard Worker } 69*635a8641SAndroid Build Coastguard Worker 70*635a8641SAndroid Build Coastguard Worker Router.prototype.associateInterface = function(handleToSend) { 71*635a8641SAndroid Build Coastguard Worker if (!handleToSend.pendingAssociation()) { 72*635a8641SAndroid Build Coastguard Worker return internal.kInvalidInterfaceId; 73*635a8641SAndroid Build Coastguard Worker } 74*635a8641SAndroid Build Coastguard Worker 75*635a8641SAndroid Build Coastguard Worker var id = 0; 76*635a8641SAndroid Build Coastguard Worker do { 77*635a8641SAndroid Build Coastguard Worker if (this.nextInterfaceIdValue_ >= internal.kInterfaceIdNamespaceMask) { 78*635a8641SAndroid Build Coastguard Worker this.nextInterfaceIdValue_ = 1; 79*635a8641SAndroid Build Coastguard Worker } 80*635a8641SAndroid Build Coastguard Worker id = this.nextInterfaceIdValue_++; 81*635a8641SAndroid Build Coastguard Worker if (this.setInterfaceIdNamespaceBit_) { 82*635a8641SAndroid Build Coastguard Worker id += internal.kInterfaceIdNamespaceMask; 83*635a8641SAndroid Build Coastguard Worker } 84*635a8641SAndroid Build Coastguard Worker } while (this.endpoints_.has(id)); 85*635a8641SAndroid Build Coastguard Worker 86*635a8641SAndroid Build Coastguard Worker var endpoint = new InterfaceEndpoint(this, id); 87*635a8641SAndroid Build Coastguard Worker this.endpoints_.set(id, endpoint); 88*635a8641SAndroid Build Coastguard Worker if (this.encounteredError_) { 89*635a8641SAndroid Build Coastguard Worker this.updateEndpointStateMayRemove(endpoint, 90*635a8641SAndroid Build Coastguard Worker EndpointStateUpdateType.PEER_ENDPOINT_CLOSED); 91*635a8641SAndroid Build Coastguard Worker } 92*635a8641SAndroid Build Coastguard Worker endpoint.handleCreated = true; 93*635a8641SAndroid Build Coastguard Worker 94*635a8641SAndroid Build Coastguard Worker if (!handleToSend.notifyAssociation(id, this)) { 95*635a8641SAndroid Build Coastguard Worker // The peer handle of |handleToSend|, which is supposed to join this 96*635a8641SAndroid Build Coastguard Worker // associated group, has been closed. 97*635a8641SAndroid Build Coastguard Worker this.updateEndpointStateMayRemove(endpoint, 98*635a8641SAndroid Build Coastguard Worker EndpointStateUpdateType.ENDPOINT_CLOSED); 99*635a8641SAndroid Build Coastguard Worker 100*635a8641SAndroid Build Coastguard Worker pipeControlMessageproxy.notifyPeerEndpointClosed(id, 101*635a8641SAndroid Build Coastguard Worker handleToSend.disconnectReason()); 102*635a8641SAndroid Build Coastguard Worker } 103*635a8641SAndroid Build Coastguard Worker 104*635a8641SAndroid Build Coastguard Worker return id; 105*635a8641SAndroid Build Coastguard Worker }; 106*635a8641SAndroid Build Coastguard Worker 107*635a8641SAndroid Build Coastguard Worker Router.prototype.attachEndpointClient = function( 108*635a8641SAndroid Build Coastguard Worker interfaceEndpointHandle, interfaceEndpointClient) { 109*635a8641SAndroid Build Coastguard Worker check(internal.isValidInterfaceId(interfaceEndpointHandle.id())); 110*635a8641SAndroid Build Coastguard Worker check(interfaceEndpointClient); 111*635a8641SAndroid Build Coastguard Worker 112*635a8641SAndroid Build Coastguard Worker var endpoint = this.endpoints_.get(interfaceEndpointHandle.id()); 113*635a8641SAndroid Build Coastguard Worker check(endpoint); 114*635a8641SAndroid Build Coastguard Worker check(!endpoint.client); 115*635a8641SAndroid Build Coastguard Worker check(!endpoint.closed); 116*635a8641SAndroid Build Coastguard Worker endpoint.client = interfaceEndpointClient; 117*635a8641SAndroid Build Coastguard Worker 118*635a8641SAndroid Build Coastguard Worker if (endpoint.peerClosed) { 119*635a8641SAndroid Build Coastguard Worker setTimeout(endpoint.client.notifyError.bind(endpoint.client), 0); 120*635a8641SAndroid Build Coastguard Worker } 121*635a8641SAndroid Build Coastguard Worker 122*635a8641SAndroid Build Coastguard Worker if (this.cachedMessageData && interfaceEndpointHandle.id() === 123*635a8641SAndroid Build Coastguard Worker this.cachedMessageData.message.getInterfaceId()) { 124*635a8641SAndroid Build Coastguard Worker setTimeout((function() { 125*635a8641SAndroid Build Coastguard Worker if (!this.cachedMessageData) { 126*635a8641SAndroid Build Coastguard Worker return; 127*635a8641SAndroid Build Coastguard Worker } 128*635a8641SAndroid Build Coastguard Worker 129*635a8641SAndroid Build Coastguard Worker var targetEndpoint = this.endpoints_.get( 130*635a8641SAndroid Build Coastguard Worker this.cachedMessageData.message.getInterfaceId()); 131*635a8641SAndroid Build Coastguard Worker // Check that the target endpoint's client still exists. 132*635a8641SAndroid Build Coastguard Worker if (targetEndpoint && targetEndpoint.client) { 133*635a8641SAndroid Build Coastguard Worker var message = this.cachedMessageData.message; 134*635a8641SAndroid Build Coastguard Worker var messageValidator = this.cachedMessageData.messageValidator; 135*635a8641SAndroid Build Coastguard Worker this.cachedMessageData = null; 136*635a8641SAndroid Build Coastguard Worker this.connector_.resumeIncomingMethodCallProcessing(); 137*635a8641SAndroid Build Coastguard Worker var ok = endpoint.client.handleIncomingMessage(message, 138*635a8641SAndroid Build Coastguard Worker messageValidator); 139*635a8641SAndroid Build Coastguard Worker 140*635a8641SAndroid Build Coastguard Worker // Handle invalid cached incoming message. 141*635a8641SAndroid Build Coastguard Worker if (!internal.isTestingMode() && !ok) { 142*635a8641SAndroid Build Coastguard Worker this.connector_.handleError(true, true); 143*635a8641SAndroid Build Coastguard Worker } 144*635a8641SAndroid Build Coastguard Worker } 145*635a8641SAndroid Build Coastguard Worker }).bind(this), 0); 146*635a8641SAndroid Build Coastguard Worker } 147*635a8641SAndroid Build Coastguard Worker 148*635a8641SAndroid Build Coastguard Worker return endpoint; 149*635a8641SAndroid Build Coastguard Worker }; 150*635a8641SAndroid Build Coastguard Worker 151*635a8641SAndroid Build Coastguard Worker Router.prototype.detachEndpointClient = function( 152*635a8641SAndroid Build Coastguard Worker interfaceEndpointHandle) { 153*635a8641SAndroid Build Coastguard Worker check(internal.isValidInterfaceId(interfaceEndpointHandle.id())); 154*635a8641SAndroid Build Coastguard Worker var endpoint = this.endpoints_.get(interfaceEndpointHandle.id()); 155*635a8641SAndroid Build Coastguard Worker check(endpoint); 156*635a8641SAndroid Build Coastguard Worker check(endpoint.client); 157*635a8641SAndroid Build Coastguard Worker check(!endpoint.closed); 158*635a8641SAndroid Build Coastguard Worker 159*635a8641SAndroid Build Coastguard Worker endpoint.client = null; 160*635a8641SAndroid Build Coastguard Worker }; 161*635a8641SAndroid Build Coastguard Worker 162*635a8641SAndroid Build Coastguard Worker Router.prototype.createLocalEndpointHandle = function( 163*635a8641SAndroid Build Coastguard Worker interfaceId) { 164*635a8641SAndroid Build Coastguard Worker if (!internal.isValidInterfaceId(interfaceId)) { 165*635a8641SAndroid Build Coastguard Worker return new internal.InterfaceEndpointHandle(); 166*635a8641SAndroid Build Coastguard Worker } 167*635a8641SAndroid Build Coastguard Worker 168*635a8641SAndroid Build Coastguard Worker // Unless it is the master ID, |interfaceId| is from the remote side and 169*635a8641SAndroid Build Coastguard Worker // therefore its namespace bit is supposed to be different than the value 170*635a8641SAndroid Build Coastguard Worker // that this router would use. 171*635a8641SAndroid Build Coastguard Worker if (!internal.isMasterInterfaceId(interfaceId) && 172*635a8641SAndroid Build Coastguard Worker this.setInterfaceIdNamespaceBit_ === 173*635a8641SAndroid Build Coastguard Worker internal.hasInterfaceIdNamespaceBitSet(interfaceId)) { 174*635a8641SAndroid Build Coastguard Worker return new internal.InterfaceEndpointHandle(); 175*635a8641SAndroid Build Coastguard Worker } 176*635a8641SAndroid Build Coastguard Worker 177*635a8641SAndroid Build Coastguard Worker var endpoint = this.endpoints_.get(interfaceId); 178*635a8641SAndroid Build Coastguard Worker 179*635a8641SAndroid Build Coastguard Worker if (!endpoint) { 180*635a8641SAndroid Build Coastguard Worker endpoint = new InterfaceEndpoint(this, interfaceId); 181*635a8641SAndroid Build Coastguard Worker this.endpoints_.set(interfaceId, endpoint); 182*635a8641SAndroid Build Coastguard Worker 183*635a8641SAndroid Build Coastguard Worker check(!endpoint.handleCreated); 184*635a8641SAndroid Build Coastguard Worker 185*635a8641SAndroid Build Coastguard Worker if (this.encounteredError_) { 186*635a8641SAndroid Build Coastguard Worker this.updateEndpointStateMayRemove(endpoint, 187*635a8641SAndroid Build Coastguard Worker EndpointStateUpdateType.PEER_ENDPOINT_CLOSED); 188*635a8641SAndroid Build Coastguard Worker } 189*635a8641SAndroid Build Coastguard Worker } else { 190*635a8641SAndroid Build Coastguard Worker // If the endpoint already exist, it is because we have received a 191*635a8641SAndroid Build Coastguard Worker // notification that the peer endpoint has closed. 192*635a8641SAndroid Build Coastguard Worker check(!endpoint.closed); 193*635a8641SAndroid Build Coastguard Worker check(endpoint.peerClosed); 194*635a8641SAndroid Build Coastguard Worker 195*635a8641SAndroid Build Coastguard Worker if (endpoint.handleCreated) { 196*635a8641SAndroid Build Coastguard Worker return new internal.InterfaceEndpointHandle(); 197*635a8641SAndroid Build Coastguard Worker } 198*635a8641SAndroid Build Coastguard Worker } 199*635a8641SAndroid Build Coastguard Worker 200*635a8641SAndroid Build Coastguard Worker endpoint.handleCreated = true; 201*635a8641SAndroid Build Coastguard Worker return new internal.InterfaceEndpointHandle(interfaceId, this); 202*635a8641SAndroid Build Coastguard Worker }; 203*635a8641SAndroid Build Coastguard Worker 204*635a8641SAndroid Build Coastguard Worker Router.prototype.accept = function(message) { 205*635a8641SAndroid Build Coastguard Worker var messageValidator = new internal.Validator(message); 206*635a8641SAndroid Build Coastguard Worker var err = messageValidator.validateMessageHeader(); 207*635a8641SAndroid Build Coastguard Worker 208*635a8641SAndroid Build Coastguard Worker var ok = false; 209*635a8641SAndroid Build Coastguard Worker if (err !== internal.validationError.NONE) { 210*635a8641SAndroid Build Coastguard Worker internal.reportValidationError(err); 211*635a8641SAndroid Build Coastguard Worker } else if (message.deserializeAssociatedEndpointHandles(this)) { 212*635a8641SAndroid Build Coastguard Worker if (internal.isPipeControlMessage(message)) { 213*635a8641SAndroid Build Coastguard Worker ok = this.controlMessageHandler_.accept(message); 214*635a8641SAndroid Build Coastguard Worker } else { 215*635a8641SAndroid Build Coastguard Worker var interfaceId = message.getInterfaceId(); 216*635a8641SAndroid Build Coastguard Worker var endpoint = this.endpoints_.get(interfaceId); 217*635a8641SAndroid Build Coastguard Worker if (!endpoint || endpoint.closed) { 218*635a8641SAndroid Build Coastguard Worker return true; 219*635a8641SAndroid Build Coastguard Worker } 220*635a8641SAndroid Build Coastguard Worker 221*635a8641SAndroid Build Coastguard Worker if (!endpoint.client) { 222*635a8641SAndroid Build Coastguard Worker // We need to wait until a client is attached in order to dispatch 223*635a8641SAndroid Build Coastguard Worker // further messages. 224*635a8641SAndroid Build Coastguard Worker this.cachedMessageData = {message: message, 225*635a8641SAndroid Build Coastguard Worker messageValidator: messageValidator}; 226*635a8641SAndroid Build Coastguard Worker this.connector_.pauseIncomingMethodCallProcessing(); 227*635a8641SAndroid Build Coastguard Worker return true; 228*635a8641SAndroid Build Coastguard Worker } 229*635a8641SAndroid Build Coastguard Worker ok = endpoint.client.handleIncomingMessage(message, messageValidator); 230*635a8641SAndroid Build Coastguard Worker } 231*635a8641SAndroid Build Coastguard Worker } 232*635a8641SAndroid Build Coastguard Worker return ok; 233*635a8641SAndroid Build Coastguard Worker }; 234*635a8641SAndroid Build Coastguard Worker 235*635a8641SAndroid Build Coastguard Worker Router.prototype.close = function() { 236*635a8641SAndroid Build Coastguard Worker this.connector_.close(); 237*635a8641SAndroid Build Coastguard Worker // Closing the message pipe won't trigger connection error handler. 238*635a8641SAndroid Build Coastguard Worker // Explicitly call onPipeConnectionError() so that associated endpoints 239*635a8641SAndroid Build Coastguard Worker // will get notified. 240*635a8641SAndroid Build Coastguard Worker this.onPipeConnectionError(); 241*635a8641SAndroid Build Coastguard Worker }; 242*635a8641SAndroid Build Coastguard Worker 243*635a8641SAndroid Build Coastguard Worker Router.prototype.onPeerAssociatedEndpointClosed = function(interfaceId, 244*635a8641SAndroid Build Coastguard Worker reason) { 245*635a8641SAndroid Build Coastguard Worker var endpoint = this.endpoints_.get(interfaceId); 246*635a8641SAndroid Build Coastguard Worker if (!endpoint) { 247*635a8641SAndroid Build Coastguard Worker endpoint = new InterfaceEndpoint(this, interfaceId); 248*635a8641SAndroid Build Coastguard Worker this.endpoints_.set(interfaceId, endpoint); 249*635a8641SAndroid Build Coastguard Worker } 250*635a8641SAndroid Build Coastguard Worker 251*635a8641SAndroid Build Coastguard Worker if (reason) { 252*635a8641SAndroid Build Coastguard Worker endpoint.disconnectReason = reason; 253*635a8641SAndroid Build Coastguard Worker } 254*635a8641SAndroid Build Coastguard Worker 255*635a8641SAndroid Build Coastguard Worker if (!endpoint.peerClosed) { 256*635a8641SAndroid Build Coastguard Worker if (endpoint.client) { 257*635a8641SAndroid Build Coastguard Worker setTimeout(endpoint.client.notifyError.bind(endpoint.client, reason), 258*635a8641SAndroid Build Coastguard Worker 0); 259*635a8641SAndroid Build Coastguard Worker } 260*635a8641SAndroid Build Coastguard Worker this.updateEndpointStateMayRemove(endpoint, 261*635a8641SAndroid Build Coastguard Worker EndpointStateUpdateType.PEER_ENDPOINT_CLOSED); 262*635a8641SAndroid Build Coastguard Worker } 263*635a8641SAndroid Build Coastguard Worker return true; 264*635a8641SAndroid Build Coastguard Worker }; 265*635a8641SAndroid Build Coastguard Worker 266*635a8641SAndroid Build Coastguard Worker Router.prototype.onPipeConnectionError = function() { 267*635a8641SAndroid Build Coastguard Worker this.encounteredError_ = true; 268*635a8641SAndroid Build Coastguard Worker 269*635a8641SAndroid Build Coastguard Worker for (var endpoint of this.endpoints_.values()) { 270*635a8641SAndroid Build Coastguard Worker if (endpoint.client) { 271*635a8641SAndroid Build Coastguard Worker setTimeout( 272*635a8641SAndroid Build Coastguard Worker endpoint.client.notifyError.bind( 273*635a8641SAndroid Build Coastguard Worker endpoint.client, endpoint.disconnectReason), 274*635a8641SAndroid Build Coastguard Worker 0); 275*635a8641SAndroid Build Coastguard Worker } 276*635a8641SAndroid Build Coastguard Worker this.updateEndpointStateMayRemove(endpoint, 277*635a8641SAndroid Build Coastguard Worker EndpointStateUpdateType.PEER_ENDPOINT_CLOSED); 278*635a8641SAndroid Build Coastguard Worker } 279*635a8641SAndroid Build Coastguard Worker }; 280*635a8641SAndroid Build Coastguard Worker 281*635a8641SAndroid Build Coastguard Worker Router.prototype.closeEndpointHandle = function(interfaceId, reason) { 282*635a8641SAndroid Build Coastguard Worker if (!internal.isValidInterfaceId(interfaceId)) { 283*635a8641SAndroid Build Coastguard Worker return; 284*635a8641SAndroid Build Coastguard Worker } 285*635a8641SAndroid Build Coastguard Worker var endpoint = this.endpoints_.get(interfaceId); 286*635a8641SAndroid Build Coastguard Worker check(endpoint); 287*635a8641SAndroid Build Coastguard Worker check(!endpoint.client); 288*635a8641SAndroid Build Coastguard Worker check(!endpoint.closed); 289*635a8641SAndroid Build Coastguard Worker 290*635a8641SAndroid Build Coastguard Worker this.updateEndpointStateMayRemove(endpoint, 291*635a8641SAndroid Build Coastguard Worker EndpointStateUpdateType.ENDPOINT_CLOSED); 292*635a8641SAndroid Build Coastguard Worker 293*635a8641SAndroid Build Coastguard Worker if (!internal.isMasterInterfaceId(interfaceId) || reason) { 294*635a8641SAndroid Build Coastguard Worker this.controlMessageProxy_.notifyPeerEndpointClosed(interfaceId, reason); 295*635a8641SAndroid Build Coastguard Worker } 296*635a8641SAndroid Build Coastguard Worker 297*635a8641SAndroid Build Coastguard Worker if (this.cachedMessageData && interfaceId === 298*635a8641SAndroid Build Coastguard Worker this.cachedMessageData.message.getInterfaceId()) { 299*635a8641SAndroid Build Coastguard Worker this.cachedMessageData = null; 300*635a8641SAndroid Build Coastguard Worker this.connector_.resumeIncomingMethodCallProcessing(); 301*635a8641SAndroid Build Coastguard Worker } 302*635a8641SAndroid Build Coastguard Worker }; 303*635a8641SAndroid Build Coastguard Worker 304*635a8641SAndroid Build Coastguard Worker Router.prototype.updateEndpointStateMayRemove = function(endpoint, 305*635a8641SAndroid Build Coastguard Worker endpointStateUpdateType) { 306*635a8641SAndroid Build Coastguard Worker if (endpointStateUpdateType === EndpointStateUpdateType.ENDPOINT_CLOSED) { 307*635a8641SAndroid Build Coastguard Worker endpoint.closed = true; 308*635a8641SAndroid Build Coastguard Worker } else { 309*635a8641SAndroid Build Coastguard Worker endpoint.peerClosed = true; 310*635a8641SAndroid Build Coastguard Worker } 311*635a8641SAndroid Build Coastguard Worker if (endpoint.closed && endpoint.peerClosed) { 312*635a8641SAndroid Build Coastguard Worker this.endpoints_.delete(endpoint.id); 313*635a8641SAndroid Build Coastguard Worker } 314*635a8641SAndroid Build Coastguard Worker }; 315*635a8641SAndroid Build Coastguard Worker 316*635a8641SAndroid Build Coastguard Worker internal.Router = Router; 317*635a8641SAndroid Build Coastguard Worker})(); 318