fix(bluetooth):bluetooth continuous to be pairing

蓝牙持续配对所有设备 task:20341

(cherry picked from commit d7c5842f96697d9dbf61b83a7e4f0e014b6ecaf2)
This commit is contained in:
zhaolong 2020-04-23 18:29:59 +08:00 committed by fpc_diesel
parent 1633d1b23d
commit 5a4a76bd0c
11 changed files with 179 additions and 25 deletions

View File

@ -45,9 +45,16 @@ BluetoothApplet::BluetoothApplet(QWidget *parent)
m_appletName->setText(tr("Bluetooth")); m_appletName->setText(tr("Bluetooth"));
m_appletName->setVisible(false); m_appletName->setVisible(false);
auto appletNameLayout = new QHBoxLayout;
appletNameLayout->setMargin(0);
appletNameLayout->setSpacing(0);
appletNameLayout->addSpacing(12);
appletNameLayout->addWidget(m_appletName);
appletNameLayout->addStretch();
m_centrealLayout->setMargin(0); m_centrealLayout->setMargin(0);
m_centrealLayout->setSpacing(0); m_centrealLayout->setSpacing(0);
m_centrealLayout->addWidget(m_appletName); m_centrealLayout->addLayout(appletNameLayout);
m_centrealLayout->addWidget(m_line); m_centrealLayout->addWidget(m_line);
m_centralWidget->setLayout(m_centrealLayout); m_centralWidget->setLayout(m_centrealLayout);
m_centralWidget->setFixedWidth(Width); m_centralWidget->setFixedWidth(Width);
@ -83,18 +90,71 @@ bool BluetoothApplet::hasAadapter()
return m_adaptersManager->adaptersCount(); return m_adaptersManager->adaptersCount();
} }
Device::State BluetoothApplet::initDeviceState()
{
m_initDeviceState = Device::StateUnavailable;
for (auto adapterItem : m_adapterItems) {
if (adapterItem)
if (Device::StateAvailable == adapterItem->initDeviceState()) {
m_initDeviceState = Device::StateAvailable;
continue;
}
if (Device::StateConnected == adapterItem->initDeviceState()) {
m_initDeviceState = Device::StateConnected;
break;
}
}
return m_initDeviceState;
}
void BluetoothApplet::onPowerChanged(bool state)
{
Q_UNUSED(state)
bool powerState = false;
for (auto adapterItem : m_adapterItems) {
if (adapterItem->isPowered()) {
powerState = true;
break;
}
}
emit powerChanged(powerState);
}
void BluetoothApplet::onDeviceStateChanged(const Device::State state)
{
Q_UNUSED(state)
Device::State deviceState = Device::StateUnavailable;
for (auto adapterItem : m_adapterItems) {
if (Device::StateAvailable == adapterItem->currentDeviceState()) {
deviceState = Device::StateAvailable;
continue;
}
if (Device::StateConnected == adapterItem->currentDeviceState()) {
deviceState = Device::StateConnected;
break;
}
}
emit deviceStateChanged(deviceState);
}
void BluetoothApplet::addAdapter(Adapter *adapter) void BluetoothApplet::addAdapter(Adapter *adapter)
{ {
if (!adapter) if (!adapter)
return; return;
if (!m_adapterItems.size()) {
emit justHasAdapter();
}
auto adapterId = adapter->id(); auto adapterId = adapter->id();
auto adatpterItem = new AdapterItem(m_adaptersManager, adapter, this); auto adatpterItem = new AdapterItem(m_adaptersManager, adapter, this);
m_adapterItems[adapterId] = adatpterItem; m_adapterItems[adapterId] = adatpterItem;
m_centrealLayout->addWidget(adatpterItem); m_centrealLayout->addWidget(adatpterItem);
connect(adatpterItem, &AdapterItem::deviceStateChanged, this, &BluetoothApplet::deviceStateChanged); connect(adatpterItem, &AdapterItem::deviceStateChanged, this, &BluetoothApplet::onDeviceStateChanged);
connect(adatpterItem, &AdapterItem::powerChanged, this, &BluetoothApplet::powerChanged); connect(adatpterItem, &AdapterItem::powerChanged, this, &BluetoothApplet::onPowerChanged);
connect(adatpterItem, &AdapterItem::sizeChange, this, &BluetoothApplet::updateView); connect(adatpterItem, &AdapterItem::sizeChange, this, &BluetoothApplet::updateView);
updateView(); updateView();
@ -120,13 +180,15 @@ void BluetoothApplet::updateView()
int contentHeight = 0; int contentHeight = 0;
int itemCount = 0; int itemCount = 0;
for (auto adapterItem : m_adapterItems) { for (auto adapterItem : m_adapterItems) {
if (adapterItem && adapterItem->isPowered()) { if (adapterItem) {
itemCount += adapterItem->deviceCount(); contentHeight += adapterItem->viewHeight();
contentHeight += ControlHeight; if (adapterItem->isPowered())
itemCount += adapterItem->deviceCount();
} }
} }
if (m_adapterItems.size() > 1) { auto adaptersCnt = m_adapterItems.size();
if (adaptersCnt > 1) {
m_line->setVisible(true); m_line->setVisible(true);
m_appletName->setVisible(true); m_appletName->setVisible(true);
} else { } else {
@ -134,15 +196,18 @@ void BluetoothApplet::updateView()
m_appletName->setVisible(false); m_appletName->setVisible(false);
} }
if (itemCount <= 16) { if (adaptersCnt > 1)
contentHeight += m_appletName->height();
if (itemCount <= 10) {
contentHeight += itemCount * ItemHeight; contentHeight += itemCount * ItemHeight;
m_centralWidget->setFixedHeight(contentHeight); m_centralWidget->setFixedHeight(contentHeight);
setFixedHeight(contentHeight); setFixedHeight(contentHeight);
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
} else { } else {
contentHeight += 16 * ItemHeight; contentHeight += itemCount * ItemHeight;
m_centralWidget->setFixedHeight(contentHeight); m_centralWidget->setFixedHeight(contentHeight);
setFixedHeight(contentHeight); setFixedHeight(10 * ItemHeight);
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
} }
} }

