Skip to content

feat(audio): disable system audio in virtual machines#839

Merged
deepin-bot[bot] merged 1 commit into
linuxdeepin:release/eaglefrom
add-uos:release/eagle
May 12, 2026
Merged

feat(audio): disable system audio in virtual machines#839
deepin-bot[bot] merged 1 commit into
linuxdeepin:release/eaglefrom
add-uos:release/eagle

Conversation

@add-uos
Copy link
Copy Markdown
Contributor

@add-uos add-uos commented May 12, 2026

Add virtual machine detection using systemd-detect-virt to automatically disable system audio recording when running in a VM environment. System audio is now
unavailable in virtual machines due to driver compatibility issues. Add helper function to uncheck all audio recording options
(microphone and system audio) for consistent UI state management.

bug: https://pms.uniontech.com/bug-view-360853.html
log: disable system audio in virtual machines

max-lvs
max-lvs previously approved these changes May 12, 2026
Copy link
Copy Markdown
Contributor

@max-lvs max-lvs left a comment

Choose a reason for hiding this comment

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

先看看代码安全检查

Add virtual machine detection using systemd-detect-virt
to automatically disable system audio recording when
running in a VM environment. System audio is now
unavailable in virtual machines due to driver compatibility issues.
Add helper function to uncheck all audio recording options
 (microphone and system audio) for consistent UI state management.

bug: https://pms.uniontech.com/bug-view-360853.html
log: disable system audio in virtual machines
@deepin-ci-robot
Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: add-uos

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

1 similar comment
@deepin-ci-robot
Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: add-uos

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

@deepin-ci-robot
Copy link
Copy Markdown

deepin pr auto review

你好!我是CodeGeeX,你的智能编程助手。我已经仔细审查了你提供的Git Diff代码。本次修改主要涉及.gitignore的完善、版权年份的更新、虚拟机检测功能的添加以及在录音逻辑中针对虚拟机环境的适配。

总体来说,代码逻辑清晰,意图明确。但为了提升代码的健壮性、性能和安全性,我为你提供以下详细的审查意见和改进建议:

1. 语法与逻辑

问题:QAction::triggered 信号重载导致 emit 语法歧义

  • 位置src/widgets/subtoolwidget.cpp 第1463行 emit m_systemAudioAction->triggered(false);
  • 分析:Qt中 QAction::triggered 信号有两个重载:triggered()triggered(bool checked)。直接使用 emit m_systemAudioAction->triggered(false) 在某些编译器或Qt版本中可能会因为信号重载解析失败而导致编译错误。
  • 建议:使用Qt5/Qt6推荐的函数指针语法来明确指定调用哪个信号。
  • 改进代码
    // 修改前
    emit m_systemAudioAction->triggered(false);
    
    // 修改后
    emit static_cast<void(QAction::*)(bool)>(&QAction::triggered)(false);
    // 或者更推荐的做法:如果只是想取消选中并触发,可以直接调用 setChecked(false) 然后 trigger()

问题:重复调用 isRunningInVirtualMachine 导致性能损耗

  • 位置src/widgets/subtoolwidget.cpp 第1459-1463行
  • 分析:在 setSystemAudioEnable 函数中,Utils::isRunningInVirtualMachine() 被调用了两次。该函数内部会启动一个 QProcess 并阻塞等待其结束,这是一个相对耗时的I/O操作。在同一个函数中执行两次这样的阻塞操作是不必要的。
  • 建议:将结果缓存到局部变量中复用。
  • 改进代码
    void SubToolWidget::setSystemAudioEnable(bool status)
    {
        m_haveSystemAudio = status;
        m_systemAudioAction->setEnabled(status);
        m_systemAudioAction->setCheckable(status);
        
        bool isVM = Utils::isRunningInVirtualMachine(); // 缓存结果
        m_systemAudioAction->setChecked(!status && !isVM);
        if (isVM)
            emit static_cast<void(QAction::*)(bool)>(&QAction::triggered)(false);
        else
            m_systemAudioAction->trigger();
    }

2. 代码性能

