Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1329)

Unified Diff: mojo/public/js/new_bindings/bindings.js

Issue 2893493002: Mojo JS bindings: update the new bindings with the associated interface feature. (Closed)
Patch Set: . Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « mojo/public/js/BUILD.gn ('k') | mojo/public/js/new_bindings/codec.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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;
« no previous file with comments | « mojo/public/js/BUILD.gn ('k') | mojo/public/js/new_bindings/codec.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698