| // Copyright 2018 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| // Package services implements a convenient frontend to a directory that |
| // contains services. |
| package services |
| |
| import ( |
| "syscall/zx" |
| "syscall/zx/fdio" |
| "syscall/zx/fidl" |
| "syscall/zx/io" |
| ) |
| |
| // A Provider holds a zx.Channel that references a directory that contains services. |
| type Provider struct { |
| directory *io.DirectoryInterface |
| } |
| |
| // NewProvider returns a new Provider object. |
| func NewProvider() *Provider { |
| return &Provider{} |
| } |
| |
| // NewRequest creates a directory request and stores the other end of the channel |
| // in the Provider object. If another channel was already held in the Provider, |
| // it will be closed. |
| func (p *Provider) NewRequest() (zx.Channel, error) { |
| req, pxy, err := io.NewDirectoryInterfaceRequest() |
| if err != nil { |
| return zx.Channel(zx.HandleInvalid), err |
| } |
| if p.directory != nil && p.directory.Handle().IsValid() { |
| p.directory.Close() |
| } |
| p.directory = pxy |
| return (fidl.InterfaceRequest(req)).Channel, nil |
| } |
| |
| // Bind stores an io.DirectoryInterface in the Provider. If another channel was already held in |
| // the Provider, it will be closed. |
| func (p *Provider) Bind(dir *io.DirectoryInterface) { |
| if p.directory != nil && p.directory.Handle().IsValid() { |
| p.directory.Close() |
| } |
| p.directory = dir |
| } |
| |
| // Close closes the channel held in the Provider object. |
| func (p *Provider) Close() { |
| if p.directory != nil && p.directory.Handle().IsValid() { |
| p.directory.Close() |
| } |
| } |
| |
| // ConnectToServiceAt connects an InterfaceRequest to a service located at path in the |
| // directory referenced by the Provider. |
| func (p *Provider) ConnectToServiceAt(c zx.Channel, path string) error { |
| return fdio.ServiceConnectAt(*p.directory.Handle(), path, *c.Handle()) |
| } |
| |
| // ConnectToService connects an InterfaceRequest to a service in the directory referenced |
| // by the Provider using the interface name as the path. |
| func (p *Provider) ConnectToService(sr fidl.ServiceRequest) error { |
| return p.ConnectToServiceAt(sr.ToChannel(), sr.Name()) |
| } |