-
Notifications
You must be signed in to change notification settings - Fork 106
fix: 解决音频端口初始化时为null-sink的问题 #988
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
初始化时会加载null-sink, 概率性触发底层事件,将默认输入输出设置为null-sink. 当输入输出设置为null-sink时,再检查一次端口是否有可用端口,如果有则切换 Log: PMS: BUG-340327 Influence: audio
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: fly602 The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
Reviewer's GuideThis PR changes when and how the PulseAudio null-sink module is loaded and adds null-sink–specific fallback logic for default input/output selection to avoid ending up with null-sink as the active device when real ports are available. Sequence diagram for audio initialization and null-sink module loadingsequenceDiagram
actor System
participant Audio
participant PulseContext
System->>Audio: init()
Audio->>Audio: connect()
Audio-->>System: error?
System->>Audio: (on success) continue init
Audio->>Audio: LoadNullSinkModule()
Audio->>Audio: isModuleExist(nullSinkModuleName)
alt module not loaded
Audio->>PulseContext: LoadModule(nullSinkModuleName, "")
else module already loaded
Audio-->>Audio: skip loading
end
Audio->>Audio: refresh()
Audio-->>System: init complete
Sequence diagram for default sink update with null-sink fallback and auto-switchsequenceDiagram
actor System
participant Audio
participant PulseContext
System->>Audio: updateDefaultSink(sinkName)
Audio->>Audio: getPhySinkInfoByName(sinkName)
alt sinkInfo is nil
Audio->>Audio: setPropDefaultSink("/")
Audio->>Audio: defaultSink = nil
alt sinkName contains null-sink
Audio->>Audio: autoSwitchOutputPort()
Audio->>Audio: checkAutoSwitchOutputPort()
alt auto and real port available
Audio->>Audio: setPort(cardId, portName, DirectionSink, true)
else auto and no real port
Audio->>PulseContext: GetDefaultSink()
alt default sink not null-sink
Audio->>Audio: LoadNullSinkModule()
Audio->>PulseContext: SetDefaultSink(nullSinkName)
else default sink already null-sink
Audio-->>Audio: keep current default
end
end
else sinkName does not contain null-sink
Audio-->>System: log warning failed to get sinkInfo
end
else sinkInfo found
Audio->>Audio: moveSinkInputsToSink(sinkInfo)
Audio->>PulseContext: SetDefaultSink(sinkName)
Audio->>Audio: defaultSink = sinkInfo
end
System-->>Audio: updateDefaultSink complete
Class diagram for Audio null-sink handling changesclassDiagram
class Audio {
+init() error
+refreshSinks()
+updateDefaultSink(sinkName string)
+updateDefaultSource(sourceName string)
+autoSwitchOutputPort() bool
+autoSwitchInputPort() bool
+LoadNullSinkModule()
+isModuleExist(moduleName string) bool
}
class PulseContext {
+LoadModule(name string, args string)
+GetDefaultSink() string
+GetDefaultSource() string
+SetDefaultSink(name string)
+SetDefaultSource(name string)
}
Audio --> PulseContext : uses
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey - I've found 2 issues, and left some high level feedback:
- The checks for
strings.Contains(..., "null-sink")introduce magic strings and partial matches; consider using the existingnullSinkNameconstant (and, where needed, appending.monitor) or a small helper likeisNullSink(name string)to keep the logic consistent and less error-prone. - The new
updateDefaultSink/updateDefaultSourcebranches that auto-switch when encounteringnull-sinkskip the previous warning log; it may be useful to log an explicit info/debug message whenautoSwitch*Portis triggered to aid in diagnosing unexpected default device changes.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The checks for `strings.Contains(..., "null-sink")` introduce magic strings and partial matches; consider using the existing `nullSinkName` constant (and, where needed, appending `.monitor`) or a small helper like `isNullSink(name string)` to keep the logic consistent and less error-prone.
- The new `updateDefaultSink`/`updateDefaultSource` branches that auto-switch when encountering `null-sink` skip the previous warning log; it may be useful to log an explicit info/debug message when `autoSwitch*Port` is triggered to aid in diagnosing unexpected default device changes.
## Individual Comments
### Comment 1
<location> `audio1/audio_events.go:209-210` </location>
<code_context>
auto, cardId, portName := a.checkAutoSwitchOutputPort()
if auto {
if cardId == 0 || portName == "" {
- if !a.isModuleExist(nullSinkModuleName) {
- a.ctx.LoadModule(nullSinkModuleName, "")
+ if !strings.Contains(a.ctx.GetDefaultSink(), "null-sink") {
+ a.LoadNullSinkModule()
+ logger.Info("no prefer port, set defaut sink to", nullSinkName)
</code_context>
<issue_to_address>
**suggestion:** Avoid hard-coding "null-sink" and reuse the existing constant instead.
In both this check and the input case below, use the `nullSinkName` constant instead of the literal "null-sink" to avoid hidden coupling. That way, future changes to the sink name won’t silently break these `Contains` checks.
Suggested implementation:
```golang
if cardId == 0 || portName == "" {
if !strings.Contains(a.ctx.GetDefaultSink(), nullSinkName) {
a.LoadNullSinkModule()
logger.Info("no prefer port, set defaut sink to", nullSinkName)
a.ctx.SetDefaultSink(nullSinkName)
} else {
logger.Info("no prefer port, default sink is", nullSinkName)
}
return true
} else {
err := a.setPort(cardId, portName, pulse.DirectionSink, true)
```
There is likely a similar `"null-sink"` literal in the "input case below" you mentioned (perhaps checking the default source or input module). That occurrence should be updated in the same way: replace the hard-coded `"null-sink"` with `nullSinkName` in both any `Contains` checks and log messages to keep the coupling explicit and centralized on the constant.
</issue_to_address>
### Comment 2
<location> `audio1/audio_events.go:212` </location>
<code_context>
- a.ctx.LoadModule(nullSinkModuleName, "")
+ if !strings.Contains(a.ctx.GetDefaultSink(), "null-sink") {
+ a.LoadNullSinkModule()
+ logger.Info("no prefer port, set defaut sink to", nullSinkName)
+ a.ctx.SetDefaultSink(nullSinkName)
+ } else {
</code_context>
<issue_to_address>
**nitpick (typo):** Minor typo in log message: "defaut" should be "default".
The same misspelling (`"defaut"`) exists in the source-side log message; please correct both so log searches remain consistent and reliable.
Suggested implementation:
```golang
a.LoadNullSinkModule()
logger.Info("no prefer port, set default sink to", nullSinkName)
a.ctx.SetDefaultSink(nullSinkName)
```
There is another log message on the "source" side with the same typo `"defaut"`. In `audio1/audio_events.go`, search for the string `set defaut source` (or any log line containing `"defaut"` related to the source/default source) and update it to `"set default source"` (or similarly correct wording) to keep logging consistent for sink and source.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| a.ctx.LoadModule(nullSinkModuleName, "") | ||
| if !strings.Contains(a.ctx.GetDefaultSink(), "null-sink") { | ||
| a.LoadNullSinkModule() | ||
| logger.Info("no prefer port, set defaut sink to", nullSinkName) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nitpick (typo): Minor typo in log message: "defaut" should be "default".
The same misspelling ("defaut") exists in the source-side log message; please correct both so log searches remain consistent and reliable.
Suggested implementation:
a.LoadNullSinkModule()
logger.Info("no prefer port, set default sink to", nullSinkName)
a.ctx.SetDefaultSink(nullSinkName)There is another log message on the "source" side with the same typo "defaut". In audio1/audio_events.go, search for the string set defaut source (or any log line containing "defaut" related to the source/default source) and update it to "set default source" (or similarly correct wording) to keep logging consistent for sink and source.
初始化时会加载null-sink, 概率性触发底层事件,将默认输入输出设置为null-sink.
当输入输出设置为null-sink时,再检查一次端口是否有可用端口,如果有则切换
Log:
PMS: BUG-340327
Influence: audio
Summary by Sourcery
Ensure null-sink audio module is safely initialized and avoid keeping default input/output on null-sink by auto-switching to available ports.
Bug Fixes:
Enhancements: