OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 package application | 5 package application |
6 | 6 |
7 import ( | 7 import ( |
8 "log" | 8 "log" |
9 | 9 |
10 "mojo/public/go/bindings" | 10 "mojo/public/go/bindings" |
11 "mojo/public/go/system" | 11 "mojo/public/go/system" |
12 | 12 |
13 sp "mojo/public/interfaces/application/service_provider" | 13 sp "mojo/public/interfaces/application/service_provider" |
| 14 "mojo/public/interfaces/bindings/service_describer" |
14 ) | 15 ) |
15 | 16 |
16 type connectionInfo struct { | 17 type connectionInfo struct { |
17 requestorURL string | 18 requestorURL string |
18 connectionURL string | 19 connectionURL string |
19 } | 20 } |
20 | 21 |
21 // RequestorURL returns the URL of application that established the connection. | 22 // RequestorURL returns the URL of application that established the connection. |
22 func (c *connectionInfo) RequestorURL() string { | 23 func (c *connectionInfo) RequestorURL() string { |
23 return c.requestorURL | 24 return c.requestorURL |
24 } | 25 } |
25 | 26 |
26 // ConnectionURL returns the URL that was used by the source application to | 27 // ConnectionURL returns the URL that was used by the source application to |
27 // establish a connection to the destination application. | 28 // establish a connection to the destination application. |
28 func (c *connectionInfo) ConnectionURL() string { | 29 func (c *connectionInfo) ConnectionURL() string { |
29 return c.connectionURL | 30 return c.connectionURL |
30 } | 31 } |
31 | 32 |
32 // ServiceRequest is an interface request for a specified mojo service. | 33 // ServiceRequest is an interface request for a specified mojo service. |
33 type ServiceRequest interface { | 34 type ServiceRequest interface { |
34 // Name returns the name of requested mojo service. | 35 // Name returns the name of requested mojo service. |
35 Name() string | 36 Name() string |
36 | 37 |
| 38 // ServiceDescription returns a service description, which can be querie
d to |
| 39 // examine the type information of the service associated with this |
| 40 // ServiceRequest. |
| 41 // Note: In some implementations, the ServiceDescription returned will n
ot |
| 42 // provide type information. Methods called may return nil or an error. |
| 43 ServiceDescription() service_describer.ServiceDescription |
| 44 |
37 // PassMessagePipe passes ownership of the underlying message pipe | 45 // PassMessagePipe passes ownership of the underlying message pipe |
38 // handle to the newly created handle object, invalidating the | 46 // handle to the newly created handle object, invalidating the |
39 // underlying handle object in the process. | 47 // underlying handle object in the process. |
40 PassMessagePipe() system.MessagePipeHandle | 48 PassMessagePipe() system.MessagePipeHandle |
41 } | 49 } |
42 | 50 |
43 // ServiceFactory provides implementation of a mojo service. | 51 // ServiceFactory provides implementation of a mojo service. |
44 type ServiceFactory interface { | 52 type ServiceFactory interface { |
45 // Name returns the name of provided mojo service. | 53 // Name returns the name of provided mojo service. |
46 Name() string | 54 Name() string |
47 | 55 |
| 56 // ServiceDescription returns a service description, which can be querie
d to |
| 57 // examine the type information of the mojo service associated with this |
| 58 // ServiceFactory. |
| 59 // Note: In some implementations, the ServiceDescription returned will n
ot |
| 60 // provide type information. Methods called may return nil or an error. |
| 61 ServiceDescription() service_describer.ServiceDescription |
| 62 |
48 // Create binds an implementation of mojo service to the provided | 63 // Create binds an implementation of mojo service to the provided |
49 // message pipe and runs it. | 64 // message pipe and runs it. |
50 Create(pipe system.MessagePipeHandle) | 65 Create(pipe system.MessagePipeHandle) |
51 } | 66 } |
52 | 67 |
53 // Connection represents a connection to another application. An instance of | 68 // Connection represents a connection to another application. An instance of |
54 // this struct is passed to Delegate's AcceptConnection() function each time a | 69 // this struct is passed to Delegate's AcceptConnection() function each time a |
55 // connection is made to this application. | 70 // connection is made to this application. |
56 type Connection struct { | 71 type Connection struct { |
57 connectionInfo | 72 connectionInfo |
58 // Request for local services. Is valid until ProvideServices is called. | 73 // Request for local services. Is valid until ProvideServices is called. |
59 servicesRequest *sp.ServiceProvider_Request | 74 servicesRequest *sp.ServiceProvider_Request |
60 // Indicates that ProvideServices function was already called. | 75 // Indicates that ProvideServices function was already called. |
61 servicesProvided bool | 76 servicesProvided bool |
62 localServices *bindings.Stub | 77 localServices *bindings.Stub |
63 outgoingConnection *OutgoingConnection | 78 outgoingConnection *OutgoingConnection |
64 isClosed bool | 79 isClosed bool |
| 80 // Is set if ProvideServicesWithDescriber was called. |
| 81 // Note: When DescribeServices is invoked, some implementations may retu
rn |
| 82 // incomplete ServiceDescriptions. For example, if type information was
not |
| 83 // generated, then the methods called may return nil or an error. |
| 84 describer *ServiceDescriberFactory |
65 } | 85 } |
66 | 86 |
67 func newConnection(requestorURL string, services *sp.ServiceProvider_Request, ex
posedServices *sp.ServiceProvider_Pointer, resolvedURL string) *Connection { | 87 func newConnection(requestorURL string, services *sp.ServiceProvider_Request, ex
posedServices *sp.ServiceProvider_Pointer, resolvedURL string) *Connection { |
68 info := connectionInfo{ | 88 info := connectionInfo{ |
69 requestorURL, | 89 requestorURL, |
70 resolvedURL, | 90 resolvedURL, |
71 } | 91 } |
72 var remoteServices *sp.ServiceProvider_Proxy | 92 var remoteServices *sp.ServiceProvider_Proxy |
73 if exposedServices != nil { | 93 if exposedServices != nil { |
74 remoteServices = sp.NewServiceProviderProxy(*exposedServices, bi
ndings.GetAsyncWaiter()) | 94 remoteServices = sp.NewServiceProviderProxy(*exposedServices, bi
ndings.GetAsyncWaiter()) |
75 } | 95 } |
76 return &Connection{ | 96 return &Connection{ |
77 connectionInfo: info, | 97 connectionInfo: info, |
78 servicesRequest: services, | 98 servicesRequest: services, |
79 outgoingConnection: &OutgoingConnection{ | 99 outgoingConnection: &OutgoingConnection{ |
80 info, | 100 info, |
81 remoteServices, | 101 remoteServices, |
82 }, | 102 }, |
83 } | 103 } |
84 } | 104 } |
85 | 105 |
86 // ProvideServices starts a service provider on a separate goroutine that | 106 // ProvideServices starts a service provider on a separate goroutine that |
87 // provides given services to the remote application. Returns a pointer to | 107 // provides given services to the remote application. Returns a pointer to |
88 // outgoing connection that can be used to connect to services provided by | 108 // outgoing connection that can be used to connect to services provided by |
89 // remote application. | 109 // remote application. |
90 // Panics if called more than once. | 110 // Panics if called more than once. |
91 func (c *Connection) ProvideServices(services ...ServiceFactory) *OutgoingConnec
tion { | 111 func (c *Connection) ProvideServices(services ...ServiceFactory) *OutgoingConnec
tion { |
92 if c.servicesProvided { | 112 if c.servicesProvided { |
93 » » panic("ProvideServices can be called only once") | 113 » » panic("ProvideServices or ProvideServicesWithDescriber can be ca
lled only once") |
94 } | 114 } |
95 c.servicesProvided = true | 115 c.servicesProvided = true |
96 if c.servicesRequest == nil { | 116 if c.servicesRequest == nil { |
97 return c.outgoingConnection | 117 return c.outgoingConnection |
98 } | 118 } |
99 if len(services) == 0 { | 119 if len(services) == 0 { |
100 c.servicesRequest.PassMessagePipe().Close() | 120 c.servicesRequest.PassMessagePipe().Close() |
101 return c.outgoingConnection | 121 return c.outgoingConnection |
102 } | 122 } |
103 | 123 |
(...skipping 11 matching lines...) Expand all Loading... |
115 if !ok || !connectionError.Closed() { | 135 if !ok || !connectionError.Closed() { |
116 log.Println(err) | 136 log.Println(err) |
117 } | 137 } |
118 break | 138 break |
119 } | 139 } |
120 } | 140 } |
121 }() | 141 }() |
122 return c.outgoingConnection | 142 return c.outgoingConnection |
123 } | 143 } |
124 | 144 |
| 145 // ProvideServicesWithDescriber is an alternative to ProvideServices that, in |
| 146 // addition to providing the given services, also provides type descriptions of |
| 147 // the given services. See ProvideServices for a description of what it does. |
| 148 // This method will invoke ProvideServices after appending the ServiceDescriber |
| 149 // service to |services|. See service_describer.mojom for a description of the |
| 150 // ServiceDescriber interface. Client Mojo applications can choose to connect |
| 151 // to this ServiceDescriber interface, which describes the other services listed |
| 152 // in |services|. |
| 153 // Note that the implementation of ServiceDescriber will make the optional |
| 154 // DeclarationData available on all types, and in particular, the names used in |
| 155 // .mojom files will be exposed to client applications. |
| 156 func (c *Connection) ProvideServicesWithDescriber(services ...ServiceFactory) *O
utgoingConnection { |
| 157 if c.servicesProvided { |
| 158 panic("ProvideServices or ProvideServicesWithDescriber can be ca
lled only once") |
| 159 } |
| 160 mapping := make(map[string]service_describer.ServiceDescription) |
| 161 for _, service := range services { |
| 162 mapping[service.Name()] = service.ServiceDescription() |
| 163 } |
| 164 c.describer = newServiceDescriberFactory(mapping) |
| 165 servicesWithDescriber := append(services, &service_describer.ServiceDesc
riber_ServiceFactory{c.describer}) |
| 166 |
| 167 return c.ProvideServices(servicesWithDescriber...) |
| 168 } |
| 169 |
125 // Close closes both incoming and outgoing parts of the connection. | 170 // Close closes both incoming and outgoing parts of the connection. |
126 func (c *Connection) Close() { | 171 func (c *Connection) Close() { |
127 if c.servicesRequest != nil { | 172 if c.servicesRequest != nil { |
128 c.servicesRequest.Close() | 173 c.servicesRequest.Close() |
129 } | 174 } |
130 if c.localServices != nil { | 175 if c.localServices != nil { |
131 c.localServices.Close() | 176 c.localServices.Close() |
132 } | 177 } |
| 178 if c.describer != nil { |
| 179 c.describer.Close() |
| 180 } |
133 if c.outgoingConnection.remoteServices != nil { | 181 if c.outgoingConnection.remoteServices != nil { |
134 c.outgoingConnection.remoteServices.Close_Proxy() | 182 c.outgoingConnection.remoteServices.Close_Proxy() |
135 } | 183 } |
136 c.isClosed = true | 184 c.isClosed = true |
137 } | 185 } |
138 | 186 |
139 // OutgoingConnection represents outgoing part of connection to another | 187 // OutgoingConnection represents outgoing part of connection to another |
140 // application. In order to close it close the |Connection| object that returned | 188 // application. In order to close it close the |Connection| object that returned |
141 // this |OutgoingConnection|. | 189 // this |OutgoingConnection|. |
142 type OutgoingConnection struct { | 190 type OutgoingConnection struct { |
(...skipping 24 matching lines...) Expand all Loading... |
167 messagePipe.Close() | 215 messagePipe.Close() |
168 return nil | 216 return nil |
169 } | 217 } |
170 factory.Create(messagePipe) | 218 factory.Create(messagePipe) |
171 return nil | 219 return nil |
172 } | 220 } |
173 | 221 |
174 func (sp *serviceProviderImpl) AddService(factory ServiceFactory) { | 222 func (sp *serviceProviderImpl) AddService(factory ServiceFactory) { |
175 sp.factories[factory.Name()] = factory | 223 sp.factories[factory.Name()] = factory |
176 } | 224 } |
OLD | NEW |