View File

@ -41,6 +41,7 @@ public:
void setAdapterPowered(bool powered); void setAdapterPowered(bool powered);
bool poweredInitState(); bool poweredInitState();
bool hasAadapter(); bool hasAadapter();
Device::State initDeviceState();
public slots : public slots :
void addAdapter(Adapter *constadapter); void addAdapter(Adapter *constadapter);
@ -50,6 +51,11 @@ signals:
void powerChanged(bool state); void powerChanged(bool state);
void deviceStateChanged(const Device::State state); void deviceStateChanged(const Device::State state);
void noAdapter(); void noAdapter();
void justHasAdapter();
private slots:
void onPowerChanged(bool state);
void onDeviceStateChanged(const Device::State state);
private: private:
void updateView(); void updateView();
@ -63,6 +69,7 @@ private:
AdaptersManager *m_adaptersManager; AdaptersManager *m_adaptersManager;
QMap<QString, AdapterItem *> m_adapterItems; QMap<QString, AdapterItem *> m_adapterItems;
Device::State m_initDeviceState;
}; };
#endif // BLUETOOTHAPPLET_H #endif // BLUETOOTHAPPLET_H

View File

@ -43,10 +43,14 @@ DGUI_USE_NAMESPACE
BluetoothItem::BluetoothItem(QWidget *parent) BluetoothItem::BluetoothItem(QWidget *parent)
: QWidget(parent) : QWidget(parent)
, m_applet(new BluetoothApplet(this)) , m_applet(new BluetoothApplet(this))
, m_timer(new QTimer(this))
{ {
m_applet->setVisible(false); m_applet->setVisible(false);
m_adapterPowered = m_applet->poweredInitState(); m_adapterPowered = m_applet->poweredInitState();
m_devState = m_applet->initDeviceState();
connect(m_timer, &QTimer::timeout, this, &BluetoothItem::refreshIcon);
connect(m_applet, &BluetoothApplet::powerChanged, [&](bool powered) { connect(m_applet, &BluetoothApplet::powerChanged, [&](bool powered) {
m_adapterPowered = powered; m_adapterPowered = powered;
refreshIcon(); refreshIcon();
@ -56,6 +60,7 @@ BluetoothItem::BluetoothItem(QWidget *parent)
refreshIcon(); refreshIcon();
}); });
connect(m_applet, SIGNAL(noAdapter()), this, SIGNAL(noAdapter())); connect(m_applet, SIGNAL(noAdapter()), this, SIGNAL(noAdapter()));
connect(m_applet, SIGNAL(justHasAdapter()), this, SIGNAL(justHasAdapter()));
} }
//QWidget *BluetoothItem::tipsWidget() //QWidget *BluetoothItem::tipsWidget()
@ -120,10 +125,37 @@ void BluetoothItem::refreshIcon()
return; return;
QString stateString; QString stateString;
QString iconString;
m_adapterPowered ? (m_devState == Device::StateConnected ? stateString = "waiting" : stateString = "active") : stateString = "disable"; if (m_adapterPowered) {
switch (m_devState) {
case Device::StateConnected:
stateString = "active";
break;
case Device::StateAvailable: {
m_timer->start();
stateString = "waiting";
iconString = QString("bluetooth-%1-symbolic").arg(stateString);
const auto ratio = devicePixelRatioF();
int iconSize = PLUGIN_ICON_MAX_SIZE;
if (height() <= PLUGIN_BACKGROUND_MIN_SIZE && DGuiApplicationHelper::instance()->themeType() == DGuiApplicationHelper::LightType)
iconString.append(PLUGIN_MIN_ICON_NAME);
QString iconString = QString("bluetooth-%1-symbolic").arg(stateString); m_iconPixmap = ImageUtil::loadSvg(iconString, ":/", iconSize, ratio);
update();
return ;
}
case Device::StateUnavailable: {
stateString = "disable";
} break;
}
} else {
stateString = "disable";
}
m_timer->stop();
iconString = QString("bluetooth-%1-symbolic").arg(stateString);
const auto ratio = devicePixelRatioF(); const auto ratio = devicePixelRatioF();
int iconSize = PLUGIN_ICON_MAX_SIZE; int iconSize = PLUGIN_ICON_MAX_SIZE;
@ -165,5 +197,9 @@ void BluetoothItem::paintEvent(QPaintEvent *e)
const QRectF &rf = QRectF(rect()); const QRectF &rf = QRectF(rect());
const QRectF &rfp = QRectF(m_iconPixmap.rect()); const QRectF &rfp = QRectF(m_iconPixmap.rect());
painter.drawPixmap(rf.center() - rfp.center() / m_iconPixmap.devicePixelRatioF(), m_iconPixmap); painter.drawPixmap(rf.center() - rfp.center() / m_iconPixmap.devicePixelRatioF(), m_iconPixmap);
if (m_devState == Device::StateAvailable) {
QTime time = QTime::currentTime();
painter.rotate((time.second() + (time.msec() / 1000.0)) * 6.0);
}
} }