问题:waitForFinished() 阻塞主线程

  • 位置src/utils.cpp isRunningInVirtualMachine 函数
  • 分析process.waitForFinished(); 默认会阻塞当前线程直到进程结束。如果 subtoolwidget.cpp 中的相关代码是在主线程(UI线程)执行的,这会导致界面短暂卡顿。另外,没有设置超时时间,如果 systemd-detect-virt 挂起,程序将无限期阻塞。
  • 建议
    1. 必须设置超时时间(如3000毫秒)。
    2. 如果此函数被频繁调用,强烈建议将检测结果做成静态变量缓存,因为运行环境在程序生命周期内通常不会改变;或者在应用启动时在后台线程检测一次,后续直接读取缓存。
  • 改进代码
    bool Utils::isRunningInVirtualMachine(bool forceVirtualMachine)
    {
        // 使用静态变量缓存结果,避免每次都启动进程
        static bool cachedResult = []() {
            QProcess process;
            process.start("/usr/bin/systemd-detect-virt");
            // 设置超时时间,防止进程挂起导致界面卡死
            if (!process.waitForFinished(3000)) {
                qWarning() << "systemd-detect-virt timed out or failed to start:" << process.errorString();
                return false; // 检测失败时默认为物理机,保证基本功能可用
            }
            QString output = process.readAllStandardOutput().trimmed();
            return !(output.isEmpty() || output.toLower() == "none");
        }();
    
        if (forceVirtualMachine) {
            qInfo() << "Force treat as virtual machine";
            return true;
        }
    
        if (cachedResult) {
            qInfo() << "Running in a virtual machine";
        } else {
            qInfo() << "Running on physical machine, not a virtual machine";
        }
        return cachedResult;
    }

3. 代码安全与健壮性

问题:未校验外部进程的执行结果

  • 位置src/utils.cpp isRunningInVirtualMachine 函数
  • 分析:代码直接调用了 process.start() 并读取输出,但没有检查进程是否启动成功。在某些精简的Linux系统或容器中,/usr/bin/systemd-detect-virt 可能不存在,或者没有执行权限。
  • 建议:检查进程的启动状态和退出码。
  • 改进代码
    QProcess process;
    process.start("/usr/bin/systemd-detect-virt");
    if (!process.waitForFinished(3000)) {
        qWarning() << "Failed to wait for systemd-detect-virt:" << process.errorString();
        return false; // 默认安全降级
    }
    
    // 检查退出码,systemd-detect-virt 在虚拟机中返回0,非虚拟机返回1
    if (process.exitStatus() != QProcess::NormalExit || process.exitCode() != 0) {
        return false; 
    }
    // ... 后续逻辑其实可以直接用 exitCode() == 0 来判断,不需要解析字符串

问题:forceVirtualMachine 参数的设计可能引发安全隐患

  • 位置src/utils.cppsrc/utils.h
  • 分析forceVirtualMachine 参数允许强制将环境视为虚拟机。如果未来其他开发者误用此参数(例如默认传了 true),会导致物理机上的系统录音功能被意外禁用,损害用户体验。
  • 建议:如果该参数仅用于调试,建议将其移除,改用环境变量(如 export FORCE_VM=1)来控制;如果必须保留,请确保在文档中强烈标明其用途,或者改为更明确的函数名,如 isRunningInVirtualMachineOrForced()

4. 代码规范与细节

问题:文件末尾空行及格式不一致

  • 位置src/utils.h 第149行、151行
  • 分析diff 显示新增了空行,且有的地方使用了空格,有的地方使用了空行,建议保持代码风格统一。
  • 建议:移除多余的尾部空格,保持紧凑的代码风格。

问题:.gitignore 规则顺序

  • 位置.gitignore
  • 分析:新增了 moc_*.hqrc_*.cpp*.so 等规则,这些都是Qt编译生成的中间文件和产物,添加是合理的。但规则穿插在原有规则中,略显凌乱。
  • 建议:可以按类别对 .gitignore 进行排序整理,比如:先写通配符规则(*.o, *.so, *.qm),再写特定前缀规则(moc_*, qrc_*),最后写具体目录和文件(build/, deepin-screen-recorder)。

总结

核心需要修改的是避免在UI逻辑中重复调用阻塞的进程检测,以及解决 triggered(bool) 信号的emit歧义。强烈建议采用上面提到的静态变量缓存+超时控制+退出码判断的方式重构 isRunningInVirtualMachine 函数,这样既解决了性能问题,又提升了代码的健壮性。

@add-uos
Copy link
Copy Markdown
Contributor Author

add-uos commented May 12, 2026

/forcemerge

@deepin-bot
Copy link
Copy Markdown
Contributor

deepin-bot Bot commented May 12, 2026

This pr force merged! (status: blocked)

@deepin-bot deepin-bot Bot merged commit 509d83f into linuxdeepin:release/eagle May 12, 2026
7 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