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 requested mojo service. | |
rudominer
2015/10/22 21:28:47
s/of the requested mojo service/of the service ass
alexfandrianto
2015/10/22 22:58:11
Done.
| |
40 ServiceDescription() service_describer.ServiceDescription | |
41 | |
37 // PassMessagePipe passes ownership of the underlying message pipe | 42 // PassMessagePipe passes ownership of the underlying message pipe |
38 // handle to the newly created handle object, invalidating the | 43 // handle to the newly created handle object, invalidating the |
39 // underlying handle object in the process. | 44 // underlying handle object in the process. |
40 PassMessagePipe() system.MessagePipeHandle | 45 PassMessagePipe() system.MessagePipeHandle |
41 } | 46 } |
42 | 47 |
43 // ServiceFactory provides implementation of a mojo service. | 48 // ServiceFactory provides implementation of a mojo service. |
44 type ServiceFactory interface { | 49 type ServiceFactory interface { |
45 // Name returns the name of provided mojo service. | 50 // Name returns the name of provided mojo service. |
46 Name() string | 51 Name() string |
47 | 52 |
53 // ServiceDescription returns a service description, which can be querie d to | |
54 // examine the type information of the mojo service. | |
rudominer
2015/10/22 21:28:47
"of the mojo service associated with this ServiceF
alexfandrianto
2015/10/22 22:58:11
Done.
| |
55 ServiceDescription() service_describer.ServiceDescription | |
56 | |
48 // Create binds an implementation of mojo service to the provided | 57 // Create binds an implementation of mojo service to the provided |
49 // message pipe and runs it. | 58 // message pipe and runs it. |
50 Create(pipe system.MessagePipeHandle) | 59 Create(pipe system.MessagePipeHandle) |
51 } | 60 } |
52 | 61 |
53 // Connection represents a connection to another application. An instance of | 62 // Connection represents a connection to another application. An instance of |
54 // this struct is passed to Delegate's AcceptConnection() function each time a | 63 // this struct is passed to Delegate's AcceptConnection() function each time a |
55 // connection is made to this application. | 64 // connection is made to this application. |
56 type Connection struct { | 65 type Connection struct { |
57 connectionInfo | 66 connectionInfo |
58 // Request for local services. Is valid until ProvideServices is called. | 67 // Request for local services. Is valid until ProvideServices is called. |
59 servicesRequest *sp.ServiceProvider_Request | 68 servicesRequest *sp.ServiceProvider_Request |
60 // Indicates that ProvideServices function was already called. | 69 // Indicates that ProvideServices function was already called. |
61 servicesProvided bool | 70 servicesProvided bool |
62 localServices *bindings.Stub | 71 localServices *bindings.Stub |
63 outgoingConnection *OutgoingConnection | 72 outgoingConnection *OutgoingConnection |
64 isClosed bool | 73 isClosed bool |
74 describer *ServiceDescriberFactory | |
rudominer
2015/10/22 21:28:47
Please add a comment about what happens when the g
alexfandrianto
2015/10/22 22:58:11
The ServiceDescriber is functional, but the Servic
| |
65 } | 75 } |
66 | 76 |
67 func newConnection(requestorURL string, services *sp.ServiceProvider_Request, ex posedServices *sp.ServiceProvider_Pointer, resolvedURL string) *Connection { | 77 func newConnection(requestorURL string, services *sp.ServiceProvider_Request, ex posedServices *sp.ServiceProvider_Pointer, resolvedURL string) *Connection { |
68 info := connectionInfo{ | 78 info := connectionInfo{ |
69 requestorURL, | 79 requestorURL, |
70 resolvedURL, | 80 resolvedURL, |
71 } | 81 } |
72 var remoteServices *sp.ServiceProvider_Proxy | 82 var remoteServices *sp.ServiceProvider_Proxy |
73 if exposedServices != nil { | 83 if exposedServices != nil { |
74 remoteServices = sp.NewServiceProviderProxy(*exposedServices, bi ndings.GetAsyncWaiter()) | 84 remoteServices = sp.NewServiceProviderProxy(*exposedServices, bi ndings.GetAsyncWaiter()) |
75 } | 85 } |
76 return &Connection{ | 86 return &Connection{ |
77 connectionInfo: info, | 87 connectionInfo: info, |
78 servicesRequest: services, | 88 servicesRequest: services, |
79 outgoingConnection: &OutgoingConnection{ | 89 outgoingConnection: &OutgoingConnection{ |
80 info, | 90 info, |
81 remoteServices, | 91 remoteServices, |
82 }, | 92 }, |
83 } | 93 } |
84 } | 94 } |
85 | 95 |
86 // ProvideServices starts a service provider on a separate goroutine that | 96 // ProvideServices starts a service provider on a separate goroutine that |
87 // provides given services to the remote application. Returns a pointer to | 97 // provides given services to the remote application. Returns a pointer to |
88 // outgoing connection that can be used to connect to services provided by | 98 // outgoing connection that can be used to connect to services provided by |
89 // remote application. | 99 // remote application. |
90 // Panics if called more than once. | 100 // Panics if called more than once. |
91 func (c *Connection) ProvideServices(services ...ServiceFactory) *OutgoingConnec tion { | 101 func (c *Connection) ProvideServices(services ...ServiceFactory) *OutgoingConnec tion { |
92 if c.servicesProvided { | 102 if c.servicesProvided { |
93 » » panic("ProvideServices can be called only once") | 103 » » panic("ProvideServices or ProvideServicesWithDescriber can be ca lled only once") |
94 } | 104 } |
95 c.servicesProvided = true | 105 c.servicesProvided = true |
96 if c.servicesRequest == nil { | 106 if c.servicesRequest == nil { |
97 return c.outgoingConnection | 107 return c.outgoingConnection |
98 } | 108 } |
99 if len(services) == 0 { | 109 if len(services) == 0 { |
100 c.servicesRequest.PassMessagePipe().Close() | 110 c.servicesRequest.PassMessagePipe().Close() |
101 return c.outgoingConnection | 111 return c.outgoingConnection |
102 } | 112 } |
103 | 113 |
(...skipping 11 matching lines...) Expand all Loading... | |
115 if !ok || !connectionError.Closed() { | 125 if !ok || !connectionError.Closed() { |
116 log.Println(err) | 126 log.Println(err) |
117 } | 127 } |
118 break | 128 break |
119 } | 129 } |
120 } | 130 } |
121 }() | 131 }() |
122 return c.outgoingConnection | 132 return c.outgoingConnection |
123 } | 133 } |
124 | 134 |
135 // ProvideServicesWithDescriber is an alternative to ProvideServices that, in | |
136 // addition to providing the given services, also provides type descriptions of | |
137 // the given services. See ProvideServices for a description of what it does. | |
138 // This method will invoke ProvideServices after appending the ServiceDescriber | |
139 // service to |services|. See service_describer.mojom for a description of the | |
140 // ServiceDescriber interface. Client Mojo applications can choose to connect | |
141 // to this ServiceDescriber interface, which describes the other services listed | |
142 // in |services|. | |
143 // Note that the implementation of ServiceDescriber will make the optional | |
144 // DeclarationData available on all types, and in particular, the names used in | |
145 // .mojom files will be exposed to client applications. | |
146 func (c *Connection) ProvideServicesWithDescriber(services ...ServiceFactory) *O utgoingConnection { | |
147 if c.servicesProvided { | |
148 panic("ProvideServices or ProvideServicesWithDescriber can be ca lled only once") | |
149 } | |
150 mapping := make(map[string]service_describer.ServiceDescription) | |
151 for _, service := range services { | |
152 mapping[service.Name()] = service.ServiceDescription() | |
153 } | |
154 c.describer = newServiceDescriberFactory(mapping) | |
155 servicesWithDescriber := append(services, &service_describer.ServiceDesc riber_ServiceFactory{c.describer}) | |
156 | |
157 return c.ProvideServices(servicesWithDescriber...) | |
158 } | |
159 | |
125 // Close closes both incoming and outgoing parts of the connection. | 160 // Close closes both incoming and outgoing parts of the connection. |
126 func (c *Connection) Close() { | 161 func (c *Connection) Close() { |
127 if c.servicesRequest != nil { | 162 if c.servicesRequest != nil { |
128 c.servicesRequest.Close() | 163 c.servicesRequest.Close() |
129 } | 164 } |
130 if c.localServices != nil { | 165 if c.localServices != nil { |
131 c.localServices.Close() | 166 c.localServices.Close() |
132 } | 167 } |
168 if c.describer != nil { | |
169 c.describer.Close() | |
170 } | |
133 if c.outgoingConnection.remoteServices != nil { | 171 if c.outgoingConnection.remoteServices != nil { |
134 c.outgoingConnection.remoteServices.Close_Proxy() | 172 c.outgoingConnection.remoteServices.Close_Proxy() |
135 } | 173 } |
136 c.isClosed = true | 174 c.isClosed = true |
137 } | 175 } |
138 | 176 |
139 // OutgoingConnection represents outgoing part of connection to another | 177 // OutgoingConnection represents outgoing part of connection to another |
140 // application. In order to close it close the |Connection| object that returned | 178 // application. In order to close it close the |Connection| object that returned |
141 // this |OutgoingConnection|. | 179 // this |OutgoingConnection|. |
142 type OutgoingConnection struct { | 180 type OutgoingConnection struct { |
(...skipping 24 matching lines...) Expand all Loading... | |
167 messagePipe.Close() | 205 messagePipe.Close() |
168 return nil | 206 return nil |
169 } | 207 } |
170 factory.Create(messagePipe) | 208 factory.Create(messagePipe) |
171 return nil | 209 return nil |
172 } | 210 } |
173 | 211 |
174 func (sp *serviceProviderImpl) AddService(factory ServiceFactory) { | 212 func (sp *serviceProviderImpl) AddService(factory ServiceFactory) { |
175 sp.factories[factory.Name()] = factory | 213 sp.factories[factory.Name()] = factory |
176 } | 214 } |
OLD | NEW |