Skip to content

Commit

Permalink
feat: add audio server switch support
Browse files Browse the repository at this point in the history
add audio server switch support

Issue: linuxdeepin/developer-center#5819
Log: add audio server switch support
  • Loading branch information
chenchongbiao committed Nov 2, 2023
1 parent 2714ff8 commit 06591f7
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 6 deletions.
110 changes: 104 additions & 6 deletions audio1/audio.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@ import (

dbus "github.com/godbus/dbus/v5"
"github.com/linuxdeepin/dde-daemon/common/dsync"
notifications "github.com/linuxdeepin/go-dbus-factory/session/org.freedesktop.notifications"
systemd1 "github.com/linuxdeepin/go-dbus-factory/system/org.freedesktop.systemd1"
gio "github.com/linuxdeepin/go-gir/gio-2.0"
"github.com/linuxdeepin/go-lib/dbusutil"
"github.com/linuxdeepin/go-lib/dbusutil/gsprop"
. "github.com/linuxdeepin/go-lib/gettext"
"github.com/linuxdeepin/go-lib/pulse"
"golang.org/x/xerrors"
)
Expand Down Expand Up @@ -52,6 +54,10 @@ const (
dsgKeyAutoSwitchPort = "autoSwitchPort"
dsgKeyBluezModeFilterList = "bluezModeFilterList"
dsgKeyPortFilterList = "portFilterList"

localeIconStart = "notification-change-language-start"
localeIconFailed = "notification-change-language-failed"
localeIconFinished = "notification-change-language-finished"
)

var (
Expand All @@ -61,6 +67,20 @@ var (
gMaxUIVolume float64
)

var (
// 切换音频的提示
notifyTxtStart = Tr("Changing system language, please wait...")
notifyTxtDone = Tr("Audio Server changed, please log out and then log in")
notifyTxtFailed = Tr("Failed to change Audio Server, please try later")
)

const (
// 音频服务更改状态:已经完成
AudioStateChanged = true
// 音频服务更改状态:正在修改中
AudioStateChanging = false
)

//go:generate dbusutil-gen -type Audio,Sink,SinkInput,Source,Meter -import github.com/godbus/dbus/v5 audio.go sink.go sinkinput.go source.go meter.go
//go:generate dbusutil-gen em -type Audio,Sink,SinkInput,Source,Meter

Expand Down Expand Up @@ -108,6 +128,8 @@ type Audio struct {
BluetoothAudioMode string // 蓝牙模式
// dbusutil-gen: equal=isStrvEqual
BluetoothAudioModeOpts []string // 可用的蓝牙模式
CurrentAudioServer string // 当前使用的音频服务
AudioServerState bool // 音频服务状态

// dbusutil-gen: ignore
IncreaseVolume gsprop.Bool `prop:"access:rw"`
Expand Down Expand Up @@ -184,10 +206,11 @@ type Audio struct {

func newAudio(service *dbusutil.Service) *Audio {
a := &Audio{
service: service,
meters: make(map[string]*Meter),
MaxUIVolume: pulse.VolumeUIMax,
enableSource: true,
service: service,
meters: make(map[string]*Meter),
MaxUIVolume: pulse.VolumeUIMax,
enableSource: true,
AudioServerState: AudioStateChanged,
}

a.settings = gio.NewSettings(gsSchemaAudio)
Expand All @@ -214,16 +237,91 @@ func newAudio(service *dbusutil.Service) *Audio {
return a
}

func startAudioServer(service *dbusutil.Service) error {
func (a *Audio) setAudioServerFailed(oldAudioServer string) {
sendNotify(localeIconFailed, "",
Tr("Failed to change system language, please try later"))
// 还原音频服务
a.PropsMu.Lock()
a.setPropCurrentAudioServer(oldAudioServer)
a.setPropAudioServerState(AudioStateChanged)
a.PropsMu.Unlock()
}

func (a *Audio) SetCurrentAudioServer(serverName string) (err *dbus.Error) {
a.PropsMu.Lock()
oldAudioServer := a.CurrentAudioServer
a.setPropAudioServerState(AudioStateChanging)
a.setPropCurrentAudioServer(serverName)
a.PropsMu.Unlock()

sendNotify(localeIconStart, "", notifyTxtStart)

var activeServers, deactiveServers []string
if serverName == "pulseaudio" {
activeServers = []string{"pulseaudio.service"}
deactiveServers = []string{"pipewire-pulse.service", "pipewire.service"}
} else {
activeServers = []string{"pipewire-pulse.service", "pipewire.service"}
deactiveServers = []string{"pulseaudio.service"}
}

systemd := systemd1.NewManager(a.service.Conn())
_, e := systemd.UnmaskUnitFiles(0, activeServers, false)
if e != nil {
logger.Warning("Failed to unmask unit files", activeServers, "\nError:", e)
a.setAudioServerFailed(oldAudioServer)
sendNotify(localeIconFinished, "", notifyTxtDone)
}

_, e = systemd.MaskUnitFiles(0, deactiveServers, false, true)
if e != nil {
logger.Warning("Failed to mask unit files", deactiveServers, "\nError:", e)
a.setAudioServerFailed(oldAudioServer)
sendNotify(localeIconFinished, "", notifyTxtDone)
}

e = systemd.Reload(0)
if e != nil {
logger.Warning("Failed to reload unit files. Error:", e)
}

sendNotify(localeIconFinished, "", notifyTxtDone)

a.PropsMu.Lock()
a.setPropAudioServerState(AudioStateChanged)
a.PropsMu.Unlock()
return nil
}

func sendNotify(icon, summary, body string) {
sessionBus, err := dbus.SessionBus()
if err != nil {
logger.Warning(err)
return
}
n := notifications.NewNotifications(sessionBus)
_, err = n.Notify(0, "dde-control-center", 0,
icon, summary, body,
nil, nil, -1)
logger.Debugf("send notification icon: %q, summary: %q, body: %q",
icon, summary, body)

if err != nil {
logger.Warning(err)
}
}

func (a *Audio) startAudioServer(service *dbusutil.Service) error {
var serverPath dbus.ObjectPath
audioServers := []string{"pipewire-pulse.service", "pulseaudio.service"}
audioServers := []string{"pulseaudio.service", "pipewire-pulse.service"}

systemd := systemd1.NewManager(service.Conn())

for _, server := range audioServers {
path, err := systemd.GetUnit(0, server)
if err == nil {
serverPath = path
a.CurrentAudioServer = strings.Split(server, ".")[0]
break
}
}
Expand Down
26 changes: 26 additions & 0 deletions audio1/audio_dbusutil.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions audio1/exported_methods_auto.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 06591f7

Please sign in to comment.