1*635a8641SAndroid Build Coastguard Worker// Copyright 2017 The Chromium Authors. All rights reserved. 2*635a8641SAndroid Build Coastguard Worker// Use of this source code is governed by a BSD-style license that can be 3*635a8641SAndroid Build Coastguard Worker// found in the LICENSE file. 4*635a8641SAndroid Build Coastguard Worker 5*635a8641SAndroid Build Coastguard Worker(function() { 6*635a8641SAndroid Build Coastguard Worker var internal = mojo.internal; 7*635a8641SAndroid Build Coastguard Worker 8*635a8641SAndroid Build Coastguard Worker // --------------------------------------------------------------------------- 9*635a8641SAndroid Build Coastguard Worker 10*635a8641SAndroid Build Coastguard Worker // |output| could be an interface pointer, InterfacePtrInfo or 11*635a8641SAndroid Build Coastguard Worker // AssociatedInterfacePtrInfo. 12*635a8641SAndroid Build Coastguard Worker function makeRequest(output) { 13*635a8641SAndroid Build Coastguard Worker if (output instanceof mojo.AssociatedInterfacePtrInfo) { 14*635a8641SAndroid Build Coastguard Worker var {handle0, handle1} = internal.createPairPendingAssociation(); 15*635a8641SAndroid Build Coastguard Worker output.interfaceEndpointHandle = handle0; 16*635a8641SAndroid Build Coastguard Worker output.version = 0; 17*635a8641SAndroid Build Coastguard Worker 18*635a8641SAndroid Build Coastguard Worker return new mojo.AssociatedInterfaceRequest(handle1); 19*635a8641SAndroid Build Coastguard Worker } 20*635a8641SAndroid Build Coastguard Worker 21*635a8641SAndroid Build Coastguard Worker if (output instanceof mojo.InterfacePtrInfo) { 22*635a8641SAndroid Build Coastguard Worker var pipe = Mojo.createMessagePipe(); 23*635a8641SAndroid Build Coastguard Worker output.handle = pipe.handle0; 24*635a8641SAndroid Build Coastguard Worker output.version = 0; 25*635a8641SAndroid Build Coastguard Worker 26*635a8641SAndroid Build Coastguard Worker return new mojo.InterfaceRequest(pipe.handle1); 27*635a8641SAndroid Build Coastguard Worker } 28*635a8641SAndroid Build Coastguard Worker 29*635a8641SAndroid Build Coastguard Worker var pipe = Mojo.createMessagePipe(); 30*635a8641SAndroid Build Coastguard Worker output.ptr.bind(new mojo.InterfacePtrInfo(pipe.handle0, 0)); 31*635a8641SAndroid Build Coastguard Worker return new mojo.InterfaceRequest(pipe.handle1); 32*635a8641SAndroid Build Coastguard Worker } 33*635a8641SAndroid Build Coastguard Worker 34*635a8641SAndroid Build Coastguard Worker // --------------------------------------------------------------------------- 35*635a8641SAndroid Build Coastguard Worker 36*635a8641SAndroid Build Coastguard Worker // Operations used to setup/configure an interface pointer. Exposed as the 37*635a8641SAndroid Build Coastguard Worker // |ptr| field of generated interface pointer classes. 38*635a8641SAndroid Build Coastguard Worker // |ptrInfoOrHandle| could be omitted and passed into bind() later. 39*635a8641SAndroid Build Coastguard Worker function InterfacePtrController(interfaceType, ptrInfoOrHandle) { 40*635a8641SAndroid Build Coastguard Worker this.version = 0; 41*635a8641SAndroid Build Coastguard Worker 42*635a8641SAndroid Build Coastguard Worker this.interfaceType_ = interfaceType; 43*635a8641SAndroid Build Coastguard Worker this.router_ = null; 44*635a8641SAndroid Build Coastguard Worker this.interfaceEndpointClient_ = null; 45*635a8641SAndroid Build Coastguard Worker this.proxy_ = null; 46*635a8641SAndroid Build Coastguard Worker 47*635a8641SAndroid Build Coastguard Worker // |router_| and |interfaceEndpointClient_| are lazily initialized. 48*635a8641SAndroid Build Coastguard Worker // |handle_| is valid between bind() and 49*635a8641SAndroid Build Coastguard Worker // the initialization of |router_| and |interfaceEndpointClient_|. 50*635a8641SAndroid Build Coastguard Worker this.handle_ = null; 51*635a8641SAndroid Build Coastguard Worker 52*635a8641SAndroid Build Coastguard Worker if (ptrInfoOrHandle) 53*635a8641SAndroid Build Coastguard Worker this.bind(ptrInfoOrHandle); 54*635a8641SAndroid Build Coastguard Worker } 55*635a8641SAndroid Build Coastguard Worker 56*635a8641SAndroid Build Coastguard Worker InterfacePtrController.prototype.bind = function(ptrInfoOrHandle) { 57*635a8641SAndroid Build Coastguard Worker this.reset(); 58*635a8641SAndroid Build Coastguard Worker 59*635a8641SAndroid Build Coastguard Worker if (ptrInfoOrHandle instanceof mojo.InterfacePtrInfo) { 60*635a8641SAndroid Build Coastguard Worker this.version = ptrInfoOrHandle.version; 61*635a8641SAndroid Build Coastguard Worker this.handle_ = ptrInfoOrHandle.handle; 62*635a8641SAndroid Build Coastguard Worker } else { 63*635a8641SAndroid Build Coastguard Worker this.handle_ = ptrInfoOrHandle; 64*635a8641SAndroid Build Coastguard Worker } 65*635a8641SAndroid Build Coastguard Worker }; 66*635a8641SAndroid Build Coastguard Worker 67*635a8641SAndroid Build Coastguard Worker InterfacePtrController.prototype.isBound = function() { 68*635a8641SAndroid Build Coastguard Worker return this.interfaceEndpointClient_ !== null || this.handle_ !== null; 69*635a8641SAndroid Build Coastguard Worker }; 70*635a8641SAndroid Build Coastguard Worker 71*635a8641SAndroid Build Coastguard Worker // Although users could just discard the object, reset() closes the pipe 72*635a8641SAndroid Build Coastguard Worker // immediately. 73*635a8641SAndroid Build Coastguard Worker InterfacePtrController.prototype.reset = function() { 74*635a8641SAndroid Build Coastguard Worker this.version = 0; 75*635a8641SAndroid Build Coastguard Worker if (this.interfaceEndpointClient_) { 76*635a8641SAndroid Build Coastguard Worker this.interfaceEndpointClient_.close(); 77*635a8641SAndroid Build Coastguard Worker this.interfaceEndpointClient_ = null; 78*635a8641SAndroid Build Coastguard Worker } 79*635a8641SAndroid Build Coastguard Worker if (this.router_) { 80*635a8641SAndroid Build Coastguard Worker this.router_.close(); 81*635a8641SAndroid Build Coastguard Worker this.router_ = null; 82*635a8641SAndroid Build Coastguard Worker 83*635a8641SAndroid Build Coastguard Worker this.proxy_ = null; 84*635a8641SAndroid Build Coastguard Worker } 85*635a8641SAndroid Build Coastguard Worker if (this.handle_) { 86*635a8641SAndroid Build Coastguard Worker this.handle_.close(); 87*635a8641SAndroid Build Coastguard Worker this.handle_ = null; 88*635a8641SAndroid Build Coastguard Worker } 89*635a8641SAndroid Build Coastguard Worker }; 90*635a8641SAndroid Build Coastguard Worker 91*635a8641SAndroid Build Coastguard Worker InterfacePtrController.prototype.resetWithReason = function(reason) { 92*635a8641SAndroid Build Coastguard Worker if (this.isBound()) { 93*635a8641SAndroid Build Coastguard Worker this.configureProxyIfNecessary_(); 94*635a8641SAndroid Build Coastguard Worker this.interfaceEndpointClient_.close(reason); 95*635a8641SAndroid Build Coastguard Worker this.interfaceEndpointClient_ = null; 96*635a8641SAndroid Build Coastguard Worker } 97*635a8641SAndroid Build Coastguard Worker this.reset(); 98*635a8641SAndroid Build Coastguard Worker }; 99*635a8641SAndroid Build Coastguard Worker 100*635a8641SAndroid Build Coastguard Worker InterfacePtrController.prototype.setConnectionErrorHandler = function( 101*635a8641SAndroid Build Coastguard Worker callback) { 102*635a8641SAndroid Build Coastguard Worker if (!this.isBound()) 103*635a8641SAndroid Build Coastguard Worker throw new Error("Cannot set connection error handler if not bound."); 104*635a8641SAndroid Build Coastguard Worker 105*635a8641SAndroid Build Coastguard Worker this.configureProxyIfNecessary_(); 106*635a8641SAndroid Build Coastguard Worker this.interfaceEndpointClient_.setConnectionErrorHandler(callback); 107*635a8641SAndroid Build Coastguard Worker }; 108*635a8641SAndroid Build Coastguard Worker 109*635a8641SAndroid Build Coastguard Worker InterfacePtrController.prototype.passInterface = function() { 110*635a8641SAndroid Build Coastguard Worker var result; 111*635a8641SAndroid Build Coastguard Worker if (this.router_) { 112*635a8641SAndroid Build Coastguard Worker // TODO(yzshen): Fix Router interface to support extracting handle. 113*635a8641SAndroid Build Coastguard Worker result = new mojo.InterfacePtrInfo( 114*635a8641SAndroid Build Coastguard Worker this.router_.connector_.handle_, this.version); 115*635a8641SAndroid Build Coastguard Worker this.router_.connector_.handle_ = null; 116*635a8641SAndroid Build Coastguard Worker } else { 117*635a8641SAndroid Build Coastguard Worker // This also handles the case when this object is not bound. 118*635a8641SAndroid Build Coastguard Worker result = new mojo.InterfacePtrInfo(this.handle_, this.version); 119*635a8641SAndroid Build Coastguard Worker this.handle_ = null; 120*635a8641SAndroid Build Coastguard Worker } 121*635a8641SAndroid Build Coastguard Worker 122*635a8641SAndroid Build Coastguard Worker this.reset(); 123*635a8641SAndroid Build Coastguard Worker return result; 124*635a8641SAndroid Build Coastguard Worker }; 125*635a8641SAndroid Build Coastguard Worker 126*635a8641SAndroid Build Coastguard Worker InterfacePtrController.prototype.getProxy = function() { 127*635a8641SAndroid Build Coastguard Worker this.configureProxyIfNecessary_(); 128*635a8641SAndroid Build Coastguard Worker return this.proxy_; 129*635a8641SAndroid Build Coastguard Worker }; 130*635a8641SAndroid Build Coastguard Worker 131*635a8641SAndroid Build Coastguard Worker InterfacePtrController.prototype.configureProxyIfNecessary_ = function() { 132*635a8641SAndroid Build Coastguard Worker if (!this.handle_) 133*635a8641SAndroid Build Coastguard Worker return; 134*635a8641SAndroid Build Coastguard Worker 135*635a8641SAndroid Build Coastguard Worker this.router_ = new internal.Router(this.handle_, true); 136*635a8641SAndroid Build Coastguard Worker this.handle_ = null; 137*635a8641SAndroid Build Coastguard Worker 138*635a8641SAndroid Build Coastguard Worker this.interfaceEndpointClient_ = new internal.InterfaceEndpointClient( 139*635a8641SAndroid Build Coastguard Worker this.router_.createLocalEndpointHandle(internal.kMasterInterfaceId)); 140*635a8641SAndroid Build Coastguard Worker 141*635a8641SAndroid Build Coastguard Worker this.interfaceEndpointClient_ .setPayloadValidators([ 142*635a8641SAndroid Build Coastguard Worker this.interfaceType_.validateResponse]); 143*635a8641SAndroid Build Coastguard Worker this.proxy_ = new this.interfaceType_.proxyClass( 144*635a8641SAndroid Build Coastguard Worker this.interfaceEndpointClient_); 145*635a8641SAndroid Build Coastguard Worker }; 146*635a8641SAndroid Build Coastguard Worker 147*635a8641SAndroid Build Coastguard Worker InterfacePtrController.prototype.queryVersion = function() { 148*635a8641SAndroid Build Coastguard Worker function onQueryVersion(version) { 149*635a8641SAndroid Build Coastguard Worker this.version = version; 150*635a8641SAndroid Build Coastguard Worker return version; 151*635a8641SAndroid Build Coastguard Worker } 152*635a8641SAndroid Build Coastguard Worker 153*635a8641SAndroid Build Coastguard Worker this.configureProxyIfNecessary_(); 154*635a8641SAndroid Build Coastguard Worker return this.interfaceEndpointClient_.queryVersion().then( 155*635a8641SAndroid Build Coastguard Worker onQueryVersion.bind(this)); 156*635a8641SAndroid Build Coastguard Worker }; 157*635a8641SAndroid Build Coastguard Worker 158*635a8641SAndroid Build Coastguard Worker InterfacePtrController.prototype.requireVersion = function(version) { 159*635a8641SAndroid Build Coastguard Worker this.configureProxyIfNecessary_(); 160*635a8641SAndroid Build Coastguard Worker 161*635a8641SAndroid Build Coastguard Worker if (this.version >= version) { 162*635a8641SAndroid Build Coastguard Worker return; 163*635a8641SAndroid Build Coastguard Worker } 164*635a8641SAndroid Build Coastguard Worker this.version = version; 165*635a8641SAndroid Build Coastguard Worker this.interfaceEndpointClient_.requireVersion(version); 166*635a8641SAndroid Build Coastguard Worker }; 167*635a8641SAndroid Build Coastguard Worker 168*635a8641SAndroid Build Coastguard Worker // --------------------------------------------------------------------------- 169*635a8641SAndroid Build Coastguard Worker 170*635a8641SAndroid Build Coastguard Worker // |request| could be omitted and passed into bind() later. 171*635a8641SAndroid Build Coastguard Worker // 172*635a8641SAndroid Build Coastguard Worker // Example: 173*635a8641SAndroid Build Coastguard Worker // 174*635a8641SAndroid Build Coastguard Worker // // FooImpl implements mojom.Foo. 175*635a8641SAndroid Build Coastguard Worker // function FooImpl() { ... } 176*635a8641SAndroid Build Coastguard Worker // FooImpl.prototype.fooMethod1 = function() { ... } 177*635a8641SAndroid Build Coastguard Worker // FooImpl.prototype.fooMethod2 = function() { ... } 178*635a8641SAndroid Build Coastguard Worker // 179*635a8641SAndroid Build Coastguard Worker // var fooPtr = new mojom.FooPtr(); 180*635a8641SAndroid Build Coastguard Worker // var request = makeRequest(fooPtr); 181*635a8641SAndroid Build Coastguard Worker // var binding = new Binding(mojom.Foo, new FooImpl(), request); 182*635a8641SAndroid Build Coastguard Worker // fooPtr.fooMethod1(); 183*635a8641SAndroid Build Coastguard Worker function Binding(interfaceType, impl, requestOrHandle) { 184*635a8641SAndroid Build Coastguard Worker this.interfaceType_ = interfaceType; 185*635a8641SAndroid Build Coastguard Worker this.impl_ = impl; 186*635a8641SAndroid Build Coastguard Worker this.router_ = null; 187*635a8641SAndroid Build Coastguard Worker this.interfaceEndpointClient_ = null; 188*635a8641SAndroid Build Coastguard Worker this.stub_ = null; 189*635a8641SAndroid Build Coastguard Worker 190*635a8641SAndroid Build Coastguard Worker if (requestOrHandle) 191*635a8641SAndroid Build Coastguard Worker this.bind(requestOrHandle); 192*635a8641SAndroid Build Coastguard Worker } 193*635a8641SAndroid Build Coastguard Worker 194*635a8641SAndroid Build Coastguard Worker Binding.prototype.isBound = function() { 195*635a8641SAndroid Build Coastguard Worker return this.router_ !== null; 196*635a8641SAndroid Build Coastguard Worker }; 197*635a8641SAndroid Build Coastguard Worker 198*635a8641SAndroid Build Coastguard Worker Binding.prototype.createInterfacePtrAndBind = function() { 199*635a8641SAndroid Build Coastguard Worker var ptr = new this.interfaceType_.ptrClass(); 200*635a8641SAndroid Build Coastguard Worker // TODO(yzshen): Set the version of the interface pointer. 201*635a8641SAndroid Build Coastguard Worker this.bind(makeRequest(ptr)); 202*635a8641SAndroid Build Coastguard Worker return ptr; 203*635a8641SAndroid Build Coastguard Worker }; 204*635a8641SAndroid Build Coastguard Worker 205*635a8641SAndroid Build Coastguard Worker Binding.prototype.bind = function(requestOrHandle) { 206*635a8641SAndroid Build Coastguard Worker this.close(); 207*635a8641SAndroid Build Coastguard Worker 208*635a8641SAndroid Build Coastguard Worker var handle = requestOrHandle instanceof mojo.InterfaceRequest ? 209*635a8641SAndroid Build Coastguard Worker requestOrHandle.handle : requestOrHandle; 210*635a8641SAndroid Build Coastguard Worker if (!(handle instanceof MojoHandle)) 211*635a8641SAndroid Build Coastguard Worker return; 212*635a8641SAndroid Build Coastguard Worker 213*635a8641SAndroid Build Coastguard Worker this.router_ = new internal.Router(handle); 214*635a8641SAndroid Build Coastguard Worker 215*635a8641SAndroid Build Coastguard Worker this.stub_ = new this.interfaceType_.stubClass(this.impl_); 216*635a8641SAndroid Build Coastguard Worker this.interfaceEndpointClient_ = new internal.InterfaceEndpointClient( 217*635a8641SAndroid Build Coastguard Worker this.router_.createLocalEndpointHandle(internal.kMasterInterfaceId), 218*635a8641SAndroid Build Coastguard Worker this.stub_, this.interfaceType_.kVersion); 219*635a8641SAndroid Build Coastguard Worker 220*635a8641SAndroid Build Coastguard Worker this.interfaceEndpointClient_ .setPayloadValidators([ 221*635a8641SAndroid Build Coastguard Worker this.interfaceType_.validateRequest]); 222*635a8641SAndroid Build Coastguard Worker }; 223*635a8641SAndroid Build Coastguard Worker 224*635a8641SAndroid Build Coastguard Worker Binding.prototype.close = function() { 225*635a8641SAndroid Build Coastguard Worker if (!this.isBound()) 226*635a8641SAndroid Build Coastguard Worker return; 227*635a8641SAndroid Build Coastguard Worker 228*635a8641SAndroid Build Coastguard Worker if (this.interfaceEndpointClient_) { 229*635a8641SAndroid Build Coastguard Worker this.interfaceEndpointClient_.close(); 230*635a8641SAndroid Build Coastguard Worker this.interfaceEndpointClient_ = null; 231*635a8641SAndroid Build Coastguard Worker } 232*635a8641SAndroid Build Coastguard Worker 233*635a8641SAndroid Build Coastguard Worker this.router_.close(); 234*635a8641SAndroid Build Coastguard Worker this.router_ = null; 235*635a8641SAndroid Build Coastguard Worker this.stub_ = null; 236*635a8641SAndroid Build Coastguard Worker }; 237*635a8641SAndroid Build Coastguard Worker 238*635a8641SAndroid Build Coastguard Worker Binding.prototype.closeWithReason = function(reason) { 239*635a8641SAndroid Build Coastguard Worker if (this.interfaceEndpointClient_) { 240*635a8641SAndroid Build Coastguard Worker this.interfaceEndpointClient_.close(reason); 241*635a8641SAndroid Build Coastguard Worker this.interfaceEndpointClient_ = null; 242*635a8641SAndroid Build Coastguard Worker } 243*635a8641SAndroid Build Coastguard Worker this.close(); 244*635a8641SAndroid Build Coastguard Worker }; 245*635a8641SAndroid Build Coastguard Worker 246*635a8641SAndroid Build Coastguard Worker Binding.prototype.setConnectionErrorHandler = function(callback) { 247*635a8641SAndroid Build Coastguard Worker if (!this.isBound()) { 248*635a8641SAndroid Build Coastguard Worker throw new Error("Cannot set connection error handler if not bound."); 249*635a8641SAndroid Build Coastguard Worker } 250*635a8641SAndroid Build Coastguard Worker this.interfaceEndpointClient_.setConnectionErrorHandler(callback); 251*635a8641SAndroid Build Coastguard Worker }; 252*635a8641SAndroid Build Coastguard Worker 253*635a8641SAndroid Build Coastguard Worker Binding.prototype.unbind = function() { 254*635a8641SAndroid Build Coastguard Worker if (!this.isBound()) 255*635a8641SAndroid Build Coastguard Worker return new mojo.InterfaceRequest(null); 256*635a8641SAndroid Build Coastguard Worker 257*635a8641SAndroid Build Coastguard Worker var result = new mojo.InterfaceRequest(this.router_.connector_.handle_); 258*635a8641SAndroid Build Coastguard Worker this.router_.connector_.handle_ = null; 259*635a8641SAndroid Build Coastguard Worker this.close(); 260*635a8641SAndroid Build Coastguard Worker return result; 261*635a8641SAndroid Build Coastguard Worker }; 262*635a8641SAndroid Build Coastguard Worker 263*635a8641SAndroid Build Coastguard Worker // --------------------------------------------------------------------------- 264*635a8641SAndroid Build Coastguard Worker 265*635a8641SAndroid Build Coastguard Worker function BindingSetEntry(bindingSet, interfaceType, bindingType, impl, 266*635a8641SAndroid Build Coastguard Worker requestOrHandle, bindingId) { 267*635a8641SAndroid Build Coastguard Worker this.bindingSet_ = bindingSet; 268*635a8641SAndroid Build Coastguard Worker this.bindingId_ = bindingId; 269*635a8641SAndroid Build Coastguard Worker this.binding_ = new bindingType(interfaceType, impl, 270*635a8641SAndroid Build Coastguard Worker requestOrHandle); 271*635a8641SAndroid Build Coastguard Worker 272*635a8641SAndroid Build Coastguard Worker this.binding_.setConnectionErrorHandler(function(reason) { 273*635a8641SAndroid Build Coastguard Worker this.bindingSet_.onConnectionError(bindingId, reason); 274*635a8641SAndroid Build Coastguard Worker }.bind(this)); 275*635a8641SAndroid Build Coastguard Worker } 276*635a8641SAndroid Build Coastguard Worker 277*635a8641SAndroid Build Coastguard Worker BindingSetEntry.prototype.close = function() { 278*635a8641SAndroid Build Coastguard Worker this.binding_.close(); 279*635a8641SAndroid Build Coastguard Worker }; 280*635a8641SAndroid Build Coastguard Worker 281*635a8641SAndroid Build Coastguard Worker function BindingSet(interfaceType) { 282*635a8641SAndroid Build Coastguard Worker this.interfaceType_ = interfaceType; 283*635a8641SAndroid Build Coastguard Worker this.nextBindingId_ = 0; 284*635a8641SAndroid Build Coastguard Worker this.bindings_ = new Map(); 285*635a8641SAndroid Build Coastguard Worker this.errorHandler_ = null; 286*635a8641SAndroid Build Coastguard Worker this.bindingType_ = Binding; 287*635a8641SAndroid Build Coastguard Worker } 288*635a8641SAndroid Build Coastguard Worker 289*635a8641SAndroid Build Coastguard Worker BindingSet.prototype.isEmpty = function() { 290*635a8641SAndroid Build Coastguard Worker return this.bindings_.size == 0; 291*635a8641SAndroid Build Coastguard Worker }; 292*635a8641SAndroid Build Coastguard Worker 293*635a8641SAndroid Build Coastguard Worker BindingSet.prototype.addBinding = function(impl, requestOrHandle) { 294*635a8641SAndroid Build Coastguard Worker this.bindings_.set( 295*635a8641SAndroid Build Coastguard Worker this.nextBindingId_, 296*635a8641SAndroid Build Coastguard Worker new BindingSetEntry(this, this.interfaceType_, this.bindingType_, impl, 297*635a8641SAndroid Build Coastguard Worker requestOrHandle, this.nextBindingId_)); 298*635a8641SAndroid Build Coastguard Worker ++this.nextBindingId_; 299*635a8641SAndroid Build Coastguard Worker }; 300*635a8641SAndroid Build Coastguard Worker 301*635a8641SAndroid Build Coastguard Worker BindingSet.prototype.closeAllBindings = function() { 302*635a8641SAndroid Build Coastguard Worker for (var entry of this.bindings_.values()) 303*635a8641SAndroid Build Coastguard Worker entry.close(); 304*635a8641SAndroid Build Coastguard Worker this.bindings_.clear(); 305*635a8641SAndroid Build Coastguard Worker }; 306*635a8641SAndroid Build Coastguard Worker 307*635a8641SAndroid Build Coastguard Worker BindingSet.prototype.setConnectionErrorHandler = function(callback) { 308*635a8641SAndroid Build Coastguard Worker this.errorHandler_ = callback; 309*635a8641SAndroid Build Coastguard Worker }; 310*635a8641SAndroid Build Coastguard Worker 311*635a8641SAndroid Build Coastguard Worker BindingSet.prototype.onConnectionError = function(bindingId, reason) { 312*635a8641SAndroid Build Coastguard Worker this.bindings_.delete(bindingId); 313*635a8641SAndroid Build Coastguard Worker 314*635a8641SAndroid Build Coastguard Worker if (this.errorHandler_) 315*635a8641SAndroid Build Coastguard Worker this.errorHandler_(reason); 316*635a8641SAndroid Build Coastguard Worker }; 317*635a8641SAndroid Build Coastguard Worker 318*635a8641SAndroid Build Coastguard Worker // --------------------------------------------------------------------------- 319*635a8641SAndroid Build Coastguard Worker 320*635a8641SAndroid Build Coastguard Worker // Operations used to setup/configure an associated interface pointer. 321*635a8641SAndroid Build Coastguard Worker // Exposed as |ptr| field of generated associated interface pointer classes. 322*635a8641SAndroid Build Coastguard Worker // |associatedPtrInfo| could be omitted and passed into bind() later. 323*635a8641SAndroid Build Coastguard Worker // 324*635a8641SAndroid Build Coastguard Worker // Example: 325*635a8641SAndroid Build Coastguard Worker // // IntegerSenderImpl implements mojom.IntegerSender 326*635a8641SAndroid Build Coastguard Worker // function IntegerSenderImpl() { ... } 327*635a8641SAndroid Build Coastguard Worker // IntegerSenderImpl.prototype.echo = function() { ... } 328*635a8641SAndroid Build Coastguard Worker // 329*635a8641SAndroid Build Coastguard Worker // // IntegerSenderConnectionImpl implements mojom.IntegerSenderConnection 330*635a8641SAndroid Build Coastguard Worker // function IntegerSenderConnectionImpl() { 331*635a8641SAndroid Build Coastguard Worker // this.senderBinding_ = null; 332*635a8641SAndroid Build Coastguard Worker // } 333*635a8641SAndroid Build Coastguard Worker // IntegerSenderConnectionImpl.prototype.getSender = function( 334*635a8641SAndroid Build Coastguard Worker // associatedRequest) { 335*635a8641SAndroid Build Coastguard Worker // this.senderBinding_ = new AssociatedBinding(mojom.IntegerSender, 336*635a8641SAndroid Build Coastguard Worker // new IntegerSenderImpl(), 337*635a8641SAndroid Build Coastguard Worker // associatedRequest); 338*635a8641SAndroid Build Coastguard Worker // } 339*635a8641SAndroid Build Coastguard Worker // 340*635a8641SAndroid Build Coastguard Worker // var integerSenderConnection = new mojom.IntegerSenderConnectionPtr(); 341*635a8641SAndroid Build Coastguard Worker // var integerSenderConnectionBinding = new Binding( 342*635a8641SAndroid Build Coastguard Worker // mojom.IntegerSenderConnection, 343*635a8641SAndroid Build Coastguard Worker // new IntegerSenderConnectionImpl(), 344*635a8641SAndroid Build Coastguard Worker // mojo.makeRequest(integerSenderConnection)); 345*635a8641SAndroid Build Coastguard Worker // 346*635a8641SAndroid Build Coastguard Worker // // A locally-created associated interface pointer can only be used to 347*635a8641SAndroid Build Coastguard Worker // // make calls when the corresponding associated request is sent over 348*635a8641SAndroid Build Coastguard Worker // // another interface (either the master interface or another 349*635a8641SAndroid Build Coastguard Worker // // associated interface). 350*635a8641SAndroid Build Coastguard Worker // var associatedInterfacePtrInfo = new AssociatedInterfacePtrInfo(); 351*635a8641SAndroid Build Coastguard Worker // var associatedRequest = makeRequest(interfacePtrInfo); 352*635a8641SAndroid Build Coastguard Worker // 353*635a8641SAndroid Build Coastguard Worker // integerSenderConnection.getSender(associatedRequest); 354*635a8641SAndroid Build Coastguard Worker // 355*635a8641SAndroid Build Coastguard Worker // // Create an associated interface and bind the associated handle. 356*635a8641SAndroid Build Coastguard Worker // var integerSender = new mojom.AssociatedIntegerSenderPtr(); 357*635a8641SAndroid Build Coastguard Worker // integerSender.ptr.bind(associatedInterfacePtrInfo); 358*635a8641SAndroid Build Coastguard Worker // integerSender.echo(); 359*635a8641SAndroid Build Coastguard Worker 360*635a8641SAndroid Build Coastguard Worker function AssociatedInterfacePtrController(interfaceType, associatedPtrInfo) { 361*635a8641SAndroid Build Coastguard Worker this.version = 0; 362*635a8641SAndroid Build Coastguard Worker 363*635a8641SAndroid Build Coastguard Worker this.interfaceType_ = interfaceType; 364*635a8641SAndroid Build Coastguard Worker this.interfaceEndpointClient_ = null; 365*635a8641SAndroid Build Coastguard Worker this.proxy_ = null; 366*635a8641SAndroid Build Coastguard Worker 367*635a8641SAndroid Build Coastguard Worker if (associatedPtrInfo) { 368*635a8641SAndroid Build Coastguard Worker this.bind(associatedPtrInfo); 369*635a8641SAndroid Build Coastguard Worker } 370*635a8641SAndroid Build Coastguard Worker } 371*635a8641SAndroid Build Coastguard Worker 372*635a8641SAndroid Build Coastguard Worker AssociatedInterfacePtrController.prototype.bind = function( 373*635a8641SAndroid Build Coastguard Worker associatedPtrInfo) { 374*635a8641SAndroid Build Coastguard Worker this.reset(); 375*635a8641SAndroid Build Coastguard Worker this.version = associatedPtrInfo.version; 376*635a8641SAndroid Build Coastguard Worker 377*635a8641SAndroid Build Coastguard Worker this.interfaceEndpointClient_ = new internal.InterfaceEndpointClient( 378*635a8641SAndroid Build Coastguard Worker associatedPtrInfo.interfaceEndpointHandle); 379*635a8641SAndroid Build Coastguard Worker 380*635a8641SAndroid Build Coastguard Worker this.interfaceEndpointClient_ .setPayloadValidators([ 381*635a8641SAndroid Build Coastguard Worker this.interfaceType_.validateResponse]); 382*635a8641SAndroid Build Coastguard Worker this.proxy_ = new this.interfaceType_.proxyClass( 383*635a8641SAndroid Build Coastguard Worker this.interfaceEndpointClient_); 384*635a8641SAndroid Build Coastguard Worker }; 385*635a8641SAndroid Build Coastguard Worker 386*635a8641SAndroid Build Coastguard Worker AssociatedInterfacePtrController.prototype.isBound = function() { 387*635a8641SAndroid Build Coastguard Worker return this.interfaceEndpointClient_ !== null; 388*635a8641SAndroid Build Coastguard Worker }; 389*635a8641SAndroid Build Coastguard Worker 390*635a8641SAndroid Build Coastguard Worker AssociatedInterfacePtrController.prototype.reset = function() { 391*635a8641SAndroid Build Coastguard Worker this.version = 0; 392*635a8641SAndroid Build Coastguard Worker if (this.interfaceEndpointClient_) { 393*635a8641SAndroid Build Coastguard Worker this.interfaceEndpointClient_.close(); 394*635a8641SAndroid Build Coastguard Worker this.interfaceEndpointClient_ = null; 395*635a8641SAndroid Build Coastguard Worker } 396*635a8641SAndroid Build Coastguard Worker if (this.proxy_) { 397*635a8641SAndroid Build Coastguard Worker this.proxy_ = null; 398*635a8641SAndroid Build Coastguard Worker } 399*635a8641SAndroid Build Coastguard Worker }; 400*635a8641SAndroid Build Coastguard Worker 401*635a8641SAndroid Build Coastguard Worker AssociatedInterfacePtrController.prototype.resetWithReason = function( 402*635a8641SAndroid Build Coastguard Worker reason) { 403*635a8641SAndroid Build Coastguard Worker if (this.isBound()) { 404*635a8641SAndroid Build Coastguard Worker this.interfaceEndpointClient_.close(reason); 405*635a8641SAndroid Build Coastguard Worker this.interfaceEndpointClient_ = null; 406*635a8641SAndroid Build Coastguard Worker } 407*635a8641SAndroid Build Coastguard Worker this.reset(); 408*635a8641SAndroid Build Coastguard Worker }; 409*635a8641SAndroid Build Coastguard Worker 410*635a8641SAndroid Build Coastguard Worker // Indicates whether an error has been encountered. If true, method calls 411*635a8641SAndroid Build Coastguard Worker // on this interface will be dropped (and may already have been dropped). 412*635a8641SAndroid Build Coastguard Worker AssociatedInterfacePtrController.prototype.getEncounteredError = function() { 413*635a8641SAndroid Build Coastguard Worker return this.interfaceEndpointClient_ ? 414*635a8641SAndroid Build Coastguard Worker this.interfaceEndpointClient_.getEncounteredError() : false; 415*635a8641SAndroid Build Coastguard Worker }; 416*635a8641SAndroid Build Coastguard Worker 417*635a8641SAndroid Build Coastguard Worker AssociatedInterfacePtrController.prototype.setConnectionErrorHandler = 418*635a8641SAndroid Build Coastguard Worker function(callback) { 419*635a8641SAndroid Build Coastguard Worker if (!this.isBound()) { 420*635a8641SAndroid Build Coastguard Worker throw new Error("Cannot set connection error handler if not bound."); 421*635a8641SAndroid Build Coastguard Worker } 422*635a8641SAndroid Build Coastguard Worker 423*635a8641SAndroid Build Coastguard Worker this.interfaceEndpointClient_.setConnectionErrorHandler(callback); 424*635a8641SAndroid Build Coastguard Worker }; 425*635a8641SAndroid Build Coastguard Worker 426*635a8641SAndroid Build Coastguard Worker AssociatedInterfacePtrController.prototype.passInterface = function() { 427*635a8641SAndroid Build Coastguard Worker if (!this.isBound()) { 428*635a8641SAndroid Build Coastguard Worker return new mojo.AssociatedInterfacePtrInfo(null); 429*635a8641SAndroid Build Coastguard Worker } 430*635a8641SAndroid Build Coastguard Worker 431*635a8641SAndroid Build Coastguard Worker var result = new mojo.AssociatedInterfacePtrInfo( 432*635a8641SAndroid Build Coastguard Worker this.interfaceEndpointClient_.passHandle(), this.version); 433*635a8641SAndroid Build Coastguard Worker this.reset(); 434*635a8641SAndroid Build Coastguard Worker return result; 435*635a8641SAndroid Build Coastguard Worker }; 436*635a8641SAndroid Build Coastguard Worker 437*635a8641SAndroid Build Coastguard Worker AssociatedInterfacePtrController.prototype.getProxy = function() { 438*635a8641SAndroid Build Coastguard Worker return this.proxy_; 439*635a8641SAndroid Build Coastguard Worker }; 440*635a8641SAndroid Build Coastguard Worker 441*635a8641SAndroid Build Coastguard Worker AssociatedInterfacePtrController.prototype.queryVersion = function() { 442*635a8641SAndroid Build Coastguard Worker function onQueryVersion(version) { 443*635a8641SAndroid Build Coastguard Worker this.version = version; 444*635a8641SAndroid Build Coastguard Worker return version; 445*635a8641SAndroid Build Coastguard Worker } 446*635a8641SAndroid Build Coastguard Worker 447*635a8641SAndroid Build Coastguard Worker return this.interfaceEndpointClient_.queryVersion().then( 448*635a8641SAndroid Build Coastguard Worker onQueryVersion.bind(this)); 449*635a8641SAndroid Build Coastguard Worker }; 450*635a8641SAndroid Build Coastguard Worker 451*635a8641SAndroid Build Coastguard Worker AssociatedInterfacePtrController.prototype.requireVersion = function( 452*635a8641SAndroid Build Coastguard Worker version) { 453*635a8641SAndroid Build Coastguard Worker if (this.version >= version) { 454*635a8641SAndroid Build Coastguard Worker return; 455*635a8641SAndroid Build Coastguard Worker } 456*635a8641SAndroid Build Coastguard Worker this.version = version; 457*635a8641SAndroid Build Coastguard Worker this.interfaceEndpointClient_.requireVersion(version); 458*635a8641SAndroid Build Coastguard Worker }; 459*635a8641SAndroid Build Coastguard Worker 460*635a8641SAndroid Build Coastguard Worker // --------------------------------------------------------------------------- 461*635a8641SAndroid Build Coastguard Worker 462*635a8641SAndroid Build Coastguard Worker // |associatedInterfaceRequest| could be omitted and passed into bind() 463*635a8641SAndroid Build Coastguard Worker // later. 464*635a8641SAndroid Build Coastguard Worker function AssociatedBinding(interfaceType, impl, associatedInterfaceRequest) { 465*635a8641SAndroid Build Coastguard Worker this.interfaceType_ = interfaceType; 466*635a8641SAndroid Build Coastguard Worker this.impl_ = impl; 467*635a8641SAndroid Build Coastguard Worker this.interfaceEndpointClient_ = null; 468*635a8641SAndroid Build Coastguard Worker this.stub_ = null; 469*635a8641SAndroid Build Coastguard Worker 470*635a8641SAndroid Build Coastguard Worker if (associatedInterfaceRequest) { 471*635a8641SAndroid Build Coastguard Worker this.bind(associatedInterfaceRequest); 472*635a8641SAndroid Build Coastguard Worker } 473*635a8641SAndroid Build Coastguard Worker } 474*635a8641SAndroid Build Coastguard Worker 475*635a8641SAndroid Build Coastguard Worker AssociatedBinding.prototype.isBound = function() { 476*635a8641SAndroid Build Coastguard Worker return this.interfaceEndpointClient_ !== null; 477*635a8641SAndroid Build Coastguard Worker }; 478*635a8641SAndroid Build Coastguard Worker 479*635a8641SAndroid Build Coastguard Worker AssociatedBinding.prototype.bind = function(associatedInterfaceRequest) { 480*635a8641SAndroid Build Coastguard Worker this.close(); 481*635a8641SAndroid Build Coastguard Worker 482*635a8641SAndroid Build Coastguard Worker this.stub_ = new this.interfaceType_.stubClass(this.impl_); 483*635a8641SAndroid Build Coastguard Worker this.interfaceEndpointClient_ = new internal.InterfaceEndpointClient( 484*635a8641SAndroid Build Coastguard Worker associatedInterfaceRequest.interfaceEndpointHandle, this.stub_, 485*635a8641SAndroid Build Coastguard Worker this.interfaceType_.kVersion); 486*635a8641SAndroid Build Coastguard Worker 487*635a8641SAndroid Build Coastguard Worker this.interfaceEndpointClient_ .setPayloadValidators([ 488*635a8641SAndroid Build Coastguard Worker this.interfaceType_.validateRequest]); 489*635a8641SAndroid Build Coastguard Worker }; 490*635a8641SAndroid Build Coastguard Worker 491*635a8641SAndroid Build Coastguard Worker 492*635a8641SAndroid Build Coastguard Worker AssociatedBinding.prototype.close = function() { 493*635a8641SAndroid Build Coastguard Worker if (!this.isBound()) { 494*635a8641SAndroid Build Coastguard Worker return; 495*635a8641SAndroid Build Coastguard Worker } 496*635a8641SAndroid Build Coastguard Worker 497*635a8641SAndroid Build Coastguard Worker if (this.interfaceEndpointClient_) { 498*635a8641SAndroid Build Coastguard Worker this.interfaceEndpointClient_.close(); 499*635a8641SAndroid Build Coastguard Worker this.interfaceEndpointClient_ = null; 500*635a8641SAndroid Build Coastguard Worker } 501*635a8641SAndroid Build Coastguard Worker 502*635a8641SAndroid Build Coastguard Worker this.stub_ = null; 503*635a8641SAndroid Build Coastguard Worker }; 504*635a8641SAndroid Build Coastguard Worker 505*635a8641SAndroid Build Coastguard Worker AssociatedBinding.prototype.closeWithReason = function(reason) { 506*635a8641SAndroid Build Coastguard Worker if (this.interfaceEndpointClient_) { 507*635a8641SAndroid Build Coastguard Worker this.interfaceEndpointClient_.close(reason); 508*635a8641SAndroid Build Coastguard Worker this.interfaceEndpointClient_ = null; 509*635a8641SAndroid Build Coastguard Worker } 510*635a8641SAndroid Build Coastguard Worker this.close(); 511*635a8641SAndroid Build Coastguard Worker }; 512*635a8641SAndroid Build Coastguard Worker 513*635a8641SAndroid Build Coastguard Worker AssociatedBinding.prototype.setConnectionErrorHandler = function(callback) { 514*635a8641SAndroid Build Coastguard Worker if (!this.isBound()) { 515*635a8641SAndroid Build Coastguard Worker throw new Error("Cannot set connection error handler if not bound."); 516*635a8641SAndroid Build Coastguard Worker } 517*635a8641SAndroid Build Coastguard Worker this.interfaceEndpointClient_.setConnectionErrorHandler(callback); 518*635a8641SAndroid Build Coastguard Worker }; 519*635a8641SAndroid Build Coastguard Worker 520*635a8641SAndroid Build Coastguard Worker AssociatedBinding.prototype.unbind = function() { 521*635a8641SAndroid Build Coastguard Worker if (!this.isBound()) { 522*635a8641SAndroid Build Coastguard Worker return new mojo.AssociatedInterfaceRequest(null); 523*635a8641SAndroid Build Coastguard Worker } 524*635a8641SAndroid Build Coastguard Worker 525*635a8641SAndroid Build Coastguard Worker var result = new mojo.AssociatedInterfaceRequest( 526*635a8641SAndroid Build Coastguard Worker this.interfaceEndpointClient_.passHandle()); 527*635a8641SAndroid Build Coastguard Worker this.close(); 528*635a8641SAndroid Build Coastguard Worker return result; 529*635a8641SAndroid Build Coastguard Worker }; 530*635a8641SAndroid Build Coastguard Worker 531*635a8641SAndroid Build Coastguard Worker // --------------------------------------------------------------------------- 532*635a8641SAndroid Build Coastguard Worker 533*635a8641SAndroid Build Coastguard Worker function AssociatedBindingSet(interfaceType) { 534*635a8641SAndroid Build Coastguard Worker mojo.BindingSet.call(this, interfaceType); 535*635a8641SAndroid Build Coastguard Worker this.bindingType_ = AssociatedBinding; 536*635a8641SAndroid Build Coastguard Worker } 537*635a8641SAndroid Build Coastguard Worker 538*635a8641SAndroid Build Coastguard Worker AssociatedBindingSet.prototype = Object.create(BindingSet.prototype); 539*635a8641SAndroid Build Coastguard Worker AssociatedBindingSet.prototype.constructor = AssociatedBindingSet; 540*635a8641SAndroid Build Coastguard Worker 541*635a8641SAndroid Build Coastguard Worker mojo.makeRequest = makeRequest; 542*635a8641SAndroid Build Coastguard Worker mojo.AssociatedInterfacePtrController = AssociatedInterfacePtrController; 543*635a8641SAndroid Build Coastguard Worker mojo.AssociatedBinding = AssociatedBinding; 544*635a8641SAndroid Build Coastguard Worker mojo.AssociatedBindingSet = AssociatedBindingSet; 545*635a8641SAndroid Build Coastguard Worker mojo.Binding = Binding; 546*635a8641SAndroid Build Coastguard Worker mojo.BindingSet = BindingSet; 547*635a8641SAndroid Build Coastguard Worker mojo.InterfacePtrController = InterfacePtrController; 548*635a8641SAndroid Build Coastguard Worker})(); 549