Skip to content

Conversation

@fly602
Copy link
Contributor

@fly602 fly602 commented Jan 13, 2026

处理一些特殊场景,当声卡的端口可用性发生变化时,没有自动切换端口,因为此时sink/source还没有更新,导致切换失败. 当sink/source收到事件时,也只是change的事件,不会触发端口切换逻辑,导致端口一直没有变化. 一些warning日志不太重要,应该为debug或者info级别的调试辅助信息.

Log: 解决接入优先耳机,输入和输出为null的问题
PMS: BUG-346985
Influence: audio

Summary by Sourcery

Improve automatic audio port switching behavior when wired devices change availability to avoid null input/output, and adjust log levels for routine operations.

Bug Fixes:

  • Ensure audio ports auto-switch correctly when sink/source port availability changes, preventing input/output from remaining null in wired headset scenarios.

Enhancements:

  • Trigger output/input port auto-switching on sink/source change events only after the corresponding card is ready, and refine handling of card change events for physical devices.
  • Downgrade non-critical warning logs in audio switching and service stop flows to debug/info to reduce log noise.

处理一些特殊场景,当声卡的端口可用性发生变化时,没有自动切换端口,因为此时sink/source还没有更新,导致切换失败.
当sink/source收到事件时,也只是change的事件,不会触发端口切换逻辑,导致端口一直没有变化.
一些warning日志不太重要,应该为debug或者info级别的调试辅助信息.

Log: 解决接入优先耳机,输入和输出为null的问题
PMS: BUG-346985
Influence: audio
@sourcery-ai
Copy link

sourcery-ai bot commented Jan 13, 2026

Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Adjusts audio port auto-switching logic to correctly react when physical sink/source port availability changes, especially for preferred wired headsets, and downgrades several noisy warning logs to debug/info levels.

Sequence diagram for updated sink change auto-switch behavior

sequenceDiagram
    participant PulseServer
    participant Audio
    participant Sink

    PulseServer->>Audio: handleSinkChanged(idx)
    Audio->>PulseServer: GetSinkInfo(idx)
    PulseServer-->>Audio: sink
    Audio->>Sink: update(sink)
    Audio->>Audio: isPhysicalDevice(sink.Name)?
    alt sink is physical device
        Audio->>Audio: checkCardIsReady(sink.Card)
        alt card is ready
            Audio->>Audio: autoSwitchPort()
            Audio->>Audio: autoSwitchOutputPort()
            Audio->>Audio: autoSwitchInputPort()
        else card not ready
            Audio-->>PulseServer: return (no auto switch)
        end
    else sink is virtual device
        Audio-->>PulseServer: return (no auto switch)
    end
Loading

Sequence diagram for updated source events auto-switch behavior

sequenceDiagram
    participant PulseServer
    participant Audio
    participant Source

    rect rgb(230,230,230)
        PulseServer->>Audio: handleSourceAdded(idx)
        Audio->>PulseServer: GetSourceInfo(idx)
        PulseServer-->>Audio: source
        Audio->>Audio: isPhysicalDevice(source.Name)?
        alt source is physical device
            Audio->>Audio: checkCardIsReady(source.Card)
            alt card is ready
                Audio->>Audio: autoSwitchInputPort()
            else card not ready
                Audio-->>PulseServer: return (no auto switch)
            end
        else source is virtual device
            Audio-->>PulseServer: return (no auto switch)
        end
    end

    rect rgb(230,230,230)
        PulseServer->>Audio: handleSourceChanged(idx)
        Audio->>PulseServer: GetSourceInfo(idx)
        PulseServer-->>Audio: source
        Audio->>Source: update(source)
        Audio->>Audio: isPhysicalDevice(source.Name)?
        alt source is physical device
            Audio->>Audio: checkCardIsReady(source.Card)
            alt card is ready
                Audio->>Audio: autoSwitchInputPort()
            else card not ready
                Audio-->>PulseServer: return (no auto switch)
            end
        else source is virtual device
            Audio-->>PulseServer: return (no auto switch)
        end
    end

    rect rgb(230,230,230)
        PulseServer->>Audio: handleSourceRemoved(idx)
        Audio->>Audio: isPhysicalDevice(removedSource.Name)?
        alt removed source is physical device
            Audio->>Audio: checkCardIsReady(cardId)
            alt card is ready
                Audio->>Audio: autoSwitchInputPort()
            else card not ready
                Audio-->>PulseServer: return (no auto switch)
            end
        else removed source is virtual device
            Audio-->>PulseServer: return (no auto switch)
        end
    end
Loading

File-Level Changes

Change Details Files
Ensure auto-switch logic runs when card, sink, or source port availability changes so preferred physical ports are selected correctly.
  • Trigger autoSwitchPort() when handling physical sink changes after sink data is updated and the card is ready.
  • Trigger autoSwitchInputPort() when handling physical source changes after source data is updated and the card is ready.
  • On card change events, delegate to handleCardChanged(idx) and rely on its return value to decide whether to auto-switch ports, with added comments explaining scenarios where port availability changes without sink/source events.
  • For physical sources on add/remove events, only auto-switch the input side via autoSwitchInputPort() instead of switching both input and output ports.
