func (conn *Conn) Names() []string {
	return conn.names.listKnownNames()
}
Names returns the list of all names that are currently owned by this
connection. The slice is always at least one element long, the first element
being the unique name of the connection.
package dbus
import (
	"context"
	"errors"
	"io"
	"os"
	"strings"
	"sync"
)
var (
	systemBus     *Conn
	systemBusLck  sync.Mutex
	sessionBus    *Conn
	sessionBusLck sync.Mutex
)
var ErrClosed = errors.New("dbus: connection closed by user")
type Conn struct {
	transport
	ctx       context.Context
	cancelCtx context.CancelFunc
	closeOnce sync.Once
	closeErr  error
	busObj BusObject
	unixFD bool
	uuid   string
	handler       Handler
	signalHandler SignalHandler
	serialGen     SerialGenerator
	inInt         Interceptor
	outInt        Interceptor
	auth          []Auth
	names      *nameTracker
	calls      *callTracker
	outHandler *outputHandler
	eavesdropped    chan<- *Message
	eavesdroppedLck sync.Mutex
}
func SessionBus() (conn *Conn, err error) {
	sessionBusLck.Lock()
	defer sessionBusLck.Unlock()
	if sessionBus != nil &&
		sessionBus.Connected() {
		return sessionBus, nil
	}
	defer func() {
		if conn != nil {
			sessionBus = conn
		}
	}()
	conn, err = ConnectSessionBus()
	return
}
func getSessionBusAddress() (string, error) {
	if address := os.Getenv("DBUS_SESSION_BUS_ADDRESS"); address != "" && address != "autolaunch:" {
		return address, nil
	} else if address := tryDiscoverDbusSessionBusAddress(); address != "" {
		os.Setenv("DBUS_SESSION_BUS_ADDRESS", address)
		return address, nil
	}
	return getSessionBusPlatformAddress()
}
func SessionBusPrivate(opts ...ConnOption) (*Conn, error) {
	address, err := getSessionBusAddress()
	if err != nil {
		return nil, err
	}
	return Dial(address, opts...)
}
func SessionBusPrivateHandler(handler Handler, signalHandler SignalHandler) (*Conn, error) {
	return SessionBusPrivate(WithHandler(handler), WithSignalHandler(signalHandler))
}
func SystemBus() (conn *Conn, err error) {
	systemBusLck.Lock()
	defer systemBusLck.Unlock()
	if systemBus != nil &&
		systemBus.Connected() {
		return systemBus, nil
	}
	defer func() {
		if conn != nil {
			systemBus = conn
		}
	}()
	conn, err = ConnectSystemBus()
	return
}
func ConnectSessionBus(opts ...ConnOption) (*Conn, error) {
	address, err := getSessionBusAddress()
	if err != nil {
		return nil, err
	}
	return Connect(address, opts...)
}
func ConnectSystemBus(opts ...ConnOption) (*Conn, error) {
	return Connect(getSystemBusPlatformAddress(), opts...)
}
func Connect(address string, opts ...ConnOption) (*Conn, error) {
	conn, err := Dial(address, opts...)
	if err != nil {
		return nil, err
	}
	if err = conn.Auth(conn.auth); err != nil {
		_ = conn.Close()
		return nil, err
	}
	if err = conn.Hello(); err != nil {
		_ = conn.Close()
		return nil, err
	}
	return conn, nil
}
func SystemBusPrivate(opts ...ConnOption) (*Conn, error) {
	return Dial(getSystemBusPlatformAddress(), opts...)
}
func SystemBusPrivateHandler(handler Handler, signalHandler SignalHandler) (*Conn, error) {
	return SystemBusPrivate(WithHandler(handler), WithSignalHandler(signalHandler))
}
func Dial(address string, opts ...ConnOption) (*Conn, error) {
	tr, err := getTransport(address)
	if err != nil {
		return nil, err
	}
	return newConn(tr, opts...)
}
func DialHandler(address string, handler Handler, signalHandler SignalHandler) (*Conn, error) {
	return Dial(address, WithSignalHandler(signalHandler))
}
type ConnOption func(conn *Conn) error
func WithHandler(handler Handler) ConnOption {
	return func(conn *Conn) error {
		conn.handler = handler
		return nil
	}
}
func WithSignalHandler(handler SignalHandler) ConnOption {
	return func(conn *Conn) error {
		conn.signalHandler = handler
		return nil
	}
}
func WithSerialGenerator(gen SerialGenerator) ConnOption {
	return func(conn *Conn) error {
		conn.serialGen = gen
		return nil
	}
}
func WithAuth(methods ...Auth) ConnOption {
	return func(conn *Conn) error {
		conn.auth = methods
		return nil
	}
}
type Interceptor func(msg *Message)
func WithIncomingInterceptor(interceptor Interceptor) ConnOption {
	return func(conn *Conn) error {
		conn.inInt = interceptor
		return nil
	}
}
func WithOutgoingInterceptor(interceptor Interceptor) ConnOption {
	return func(conn *Conn) error {
		conn.outInt = interceptor
		return nil
	}
}
func WithContext(ctx context.Context) ConnOption {
	return func(conn *Conn) error {
		conn.ctx = ctx
		return nil
	}
}
func NewConn(conn io.ReadWriteCloser, opts ...ConnOption) (*Conn, error) {
	return newConn(genericTransport{conn}, opts...)
}
func NewConnHandler(conn io.ReadWriteCloser, handler Handler, signalHandler SignalHandler) (*Conn, error) {
	return NewConn(genericTransport{conn}, WithHandler(handler), WithSignalHandler(signalHandler))
}
func newConn(tr transport, opts ...ConnOption) (*Conn, error) {
	conn := new(Conn)
	conn.transport = tr
	for _, opt := range opts {
		if err := opt(conn); err != nil {
			return nil, err
		}
	}
	if conn.ctx == nil {
		conn.ctx = context.Background()
	}
	conn.ctx, conn.cancelCtx = context.WithCancel(conn.ctx)
	go func() {
		<-conn.ctx.Done()
		conn.Close()
	}()
	conn.calls = newCallTracker()
	if conn.handler == nil {
		conn.handler = NewDefaultHandler()
	}
	if conn.signalHandler == nil {
		conn.signalHandler = NewDefaultSignalHandler()
	}
	if conn.serialGen == nil {
		conn.serialGen = newSerialGenerator()
	}
	conn.outHandler = &outputHandler{conn: conn}
	conn.names = newNameTracker()
	conn.busObj = conn.Object("org.freedesktop.DBus", "/org/freedesktop/DBus")
	return conn, nil
}
func (conn *Conn) BusObject() BusObject {
	return conn.busObj
}
func (conn *Conn) Close() error {
	conn.closeOnce.Do(func() {
		conn.outHandler.close()
		if term, ok := conn.signalHandler.(Terminator); ok {
			term.Terminate()
		}
		if term, ok := conn.handler.(Terminator); ok {
			term.Terminate()
		}
		conn.eavesdroppedLck.Lock()
		if conn.eavesdropped != nil {
			close(conn.eavesdropped)
		}
		conn.eavesdroppedLck.Unlock()
		conn.cancelCtx()
		conn.closeErr = conn.transport.Close()
	})
	return conn.closeErr
}
func (conn *Conn) Context() context.Context {
	return conn.ctx
}
func (conn *Conn) Connected() bool {
	return conn.ctx.Err() == nil
}
func (conn *Conn) Eavesdrop(ch chan<- *Message) {
	conn.eavesdroppedLck.Lock()
	conn.eavesdropped = ch
	conn.eavesdroppedLck.Unlock()
}
func (conn *Conn) getSerial() uint32 {
	return conn.serialGen.GetSerial()
}
func (conn *Conn) Hello() error {
	var s string
	err := conn.busObj.Call("org.freedesktop.DBus.Hello", 0).Store(&s)
	if err != nil {
		return err
	}
	conn.names.acquireUniqueConnectionName(s)
	return nil
}
func (conn *Conn) inWorker() {
	sequenceGen := newSequenceGenerator()
	for {
		msg, err := conn.ReadMessage()
		if err != nil {
			if _, ok := err.(InvalidMessageError); !ok {
				conn.Close()
				conn.calls.finalizeAllWithError(sequenceGen, err)
				return
			}
			continue
		}
		conn.eavesdroppedLck.Lock()
		if conn.eavesdropped != nil {
			select {
			case conn.eavesdropped <- msg:
			default:
			}
			conn.eavesdroppedLck.Unlock()
			continue
		}
		conn.eavesdroppedLck.Unlock()
		dest, _ := msg.Headers[FieldDestination].value.(string)
		found := dest == "" ||
			!conn.names.uniqueNameIsKnown() ||
			conn.names.isKnownName(dest)
		if !found {
			continue
		}
		if conn.inInt != nil {
			conn.inInt(msg)
		}
		sequence := sequenceGen.next()
		switch msg.Type {
		case TypeError:
			conn.serialGen.RetireSerial(conn.calls.handleDBusError(sequence, msg))
		case TypeMethodReply:
			conn.serialGen.RetireSerial(conn.calls.handleReply(sequence, msg))
		case TypeSignal:
			conn.handleSignal(sequence, msg)
		case TypeMethodCall:
			go conn.handleCall(msg)
		}
	}
}
func (conn *Conn) handleSignal(sequence Sequence, msg *Message) {
	iface := msg.Headers[FieldInterface].value.(string)
	member := msg.Headers[FieldMember].value.(string)
	sender, _ := msg.Headers[FieldSender].value.(string)
	if iface == "org.freedesktop.DBus" && sender == "org.freedesktop.DBus" {
		if member == "NameLost" {
			name, ok := msg.Body[0].(string)
			if !ok {
				panic("Unable to read the lost name")
			}
			conn.names.loseName(name)
		} else if member == "NameAcquired" {
			name, ok := msg.Body[0].(string)
			if !ok {
				panic("Unable to read the acquired name")
			}
			conn.names.acquireName(name)
		}
	}
	signal := &Signal{
		Sender:   sender,
		Path:     msg.Headers[FieldPath].value.(ObjectPath),
		Name:     iface + "." + member,
		Body:     msg.Body,
		Sequence: sequence,
	}
	conn.signalHandler.DeliverSignal(iface, member, signal)
}