OLD | NEW |
| (Empty) |
1 // Copyright 2017 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 define("mojo/public/js/lib/interface_endpoint_handle", [ | |
6 "mojo/public/js/interface_types", | |
7 "timer", | |
8 ], function(types, timer) { | |
9 | |
10 var AssociationEvent = { | |
11 // The interface has been associated with a message pipe. | |
12 ASSOCIATED: 'associated', | |
13 // The peer of this object has been closed before association. | |
14 PEER_CLOSED_BEFORE_ASSOCIATION: 'peer_closed_before_association' | |
15 }; | |
16 | |
17 function State(interfaceId, associatedGroupController) { | |
18 if (interfaceId === undefined) { | |
19 interfaceId = types.kInvalidInterfaceId; | |
20 } | |
21 | |
22 this.interfaceId = interfaceId; | |
23 this.associatedGroupController = associatedGroupController; | |
24 this.pendingAssociation = false; | |
25 this.disconnectReason = null; | |
26 this.peerState_ = null; | |
27 this.associationEventHandler_ = null; | |
28 } | |
29 | |
30 State.prototype.initPendingState = function(peer) { | |
31 this.pendingAssociation = true; | |
32 this.peerState_ = peer; | |
33 }; | |
34 | |
35 State.prototype.isValid = function() { | |
36 return this.pendingAssociation || | |
37 types.isValidInterfaceId(this.interfaceId); | |
38 }; | |
39 | |
40 State.prototype.close = function(disconnectReason) { | |
41 var cachedGroupController; | |
42 var cachedPeerState; | |
43 var cachedId = types.kInvalidInterfaceId; | |
44 | |
45 if (!this.pendingAssociation) { | |
46 if (types.isValidInterfaceId(this.interfaceId)) { | |
47 cachedGroupController = this.associatedGroupController; | |
48 this.associatedGroupController = null; | |
49 cachedId = this.interfaceId; | |
50 this.interfaceId = types.kInvalidInterfaceId; | |
51 } | |
52 } else { | |
53 this.pendingAssociation = false; | |
54 cachedPeerState = this.peerState_; | |
55 this.peerState_ = null; | |
56 } | |
57 | |
58 if (cachedGroupController) { | |
59 cachedGroupController.closeEndpointHandle(cachedId, | |
60 disconnectReason); | |
61 } else if (cachedPeerState) { | |
62 cachedPeerState.onPeerClosedBeforeAssociation(disconnectReason); | |
63 } | |
64 }; | |
65 | |
66 State.prototype.runAssociationEventHandler = function(associationEvent) { | |
67 if (this.associationEventHandler_) { | |
68 var handler = this.associationEventHandler_; | |
69 this.associationEventHandler_ = null; | |
70 handler(associationEvent); | |
71 } | |
72 }; | |
73 | |
74 State.prototype.setAssociationEventHandler = function(handler) { | |
75 if (!this.pendingAssociation && | |
76 !types.isValidInterfaceId(this.interfaceId)) { | |
77 return; | |
78 } | |
79 | |
80 if (!handler) { | |
81 this.associationEventHandler_ = null; | |
82 return; | |
83 } | |
84 | |
85 this.associationEventHandler_ = handler; | |
86 if (!this.pendingAssociation) { | |
87 timer.createOneShot(0, this.runAssociationEventHandler.bind(this, | |
88 AssociationEvent.ASSOCIATED)); | |
89 } else if (!this.peerState_) { | |
90 timer.createOneShot(0, this.runAssociationEventHandler.bind(this, | |
91 AssociationEvent.PEER_CLOSED_BEFORE_ASSOCIATION)); | |
92 } | |
93 }; | |
94 | |
95 State.prototype.onAssociated = function(interfaceId, | |
96 associatedGroupController) { | |
97 if (!this.pendingAssociation) { | |
98 return; | |
99 } | |
100 | |
101 this.pendingAssociation = false; | |
102 this.peerState_ = null; | |
103 this.interfaceId = interfaceId; | |
104 this.associatedGroupController = associatedGroupController; | |
105 this.runAssociationEventHandler(AssociationEvent.ASSOCIATED); | |
106 }; | |
107 | |
108 State.prototype.onPeerClosedBeforeAssociation = function(disconnectReason) { | |
109 if (!this.pendingAssociation) { | |
110 return; | |
111 } | |
112 | |
113 this.peerState_ = null; | |
114 this.disconnectReason = disconnectReason; | |
115 | |
116 this.runAssociationEventHandler( | |
117 AssociationEvent.PEER_CLOSED_BEFORE_ASSOCIATION); | |
118 }; | |
119 | |
120 function InterfaceEndpointHandle(interfaceId, associatedGroupController) { | |
121 this.state_ = new State(interfaceId, associatedGroupController); | |
122 } | |
123 | |
124 InterfaceEndpointHandle.prototype.isValid = function() { | |
125 return this.state_.isValid(); | |
126 }; | |
127 | |
128 InterfaceEndpointHandle.prototype.pendingAssociation = function() { | |
129 return this.state_.pendingAssociation; | |
130 }; | |
131 | |
132 InterfaceEndpointHandle.prototype.id = function() { | |
133 return this.state_.interfaceId; | |
134 }; | |
135 | |
136 InterfaceEndpointHandle.prototype.groupController = function() { | |
137 return this.state_.associatedGroupController; | |
138 }; | |
139 | |
140 InterfaceEndpointHandle.prototype.disconnectReason = function() { | |
141 return this.state_.disconnectReason; | |
142 }; | |
143 | |
144 InterfaceEndpointHandle.prototype.setAssociationEventHandler = function( | |
145 handler) { | |
146 this.state_.setAssociationEventHandler(handler); | |
147 }; | |
148 | |
149 InterfaceEndpointHandle.prototype.reset = function(reason) { | |
150 this.state_.close(reason); | |
151 this.state_ = new State(); | |
152 }; | |
153 | |
154 var exports = {}; | |
155 exports.InterfaceEndpointHandle = InterfaceEndpointHandle; | |
156 | |
157 return exports; | |
158 }); | |
OLD | NEW |