View File

@ -55,6 +55,7 @@ protected:
signals: signals:
void requestContextMenu() const; void requestContextMenu() const;
void noAdapter(); void noAdapter();
void justHasAdapter();
private: private:
// TipsWidget *m_tipsLabel; // TipsWidget *m_tipsLabel;
@ -63,6 +64,7 @@ private:
Device::State m_devState; Device::State m_devState;
bool m_adapterPowered; bool m_adapterPowered;
QTimer *m_timer;
}; };
#endif // BLUETOOTHITEM_H #endif // BLUETOOTHITEM_H

View File

@ -49,9 +49,13 @@ void BluetoothPlugin::init(PluginProxyInterface *proxyInter)
m_bluetoothItem = new BluetoothItem; m_bluetoothItem = new BluetoothItem;
connect(m_bluetoothItem, &BluetoothItem::justHasAdapter, [&]{
m_enableState = true;
refreshPluginItemsVisible();
});
connect(m_bluetoothItem, &BluetoothItem::noAdapter, [&]{ connect(m_bluetoothItem, &BluetoothItem::noAdapter, [&]{
m_enableState = false; m_enableState = false;
pluginIsDisable(); refreshPluginItemsVisible();
}); });
m_enableState = m_bluetoothItem->hasAdapter(); m_enableState = m_bluetoothItem->hasAdapter();

