OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 define("mojo/services/public/js/service_provider", [ | 5 define("mojo/services/public/js/service_provider", [ |
| 6 "mojo/public/js/bindings", |
6 "mojo/public/interfaces/application/service_provider.mojom", | 7 "mojo/public/interfaces/application/service_provider.mojom", |
7 "mojo/public/js/connection", | 8 "mojo/public/js/connection", |
8 ], function(serviceProviderMojom, connection) { | 9 ], function(bindings, serviceProviderMojom, connection) { |
9 | 10 |
| 11 const ProxyBindings = bindings.ProxyBindings; |
| 12 const StubBindings = bindings.StubBindings; |
10 const ServiceProviderInterface = serviceProviderMojom.ServiceProvider; | 13 const ServiceProviderInterface = serviceProviderMojom.ServiceProvider; |
11 | 14 |
12 function checkServiceProvider(sp) { | 15 function checkServiceProvider(sp) { |
13 if (!sp.providers_) | 16 if (!sp.providers_) |
14 throw new Error("Service was closed"); | 17 throw new Error("Service was closed"); |
15 } | 18 } |
16 | 19 |
17 class ServiceProvider { | 20 class ServiceProvider { |
18 constructor(service) { | 21 constructor(service) { |
19 if (!(service instanceof ServiceProviderInterface.proxyClass)) | 22 if (!(service instanceof ServiceProviderInterface.proxyClass)) |
20 throw new Error("service must be a ServiceProvider proxy"); | 23 throw new Error("service must be a ServiceProvider proxy"); |
21 service.local$ = this; // Implicitly sets this.remote$ to service. | 24 this.proxy = service; |
| 25 ProxyBindings(this.proxy).setLocalDelegate(this); |
22 this.providers_ = new Map(); // serviceName => see provideService() below | 26 this.providers_ = new Map(); // serviceName => see provideService() below |
23 this.pendingRequests_ = new Map(); // serviceName => serviceHandle | 27 this.pendingRequests_ = new Map(); // serviceName => serviceHandle |
24 } | 28 } |
25 | 29 |
26 // Incoming requests | 30 // Incoming requests |
27 connectToService(serviceName, serviceHandle) { | 31 connectToService(serviceName, serviceHandle) { |
28 if (!this.providers_) // We're closed. | 32 if (!this.providers_) // We're closed. |
29 return; | 33 return; |
30 | 34 |
31 var provider = this.providers_.get(serviceName); | 35 var provider = this.providers_.get(serviceName); |
32 if (!provider) { | 36 if (!provider) { |
33 this.pendingRequests_.set(serviceName, serviceHandle); | 37 this.pendingRequests_.set(serviceName, serviceHandle); |
34 return; | 38 return; |
35 } | 39 } |
36 var proxy = connection.bindProxyHandle( | 40 var proxy = connection.bindProxyHandle( |
37 serviceHandle, provider.service, provider.service.client); | 41 serviceHandle, provider.service, provider.service.client); |
38 proxy.local$ = new provider.factory(proxy); | 42 if (ProxyBindings(proxy).local) |
39 provider.connections.push(proxy.connection$); | 43 ProxyBindings(proxy).setLocalDelegate(new provider.factory(proxy)); |
| 44 provider.connections.push(ProxyBindings(proxy).connection); |
40 } | 45 } |
41 | 46 |
42 provideService(service, factory) { | 47 provideService(service, factory) { |
43 checkServiceProvider(this); | 48 checkServiceProvider(this); |
44 | 49 |
45 var provider = { | 50 var provider = { |
46 service: service, // A JS bindings interface object. | 51 service: service, // A JS bindings interface object. |
47 factory: factory, // factory(clientProxy) => interface implemntation | 52 factory: factory, // factory(clientProxy) => interface implemntation |
48 connections: [], | 53 connections: [], |
49 }; | 54 }; |
50 this.providers_.set(service.name, provider); | 55 this.providers_.set(service.name, provider); |
51 | 56 |
52 if (this.pendingRequests_.has(service.name)) { | 57 if (this.pendingRequests_.has(service.name)) { |
53 this.connectToService(service.name, pendingRequests_.get(service.name)); | 58 this.connectToService(service.name, pendingRequests_.get(service.name)); |
54 pendingRequests_.delete(service.name); | 59 pendingRequests_.delete(service.name); |
55 } | 60 } |
56 return this; | 61 return this; |
57 } | 62 } |
58 | 63 |
59 // Outgoing requests | 64 // Outgoing requests |
60 requestService(interfaceObject, clientImpl) { | 65 requestService(interfaceObject, clientImpl) { |
61 checkServiceProvider(this); | 66 checkServiceProvider(this); |
62 if (!interfaceObject.name) | 67 if (!interfaceObject.name) |
63 throw new Error("Invalid service parameter"); | 68 throw new Error("Invalid service parameter"); |
64 if (!clientImpl && interfaceObject.client) | 69 if (!clientImpl && interfaceObject.client) |
65 throw new Error("Client implementation must be provided"); | 70 throw new Error("Client implementation must be provided"); |
66 | 71 |
67 if (!clientImpl) | 72 var remoteProxy; |
68 clientImpl = {}; | 73 var clientFactory = function(x) {remoteProxy = x; return clientImpl;}; |
69 var messagePipeHandle = connection.bindProxyClient( | 74 var messagePipeHandle = connection.bindProxyClient( |
70 clientImpl, interfaceObject.client, interfaceObject); | 75 clientFactory, interfaceObject.client, interfaceObject); |
71 this.remote$.connectToService(interfaceObject.name, messagePipeHandle); | 76 this.proxy.connectToService(interfaceObject.name, messagePipeHandle); |
72 return clientImpl.remote$; | 77 return remoteProxy; |
73 }; | 78 }; |
74 | 79 |
75 close() { | 80 close() { |
76 this.providers_ = null; | 81 this.providers_ = null; |
77 this.pendingRequests_ = null; | 82 this.pendingRequests_ = null; |
78 } | 83 } |
79 } | 84 } |
80 | 85 |
81 var exports = {}; | 86 var exports = {}; |
82 exports.ServiceProvider = ServiceProvider; | 87 exports.ServiceProvider = ServiceProvider; |
83 return exports; | 88 return exports; |
84 }); | 89 }); |
OLD | NEW |