Skip to content

Conversation

@yixinshark
Copy link
Contributor

@yixinshark yixinshark commented Jan 28, 2026

When airplane mode is enabled, bluetooth is automatically turned off. However, the device list was not being cleared, causing residual device information to be displayed in the bluetooth plugin panel.

This fix ensures that when the bluetooth adapter is powered off, all device items and models are properly cleared to prevent display issues.

Log: clear bluetooth device list when adapter is powered off
Pms: BUG-338867

Summary by Sourcery

Bug Fixes:

  • Remove residual Bluetooth devices from the dock plugin panel when the adapter is turned off, such as when airplane mode is enabled.

@sourcery-ai
Copy link

sourcery-ai bot commented Jan 28, 2026

Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Update Bluetooth adapter powered-state handling so that device items and backing models are cleared when the adapter powers off, while preserving existing initialization when it powers on.

Sequence diagram for bluetooth adapter poweredChanged handling

sequenceDiagram
    participant Adapter
    participant BluetoothAdapterItem
    participant MyDeviceModel
    participant OtherDeviceModel

    Adapter->>BluetoothAdapterItem: poweredChanged(state)
    alt state is true (adapter powered on)
        BluetoothAdapterItem->>BluetoothAdapterItem: initData()
        BluetoothAdapterItem->>MyDeviceModel: populate device list
        BluetoothAdapterItem->>OtherDeviceModel: populate device list
    else state is false (adapter powered off)
        BluetoothAdapterItem->>BluetoothAdapterItem: qDeleteAll(m_deviceItems)
        BluetoothAdapterItem->>BluetoothAdapterItem: m_deviceItems.clear()
        BluetoothAdapterItem->>MyDeviceModel: clear()
        BluetoothAdapterItem->>OtherDeviceModel: clear()
    end
    BluetoothAdapterItem->>BluetoothAdapterItem: m_refreshBtn.setVisible(state)
    BluetoothAdapterItem->>BluetoothAdapterItem: m_myDeviceWidget.setVisible(m_myDeviceModel.rowCount() > 0 and state)
    BluetoothAdapterItem->>BluetoothAdapterItem: m_otherDeviceListView.setVisible(state and (m_otherDeviceControlWidget.isExpand() or m_myDeviceModel.rowCount() < 1))
Loading

Class diagram for BluetoothAdapterItem powered state handling

classDiagram
    class BluetoothAdapterItem {
        - Adapter m_adapter
        - QList~BluetoothDeviceItem~ m_deviceItems
        - DeviceModel m_myDeviceModel
        - DeviceModel m_otherDeviceModel
        - QPushButton m_refreshBtn
        - QWidget m_myDeviceWidget
        - QListView m_otherDeviceListView
        - OtherDeviceControlWidget m_otherDeviceControlWidget
        + initConnect() void
        + initData() void
    }

    class Adapter {
        + poweredChanged(bool state) signal
    }

    class DeviceModel {
        + clear() void
        + rowCount() int
    }

    class BluetoothDeviceItem

    class OtherDeviceControlWidget {
        + isExpand() bool
    }

    class QPushButton {
        + setVisible(bool visible) void
    }

    class QWidget {
        + setVisible(bool visible) void
    }

    class QListView {
        + setVisible(bool visible) void
    }

    BluetoothAdapterItem --> Adapter : uses
    BluetoothAdapterItem o-- BluetoothDeviceItem : m_deviceItems
    BluetoothAdapterItem --> DeviceModel : uses m_myDeviceModel
    BluetoothAdapterItem --> DeviceModel : uses m_otherDeviceModel
    BluetoothAdapterItem --> QPushButton : uses m_refreshBtn
    BluetoothAdapterItem --> QWidget : uses m_myDeviceWidget
    BluetoothAdapterItem --> QListView : uses m_otherDeviceListView
    BluetoothAdapterItem --> OtherDeviceControlWidget : uses m_otherDeviceControlWidget
Loading

File-Level Changes

Change Details Files
Handle adapter power state changes by separating initialization on power-on from teardown/cleanup on power-off.
  • Replace unconditional initData() call in poweredChanged lambda with explicit branch on powered state.
  • On power-on, keep existing behavior by calling initData() to populate device list and models.
  • On power-off, delete all device item objects, clear the device items container, and clear both "my device" and "other device" models to remove stale entries.
  • Maintain existing UI visibility logic for refresh button, my-device widget, and other-device list view based on power state and model contents.
plugins/dde-dock/bluetooth/componments/bluetoothadapteritem.cpp

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

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:

  • Consider extracting the device-list clearing logic into a dedicated helper method (e.g., clearDevices()), so it can be reused from other code paths that may need to reset the adapter state and to keep the poweredChanged lambda focused and readable.
  • Since you are manually deleting m_deviceItems with qDeleteAll, it may be worth revisiting ownership of these objects to see if Qt parent-child ownership could handle their lifetime instead of keeping a separate list of raw pointers to manage.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Consider extracting the device-list clearing logic into a dedicated helper method (e.g., `clearDevices()`), so it can be reused from other code paths that may need to reset the adapter state and to keep the `poweredChanged` lambda focused and readable.
- Since you are manually deleting `m_deviceItems` with `qDeleteAll`, it may be worth revisiting ownership of these objects to see if Qt parent-child ownership could handle their lifetime instead of keeping a separate list of raw pointers to manage.

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.