View File

@ -28,6 +28,8 @@
#include <DDBusSender> #include <DDBusSender>
extern const int ItemHeight;
extern const int ControlHeight;
const int Width = 200; const int Width = 200;
AdapterItem::AdapterItem(AdaptersManager *adapterManager, Adapter *adapter, QWidget *parent) AdapterItem::AdapterItem(AdaptersManager *adapterManager, Adapter *adapter, QWidget *parent)
@ -45,6 +47,7 @@ AdapterItem::AdapterItem(AdaptersManager *adapterManager, Adapter *adapter, QWid
m_deviceLayout->setMargin(0); m_deviceLayout->setMargin(0);
m_deviceLayout->setSpacing(0); m_deviceLayout->setSpacing(0);
m_openControlCenter->setText("Bluetooth settings"); m_openControlCenter->setText("Bluetooth settings");
m_openControlCenter->setFixedHeight(ItemHeight);
m_openControlCenter->setVisible(false); m_openControlCenter->setVisible(false);
m_switchItem->setTitle(adapter->name()); m_switchItem->setTitle(adapter->name());
m_switchItem->setChecked(adapter->powered()); m_switchItem->setChecked(adapter->powered());
@ -72,6 +75,21 @@ AdapterItem::AdapterItem(AdaptersManager *adapterManager, Adapter *adapter, QWid
} }
} }
m_initDeviceState = Device::StateUnavailable;
for (auto constDevice : myDevices) {
auto device = const_cast<Device *>(constDevice);
if (device) {
if (device->state() == Device::StateAvailable) {
m_initDeviceState = Device::StateConnected;
continue;
}
if (device->state() == Device::StateConnected) {
m_initDeviceState = Device::StateConnected;
break;
}
}
}
connect(m_switchItem, &SwitchItem::checkedChanged, this, &AdapterItem::showAndConnect); connect(m_switchItem, &SwitchItem::checkedChanged, this, &AdapterItem::showAndConnect);
connect(adapter, &Adapter::nameChanged, m_switchItem, &SwitchItem::setTitle); connect(adapter, &Adapter::nameChanged, m_switchItem, &SwitchItem::setTitle);
connect(adapter, &Adapter::deviceAdded, this, &AdapterItem::addDeviceItem); connect(adapter, &Adapter::deviceAdded, this, &AdapterItem::addDeviceItem);
@ -107,7 +125,12 @@ void AdapterItem::setPowered(bool powered)
bool AdapterItem::isPowered() bool AdapterItem::isPowered()
{ {
return m_adapter->powered(); return m_switchItem->checkState();
}
int AdapterItem::viewHeight()
{
return m_openControlCenter->isVisible() ? ControlHeight + ItemHeight : ControlHeight;
} }
void AdapterItem::deviceItemPaired(const bool paired) void AdapterItem::deviceItemPaired(const bool paired)
@ -136,21 +159,21 @@ void AdapterItem::removeDeviceItem(const Device *device)
m_deviceItems.remove(device->id()); m_deviceItems.remove(device->id());
if (device->paired()) { if (device->paired()) {
// m_pairedDeviceItems.remove(device->id()); // m_pairedDeviceItems.remove(device->id());
m_deviceLayout->removeWidget(deviceItem);
} }
m_deviceLayout->removeWidget(deviceItem);
delete deviceItem; delete deviceItem;
showDevices(m_adapter->powered());
} }
showDevices(m_adapter->powered());
} }
void AdapterItem::showAndConnect(bool change) void AdapterItem::showAndConnect(bool change)
{ {
showDevices(change);
m_adaptersManager->setAdapterPowered(m_adapter, change); m_adaptersManager->setAdapterPowered(m_adapter, change);
if (change) { if (change) {
m_adaptersManager->connectAllPairedDevice(m_adapter); // m_adaptersManager->connectAllPairedDevice(m_adapter);
} }
showDevices(change);
emit powerChanged(change); emit powerChanged(change);
} }
@ -178,6 +201,7 @@ void AdapterItem::deviceChangeState(const Device::State state)
} }
} }
m_currentDeviceState = state;
emit deviceStateChanged(state); emit deviceStateChanged(state);
} }
@ -204,7 +228,8 @@ void AdapterItem::createDeviceItem(Device *device)
void AdapterItem::updateView() void AdapterItem::updateView()
{ {
auto contentHeight = m_centralWidget->sizeHint().height(); auto contentHeight = m_switchItem->height();
contentHeight += (m_deviceLayout->count() - 3) * ItemHeight;
m_centralWidget->setFixedHeight(contentHeight); m_centralWidget->setFixedHeight(contentHeight);
setFixedHeight(contentHeight); setFixedHeight(contentHeight);
emit sizeChange(); emit sizeChange();

View File

@ -45,6 +45,9 @@ public:
int deviceCount(); int deviceCount();
void setPowered(bool powered); void setPowered(bool powered);
bool isPowered(); bool isPowered();
int viewHeight();
inline Device::State initDeviceState() { return m_initDeviceState; }
inline Device::State currentDeviceState() { return m_currentDeviceState; }
signals: signals:
void deviceStateChanged(const Device::State state); void deviceStateChanged(const Device::State state);
@ -74,6 +77,8 @@ private:
Adapter *m_adapter; Adapter *m_adapter;
SwitchItem *m_switchItem; SwitchItem *m_switchItem;
QMap<QString, DeviceItem*> m_deviceItems; QMap<QString, DeviceItem*> m_deviceItems;
Device::State m_initDeviceState;
Device::State m_currentDeviceState;
// QMap<QString, DeviceItem*> m_pairedDeviceItems; // QMap<QString, DeviceItem*> m_pairedDeviceItems;
}; };

View File

@ -43,6 +43,7 @@ AdaptersManager::AdaptersManager(QObject *parent)
connect(m_bluetoothInter, &DBusBluetooth::DeviceRemoved, this, &AdaptersManager::removeDevice); connect(m_bluetoothInter, &DBusBluetooth::DeviceRemoved, this, &AdaptersManager::removeDevice);
connect(m_bluetoothInter, &DBusBluetooth::DevicePropertiesChanged, this, &AdaptersManager::onDevicePropertiesChanged); connect(m_bluetoothInter, &DBusBluetooth::DevicePropertiesChanged, this, &AdaptersManager::onDevicePropertiesChanged);
#ifdef QT_DEBUG
connect(m_bluetoothInter, &DBusBluetooth::RequestAuthorization, this, [](const QDBusObjectPath & in0) { connect(m_bluetoothInter, &DBusBluetooth::RequestAuthorization, this, [](const QDBusObjectPath & in0) {
qDebug() << "request authorization: " << in0.path(); qDebug() << "request authorization: " << in0.path();
}); });
@ -62,6 +63,7 @@ AdaptersManager::AdaptersManager(QObject *parent)
connect(m_bluetoothInter, &DBusBluetooth::DisplayPinCode, this, [](const QDBusObjectPath & in0, const QString & in1) { connect(m_bluetoothInter, &DBusBluetooth::DisplayPinCode, this, [](const QDBusObjectPath & in0, const QString & in1) {
qDebug() << "request display pincode: " << in0.path() << in1; qDebug() << "request display pincode: " << in0.path() << in1;
}); });
#endif
QDBusInterface *inter = new QDBusInterface("com.deepin.daemon.Bluetooth", QDBusInterface *inter = new QDBusInterface("com.deepin.daemon.Bluetooth",
"/com/deepin/daemon/Bluetooth", "/com/deepin/daemon/Bluetooth",
@ -116,7 +118,7 @@ void AdaptersManager::setAdapterPowered(const Adapter *adapter, const bool &powe
void AdaptersManager::connectAllPairedDevice(const Adapter *adapter) void AdaptersManager::connectAllPairedDevice(const Adapter *adapter)
{ {
for (const Device *d : adapter->devices()) { for (const Device *d : adapter->paredDevices()) {
Device *vd = const_cast<Device *>(d); Device *vd = const_cast<Device *>(d);
if (vd) { if (vd) {
QDBusObjectPath path(vd->id()); QDBusObjectPath path(vd->id());
@ -162,9 +164,13 @@ void AdaptersManager::onAdapterPropertiesChanged(const QString &json)
const QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8()); const QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8());
const QJsonObject obj = doc.object(); const QJsonObject obj = doc.object();
const QString id = obj["Path"].toString(); const QString id = obj["Path"].toString();
const bool isDiscovering = obj["Discovering"].toBool();
QDBusObjectPath dPath(id);
Adapter *adapter = const_cast<Adapter *>(m_adapters[id]); Adapter *adapter = const_cast<Adapter *>(m_adapters[id]);
if (adapter) { if (adapter) {
if (!isDiscovering)
m_bluetoothInter->SetAdapterDiscovering(dPath, true);
inflateAdapter(adapter, obj); inflateAdapter(adapter, obj);
} }
} }

View File

@ -61,12 +61,12 @@ DeviceItem::DeviceItem(const QString &title, QWidget *parent)
auto itemLayout = new QHBoxLayout(this); auto itemLayout = new QHBoxLayout(this);
itemLayout->setMargin(0); itemLayout->setMargin(0);
itemLayout->setSpacing(0); itemLayout->setSpacing(0);
itemLayout->addSpacing(5); itemLayout->addSpacing(12);
itemLayout->addWidget(m_title); itemLayout->addWidget(m_title);
itemLayout->addStretch(); itemLayout->addStretch();
itemLayout->addWidget(m_state); itemLayout->addWidget(m_state);
itemLayout->addWidget(m_loadingStat); itemLayout->addWidget(m_loadingStat);
itemLayout->addSpacing(5); itemLayout->addSpacing(12);
deviceLayout->addLayout(itemLayout); deviceLayout->addLayout(itemLayout);
setLayout(deviceLayout); setLayout(deviceLayout);
} }

View File

@ -36,14 +36,15 @@ SwitchItem::SwitchItem(QWidget *parent)
auto switchLayout = new QHBoxLayout(this); auto switchLayout = new QHBoxLayout(this);
switchLayout->setSpacing(0); switchLayout->setSpacing(0);
switchLayout->setMargin(0); switchLayout->setMargin(0);
switchLayout->addSpacing(5); switchLayout->addSpacing(12);
switchLayout->addWidget(m_title); switchLayout->addWidget(m_title);
switchLayout->addStretch(); switchLayout->addStretch();
switchLayout->addWidget(m_switchBtn); switchLayout->addWidget(m_switchBtn);
switchLayout->addSpacing(5); switchLayout->addSpacing(12);
setLayout(switchLayout); setLayout(switchLayout);
connect(m_switchBtn, &DSwitchButton::toggled, [&](bool change) { connect(m_switchBtn, &DSwitchButton::toggled, [&](bool change) {
m_checkState = change;
emit checkedChanged(change); emit checkedChanged(change);
}); });
} }
@ -51,6 +52,7 @@ SwitchItem::SwitchItem(QWidget *parent)
void SwitchItem::setChecked(const bool checked) void SwitchItem::setChecked(const bool checked)
{ {
m_switchBtn->setChecked(checked); m_switchBtn->setChecked(checked);
m_checkState = checked;
} }
void SwitchItem::setTitle(const QString &title) void SwitchItem::setTitle(const QString &title)

View File

@ -36,6 +36,7 @@ public:
explicit SwitchItem(QWidget *parent = nullptr); explicit SwitchItem(QWidget *parent = nullptr);
void setChecked(const bool checked = true); void setChecked(const bool checked = true);
void setTitle(const QString &title); void setTitle(const QString &title);
inline bool checkState() { return m_checkState; }
inline bool isdefault() { return m_default; } inline bool isdefault() { return m_default; }
inline void setDefault(bool def) { m_default = def; } inline void setDefault(bool def) { m_default = def; }
@ -51,6 +52,7 @@ private:
QLabel *m_title; QLabel *m_title;
DSwitchButton *m_switchBtn; DSwitchButton *m_switchBtn;
bool m_default; bool m_default;
bool m_checkState;
}; };
#endif // SWITCHITEM_H #endif // SWITCHITEM_H