Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(220)

Side by Side Diff: mojo/public/go/application/connection.go

Issue 2250183003: Make the fuchsia mojo/public repo the source of truth. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « mojo/public/go/application/application_impl.go ('k') | mojo/public/go/application/describer.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 package application
6
7 import (
8 "log"
9
10 "mojo/public/go/bindings"
11 "mojo/public/go/system"
12
13 sp "mojo/public/interfaces/application/service_provider"
14 "mojo/public/interfaces/bindings/service_describer"
15 )
16
17 type connectionInfo struct {
18 requestorURL string
19 connectionURL string
20 }
21
22 // RequestorURL returns the URL of application that established the connection.
23 func (c *connectionInfo) RequestorURL() string {
24 return c.requestorURL
25 }
26
27 // ConnectionURL returns the URL that was used by the source application to
28 // establish a connection to the destination application.
29 func (c *connectionInfo) ConnectionURL() string {
30 return c.connectionURL
31 }
32
33 // ServiceRequest is an interface request for a specified mojo service.
34 type ServiceRequest interface {
35 // Name returns the name of requested mojo service.
36 Name() string
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
45 // PassMessagePipe passes ownership of the underlying message pipe
46 // handle to the newly created handle object, invalidating the
47 // underlying handle object in the process.
48 PassMessagePipe() system.MessagePipeHandle
49 }
50
51 // ServiceFactory provides implementation of a mojo service.
52 type ServiceFactory interface {
53 // Name returns the name of provided mojo service.
54 Name() string
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
63 // Create binds an implementation of mojo service to the provided
64 // message pipe and runs it.
65 Create(pipe system.MessagePipeHandle)
66 }
67
68 // Connection represents a connection to another application. An instance of
69 // this struct is passed to Delegate's AcceptConnection() function each time a
70 // connection is made to this application.
71 // TODO(vtl): This is largely overkill now that we no longer have "wrong way"
72 // service providers (a.k.a. "exposed services"). Things should be simplified.
73 // https://github.com/domokit/mojo/issues/762
74 type Connection struct {
75 connectionInfo
76 // Request for local services. Is valid until ProvideServices is called.
77 servicesRequest *sp.ServiceProvider_Request
78 // Indicates that ProvideServices function was already called.
79 servicesProvided bool
80 localServices *bindings.Stub
81 outgoingConnection *OutgoingConnection
82 isClosed bool
83 // Is set if ProvideServicesWithDescriber was called.
84 // Note: When DescribeServices is invoked, some implementations may retu rn
85 // incomplete ServiceDescriptions. For example, if type information was not
86 // generated, then the methods called may return nil or an error.
87 describer *ServiceDescriberFactory
88 }
89
90 func newConnection(requestorURL string, services sp.ServiceProvider_Request, res olvedURL string) *Connection {
91 info := connectionInfo{
92 requestorURL,
93 resolvedURL,
94 }
95 return &Connection{
96 connectionInfo: info,
97 servicesRequest: &services,
98 outgoingConnection: &OutgoingConnection{
99 info,
100 nil,
101 },
102 }
103 }
104
105 // ProvideServices starts a service provider on a separate goroutine that
106 // provides given services to the remote application. Returns a pointer to
107 // outgoing connection that can be used to connect to services provided by
108 // remote application.
109 // Panics if called more than once.
110 func (c *Connection) ProvideServices(services ...ServiceFactory) *OutgoingConnec tion {
111 if c.servicesProvided {
112 panic("ProvideServices or ProvideServicesWithDescriber can be ca lled only once")
113 }
114 c.servicesProvided = true
115 if c.servicesRequest == nil {
116 return c.outgoingConnection
117 }
118 if len(services) == 0 {
119 c.servicesRequest.PassMessagePipe().Close()
120 return c.outgoingConnection
121 }
122
123 provider := &serviceProviderImpl{
124 make(map[string]ServiceFactory),
125 }
126 for _, service := range services {
127 provider.AddService(service)
128 }
129 c.localServices = sp.NewServiceProviderStub(*c.servicesRequest, provider , bindings.GetAsyncWaiter())
130 go func() {
131 for {
132 if err := c.localServices.ServeRequest(); err != nil {
133 connectionError, ok := err.(*bindings.Connection Error)
134 if !ok || !connectionError.Closed() {
135 log.Println(err)
136 }
137 break
138 }
139 }
140 }()
141 return c.outgoingConnection
142 }
143
144 // ProvideServicesWithDescriber is an alternative to ProvideServices that, in
145 // addition to providing the given services, also provides type descriptions of
146 // the given services. See ProvideServices for a description of what it does.
147 // This method will invoke ProvideServices after appending the ServiceDescriber
148 // service to |services|. See service_describer.mojom for a description of the
149 // ServiceDescriber interface. Client Mojo applications can choose to connect
150 // to this ServiceDescriber interface, which describes the other services listed
151 // in |services|.
152 // Note that the implementation of ServiceDescriber will make the optional
153 // DeclarationData available on all types, and in particular, the names used in
154 // .mojom files will be exposed to client applications.
155 func (c *Connection) ProvideServicesWithDescriber(services ...ServiceFactory) *O utgoingConnection {
156 if c.servicesProvided {
157 panic("ProvideServices or ProvideServicesWithDescriber can be ca lled only once")
158 }
159 mapping := make(map[string]service_describer.ServiceDescription)
160 for _, service := range services {
161 mapping[service.Name()] = service.ServiceDescription()
162 }
163 c.describer = newServiceDescriberFactory(mapping)
164 servicesWithDescriber := append(services, &service_describer.ServiceDesc riber_ServiceFactory{c.describer})
165
166 return c.ProvideServices(servicesWithDescriber...)
167 }
168
169 // Close closes both incoming and outgoing parts of the connection.
170 func (c *Connection) Close() {
171 if c.servicesRequest != nil {
172 c.servicesRequest.Close()
173 }
174 if c.localServices != nil {
175 c.localServices.Close()
176 }
177 if c.describer != nil {
178 c.describer.Close()
179 }
180 if c.outgoingConnection.remoteServices != nil {
181 c.outgoingConnection.remoteServices.Close_Proxy()
182 }
183 c.isClosed = true
184 }
185
186 // OutgoingConnection represents outgoing part of connection to another
187 // application. In order to close it close the |Connection| object that returned
188 // this |OutgoingConnection|.
189 type OutgoingConnection struct {
190 connectionInfo
191 remoteServices *sp.ServiceProvider_Proxy
192 }
193
194 // ConnectToService asks remote application to provide a service through the
195 // message pipe endpoint supplied by the caller.
196 func (c *OutgoingConnection) ConnectToService(request ServiceRequest) {
197 pipe := request.PassMessagePipe()
198 if c.remoteServices == nil {
199 pipe.Close()
200 return
201 }
202 c.remoteServices.ConnectToService(request.Name(), pipe)
203 }
204
205 // serviceProviderImpl is an implementation of mojo ServiceProvider interface.
206 type serviceProviderImpl struct {
207 factories map[string]ServiceFactory
208 }
209
210 // Mojo ServiceProvider implementation.
211 func (sp *serviceProviderImpl) ConnectToService(name string, messagePipe system. MessagePipeHandle) error {
212 factory, ok := sp.factories[name]
213 if !ok {
214 messagePipe.Close()
215 return nil
216 }
217 factory.Create(messagePipe)
218 return nil
219 }
220
221 func (sp *serviceProviderImpl) AddService(factory ServiceFactory) {
222 sp.factories[factory.Name()] = factory
223 }
OLDNEW
« no previous file with comments | « mojo/public/go/application/application_impl.go ('k') | mojo/public/go/application/describer.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698