Commit 348e013f authored by yzshen's avatar yzshen Committed by Commit bot

Mojo JS bindings: lazily initialize the underlying connection of interface ptr.

This is useful when the user creates a bound interface ptr and passes it without
actually using it to make any calls, which is pretty common.

BUG=579646

Review-Url: https://codereview.chromium.org/2563593005
Cr-Commit-Position: refs/heads/master@{#437957}
parent 77932377
...@@ -16,7 +16,7 @@ define("mojo/public/js/bindings", [ ...@@ -16,7 +16,7 @@ define("mojo/public/js/bindings", [
InterfacePtrInfo.prototype.isValid = function() { InterfacePtrInfo.prototype.isValid = function() {
return core.isHandle(this.handle); return core.isHandle(this.handle);
} };
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
...@@ -26,7 +26,7 @@ define("mojo/public/js/bindings", [ ...@@ -26,7 +26,7 @@ define("mojo/public/js/bindings", [
InterfaceRequest.prototype.isValid = function() { InterfaceRequest.prototype.isValid = function() {
return core.isHandle(this.handle); return core.isHandle(this.handle);
} };
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
...@@ -42,50 +42,77 @@ define("mojo/public/js/bindings", [ ...@@ -42,50 +42,77 @@ define("mojo/public/js/bindings", [
// |ptr| field of generated interface pointer classes. // |ptr| field of generated interface pointer classes.
function InterfacePtrController(interfaceType) { function InterfacePtrController(interfaceType) {
this.version = 0; this.version = 0;
this.connection = null;
this.interfaceType_ = interfaceType; this.interfaceType_ = interfaceType;
this.connection_ = null;
// |connection_| is lazily initialized. |handle_| is valid between bind()
// and the initialization of |connection_|.
this.handle_ = null;
} }
InterfacePtrController.prototype.bind = function(interfacePtrInfo) { InterfacePtrController.prototype.bind = function(interfacePtrInfo) {
this.reset(); this.reset();
this.version = interfacePtrInfo.version; this.version = interfacePtrInfo.version;
this.connection = new connection.Connection( this.handle_ = interfacePtrInfo.handle;
interfacePtrInfo.handle, undefined, this.interfaceType_.proxyClass); };
}
InterfacePtrController.prototype.isBound = function() { InterfacePtrController.prototype.isBound = function() {
return this.connection !== null; return this.connection_ !== null || this.handle_ !== null;
} };
// Although users could just discard the object, reset() closes the pipe // Although users could just discard the object, reset() closes the pipe
// immediately. // immediately.
InterfacePtrController.prototype.reset = function() { InterfacePtrController.prototype.reset = function() {
if (!this.isBound())
return;
this.version = 0; this.version = 0;
this.connection.close(); if (this.connection_) {
this.connection = null; this.connection_.close();
} this.connection_ = null;
}
if (this.handle_) {
core.close(this.handle_);
this.handle_ = null;
}
};
InterfacePtrController.prototype.setConnectionErrorHandler InterfacePtrController.prototype.setConnectionErrorHandler
= function(callback) { = function(callback) {
if (!this.isBound()) if (!this.isBound())
throw new Error("Cannot set connection error handler if not bound."); throw new Error("Cannot set connection error handler if not bound.");
this.connection.router_.setErrorHandler(callback);
} this.configureProxyIfNecessary_();
this.connection_.router_.setErrorHandler(callback);
};
InterfacePtrController.prototype.passInterface = function() { InterfacePtrController.prototype.passInterface = function() {
if (!this.isBound()) var result;
return new InterfacePtrInfo(null, 0); if (this.connection_) {
result = new InterfacePtrInfo(
this.connection_.router_.connector_.handle_, this.version);
this.connection_.router_.connector_.handle_ = null;
} else {
// This also handles the case when this object is not bound.
result = new InterfacePtrInfo(this.handle_, this.version);
this.handle_ = null;
}
var result = new InterfacePtrInfo(
this.connection.router_.connector_.handle_, this.version);
this.connection.router_.connector_.handle_ = null;
this.reset(); this.reset();
return result; return result;
} };
InterfacePtrController.prototype.getProxy = function() {
this.configureProxyIfNecessary_();
return this.connection_.remote;
};
InterfacePtrController.prototype.configureProxyIfNecessary_ = function() {
if (!this.handle_)
return;
this.connection_ = new connection.Connection(
this.handle_, undefined, this.interfaceType_.proxyClass);
this.handle_ = null;
};
// TODO(yzshen): Implement the following methods. // TODO(yzshen): Implement the following methods.
// InterfacePtrController.prototype.queryVersion // InterfacePtrController.prototype.queryVersion
...@@ -119,21 +146,23 @@ define("mojo/public/js/bindings", [ ...@@ -119,21 +146,23 @@ define("mojo/public/js/bindings", [
Binding.prototype.isBound = function() { Binding.prototype.isBound = function() {
return this.stub_ !== null; return this.stub_ !== null;
} };
Binding.prototype.bind = function(request) { Binding.prototype.bind = function(request) {
this.close(); this.close();
this.stub_ = connection.bindHandleToStub(request.handle, if (request.isValid()) {
this.interfaceType_); this.stub_ = connection.bindHandleToStub(request.handle,
connection.StubBindings(this.stub_).delegate = this.impl_; this.interfaceType_);
} connection.StubBindings(this.stub_).delegate = this.impl_;
}
};
Binding.prototype.close = function() { Binding.prototype.close = function() {
if (!this.isBound()) if (!this.isBound())
return; return;
connection.StubBindings(this.stub_).close(); connection.StubBindings(this.stub_).close();
this.stub_ = null; this.stub_ = null;
} };
Binding.prototype.setConnectionErrorHandler Binding.prototype.setConnectionErrorHandler
= function(callback) { = function(callback) {
...@@ -141,7 +170,7 @@ define("mojo/public/js/bindings", [ ...@@ -141,7 +170,7 @@ define("mojo/public/js/bindings", [
throw new Error("Cannot set connection error handler if not bound."); throw new Error("Cannot set connection error handler if not bound.");
connection.StubBindings(this.stub_).connection.router_.setErrorHandler( connection.StubBindings(this.stub_).connection.router_.setErrorHandler(
callback); callback);
} };
Binding.prototype.unbind = function() { Binding.prototype.unbind = function() {
if (!this.isBound()) if (!this.isBound())
...@@ -154,7 +183,7 @@ define("mojo/public/js/bindings", [ ...@@ -154,7 +183,7 @@ define("mojo/public/js/bindings", [
null; null;
this.close(); this.close();
return result; return result;
} };
var exports = {}; var exports = {};
exports.InterfacePtrInfo = InterfacePtrInfo; exports.InterfacePtrInfo = InterfacePtrInfo;
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
{%- for method in interface.methods %} {%- for method in interface.methods %}
{{interface.name}}Ptr.prototype.{{method.name|stylize_method}} = function() { {{interface.name}}Ptr.prototype.{{method.name|stylize_method}} = function() {
return {{interface.name}}Proxy.prototype.{{method.name|stylize_method}} return {{interface.name}}Proxy.prototype.{{method.name|stylize_method}}
.apply(this.ptr.connection.remote, arguments); .apply(this.ptr.getProxy(), arguments);
}; };
{{interface.name}}Proxy.prototype.{{method.name|stylize_method}} = function( {{interface.name}}Proxy.prototype.{{method.name|stylize_method}} = function(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment