| Index: mojo/public/js/new_bindings/bindings.js
|
| diff --git a/mojo/public/js/new_bindings/bindings.js b/mojo/public/js/new_bindings/bindings.js
|
| index 5b3b66ecea59860482728b74a93cf70e2b207f0e..98213a825e1360f869a4bd49e6f7ae066c0ed773 100644
|
| --- a/mojo/public/js/new_bindings/bindings.js
|
| +++ b/mojo/public/js/new_bindings/bindings.js
|
| @@ -1,14 +1,33 @@
|
| -// Copyright 2014 The Chromium Authors. All rights reserved.
|
| +// Copyright 2017 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.
|
|
|
| (function() {
|
| var internal = mojo.internal;
|
| +
|
| // ---------------------------------------------------------------------------
|
|
|
| - function makeRequest(interfacePtr) {
|
| + // |output| could be an interface pointer, InterfacePtrInfo or
|
| + // AssociatedInterfacePtrInfo.
|
| + function makeRequest(output) {
|
| + if (output instanceof mojo.AssociatedInterfacePtrInfo) {
|
| + var {handle0, handle1} = internal.createPairPendingAssociation();
|
| + output.interfaceEndpointHandle = handle0;
|
| + output.version = 0;
|
| +
|
| + return new mojo.AssociatedInterfaceRequest(handle1);
|
| + }
|
| +
|
| + if (output instanceof mojo.InterfacePtrInfo) {
|
| + var pipe = Mojo.createMessagePipe();
|
| + output.handle = pipe.handle0;
|
| + output.version = 0;
|
| +
|
| + return new mojo.InterfaceRequest(pipe.handle1);
|
| + }
|
| +
|
| var pipe = Mojo.createMessagePipe();
|
| - interfacePtr.ptr.bind(new mojo.InterfacePtrInfo(pipe.handle0, 0));
|
| + output.ptr.bind(new mojo.InterfacePtrInfo(pipe.handle0, 0));
|
| return new mojo.InterfaceRequest(pipe.handle1);
|
| }
|
|
|
| @@ -22,12 +41,13 @@
|
|
|
| this.interfaceType_ = interfaceType;
|
| this.router_ = null;
|
| + this.interfaceEndpointClient_ = null;
|
| this.proxy_ = null;
|
|
|
| - // |router_| is lazily initialized. |handle_| is valid between bind() and
|
| - // the initialization of |router_|.
|
| + // |router_| and |interfaceEndpointClient_| are lazily initialized.
|
| + // |handle_| is valid between bind() and
|
| + // the initialization of |router_| and |interfaceEndpointClient_|.
|
| this.handle_ = null;
|
| - this.controlMessageProxy_ = null;
|
|
|
| if (ptrInfoOrHandle)
|
| this.bind(ptrInfoOrHandle);
|
| @@ -45,13 +65,17 @@
|
| };
|
|
|
| InterfacePtrController.prototype.isBound = function() {
|
| - return this.router_ !== null || this.handle_ !== null;
|
| + return this.interfaceEndpointClient_ !== null || this.handle_ !== null;
|
| };
|
|
|
| // Although users could just discard the object, reset() closes the pipe
|
| // immediately.
|
| InterfacePtrController.prototype.reset = function() {
|
| this.version = 0;
|
| + if (this.interfaceEndpointClient_) {
|
| + this.interfaceEndpointClient_.close();
|
| + this.interfaceEndpointClient_ = null;
|
| + }
|
| if (this.router_) {
|
| this.router_.close();
|
| this.router_ = null;
|
| @@ -64,13 +88,22 @@
|
| }
|
| };
|
|
|
| - InterfacePtrController.prototype.setConnectionErrorHandler
|
| - = function(callback) {
|
| + InterfacePtrController.prototype.resetWithReason = function(reason) {
|
| + if (this.isBound()) {
|
| + this.configureProxyIfNecessary_();
|
| + this.interfaceEndpointClient_.close(reason);
|
| + this.interfaceEndpointClient_ = null;
|
| + }
|
| + this.reset();
|
| + };
|
| +
|
| + InterfacePtrController.prototype.setConnectionErrorHandler = function(
|
| + callback) {
|
| if (!this.isBound())
|
| throw new Error("Cannot set connection error handler if not bound.");
|
|
|
| this.configureProxyIfNecessary_();
|
| - this.router_.setErrorHandler(callback);
|
| + this.interfaceEndpointClient_.setConnectionErrorHandler(callback);
|
| };
|
|
|
| InterfacePtrController.prototype.passInterface = function() {
|
| @@ -95,22 +128,25 @@
|
| return this.proxy_;
|
| };
|
|
|
| - InterfacePtrController.prototype.enableTestingMode = function() {
|
| + InterfacePtrController.prototype.waitForNextMessageForTesting = function() {
|
| this.configureProxyIfNecessary_();
|
| - return this.router_.enableTestingMode();
|
| + this.router_.waitForNextMessageForTesting();
|
| };
|
|
|
| InterfacePtrController.prototype.configureProxyIfNecessary_ = function() {
|
| if (!this.handle_)
|
| return;
|
|
|
| - this.router_ = new internal.Router(this.handle_);
|
| + this.router_ = new internal.Router(this.handle_, true);
|
| this.handle_ = null;
|
| - this.router_ .setPayloadValidators([this.interfaceType_.validateResponse]);
|
|
|
| - this.controlMessageProxy_ = new internal.ControlMessageProxy(this.router_);
|
| + this.interfaceEndpointClient_ = new internal.InterfaceEndpointClient(
|
| + this.router_.createLocalEndpointHandle(internal.kMasterInterfaceId));
|
|
|
| - this.proxy_ = new this.interfaceType_.proxyClass(this.router_);
|
| + this.interfaceEndpointClient_ .setPayloadValidators([
|
| + this.interfaceType_.validateResponse]);
|
| + this.proxy_ = new this.interfaceType_.proxyClass(
|
| + this.interfaceEndpointClient_);
|
| };
|
|
|
| InterfacePtrController.prototype.queryVersion = function() {
|
| @@ -120,7 +156,7 @@
|
| }
|
|
|
| this.configureProxyIfNecessary_();
|
| - return this.controlMessageProxy_.queryVersion().then(
|
| + return this.interfaceEndpointClient_.queryVersion().then(
|
| onQueryVersion.bind(this));
|
| };
|
|
|
| @@ -131,7 +167,7 @@
|
| return;
|
| }
|
| this.version = version;
|
| - this.controlMessageProxy_.requireVersion(version);
|
| + this.interfaceEndpointClient_.requireVersion(version);
|
| };
|
|
|
| // ---------------------------------------------------------------------------
|
| @@ -153,6 +189,7 @@
|
| this.interfaceType_ = interfaceType;
|
| this.impl_ = impl;
|
| this.router_ = null;
|
| + this.interfaceEndpointClient_ = null;
|
| this.stub_ = null;
|
|
|
| if (requestOrHandle)
|
| @@ -168,7 +205,7 @@
|
| // TODO(yzshen): Set the version of the interface pointer.
|
| this.bind(makeRequest(ptr));
|
| return ptr;
|
| - }
|
| + };
|
|
|
| Binding.prototype.bind = function(requestOrHandle) {
|
| this.close();
|
| @@ -178,26 +215,44 @@
|
| if (!(handle instanceof MojoHandle))
|
| return;
|
|
|
| + this.router_ = new internal.Router(handle);
|
| +
|
| this.stub_ = new this.interfaceType_.stubClass(this.impl_);
|
| - this.router_ = new internal.Router(handle, this.interfaceType_.kVersion);
|
| - this.router_.setIncomingReceiver(this.stub_);
|
| - this.router_ .setPayloadValidators([this.interfaceType_.validateRequest]);
|
| + this.interfaceEndpointClient_ = new internal.InterfaceEndpointClient(
|
| + this.router_.createLocalEndpointHandle(internal.kMasterInterfaceId),
|
| + this.stub_, this.interfaceType_.kVersion);
|
| +
|
| + this.interfaceEndpointClient_ .setPayloadValidators([
|
| + this.interfaceType_.validateRequest]);
|
| };
|
|
|
| Binding.prototype.close = function() {
|
| if (!this.isBound())
|
| return;
|
|
|
| + if (this.interfaceEndpointClient_) {
|
| + this.interfaceEndpointClient_.close();
|
| + this.interfaceEndpointClient_ = null;
|
| + }
|
| +
|
| this.router_.close();
|
| this.router_ = null;
|
| this.stub_ = null;
|
| };
|
|
|
| - Binding.prototype.setConnectionErrorHandler
|
| - = function(callback) {
|
| - if (!this.isBound())
|
| + Binding.prototype.closeWithReason = function(reason) {
|
| + if (this.interfaceEndpointClient_) {
|
| + this.interfaceEndpointClient_.close(reason);
|
| + this.interfaceEndpointClient_ = null;
|
| + }
|
| + this.close();
|
| + };
|
| +
|
| + Binding.prototype.setConnectionErrorHandler = function(callback) {
|
| + if (!this.isBound()) {
|
| throw new Error("Cannot set connection error handler if not bound.");
|
| - this.router_.setErrorHandler(callback);
|
| + }
|
| + this.interfaceEndpointClient_.setConnectionErrorHandler(callback);
|
| };
|
|
|
| Binding.prototype.unbind = function() {
|
| @@ -210,20 +265,21 @@
|
| return result;
|
| };
|
|
|
| - Binding.prototype.enableTestingMode = function() {
|
| - return this.router_.enableTestingMode();
|
| + Binding.prototype.waitForNextMessageForTesting = function() {
|
| + this.router_.waitForNextMessageForTesting();
|
| };
|
|
|
| // ---------------------------------------------------------------------------
|
|
|
| - function BindingSetEntry(bindingSet, interfaceType, impl, requestOrHandle,
|
| - bindingId) {
|
| + function BindingSetEntry(bindingSet, interfaceType, bindingType, impl,
|
| + requestOrHandle, bindingId) {
|
| this.bindingSet_ = bindingSet;
|
| this.bindingId_ = bindingId;
|
| - this.binding_ = new Binding(interfaceType, impl, requestOrHandle);
|
| + this.binding_ = new bindingType(interfaceType, impl,
|
| + requestOrHandle);
|
|
|
| - this.binding_.setConnectionErrorHandler(function() {
|
| - this.bindingSet_.onConnectionError(bindingId);
|
| + this.binding_.setConnectionErrorHandler(function(reason) {
|
| + this.bindingSet_.onConnectionError(bindingId, reason);
|
| }.bind(this));
|
| }
|
|
|
| @@ -236,6 +292,7 @@
|
| this.nextBindingId_ = 0;
|
| this.bindings_ = new Map();
|
| this.errorHandler_ = null;
|
| + this.bindingType_ = Binding;
|
| }
|
|
|
| BindingSet.prototype.isEmpty = function() {
|
| @@ -245,8 +302,8 @@
|
| BindingSet.prototype.addBinding = function(impl, requestOrHandle) {
|
| this.bindings_.set(
|
| this.nextBindingId_,
|
| - new BindingSetEntry(this, this.interfaceType_, impl, requestOrHandle,
|
| - this.nextBindingId_));
|
| + new BindingSetEntry(this, this.interfaceType_, this.bindingType_, impl,
|
| + requestOrHandle, this.nextBindingId_));
|
| ++this.nextBindingId_;
|
| };
|
|
|
| @@ -260,15 +317,240 @@
|
| this.errorHandler_ = callback;
|
| };
|
|
|
| - BindingSet.prototype.onConnectionError = function(bindingId) {
|
| + BindingSet.prototype.onConnectionError = function(bindingId, reason) {
|
| this.bindings_.delete(bindingId);
|
|
|
| if (this.errorHandler_)
|
| - this.errorHandler_();
|
| + this.errorHandler_(reason);
|
| };
|
|
|
| + // ---------------------------------------------------------------------------
|
| +
|
| + // Operations used to setup/configure an associated interface pointer.
|
| + // Exposed as |ptr| field of generated associated interface pointer classes.
|
| + // |associatedPtrInfo| could be omitted and passed into bind() later.
|
| + //
|
| + // Example:
|
| + // // IntegerSenderImpl implements mojom.IntegerSender
|
| + // function IntegerSenderImpl() { ... }
|
| + // IntegerSenderImpl.prototype.echo = function() { ... }
|
| + //
|
| + // // IntegerSenderConnectionImpl implements mojom.IntegerSenderConnection
|
| + // function IntegerSenderConnectionImpl() {
|
| + // this.senderBinding_ = null;
|
| + // }
|
| + // IntegerSenderConnectionImpl.prototype.getSender = function(
|
| + // associatedRequest) {
|
| + // this.senderBinding_ = new AssociatedBinding(mojom.IntegerSender,
|
| + // new IntegerSenderImpl(),
|
| + // associatedRequest);
|
| + // }
|
| + //
|
| + // var integerSenderConnection = new mojom.IntegerSenderConnectionPtr();
|
| + // var integerSenderConnectionBinding = new Binding(
|
| + // mojom.IntegerSenderConnection,
|
| + // new IntegerSenderConnectionImpl(),
|
| + // mojo.makeRequest(integerSenderConnection));
|
| + //
|
| + // // A locally-created associated interface pointer can only be used to
|
| + // // make calls when the corresponding associated request is sent over
|
| + // // another interface (either the master interface or another
|
| + // // associated interface).
|
| + // var associatedInterfacePtrInfo = new AssociatedInterfacePtrInfo();
|
| + // var associatedRequest = makeRequest(interfacePtrInfo);
|
| + //
|
| + // integerSenderConnection.getSender(associatedRequest);
|
| + //
|
| + // // Create an associated interface and bind the associated handle.
|
| + // var integerSender = new mojom.AssociatedIntegerSenderPtr();
|
| + // integerSender.ptr.bind(associatedInterfacePtrInfo);
|
| + // integerSender.echo();
|
| +
|
| + function AssociatedInterfacePtrController(interfaceType, associatedPtrInfo) {
|
| + this.version = 0;
|
| +
|
| + this.interfaceType_ = interfaceType;
|
| + this.interfaceEndpointClient_ = null;
|
| + this.proxy_ = null;
|
| +
|
| + if (associatedPtrInfo) {
|
| + this.bind(associatedPtrInfo);
|
| + }
|
| + }
|
| +
|
| + AssociatedInterfacePtrController.prototype.bind = function(
|
| + associatedPtrInfo) {
|
| + this.reset();
|
| + this.version = associatedPtrInfo.version;
|
| +
|
| + this.interfaceEndpointClient_ = new internal.InterfaceEndpointClient(
|
| + associatedPtrInfo.interfaceEndpointHandle);
|
| +
|
| + this.interfaceEndpointClient_ .setPayloadValidators([
|
| + this.interfaceType_.validateResponse]);
|
| + this.proxy_ = new this.interfaceType_.proxyClass(
|
| + this.interfaceEndpointClient_);
|
| + };
|
| +
|
| + AssociatedInterfacePtrController.prototype.isBound = function() {
|
| + return this.interfaceEndpointClient_ !== null;
|
| + };
|
| +
|
| + AssociatedInterfacePtrController.prototype.reset = function() {
|
| + this.version = 0;
|
| + if (this.interfaceEndpointClient_) {
|
| + this.interfaceEndpointClient_.close();
|
| + this.interfaceEndpointClient_ = null;
|
| + }
|
| + if (this.proxy_) {
|
| + this.proxy_ = null;
|
| + }
|
| + };
|
| +
|
| + AssociatedInterfacePtrController.prototype.resetWithReason = function(
|
| + reason) {
|
| + if (this.isBound()) {
|
| + this.interfaceEndpointClient_.close(reason);
|
| + this.interfaceEndpointClient_ = null;
|
| + }
|
| + this.reset();
|
| + };
|
| +
|
| + // Indicates whether an error has been encountered. If true, method calls
|
| + // on this interface will be dropped (and may already have been dropped).
|
| + AssociatedInterfacePtrController.prototype.getEncounteredError = function() {
|
| + return this.interfaceEndpointClient_ ?
|
| + this.interfaceEndpointClient_.getEncounteredError() : false;
|
| + };
|
| +
|
| + AssociatedInterfacePtrController.prototype.setConnectionErrorHandler =
|
| + function(callback) {
|
| + if (!this.isBound()) {
|
| + throw new Error("Cannot set connection error handler if not bound.");
|
| + }
|
| +
|
| + this.interfaceEndpointClient_.setConnectionErrorHandler(callback);
|
| + };
|
| +
|
| + AssociatedInterfacePtrController.prototype.passInterface = function() {
|
| + if (!this.isBound()) {
|
| + return new mojo.AssociatedInterfacePtrInfo(null);
|
| + }
|
| +
|
| + var result = new mojo.AssociatedInterfacePtrInfo(
|
| + this.interfaceEndpointClient_.passHandle(), this.version);
|
| + this.reset();
|
| + return result;
|
| + };
|
| +
|
| + AssociatedInterfacePtrController.prototype.getProxy = function() {
|
| + return this.proxy_;
|
| + };
|
| +
|
| + AssociatedInterfacePtrController.prototype.queryVersion = function() {
|
| + function onQueryVersion(version) {
|
| + this.version = version;
|
| + return version;
|
| + }
|
| +
|
| + return this.interfaceEndpointClient_.queryVersion().then(
|
| + onQueryVersion.bind(this));
|
| + };
|
| +
|
| + AssociatedInterfacePtrController.prototype.requireVersion = function(
|
| + version) {
|
| + if (this.version >= version) {
|
| + return;
|
| + }
|
| + this.version = version;
|
| + this.interfaceEndpointClient_.requireVersion(version);
|
| + };
|
| +
|
| + // ---------------------------------------------------------------------------
|
| +
|
| + // |associatedInterfaceRequest| could be omitted and passed into bind()
|
| + // later.
|
| + function AssociatedBinding(interfaceType, impl, associatedInterfaceRequest) {
|
| + this.interfaceType_ = interfaceType;
|
| + this.impl_ = impl;
|
| + this.interfaceEndpointClient_ = null;
|
| + this.stub_ = null;
|
| +
|
| + if (associatedInterfaceRequest) {
|
| + this.bind(associatedInterfaceRequest);
|
| + }
|
| + }
|
| +
|
| + AssociatedBinding.prototype.isBound = function() {
|
| + return this.interfaceEndpointClient_ !== null;
|
| + };
|
| +
|
| + AssociatedBinding.prototype.bind = function(associatedInterfaceRequest) {
|
| + this.close();
|
| +
|
| + this.stub_ = new this.interfaceType_.stubClass(this.impl_);
|
| + this.interfaceEndpointClient_ = new internal.InterfaceEndpointClient(
|
| + associatedInterfaceRequest.interfaceEndpointHandle, this.stub_,
|
| + this.interfaceType_.kVersion);
|
| +
|
| + this.interfaceEndpointClient_ .setPayloadValidators([
|
| + this.interfaceType_.validateRequest]);
|
| + };
|
| +
|
| +
|
| + AssociatedBinding.prototype.close = function() {
|
| + if (!this.isBound()) {
|
| + return;
|
| + }
|
| +
|
| + if (this.interfaceEndpointClient_) {
|
| + this.interfaceEndpointClient_.close();
|
| + this.interfaceEndpointClient_ = null;
|
| + }
|
| +
|
| + this.stub_ = null;
|
| + };
|
| +
|
| + AssociatedBinding.prototype.closeWithReason = function(reason) {
|
| + if (this.interfaceEndpointClient_) {
|
| + this.interfaceEndpointClient_.close(reason);
|
| + this.interfaceEndpointClient_ = null;
|
| + }
|
| + this.close();
|
| + };
|
| +
|
| + AssociatedBinding.prototype.setConnectionErrorHandler = function(callback) {
|
| + if (!this.isBound()) {
|
| + throw new Error("Cannot set connection error handler if not bound.");
|
| + }
|
| + this.interfaceEndpointClient_.setConnectionErrorHandler(callback);
|
| + };
|
| +
|
| + AssociatedBinding.prototype.unbind = function() {
|
| + if (!this.isBound()) {
|
| + return new mojo.AssociatedInterfaceRequest(null);
|
| + }
|
| +
|
| + var result = new mojo.AssociatedInterfaceRequest(
|
| + this.interfaceEndpointClient_.passHandle());
|
| + this.close();
|
| + return result;
|
| + };
|
| +
|
| + // ---------------------------------------------------------------------------
|
| +
|
| + function AssociatedBindingSet(interfaceType) {
|
| + mojo.BindingSet.call(this, interfaceType);
|
| + this.bindingType_ = AssociatedBinding;
|
| + }
|
| +
|
| + AssociatedBindingSet.prototype = Object.create(BindingSet.prototype);
|
| + AssociatedBindingSet.prototype.constructor = AssociatedBindingSet;
|
|
|
| mojo.makeRequest = makeRequest;
|
| + mojo.AssociatedInterfacePtrController = AssociatedInterfacePtrController;
|
| + mojo.AssociatedBinding = AssociatedBinding;
|
| + mojo.AssociatedBindingSet = AssociatedBindingSet;
|
| mojo.Binding = Binding;
|
| mojo.BindingSet = BindingSet;
|
| mojo.InterfacePtrController = InterfacePtrController;
|
|
|