dde-dock/plugins/network/networkmanager.cpp
石博文 133b711d1f update license
Change-Id: I9df92e43b79f7c2b3688b595f80df7b3a7bb7ed2
2018-02-07 11:52:47 +08:00

257 lines
7.2 KiB
C++

/*
* Copyright (C) 2011 ~ 2018 Deepin Technology Co., Ltd.
*
* Author: sbw <sbw@sbw.so>
*
* Maintainer: sbw <sbw@sbw.so>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "networkmanager.h"
#include "networkdevice.h"
NetworkManager *NetworkManager::INSTANCE = nullptr;
NetworkManager *NetworkManager::instance(QObject *parent)
{
if (!INSTANCE)
INSTANCE = new NetworkManager(parent);
return INSTANCE;
}
void NetworkManager::init()
{
QTimer *dbusCheckTimer = new QTimer;
dbusCheckTimer->setInterval(100);
dbusCheckTimer->setSingleShot(false);
auto checkFunc = [=] {
if (!m_networkInter->isValid())
return;
QTimer::singleShot(100, this, &NetworkManager::reloadDevices);
QTimer::singleShot(150, this, &NetworkManager::reloadActiveConnections);
dbusCheckTimer->deleteLater();
};
connect(dbusCheckTimer, &QTimer::timeout, checkFunc);
dbusCheckTimer->start();
}
NetworkManager::GlobalNetworkState NetworkManager::globalNetworkState() const
{
return GlobalNetworkState(m_networkInter->state());
}
const NetworkDevice::NetworkTypes NetworkManager::states() const
{
return m_states;
}
const NetworkDevice::NetworkTypes NetworkManager::types() const
{
return m_types;
}
const QSet<NetworkDevice> NetworkManager::deviceList() const
{
return m_deviceSet;
}
const QSet<QUuid> NetworkManager::activeConnSet() const
{
return m_activeConnSet;
}
NetworkDevice::NetworkState NetworkManager::deviceState(const QString &path) const
{
const auto item = device(path);
if (item == m_deviceSet.cend())
return NetworkDevice::Unknow;
return item->state();
}
bool NetworkManager::deviceEnabled(const QString &path) const
{
return m_networkInter->IsDeviceEnabled(QDBusObjectPath(path));
}
void NetworkManager::setDeviceEnabled(const QString path, const bool enable)
{
m_networkInter->EnableDevice(QDBusObjectPath(path), enable);
}
const QString NetworkManager::deviceHwAddr(const QString &path) const
{
const auto item = device(path);
if (item == m_deviceSet.cend())
return QString();
return item->usingHwAddr();
}
const QString NetworkManager::devicePath(const QString &path) const
{
const auto item = device(path);
if (item == m_deviceSet.cend())
return QString();
return item->path();
}
const QJsonObject NetworkManager::deviceConnInfo(const QString &path) const
{
const QString addr = deviceHwAddr(path);
if (addr.isEmpty())
return QJsonObject();
const QJsonDocument infos = QJsonDocument::fromJson(m_networkInter->GetActiveConnectionInfo().value().toUtf8());
Q_ASSERT(infos.isArray());
for (auto info : infos.array())
{
Q_ASSERT(info.isObject());
const QJsonObject obj = info.toObject();
if (obj.contains("HwAddress") && obj.value("HwAddress").toString() == addr)
return obj;
}
return QJsonObject();
}
NetworkManager::NetworkManager(QObject *parent)
: QObject(parent),
m_states(NetworkDevice::None),
m_types(NetworkDevice::None),
m_networkInter(new DBusNetwork(this))
{
connect(m_networkInter, &DBusNetwork::StateChanged, this, &NetworkManager::globalNetworkStateChanged);
connect(m_networkInter, &DBusNetwork::DevicesChanged, this, &NetworkManager::reloadDevices);
connect(m_networkInter, &DBusNetwork::ActiveConnectionsChanged, this, &NetworkManager::reloadActiveConnections);
}
const QSet<NetworkDevice>::const_iterator NetworkManager::device(const QString &path) const
{
return std::find_if(m_deviceSet.cbegin(), m_deviceSet.cend(),
[&] (const NetworkDevice &dev) {return dev.path() == path;});
}
void NetworkManager::reloadDevices()
{
const QJsonDocument doc = QJsonDocument::fromJson(m_networkInter->devices().toUtf8());
Q_ASSERT(doc.isObject());
const QJsonObject obj = doc.object();
NetworkDevice::NetworkTypes types = NetworkDevice::None;
QSet<NetworkDevice> deviceSet;
for (auto infoList(obj.constBegin()); infoList != obj.constEnd(); ++infoList)
{
Q_ASSERT(infoList.value().isArray());
const NetworkDevice::NetworkType deviceType = NetworkDevice::deviceType(infoList.key());
const auto list = infoList.value().toArray();
if (list.isEmpty())
continue;
types |= deviceType;
for (auto device : list)
deviceSet.insert(NetworkDevice(deviceType, device.toObject()));
}
const QSet<NetworkDevice> removedDeviceList = m_deviceSet - deviceSet;
for (auto dev : removedDeviceList)
emit deviceRemoved(dev);
for (auto dev : deviceSet)
{
if (m_deviceSet.contains(dev))
emit deviceChanged(dev);
else
emit deviceAdded(dev);
}
m_deviceSet = std::move(deviceSet);
if (m_types == types)
return;
m_types = types;
emit deviceTypesChanged(m_types);
// qDebug() << "device type: " << m_types;
}
void NetworkManager::reloadActiveConnections()
{
const QJsonDocument doc = QJsonDocument::fromJson(m_networkInter->activeConnections().toUtf8());
Q_ASSERT(doc.isObject());
const QJsonObject obj = doc.object();
QSet<QUuid> activeConnList;
for (auto info(obj.constBegin()); info != obj.constEnd(); ++info)
{
Q_ASSERT(info.value().isObject());
const QJsonObject infoObj = info.value().toObject();
const QUuid uuid = infoObj.value("Uuid").toString();
activeConnList.insert(uuid);
}
const QSet<QUuid> removedConnList = m_activeConnSet - activeConnList;
m_activeConnSet = std::move(activeConnList);
reloadNetworkState();
for (auto uuid : removedConnList)
emit activeConnectionChanged(uuid);
for (auto uuid : m_activeConnSet)
emit activeConnectionChanged(uuid);
}
void NetworkManager::reloadNetworkState()
{
NetworkDevice::NetworkTypes states = NetworkDevice::None;
QSet<QString> activedDevices;
const QJsonDocument doc = QJsonDocument::fromJson(m_networkInter->GetActiveConnectionInfo().value().toUtf8());
for (const auto info : doc.array())
{
const auto detail = info.toObject();
const QString type = detail.value("ConnectionType").toString();
const QString device = detail.value("Device").toString();
activedDevices.insert(device);
if (type == "wired")
states |= NetworkDevice::Wired;
else if (type == "wireless")
states |= NetworkDevice::Wireless;
}
m_activeDeviceSet = std::move(activedDevices);
if (m_states == states)
return;
m_states = states;
emit networkStateChanged(m_states);
// qDebug() << "network states: " << m_states;
}