| // Copyright 2014 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/connection", [ |
| "mojo/public/js/bindings", |
| "mojo/public/js/connector", |
| "mojo/public/js/core", |
| "mojo/public/js/router", |
| ], function(bindings, connector, core, router) { |
| |
| var Router = router.Router; |
| var EmptyProxy = bindings.EmptyProxy; |
| var EmptyStub = bindings.EmptyStub; |
| var ProxyBindings = bindings.ProxyBindings; |
| var StubBindings = bindings.StubBindings; |
| var TestConnector = connector.TestConnector; |
| var TestRouter = router.TestRouter; |
| |
| // TODO(hansmuller): the proxy receiver_ property should be receiver$ |
| |
| function BaseConnection(localStub, remoteProxy, router) { |
| this.router_ = router; |
| this.local = localStub; |
| this.remote = remoteProxy; |
| |
| this.router_.setIncomingReceiver(localStub); |
| this.router_.setErrorHandler(function() { |
| if (StubBindings(this.local) && |
| StubBindings(this.local).connectionErrorHandler) |
| StubBindings(this.local).connectionErrorHandler(); |
| }.bind(this)); |
| if (this.remote) |
| this.remote.receiver_ = router; |
| |
| // Validate incoming messages: remote responses and local requests. |
| var validateRequest = localStub && localStub.validator; |
| var validateResponse = remoteProxy && remoteProxy.validator; |
| var payloadValidators = []; |
| if (validateRequest) |
| payloadValidators.push(validateRequest); |
| if (validateResponse) |
| payloadValidators.push(validateResponse); |
| this.router_.setPayloadValidators(payloadValidators); |
| } |
| |
| BaseConnection.prototype.close = function() { |
| this.router_.close(); |
| this.router_ = null; |
| this.local = null; |
| this.remote = null; |
| }; |
| |
| BaseConnection.prototype.encounteredError = function() { |
| return this.router_.encounteredError(); |
| }; |
| |
| function Connection( |
| handle, localFactory, remoteFactory, routerFactory, connectorFactory) { |
| var routerClass = routerFactory || Router; |
| var router = new routerClass(handle, connectorFactory); |
| var remoteProxy = remoteFactory && new remoteFactory(router); |
| var localStub = localFactory && new localFactory(remoteProxy); |
| BaseConnection.call(this, localStub, remoteProxy, router); |
| } |
| |
| Connection.prototype = Object.create(BaseConnection.prototype); |
| |
| // The TestConnection subclass is only intended to be used in unit tests. |
| function TestConnection(handle, localFactory, remoteFactory) { |
| Connection.call(this, |
| handle, |
| localFactory, |
| remoteFactory, |
| TestRouter, |
| TestConnector); |
| } |
| |
| TestConnection.prototype = Object.create(Connection.prototype); |
| |
| // Return a handle for a message pipe that's connected to a proxy |
| // for remoteInterface. Used by generated code for outgoing interface& |
| // (request) parameters: the caller is given the generated proxy via |
| // |proxyCallback(proxy)| and the generated code sends the handle |
| // returned by this function. |
| function bindProxy(proxyCallback, remoteInterface) { |
| var messagePipe = core.createMessagePipe(); |
| if (messagePipe.result != core.RESULT_OK) |
| throw new Error("createMessagePipe failed " + messagePipe.result); |
| |
| var proxy = new remoteInterface.proxyClass; |
| var router = new Router(messagePipe.handle0); |
| var connection = new BaseConnection(undefined, proxy, router); |
| ProxyBindings(proxy).connection = connection; |
| if (proxyCallback) |
| proxyCallback(proxy); |
| |
| return messagePipe.handle1; |
| } |
| |
| // Return a handle for a message pipe that's connected to a stub for |
| // localInterface. Used by generated code for outgoing interface |
| // parameters: the caller is given the generated stub via |
| // |stubCallback(stub)| and the generated code sends the handle |
| // returned by this function. The caller is responsible for managing |
| // the lifetime of the stub and for setting it's implementation |
| // delegate with: StubBindings(stub).delegate = myImpl; |
| function bindImpl(stubCallback, localInterface) { |
| var messagePipe = core.createMessagePipe(); |
| if (messagePipe.result != core.RESULT_OK) |
| throw new Error("createMessagePipe failed " + messagePipe.result); |
| |
| var stub = new localInterface.stubClass; |
| var router = new Router(messagePipe.handle0); |
| var connection = new BaseConnection(stub, undefined, router); |
| StubBindings(stub).connection = connection; |
| if (stubCallback) |
| stubCallback(stub); |
| |
| return messagePipe.handle1; |
| } |
| |
| // Return a remoteInterface proxy for handle. Used by generated code |
| // for converting incoming interface parameters to proxies. |
| function bindHandleToProxy(handle, remoteInterface) { |
| if (!core.isHandle(handle)) |
| throw new Error("Not a handle " + handle); |
| |
| var proxy = new remoteInterface.proxyClass; |
| var router = new Router(handle); |
| var connection = new BaseConnection(undefined, proxy, router); |
| ProxyBindings(proxy).connection = connection; |
| return proxy; |
| } |
| |
| // Return a localInterface stub for handle. Used by generated code |
| // for converting incoming interface& request parameters to localInterface |
| // stubs. The caller can specify the stub's implementation of localInterface |
| // like this: StubBindings(stub).delegate = myStubImpl. |
| function bindHandleToStub(handle, localInterface) { |
| if (!core.isHandle(handle)) |
| throw new Error("Not a handle " + handle); |
| |
| var stub = new localInterface.stubClass; |
| var router = new Router(handle); |
| var connection = new BaseConnection(stub, undefined, router); |
| StubBindings(stub).connection = connection; |
| return stub; |
| } |
| |
| /** |
| * Creates a messape pipe and links one end of the pipe to the given object. |
| * @param {!Object} obj The object to create a handle for. Must be a subclass |
| * of an auto-generated stub class. |
| * @return {!MojoHandle} The other (not yet connected) end of the message |
| * pipe. |
| */ |
| function bindStubDerivedImpl(obj) { |
| var pipe = core.createMessagePipe(); |
| var router = new Router(pipe.handle0); |
| var connection = new BaseConnection(obj, undefined, router); |
| obj.connection = connection; |
| return pipe.handle1; |
| } |
| |
| var exports = {}; |
| exports.Connection = Connection; |
| exports.TestConnection = TestConnection; |
| |
| exports.bindProxy = bindProxy; |
| exports.bindImpl = bindImpl; |
| exports.bindHandleToProxy = bindHandleToProxy; |
| exports.bindHandleToStub = bindHandleToStub; |
| exports.bindStubDerivedImpl = bindStubDerivedImpl; |
| return exports; |
| }); |