audio1/audio_events.go
Downgrade overly noisy warning logs related to automatic port switching, mute setting, and service stopping to debug/info levels.
  • Change the generic "auto switch port" log from warning to debug level.
  • Change the sink mute-setting log from warningf to debugf in resumeSinkConfig.
  • Change the service stopped log from warningf to infof in StopAudioService.
audio1/audio_events.go
audio1/audio.go

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@deepin-ci-robot
Copy link

deepin pr auto review

这份代码修改主要涉及音频服务的日志级别调整和音频端口自动切换逻辑的优化。以下是对代码的详细审查意见:

1. 语法逻辑

优点:

  • 代码语法正确,符合 Go 语言规范
  • 逻辑流程清晰,条件判断合理

建议:

  • audio_events.gohandleSinkChangedhandleSourceChanged 函数中,新增的自动切换逻辑与 handleCardChanged 存在一定的逻辑重叠。建议考虑统一事件处理流程,避免多处触发自动切换逻辑,造成不必要的重复处理。

2. 代码质量

优点:

  • 日志级别调整合理:将一些常规操作的日志从 Warning 降级为 DebugInfo,减少了日志噪音
  • 注释清晰:新增的注释很好地解释了为什么需要在这些地方触发端口切换

建议:

  • handleSinkChangedhandleSourceChanged 中新增的自动切换逻辑缺少错误处理。如果 autoSwitchPort()autoSwitchInputPort() 内部发生错误,应该有相应的日志记录或错误处理机制。
  • 建议将 isPhysicalDevicecheckCardIsReady 的判断封装为一个单独的函数,例如 shouldAutoSwitchPort(device),以提高代码复用性和可读性。

3. 代码性能

优点:

  • 修改没有引入明显的性能问题

建议:

  • handleSinkChangedhandleSourceChanged 中新增的自动切换逻辑可能会在设备状态频繁变化时导致频繁的端口切换。建议考虑添加防抖(debounce)机制,避免短时间内多次触发切换操作。
  • isPhysicalDevice 函数可能会被频繁调用,建议检查其内部实现是否高效,必要时可以考虑缓存结果。

4. 代码安全

优点:

  • 没有发现明显的安全隐患

建议:

  • audio.goresumeSinkConfig 函数中,setMute 操作直接使用了配置值,建议增加对配置值的合法性校验,防止异常配置导致系统行为异常。
  • 在处理设备切换时,建议增加状态检查,确保设备确实处于可切换状态,避免在设备不稳定时进行切换操作。

5. 具体修改建议

对于 handleSinkChangedhandleSourceChanged 的修改,建议优化如下:

func (a *Audio) handleSinkChanged(idx uint32) {
    sink, err := a.getSink(idx)
    if err != nil {
        logger.Warningf("failed to get sink %d: %v", idx, err)
        return
    }
    
    if _, ok := a.sinks[idx]; ok {
        a.sinks[idx].update(sink)
    }
    
    // 处理场景:当sink的端口可用性发生变化时,切换端口
    // cardchange事件也会触发,但是处理不了,因为这时sink可能还没更新,无可用端口
    if a.shouldAutoSwitchPort(sink) {
        a.autoSwitchPort()
    }
}

// 新增辅助函数
func (a *Audio) shouldAutoSwitchPort(device interface{}) bool {
    var name string
    var cardId uint32
    
    switch d := device.(type) {
    case *Sink:
        name = d.Name
        cardId = d.Card
    case *Source:
        name = d.Name
        cardId = d.Card
    default:
        return false
    }
    
    return isPhysicalDevice(name) && a.checkCardIsReady(cardId)
}

类似地,可以优化 handleSourceChanged 函数。

总结

整体来看,这次代码修改主要是为了优化音频端口自动切换的逻辑,使其更加健壮。主要改进点包括:

  1. 调整了日志级别,使其更加合理
  2. 在设备状态变化时增加了端口切换逻辑,提高了系统的响应性
  3. 通过注释清晰地解释了修改的原因

建议在后续版本中考虑上述提到的优化点,特别是错误处理和防抖机制,以提高代码的健壮性和用户体验。

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've left some high level feedback:

  • In handleSinkChanged and handleSourceChanged, you now use the sink/source variables (for isPhysicalDevice(...) and checkCardIsReady(...)) even when the GetSink/GetSource lookup may have failed; consider returning early when ok is false to avoid relying on zero-valued structs and make the intent clearer.
  • In handleSinkChanged, calling autoSwitchPort() will also trigger input-port switching; if the intent is to react only to output device changes here, consider using autoSwitchOutputPort() for symmetry with the source-handling code which calls only autoSwitchInputPort().
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `handleSinkChanged` and `handleSourceChanged`, you now use the `sink`/`source` variables (for `isPhysicalDevice(...)` and `checkCardIsReady(...)`) even when the `GetSink`/`GetSource` lookup may have failed; consider returning early when `ok` is false to avoid relying on zero-valued structs and make the intent clearer.
- In `handleSinkChanged`, calling `autoSwitchPort()` will also trigger input-port switching; if the intent is to react only to output device changes here, consider using `autoSwitchOutputPort()` for symmetry with the source-handling code which calls only `autoSwitchInputPort()`.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@deepin-ci-robot
Copy link

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: fly602, mhduiy

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@fly602 fly602 merged commit 8492735 into linuxdeepin:master Jan 13, 2026
15 of 17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants