| 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", | |
| 7 "mojo/public/js/core", | 6 "mojo/public/js/core", |
| 8 "mojo/public/js/interface_types", | 7 "mojo/public/js/interface_types", |
| 9 ], function(connection, core, types) { | 8 "mojo/public/js/router", |
| 9 ], function(core, types, router) { |
| 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 // |ptrInfoOrHandle| could be omitted and passed into bind() later. | 23 // |ptrInfoOrHandle| could be omitted and passed into bind() later. |
| 24 function InterfacePtrController(interfaceType, ptrInfoOrHandle) { | 24 function InterfacePtrController(interfaceType, ptrInfoOrHandle) { |
| 25 this.version = 0; | 25 this.version = 0; |
| 26 | 26 |
| 27 this.interfaceType_ = interfaceType; | 27 this.interfaceType_ = interfaceType; |
| 28 this.connection_ = null; | 28 this.router_ = null; |
| 29 // |connection_| is lazily initialized. |handle_| is valid between bind() | 29 this.proxy_ = null; |
| 30 // and the initialization of |connection_|. | 30 |
| 31 // |router_| is lazily initialized. |handle_| is valid between bind() and |
| 32 // the initialization of |router_|. |
| 31 this.handle_ = null; | 33 this.handle_ = null; |
| 32 | 34 |
| 33 if (ptrInfoOrHandle) | 35 if (ptrInfoOrHandle) |
| 34 this.bind(ptrInfoOrHandle); | 36 this.bind(ptrInfoOrHandle); |
| 35 } | 37 } |
| 36 | 38 |
| 37 InterfacePtrController.prototype.bind = function(ptrInfoOrHandle) { | 39 InterfacePtrController.prototype.bind = function(ptrInfoOrHandle) { |
| 38 this.reset(); | 40 this.reset(); |
| 39 | 41 |
| 40 if (ptrInfoOrHandle instanceof types.InterfacePtrInfo) { | 42 if (ptrInfoOrHandle instanceof types.InterfacePtrInfo) { |
| 41 this.version = ptrInfoOrHandle.version; | 43 this.version = ptrInfoOrHandle.version; |
| 42 this.handle_ = ptrInfoOrHandle.handle; | 44 this.handle_ = ptrInfoOrHandle.handle; |
| 43 } else { | 45 } else { |
| 44 this.handle_ = ptrInfoOrHandle; | 46 this.handle_ = ptrInfoOrHandle; |
| 45 } | 47 } |
| 46 }; | 48 }; |
| 47 | 49 |
| 48 InterfacePtrController.prototype.isBound = function() { | 50 InterfacePtrController.prototype.isBound = function() { |
| 49 return this.connection_ !== null || this.handle_ !== null; | 51 return this.router_ !== null || this.handle_ !== null; |
| 50 }; | 52 }; |
| 51 | 53 |
| 52 // Although users could just discard the object, reset() closes the pipe | 54 // Although users could just discard the object, reset() closes the pipe |
| 53 // immediately. | 55 // immediately. |
| 54 InterfacePtrController.prototype.reset = function() { | 56 InterfacePtrController.prototype.reset = function() { |
| 55 this.version = 0; | 57 this.version = 0; |
| 56 if (this.connection_) { | 58 if (this.router_) { |
| 57 this.connection_.close(); | 59 this.router_.close(); |
| 58 this.connection_ = null; | 60 this.router_ = null; |
| 61 |
| 62 this.proxy_ = null; |
| 59 } | 63 } |
| 60 if (this.handle_) { | 64 if (this.handle_) { |
| 61 core.close(this.handle_); | 65 core.close(this.handle_); |
| 62 this.handle_ = null; | 66 this.handle_ = null; |
| 63 } | 67 } |
| 64 }; | 68 }; |
| 65 | 69 |
| 66 InterfacePtrController.prototype.setConnectionErrorHandler | 70 InterfacePtrController.prototype.setConnectionErrorHandler |
| 67 = function(callback) { | 71 = function(callback) { |
| 68 if (!this.isBound()) | 72 if (!this.isBound()) |
| 69 throw new Error("Cannot set connection error handler if not bound."); | 73 throw new Error("Cannot set connection error handler if not bound."); |
| 70 | 74 |
| 71 this.configureProxyIfNecessary_(); | 75 this.configureProxyIfNecessary_(); |
| 72 this.connection_.router_.setErrorHandler(callback); | 76 this.router_.setErrorHandler(callback); |
| 73 }; | 77 }; |
| 74 | 78 |
| 75 InterfacePtrController.prototype.passInterface = function() { | 79 InterfacePtrController.prototype.passInterface = function() { |
| 76 var result; | 80 var result; |
| 77 if (this.connection_) { | 81 if (this.router_) { |
| 82 // TODO(yzshen): Fix Router interface to support extracting handle. |
| 78 result = new types.InterfacePtrInfo( | 83 result = new types.InterfacePtrInfo( |
| 79 this.connection_.router_.connector_.handle_, this.version); | 84 this.router_.connector_.handle_, this.version); |
| 80 this.connection_.router_.connector_.handle_ = null; | 85 this.router_.connector_.handle_ = null; |
| 81 } else { | 86 } else { |
| 82 // This also handles the case when this object is not bound. | 87 // This also handles the case when this object is not bound. |
| 83 result = new types.InterfacePtrInfo(this.handle_, this.version); | 88 result = new types.InterfacePtrInfo(this.handle_, this.version); |
| 84 this.handle_ = null; | 89 this.handle_ = null; |
| 85 } | 90 } |
| 86 | 91 |
| 87 this.reset(); | 92 this.reset(); |
| 88 return result; | 93 return result; |
| 89 }; | 94 }; |
| 90 | 95 |
| 91 InterfacePtrController.prototype.getProxy = function() { | 96 InterfacePtrController.prototype.getProxy = function() { |
| 92 this.configureProxyIfNecessary_(); | 97 this.configureProxyIfNecessary_(); |
| 93 return this.connection_.remote; | 98 return this.proxy_; |
| 99 }; |
| 100 |
| 101 InterfacePtrController.prototype.enableTestingMode = function() { |
| 102 this.configureProxyIfNecessary_(); |
| 103 return this.router_.enableTestingMode(); |
| 94 }; | 104 }; |
| 95 | 105 |
| 96 InterfacePtrController.prototype.configureProxyIfNecessary_ = function() { | 106 InterfacePtrController.prototype.configureProxyIfNecessary_ = function() { |
| 97 if (!this.handle_) | 107 if (!this.handle_) |
| 98 return; | 108 return; |
| 99 | 109 |
| 100 this.connection_ = new connection.Connection( | 110 this.router_ = new router.Router(this.handle_); |
| 101 this.handle_, undefined, this.interfaceType_.proxyClass); | |
| 102 this.handle_ = null; | 111 this.handle_ = null; |
| 112 this.router_ .setPayloadValidators([this.interfaceType_.validateResponse]); |
| 113 |
| 114 this.proxy_ = new this.interfaceType_.proxyClass(this.router_); |
| 103 }; | 115 }; |
| 104 | 116 |
| 105 // TODO(yzshen): Implement the following methods. | 117 // TODO(yzshen): Implement the following methods. |
| 106 // InterfacePtrController.prototype.queryVersion | 118 // InterfacePtrController.prototype.queryVersion |
| 107 // InterfacePtrController.prototype.requireVersion | 119 // InterfacePtrController.prototype.requireVersion |
| 108 | 120 |
| 109 // --------------------------------------------------------------------------- | 121 // --------------------------------------------------------------------------- |
| 110 | 122 |
| 111 // |request| could be omitted and passed into bind() later. | 123 // |request| could be omitted and passed into bind() later. |
| 112 // | 124 // |
| 113 // Example: | 125 // Example: |
| 114 // | 126 // |
| 115 // // FooImpl implements mojom.Foo. | 127 // // FooImpl implements mojom.Foo. |
| 116 // function FooImpl() { ... } | 128 // function FooImpl() { ... } |
| 117 // FooImpl.prototype.fooMethod1 = function() { ... } | 129 // FooImpl.prototype.fooMethod1 = function() { ... } |
| 118 // FooImpl.prototype.fooMethod2 = function() { ... } | 130 // FooImpl.prototype.fooMethod2 = function() { ... } |
| 119 // | 131 // |
| 120 // var fooPtr = new mojom.FooPtr(); | 132 // var fooPtr = new mojom.FooPtr(); |
| 121 // var request = makeRequest(fooPtr); | 133 // var request = makeRequest(fooPtr); |
| 122 // var binding = new Binding(mojom.Foo, new FooImpl(), request); | 134 // var binding = new Binding(mojom.Foo, new FooImpl(), request); |
| 123 // fooPtr.fooMethod1(); | 135 // fooPtr.fooMethod1(); |
| 124 function Binding(interfaceType, impl, requestOrHandle) { | 136 function Binding(interfaceType, impl, requestOrHandle) { |
| 125 this.interfaceType_ = interfaceType; | 137 this.interfaceType_ = interfaceType; |
| 126 this.impl_ = impl; | 138 this.impl_ = impl; |
| 139 this.router_ = null; |
| 127 this.stub_ = null; | 140 this.stub_ = null; |
| 128 | 141 |
| 129 if (requestOrHandle) | 142 if (requestOrHandle) |
| 130 this.bind(requestOrHandle); | 143 this.bind(requestOrHandle); |
| 131 } | 144 } |
| 132 | 145 |
| 133 Binding.prototype.isBound = function() { | 146 Binding.prototype.isBound = function() { |
| 134 return this.stub_ !== null; | 147 return this.router_ !== null; |
| 135 }; | 148 }; |
| 136 | 149 |
| 137 Binding.prototype.createInterfacePtrAndBind = function() { | 150 Binding.prototype.createInterfacePtrAndBind = function() { |
| 138 var ptr = new this.interfaceType_.ptrClass(); | 151 var ptr = new this.interfaceType_.ptrClass(); |
| 139 // TODO(yzshen): Set the version of the interface pointer. | 152 // TODO(yzshen): Set the version of the interface pointer. |
| 140 this.bind(makeRequest(ptr)); | 153 this.bind(makeRequest(ptr)); |
| 141 return ptr; | 154 return ptr; |
| 142 } | 155 } |
| 143 | 156 |
| 144 Binding.prototype.bind = function(requestOrHandle) { | 157 Binding.prototype.bind = function(requestOrHandle) { |
| 145 this.close(); | 158 this.close(); |
| 146 | 159 |
| 147 var handle = requestOrHandle instanceof types.InterfaceRequest ? | 160 var handle = requestOrHandle instanceof types.InterfaceRequest ? |
| 148 requestOrHandle.handle : requestOrHandle; | 161 requestOrHandle.handle : requestOrHandle; |
| 149 if (core.isHandle(handle)) { | 162 if (!core.isHandle(handle)) |
| 150 this.stub_ = connection.bindHandleToStub(handle, this.interfaceType_); | 163 return; |
| 151 connection.StubBindings(this.stub_).delegate = this.impl_; | 164 |
| 152 } | 165 this.stub_ = new this.interfaceType_.stubClass(this.impl_); |
| 166 this.router_ = new router.Router(handle); |
| 167 this.router_.setIncomingReceiver(this.stub_); |
| 168 this.router_ .setPayloadValidators([this.interfaceType_.validateRequest]); |
| 153 }; | 169 }; |
| 154 | 170 |
| 155 Binding.prototype.close = function() { | 171 Binding.prototype.close = function() { |
| 156 if (!this.isBound()) | 172 if (!this.isBound()) |
| 157 return; | 173 return; |
| 158 connection.StubBindings(this.stub_).close(); | 174 |
| 175 this.router_.close(); |
| 176 this.router_ = null; |
| 159 this.stub_ = null; | 177 this.stub_ = null; |
| 160 }; | 178 }; |
| 161 | 179 |
| 162 Binding.prototype.setConnectionErrorHandler | 180 Binding.prototype.setConnectionErrorHandler |
| 163 = function(callback) { | 181 = function(callback) { |
| 164 if (!this.isBound()) | 182 if (!this.isBound()) |
| 165 throw new Error("Cannot set connection error handler if not bound."); | 183 throw new Error("Cannot set connection error handler if not bound."); |
| 166 connection.StubBindings(this.stub_).connection.router_.setErrorHandler( | 184 this.router_.setErrorHandler(callback); |
| 167 callback); | |
| 168 }; | 185 }; |
| 169 | 186 |
| 170 Binding.prototype.unbind = function() { | 187 Binding.prototype.unbind = function() { |
| 171 if (!this.isBound()) | 188 if (!this.isBound()) |
| 172 return new types.InterfaceRequest(null); | 189 return new types.InterfaceRequest(null); |
| 173 | 190 |
| 174 var result = new types.InterfaceRequest( | 191 var result = new types.InterfaceRequest(this.router_.connector_.handle_); |
| 175 connection.StubBindings(this.stub_).connection.router_.connector_ | 192 this.router_.connector_.handle_ = null; |
| 176 .handle_); | |
| 177 connection.StubBindings(this.stub_).connection.router_.connector_.handle_ = | |
| 178 null; | |
| 179 this.close(); | 193 this.close(); |
| 180 return result; | 194 return result; |
| 181 }; | 195 }; |
| 182 | 196 |
| 197 Binding.prototype.enableTestingMode = function() { |
| 198 return this.router_.enableTestingMode(); |
| 199 }; |
| 200 |
| 183 // --------------------------------------------------------------------------- | 201 // --------------------------------------------------------------------------- |
| 184 | 202 |
| 185 function BindingSetEntry(bindingSet, interfaceType, impl, requestOrHandle, | 203 function BindingSetEntry(bindingSet, interfaceType, impl, requestOrHandle, |
| 186 bindingId) { | 204 bindingId) { |
| 187 this.bindingSet_ = bindingSet; | 205 this.bindingSet_ = bindingSet; |
| 188 this.bindingId_ = bindingId; | 206 this.bindingId_ = bindingId; |
| 189 this.binding_ = new Binding(interfaceType, impl, requestOrHandle); | 207 this.binding_ = new Binding(interfaceType, impl, requestOrHandle); |
| 190 | 208 |
| 191 this.binding_.setConnectionErrorHandler(function() { | 209 this.binding_.setConnectionErrorHandler(function() { |
| 192 this.bindingSet_.onConnectionError(bindingId); | 210 this.bindingSet_.onConnectionError(bindingId); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 234 }; | 252 }; |
| 235 | 253 |
| 236 var exports = {}; | 254 var exports = {}; |
| 237 exports.InterfacePtrInfo = types.InterfacePtrInfo; | 255 exports.InterfacePtrInfo = types.InterfacePtrInfo; |
| 238 exports.InterfaceRequest = types.InterfaceRequest; | 256 exports.InterfaceRequest = types.InterfaceRequest; |
| 239 exports.makeRequest = makeRequest; | 257 exports.makeRequest = makeRequest; |
| 240 exports.InterfacePtrController = InterfacePtrController; | 258 exports.InterfacePtrController = InterfacePtrController; |
| 241 exports.Binding = Binding; | 259 exports.Binding = Binding; |
| 242 exports.BindingSet = BindingSet; | 260 exports.BindingSet = BindingSet; |
| 243 | 261 |
| 244 // TODO(yzshen): Remove the following exports. | |
| 245 exports.EmptyProxy = connection.EmptyProxy; | |
| 246 exports.EmptyStub = connection.EmptyStub; | |
| 247 exports.ProxyBase = connection.ProxyBase; | |
| 248 exports.ProxyBindings = connection.ProxyBindings; | |
| 249 exports.StubBase = connection.StubBase; | |
| 250 exports.StubBindings = connection.StubBindings; | |
| 251 | |
| 252 return exports; | 262 return exports; |
| 253 }); | 263 }); |
| OLD | NEW |