@yixinshark yixinshark force-pushed the fix-bluetoothDisplay branch from ff7e8b7 to 479c52d Compare January 28, 2026 06:35
When airplane mode is enabled, bluetooth is automatically turned off.
However, the device list was not being cleared, causing residual device
information to be displayed in the bluetooth plugin panel.

This fix ensures that when the bluetooth adapter is powered off, all
device items and models are properly cleared to prevent display issues.

Log: clear bluetooth device list when adapter is powered off
Pms: BUG-338867
@yixinshark yixinshark force-pushed the fix-bluetoothDisplay branch from 479c52d to 6a6ab82 Compare January 28, 2026 06:41
@deepin-ci-robot
Copy link

deepin pr auto review

这段代码主要对蓝牙适配器的状态变化处理进行了重构,提取了公共的清理逻辑。以下是对这段代码的审查意见,包括语法逻辑、代码质量、代码性能和代码安全四个方面:

1. 语法逻辑

  • 逻辑正确性:逻辑是正确的。
    • poweredChanged 信号槽中,增加了对蓝牙开关状态(state)的判断。当蓝牙开启时初始化设备列表,关闭时清理设备列表。这比之前无论开关状态如何都调用 initData() 更合理。
    • clicked 信号槽中,使用新提取的 clearDeviceList() 替换了原有的清理代码,逻辑保持一致。
  • 状态一致性:代码逻辑保证了 UI 状态与数据状态的一致性。当蓝牙关闭时,不仅清空了内部数据模型(m_myDeviceModel, m_otherDeviceModel),还通过 clearDeviceList 清理了对应的 UI 控件项(m_deviceItems),并隐藏了相关视图。

2. 代码质量

  • 代码复用 (DRY原则)
    • 优点:将 qDeleteAll(m_deviceItems)m_deviceItems.clear()m_myDeviceModel->clear()m_otherDeviceModel->clear() 这四行代码提取为 clearDeviceList() 函数,消除了重复代码,提高了可维护性。如果将来清理逻辑发生变化(例如需要增加日志或重置更多变量),只需修改一处。
  • 可读性
    • 优点:在 poweredChanged 中添加了注释 "Initialize device list..." 和 "Clear device list...",清晰地解释了代码意图。
    • 建议:虽然代码逻辑清晰,但 initConnect() 函数中包含的 Lambda 表达式较多,且逻辑较重。如果后续逻辑继续膨胀,建议考虑将这些 Lambda 中的逻辑提取为类的私有槽函数(Private Slots),例如 onAdapterPoweredChanged(bool)onAdapterSwitchClicked(bool),这样 initConnect 会更加整洁,且便于调试。

3. 代码性能

  • 内存管理
    • 使用 qDeleteAll(m_deviceItems) 是正确的做法,它确保了在清空列表前删除了所有的 DeviceItem 指针,防止了内存泄漏。这是 Qt 中清理 QObject 指针列表的标准高效方式。
  • UI 刷新
    • 在蓝牙关闭时调用 clearDeviceList() 会触发模型(Model)的清空,进而通知视图(View)更新。这在蓝牙关闭场景下是必要的操作,性能开销在可接受范围内。

4. 代码安全

  • 空指针检查
    • 当前代码假设 m_deviceItems 中的指针都是有效的。如果 m_deviceItems 中可能包含空指针(虽然通常 Qt 容器管理下不太可能),qDeleteAll 也能处理,但为了代码健壮性,建议确保在添加指针到 m_deviceItems 时进行非空检查。
  • 对象生命周期
    • m_deviceItems 存储的是指针。qDeleteAll 会调用 delete,这要求这些对象必须是堆分配的(new 出来的),且没有被其他父对象接管所有权(或者即使被接管,这里也需要显式删除)。考虑到这是 Qt 界面组件,通常它们会被设置父对象,父对象销毁时会自动销毁子对象。
    • 潜在风险:如果 m_deviceItems 中的对象已经设置了父对象(例如 this 或某个 Widget),那么父对象析构时会再次尝试删除这些对象,导致 Double Free(双重释放)错误。
    • 改进建议:请确认 DeviceItem 的创建方式。如果 DeviceItem 在创建时指定了父对象,建议在 clearDeviceList 中只调用 m_deviceItems.clear(),依赖 Qt 的对象树自动管理内存;如果没有指定父对象,则当前的 qDeleteAll 是正确的。如果不确定,最安全的做法是:
      // 假设 DeviceItem 继承自 QObject
      for (auto item : m_deviceItems) {
          if (item) {
              item->deleteLater(); // 使用 deleteLater 更安全,避免在事件循环中立即删除可能正在处理信号的对象
          }
      }
      m_deviceItems.clear();
      或者,如果确认所有权关系明确,保持现状亦可,但需在代码审查时确认 DeviceItem 的构造逻辑。

总结

这是一次良好的重构,主要提升了代码的可维护性和逻辑的清晰度。代码性能符合预期。唯一需要关注的是 DeviceItem 对象的所有权管理问题,以确保不会发生内存泄漏或双重释放。建议确认 DeviceItem 的内存归属,或者在 clearDeviceList 中使用更安全的 deleteLater()

@deepin-ci-robot
Copy link

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: 18202781743, yixinshark

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

@yixinshark yixinshark merged commit 8771501 into linuxdeepin:master Jan 28, 2026
10 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