OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 define("mojo/public/js/bindings", [ | 5 define("mojo/public/js/bindings", [ |
6 "mojo/public/js/connection", | 6 "mojo/public/js/connection", |
7 "mojo/public/js/core", | 7 "mojo/public/js/core", |
8 "mojo/public/js/interface_types", | 8 "mojo/public/js/interface_types", |
9 ], function(connection, core, types) { | 9 ], function(connection, core, types) { |
10 | 10 |
11 // --------------------------------------------------------------------------- | 11 // --------------------------------------------------------------------------- |
12 | 12 |
13 function makeRequest(interfacePtr) { | 13 function makeRequest(interfacePtr) { |
14 var pipe = core.createMessagePipe(); | 14 var pipe = core.createMessagePipe(); |
15 interfacePtr.ptr.bind(new types.InterfacePtrInfo(pipe.handle0, 0)); | 15 interfacePtr.ptr.bind(new types.InterfacePtrInfo(pipe.handle0, 0)); |
16 return new types.InterfaceRequest(pipe.handle1); | 16 return new types.InterfaceRequest(pipe.handle1); |
17 } | 17 } |
18 | 18 |
19 // --------------------------------------------------------------------------- | 19 // --------------------------------------------------------------------------- |
20 | 20 |
21 // Operations used to setup/configure an interface pointer. Exposed as the | 21 // Operations used to setup/configure an interface pointer. Exposed as the |
22 // |ptr| field of generated interface pointer classes. | 22 // |ptr| field of generated interface pointer classes. |
23 function InterfacePtrController(interfaceType) { | 23 // |ptrInfoOrHandle| could be omitted and passed into bind() later. |
| 24 function InterfacePtrController(interfaceType, ptrInfoOrHandle) { |
24 this.version = 0; | 25 this.version = 0; |
25 | 26 |
26 this.interfaceType_ = interfaceType; | 27 this.interfaceType_ = interfaceType; |
27 this.connection_ = null; | 28 this.connection_ = null; |
28 // |connection_| is lazily initialized. |handle_| is valid between bind() | 29 // |connection_| is lazily initialized. |handle_| is valid between bind() |
29 // and the initialization of |connection_|. | 30 // and the initialization of |connection_|. |
30 this.handle_ = null; | 31 this.handle_ = null; |
| 32 |
| 33 if (ptrInfoOrHandle) |
| 34 this.bind(ptrInfoOrHandle); |
31 } | 35 } |
32 | 36 |
33 InterfacePtrController.prototype.bind = function(interfacePtrInfo) { | 37 InterfacePtrController.prototype.bind = function(ptrInfoOrHandle) { |
34 this.reset(); | 38 this.reset(); |
35 | 39 |
36 this.version = interfacePtrInfo.version; | 40 if (ptrInfoOrHandle instanceof types.InterfacePtrInfo) { |
37 this.handle_ = interfacePtrInfo.handle; | 41 this.version = ptrInfoOrHandle.version; |
| 42 this.handle_ = ptrInfoOrHandle.handle; |
| 43 } else { |
| 44 this.handle_ = ptrInfoOrHandle; |
| 45 } |
38 }; | 46 }; |
39 | 47 |
40 InterfacePtrController.prototype.isBound = function() { | 48 InterfacePtrController.prototype.isBound = function() { |
41 return this.connection_ !== null || this.handle_ !== null; | 49 return this.connection_ !== null || this.handle_ !== null; |
42 }; | 50 }; |
43 | 51 |
44 // Although users could just discard the object, reset() closes the pipe | 52 // Although users could just discard the object, reset() closes the pipe |
45 // immediately. | 53 // immediately. |
46 InterfacePtrController.prototype.reset = function() { | 54 InterfacePtrController.prototype.reset = function() { |
47 this.version = 0; | 55 this.version = 0; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
94 this.handle_ = null; | 102 this.handle_ = null; |
95 }; | 103 }; |
96 | 104 |
97 // TODO(yzshen): Implement the following methods. | 105 // TODO(yzshen): Implement the following methods. |
98 // InterfacePtrController.prototype.queryVersion | 106 // InterfacePtrController.prototype.queryVersion |
99 // InterfacePtrController.prototype.requireVersion | 107 // InterfacePtrController.prototype.requireVersion |
100 | 108 |
101 // --------------------------------------------------------------------------- | 109 // --------------------------------------------------------------------------- |
102 | 110 |
103 // |request| could be omitted and passed into bind() later. | 111 // |request| could be omitted and passed into bind() later. |
104 // NOTE: |impl| shouldn't hold a reference to this object, because that | |
105 // results in circular references. | |
106 // | 112 // |
107 // Example: | 113 // Example: |
108 // | 114 // |
109 // // FooImpl implements mojom.Foo. | 115 // // FooImpl implements mojom.Foo. |
110 // function FooImpl() { ... } | 116 // function FooImpl() { ... } |
111 // FooImpl.prototype.fooMethod1 = function() { ... } | 117 // FooImpl.prototype.fooMethod1 = function() { ... } |
112 // FooImpl.prototype.fooMethod2 = function() { ... } | 118 // FooImpl.prototype.fooMethod2 = function() { ... } |
113 // | 119 // |
114 // var fooPtr = new mojom.FooPtr(); | 120 // var fooPtr = new mojom.FooPtr(); |
115 // var request = makeRequest(fooPtr); | 121 // var request = makeRequest(fooPtr); |
116 // var binding = new Binding(mojom.Foo, new FooImpl(), request); | 122 // var binding = new Binding(mojom.Foo, new FooImpl(), request); |
117 // fooPtr.fooMethod1(); | 123 // fooPtr.fooMethod1(); |
118 function Binding(interfaceType, impl, request) { | 124 function Binding(interfaceType, impl, requestOrHandle) { |
119 this.interfaceType_ = interfaceType; | 125 this.interfaceType_ = interfaceType; |
120 this.impl_ = impl; | 126 this.impl_ = impl; |
121 this.stub_ = null; | 127 this.stub_ = null; |
122 | 128 |
123 if (request) | 129 if (requestOrHandle) |
124 this.bind(request); | 130 this.bind(requestOrHandle); |
125 } | 131 } |
126 | 132 |
127 Binding.prototype.isBound = function() { | 133 Binding.prototype.isBound = function() { |
128 return this.stub_ !== null; | 134 return this.stub_ !== null; |
129 }; | 135 }; |
130 | 136 |
131 Binding.prototype.createInterfacePtrAndBind = function() { | 137 Binding.prototype.createInterfacePtrAndBind = function() { |
132 var ptr = new this.interfaceType_.ptrClass(); | 138 var ptr = new this.interfaceType_.ptrClass(); |
133 // TODO(yzshen): Set the version of the interface pointer. | 139 // TODO(yzshen): Set the version of the interface pointer. |
134 this.bind(makeRequest(ptr)); | 140 this.bind(makeRequest(ptr)); |
135 return ptr; | 141 return ptr; |
136 } | 142 } |
137 | 143 |
138 Binding.prototype.bind = function(request) { | 144 Binding.prototype.bind = function(requestOrHandle) { |
139 this.close(); | 145 this.close(); |
140 if (request.isValid()) { | 146 |
141 this.stub_ = connection.bindHandleToStub(request.handle, | 147 var handle = requestOrHandle instanceof types.InterfaceRequest ? |
142 this.interfaceType_); | 148 requestOrHandle.handle : requestOrHandle; |
| 149 if (core.isHandle(handle)) { |
| 150 this.stub_ = connection.bindHandleToStub(handle, this.interfaceType_); |
143 connection.StubBindings(this.stub_).delegate = this.impl_; | 151 connection.StubBindings(this.stub_).delegate = this.impl_; |
144 } | 152 } |
145 }; | 153 }; |
146 | 154 |
147 Binding.prototype.close = function() { | 155 Binding.prototype.close = function() { |
148 if (!this.isBound()) | 156 if (!this.isBound()) |
149 return; | 157 return; |
150 connection.StubBindings(this.stub_).close(); | 158 connection.StubBindings(this.stub_).close(); |
151 this.stub_ = null; | 159 this.stub_ = null; |
152 }; | 160 }; |
(...skipping 12 matching lines...) Expand all Loading... |
165 | 173 |
166 var result = new types.InterfaceRequest( | 174 var result = new types.InterfaceRequest( |
167 connection.StubBindings(this.stub_).connection.router_.connector_ | 175 connection.StubBindings(this.stub_).connection.router_.connector_ |
168 .handle_); | 176 .handle_); |
169 connection.StubBindings(this.stub_).connection.router_.connector_.handle_ = | 177 connection.StubBindings(this.stub_).connection.router_.connector_.handle_ = |
170 null; | 178 null; |
171 this.close(); | 179 this.close(); |
172 return result; | 180 return result; |
173 }; | 181 }; |
174 | 182 |
| 183 // --------------------------------------------------------------------------- |
| 184 |
| 185 function BindingSetEntry(bindingSet, interfaceType, impl, requestOrHandle, |
| 186 bindingId) { |
| 187 this.bindingSet_ = bindingSet; |
| 188 this.bindingId_ = bindingId; |
| 189 this.binding_ = new Binding(interfaceType, impl, requestOrHandle); |
| 190 |
| 191 this.binding_.setConnectionErrorHandler( |
| 192 () => this.bindingSet_.onConnectionError(bindingId)); |
| 193 } |
| 194 |
| 195 BindingSetEntry.prototype.close = function() { |
| 196 this.binding_.close(); |
| 197 }; |
| 198 |
| 199 function BindingSet(interfaceType) { |
| 200 this.interfaceType_ = interfaceType; |
| 201 this.nextBindingId_ = 0; |
| 202 this.bindings_ = new Map(); |
| 203 this.errorHandler_ = null; |
| 204 } |
| 205 |
| 206 BindingSet.prototype.isEmpty = function() { |
| 207 return this.bindings_.size == 0; |
| 208 }; |
| 209 |
| 210 BindingSet.prototype.addBinding = function(impl, requestOrHandle) { |
| 211 this.bindings_.set( |
| 212 this.nextBindingId_, |
| 213 new BindingSetEntry(this, this.interfaceType_, impl, requestOrHandle, |
| 214 this.nextBindingId_)); |
| 215 ++this.nextBindingId_; |
| 216 }; |
| 217 |
| 218 BindingSet.prototype.closeAllBindings = function() { |
| 219 for (var entry of this.bindings_.values()) |
| 220 entry.close(); |
| 221 this.bindings_.clear(); |
| 222 }; |
| 223 |
| 224 BindingSet.prototype.setConnectionErrorHandler = function(callback) { |
| 225 this.errorHandler_ = callback; |
| 226 }; |
| 227 |
| 228 BindingSet.prototype.onConnectionError = function(bindingId) { |
| 229 this.bindings_.delete(bindingId); |
| 230 |
| 231 if (this.errorHandler_) |
| 232 this.errorHandler_(); |
| 233 }; |
| 234 |
175 var exports = {}; | 235 var exports = {}; |
176 exports.InterfacePtrInfo = types.InterfacePtrInfo; | 236 exports.InterfacePtrInfo = types.InterfacePtrInfo; |
177 exports.InterfaceRequest = types.InterfaceRequest; | 237 exports.InterfaceRequest = types.InterfaceRequest; |
178 exports.makeRequest = makeRequest; | 238 exports.makeRequest = makeRequest; |
179 exports.InterfacePtrController = InterfacePtrController; | 239 exports.InterfacePtrController = InterfacePtrController; |
180 exports.Binding = Binding; | 240 exports.Binding = Binding; |
| 241 exports.BindingSet = BindingSet; |
181 | 242 |
182 // TODO(yzshen): Remove the following exports. | 243 // TODO(yzshen): Remove the following exports. |
183 exports.EmptyProxy = connection.EmptyProxy; | 244 exports.EmptyProxy = connection.EmptyProxy; |
184 exports.EmptyStub = connection.EmptyStub; | 245 exports.EmptyStub = connection.EmptyStub; |
185 exports.ProxyBase = connection.ProxyBase; | 246 exports.ProxyBase = connection.ProxyBase; |
186 exports.ProxyBindings = connection.ProxyBindings; | 247 exports.ProxyBindings = connection.ProxyBindings; |
187 exports.StubBase = connection.StubBase; | 248 exports.StubBase = connection.StubBase; |
188 exports.StubBindings = connection.StubBindings; | 249 exports.StubBindings = connection.StubBindings; |
189 | 250 |
190 return exports; | 251 return exports; |
191 }); | 252 }); |
OLD | NEW |