Commit c0e50601 authored by Christian Kandeler's avatar Christian Kandeler

DeviceManager: Remember auto-detected devices.

The current implementation "forgets" auto-detected devices when
they've been disconnected or Creator has been closed.
This has the drawback that potential changes by users to the connection
parameters cannot become persistent. This is overcome by introducing a
device fingerprint and keeping removed auto-connected devices in a
special list from which they can later be retrieved, typically when the
device gets connected again.

Change-Id: I98cfd25c677e6a2a46891a0facf3a28f0a0c3465
Reviewed-by: default avatarNikolai Kosjar <nikolai.kosjar@nokia.com>
parent 7049c72f
...@@ -52,6 +52,18 @@ ...@@ -52,6 +52,18 @@
namespace ProjectExplorer { namespace ProjectExplorer {
namespace Internal { namespace Internal {
static IDevice::Ptr findAutoDetectedDevice(const QList<IDevice::Ptr> &deviceList,
const QString &type, const QString &fingerprint)
{
foreach (const IDevice::Ptr &device, deviceList) {
if (device->isAutoDetected() && device->type() == type
&& device->fingerprint() == fingerprint) {
return device;
}
}
return IDevice::Ptr();
}
const char DeviceManagerKey[] = "DeviceManager"; const char DeviceManagerKey[] = "DeviceManager";
const char DeviceListKey[] = "DeviceList"; const char DeviceListKey[] = "DeviceList";
const char DefaultDevicesKey[] = "DefaultDevices"; const char DefaultDevicesKey[] = "DefaultDevices";
...@@ -62,6 +74,7 @@ public: ...@@ -62,6 +74,7 @@ public:
static DeviceManager *instance; static DeviceManager *instance;
static DeviceManager *clonedInstance; static DeviceManager *clonedInstance;
QList<IDevice::Ptr> devices; QList<IDevice::Ptr> devices;
QList<IDevice::Ptr> inactiveAutoDetectedDevices;
QHash<QString, IDevice::Id> defaultDevices; QHash<QString, IDevice::Id> defaultDevices;
}; };
DeviceManager *DeviceManagerPrivate::instance = 0; DeviceManager *DeviceManagerPrivate::instance = 0;
...@@ -192,7 +205,10 @@ void DeviceManager::fromMap(const QVariantMap &map) ...@@ -192,7 +205,10 @@ void DeviceManager::fromMap(const QVariantMap &map)
QTC_ASSERT(device, continue); QTC_ASSERT(device, continue);
if (device->internalId() == IDevice::invalidId()) if (device->internalId() == IDevice::invalidId())
device->setInternalId(unusedId()); device->setInternalId(unusedId());
d->devices << device; if (device->isAutoDetected())
d->inactiveAutoDetectedDevices << device;
else
d->devices << device;
} }
} }
...@@ -207,10 +223,10 @@ QVariantMap DeviceManager::toMap() const ...@@ -207,10 +223,10 @@ QVariantMap DeviceManager::toMap() const
} }
map.insert(QLatin1String(DefaultDevicesKey), defaultDeviceMap); map.insert(QLatin1String(DefaultDevicesKey), defaultDeviceMap);
QVariantList deviceList; QVariantList deviceList;
foreach (const IDevice::ConstPtr &device, d->devices) { foreach (const IDevice::ConstPtr &device, d->devices)
if (!device->isAutoDetected()) deviceList << device->toMap();
deviceList << device->toMap(); foreach (const IDevice::ConstPtr &device, d->inactiveAutoDetectedDevices)
} deviceList << device->toMap();
map.insert(QLatin1String(DeviceListKey), deviceList); map.insert(QLatin1String(DeviceListKey), deviceList);
return map; return map;
} }
...@@ -224,6 +240,8 @@ QString DeviceManager::settingsFilePath() ...@@ -224,6 +240,8 @@ QString DeviceManager::settingsFilePath()
void DeviceManager::addDevice(const IDevice::Ptr &device) void DeviceManager::addDevice(const IDevice::Ptr &device)
{ {
QTC_ASSERT(this != DeviceManagerPrivate::instance || (device->isAutoDetected()), return); QTC_ASSERT(this != DeviceManagerPrivate::instance || (device->isAutoDetected()), return);
QTC_ASSERT(!device->isAutoDetected() || !findAutoDetectedDevice(d->devices, device->type(),
device->fingerprint()), return);
// Ensure uniqueness of name. // Ensure uniqueness of name.
QString name = device->displayName(); QString name = device->displayName();
...@@ -241,13 +259,25 @@ void DeviceManager::addDevice(const IDevice::Ptr &device) ...@@ -241,13 +259,25 @@ void DeviceManager::addDevice(const IDevice::Ptr &device)
d->devices << device; d->devices << device;
if (this == d->instance && d->clonedInstance) if (this == d->instance && d->clonedInstance)
d->clonedInstance->addDevice(device->clone()); d->clonedInstance->addDevice(device->clone());
if (this == d->instance) {
QList<IDevice::Ptr>::Iterator it = d->inactiveAutoDetectedDevices.begin();
while (it != d->inactiveAutoDetectedDevices.end()) {
if (it->data()->type() == device->type()
&& it->data()->fingerprint() == device->fingerprint()) {
d->inactiveAutoDetectedDevices.erase(it);
break;
}
++it;
}
}
emit deviceAdded(device); emit deviceAdded(device);
emit updated(); emit updated();
} }
void DeviceManager::removeDevice(int idx) void DeviceManager::removeDevice(int idx)
{ {
const IDevice::ConstPtr device = deviceAt(idx); const IDevice::Ptr device = mutableDeviceAt(idx);
QTC_ASSERT(device, return); QTC_ASSERT(device, return);
QTC_ASSERT(this != DeviceManagerPrivate::instance || device->isAutoDetected(), return); QTC_ASSERT(this != DeviceManagerPrivate::instance || device->isAutoDetected(), return);
...@@ -269,6 +299,8 @@ void DeviceManager::removeDevice(int idx) ...@@ -269,6 +299,8 @@ void DeviceManager::removeDevice(int idx)
d->clonedInstance->removeDevice(d->clonedInstance-> d->clonedInstance->removeDevice(d->clonedInstance->
indexForInternalId(device->internalId())); indexForInternalId(device->internalId()));
} }
if (this == d->instance && device->isAutoDetected())
d->inactiveAutoDetectedDevices << device;
emit updated(); emit updated();
} }
...@@ -357,6 +389,12 @@ IDevice::ConstPtr DeviceManager::find(IDevice::Id id) const ...@@ -357,6 +389,12 @@ IDevice::ConstPtr DeviceManager::find(IDevice::Id id) const
return index == -1 ? IDevice::ConstPtr() : deviceAt(index); return index == -1 ? IDevice::ConstPtr() : deviceAt(index);
} }
IDevice::ConstPtr DeviceManager::findInactiveAutoDetectedDevice(const QString &type,
const QString &fingerprint)
{
return findAutoDetectedDevice(d->inactiveAutoDetectedDevices, type, fingerprint);
}
IDevice::ConstPtr DeviceManager::defaultDevice(const QString &deviceType) const IDevice::ConstPtr DeviceManager::defaultDevice(const QString &deviceType) const
{ {
const IDevice::Id id = d->defaultDevices.value(deviceType, IDevice::invalidId()); const IDevice::Id id = d->defaultDevices.value(deviceType, IDevice::invalidId());
......
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
namespace ProjectExplorer { namespace ProjectExplorer {
class IDeviceFactory; class IDeviceFactory;
namespace Internal { namespace Internal {
class DeviceManagerPrivate; class DeviceManagerPrivate;
class DeviceSettingsWidget; class DeviceSettingsWidget;
...@@ -58,6 +59,8 @@ public: ...@@ -58,6 +59,8 @@ public:
int deviceCount() const; int deviceCount() const;
IDevice::ConstPtr deviceAt(int index) const; IDevice::ConstPtr deviceAt(int index) const;
IDevice::ConstPtr find(IDevice::Id id) const; IDevice::ConstPtr find(IDevice::Id id) const;
IDevice::ConstPtr findInactiveAutoDetectedDevice(const QString &type,
const QString &fingerprint);
IDevice::ConstPtr defaultDevice(const QString &deviceType) const; IDevice::ConstPtr defaultDevice(const QString &deviceType) const;
bool hasDevice(const QString &name) const; bool hasDevice(const QString &name) const;
IDevice::Id internalId(const IDevice::ConstPtr &device) const; IDevice::Id internalId(const IDevice::ConstPtr &device) const;
......
...@@ -183,8 +183,8 @@ void DeviceSettingsWidget::displayCurrent() ...@@ -183,8 +183,8 @@ void DeviceSettingsWidget::displayCurrent()
m_ui->defaultDeviceButton->setEnabled( m_ui->defaultDeviceButton->setEnabled(
m_deviceManager->defaultDevice(current->type()) != current); m_deviceManager->defaultDevice(current->type()) != current);
m_ui->osTypeValueLabel->setText(DeviceManager::displayNameForDeviceType(current->type())); m_ui->osTypeValueLabel->setText(DeviceManager::displayNameForDeviceType(current->type()));
m_ui->autoDetectionValueLabel->setText(current->isAutoDetected() ? tr("Yes") : tr("No")); m_ui->autoDetectionValueLabel->setText(current->isAutoDetected()
? tr("Yes (fingerprint is '%1')").arg(current->fingerprint()) : tr("No"));
m_nameValidator->setDisplayName(current->displayName()); m_nameValidator->setDisplayName(current->displayName());
m_ui->removeConfigButton->setEnabled(!current->isAutoDetected()); m_ui->removeConfigButton->setEnabled(!current->isAutoDetected());
fillInValues(); fillInValues();
......
...@@ -31,6 +31,8 @@ ...@@ -31,6 +31,8 @@
**************************************************************************/ **************************************************************************/
#include "idevice.h" #include "idevice.h"
#include <utils/qtcassert.h>
#include <QString> #include <QString>
/*! /*!
...@@ -74,6 +76,15 @@ ...@@ -74,6 +76,15 @@
* \brief Identify the device internally. * \brief Identify the device internally.
*/ */
/*!
* \fn QString ProjectExplorer::IDevice::fingerprint() const
* \brief Uniquely identifies an auto-detected device.
* The fingerprint can later be used to retrieve changes the user has done to the settings
* of an auto-detected device so they are not lost when the device goes away, e.g. because
* it has been disconnected.
* \sa ProjectExplorer::DeviceManager::findInactiveAutoDetectedDevice()
*/
/*! /*!
* \fn ProjectExplorer::IDevice::Id ProjectExplorer::IDevice::invalidId() * \fn ProjectExplorer::IDevice::Id ProjectExplorer::IDevice::invalidId()
* \brief A value that no device can ever have as its internal id. * \brief A value that no device can ever have as its internal id.
...@@ -103,6 +114,8 @@ namespace ProjectExplorer { ...@@ -103,6 +114,8 @@ namespace ProjectExplorer {
const char DisplayNameKey[] = "Name"; const char DisplayNameKey[] = "Name";
const char TypeKey[] = "OsType"; const char TypeKey[] = "OsType";
const char InternalIdKey[] = "InternalId"; const char InternalIdKey[] = "InternalId";
const char OriginKey[] = "Origin";
const char FingerprintKey[] = "FingerPrint";
namespace Internal { namespace Internal {
class IDevicePrivate class IDevicePrivate
...@@ -112,6 +125,7 @@ public: ...@@ -112,6 +125,7 @@ public:
QString type; QString type;
IDevice::Origin origin; IDevice::Origin origin;
IDevice::Id internalId; IDevice::Id internalId;
QString fingerprint;
}; };
} // namespace Internal } // namespace Internal
...@@ -119,10 +133,13 @@ IDevice::IDevice() : d(new Internal::IDevicePrivate) ...@@ -119,10 +133,13 @@ IDevice::IDevice() : d(new Internal::IDevicePrivate)
{ {
} }
IDevice::IDevice(const QString &type, Origin origin) : d(new Internal::IDevicePrivate) IDevice::IDevice(const QString &type, Origin origin, const QString fingerprint)
: d(new Internal::IDevicePrivate)
{ {
d->type = type; d->type = type;
d->origin = origin; d->origin = origin;
d->fingerprint = fingerprint;
QTC_CHECK(d->origin == ManuallyAdded || !d->fingerprint.isEmpty());
} }
IDevice::IDevice(const IDevice &other) : d(new Internal::IDevicePrivate) IDevice::IDevice(const IDevice &other) : d(new Internal::IDevicePrivate)
...@@ -155,6 +172,11 @@ bool IDevice::isAutoDetected() const ...@@ -155,6 +172,11 @@ bool IDevice::isAutoDetected() const
return d->origin == AutoDetected; return d->origin == AutoDetected;
} }
QString IDevice::fingerprint() const
{
return d->fingerprint;
}
IDevice::Id IDevice::internalId() const IDevice::Id IDevice::internalId() const
{ {
return d->internalId; return d->internalId;
...@@ -178,9 +200,11 @@ QString IDevice::typeFromMap(const QVariantMap &map) ...@@ -178,9 +200,11 @@ QString IDevice::typeFromMap(const QVariantMap &map)
void IDevice::fromMap(const QVariantMap &map) void IDevice::fromMap(const QVariantMap &map)
{ {
d->type = typeFromMap(map); d->type = typeFromMap(map);
d->origin = ManuallyAdded;
d->displayName = map.value(QLatin1String(DisplayNameKey)).toString(); d->displayName = map.value(QLatin1String(DisplayNameKey)).toString();
d->internalId = map.value(QLatin1String(InternalIdKey), invalidId()).toULongLong(); d->internalId = map.value(QLatin1String(InternalIdKey), invalidId()).toULongLong();
d->origin = static_cast<Origin>(map.value(QLatin1String(OriginKey), ManuallyAdded).toInt());
d->fingerprint = map.value(QLatin1String(FingerprintKey)).toString();
QTC_CHECK(d->origin == ManuallyAdded || !d->fingerprint.isEmpty());
} }
QVariantMap IDevice::toMap() const QVariantMap IDevice::toMap() const
...@@ -189,6 +213,8 @@ QVariantMap IDevice::toMap() const ...@@ -189,6 +213,8 @@ QVariantMap IDevice::toMap() const
map.insert(QLatin1String(DisplayNameKey), d->displayName); map.insert(QLatin1String(DisplayNameKey), d->displayName);
map.insert(QLatin1String(TypeKey), d->type); map.insert(QLatin1String(TypeKey), d->type);
map.insert(QLatin1String(InternalIdKey), d->internalId); map.insert(QLatin1String(InternalIdKey), d->internalId);
map.insert(QLatin1String(OriginKey), d->origin);
map.insert(QLatin1String(FingerprintKey), d->fingerprint);
return map; return map;
} }
......
...@@ -59,6 +59,7 @@ public: ...@@ -59,6 +59,7 @@ public:
QString type() const; QString type() const;
bool isAutoDetected() const; bool isAutoDetected() const;
QString fingerprint() const;
Id internalId() const; Id internalId() const;
virtual void fromMap(const QVariantMap &map); virtual void fromMap(const QVariantMap &map);
...@@ -70,7 +71,7 @@ public: ...@@ -70,7 +71,7 @@ public:
protected: protected:
IDevice(); IDevice();
IDevice(const QString &type, Origin origin); IDevice(const QString &type, Origin origin, const QString fingerprint = QString());
IDevice(const IDevice &other); IDevice(const IDevice &other);
virtual QVariantMap toMap() const; virtual QVariantMap toMap() const;
......
...@@ -79,9 +79,9 @@ LinuxDeviceConfiguration::~LinuxDeviceConfiguration() ...@@ -79,9 +79,9 @@ LinuxDeviceConfiguration::~LinuxDeviceConfiguration()
} }
LinuxDeviceConfiguration::Ptr LinuxDeviceConfiguration::create(const QString &name, LinuxDeviceConfiguration::Ptr LinuxDeviceConfiguration::create(const QString &name,
const QString &type, MachineType machineType, Origin origin) const QString &type, MachineType machineType, Origin origin, const QString &fingerprint)
{ {
return Ptr(new LinuxDeviceConfiguration(name, type, machineType, origin)); return Ptr(new LinuxDeviceConfiguration(name, type, machineType, origin, fingerprint));
} }
LinuxDeviceConfiguration::LinuxDeviceConfiguration() : d(new LinuxDeviceConfigurationPrivate) LinuxDeviceConfiguration::LinuxDeviceConfiguration() : d(new LinuxDeviceConfigurationPrivate)
...@@ -89,8 +89,8 @@ LinuxDeviceConfiguration::LinuxDeviceConfiguration() : d(new LinuxDeviceConfigur ...@@ -89,8 +89,8 @@ LinuxDeviceConfiguration::LinuxDeviceConfiguration() : d(new LinuxDeviceConfigur
} }
LinuxDeviceConfiguration::LinuxDeviceConfiguration(const QString &name, const QString &type, LinuxDeviceConfiguration::LinuxDeviceConfiguration(const QString &name, const QString &type,
MachineType machineType, Origin origin) MachineType machineType, Origin origin, const QString &fingerprint)
: IDevice(type, origin), d(new LinuxDeviceConfigurationPrivate) : IDevice(type, origin, fingerprint), d(new LinuxDeviceConfigurationPrivate)
{ {
setDisplayName(name); setDisplayName(name);
d->machineType = machineType; d->machineType = machineType;
......
...@@ -68,14 +68,14 @@ public: ...@@ -68,14 +68,14 @@ public:
static Ptr create(); static Ptr create();
static Ptr create(const QString &name, const QString &type, MachineType machineType, static Ptr create(const QString &name, const QString &type, MachineType machineType,
Origin origin = ManuallyAdded); Origin origin = ManuallyAdded, const QString &fingerprint = QString());
void fromMap(const QVariantMap &map); void fromMap(const QVariantMap &map);
ProjectExplorer::IDevice::Ptr clone() const; ProjectExplorer::IDevice::Ptr clone() const;
private: private:
LinuxDeviceConfiguration(); LinuxDeviceConfiguration();
LinuxDeviceConfiguration(const QString &name, const QString &type, MachineType machineType, LinuxDeviceConfiguration(const QString &name, const QString &type, MachineType machineType,
Origin origin); Origin origin, const QString &fingerprint);
LinuxDeviceConfiguration(const LinuxDeviceConfiguration &other); LinuxDeviceConfiguration(const LinuxDeviceConfiguration &other);
LinuxDeviceConfiguration &operator=(const LinuxDeviceConfiguration &); LinuxDeviceConfiguration &operator=(const LinuxDeviceConfiguration &);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment