1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of Qt Creator.
7 **
8 ** Commercial License Usage
9 ** Licensees holding valid commercial Qt licenses may use this file in
10 ** accordance with the commercial license agreement provided with the
11 ** Software or, alternatively, in accordance with the terms contained in
12 ** a written agreement between you and The Qt Company. For licensing terms
13 ** and conditions see https://www.qt.io/terms-conditions. For further
14 ** information use the contact form at https://www.qt.io/contact-us.
15 **
16 ** GNU General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU
18 ** General Public License version 3 as published by the Free Software
19 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
20 ** included in the packaging of this file. Please review the following
21 ** information to ensure the GNU General Public License requirements will
22 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
23 **
24 ****************************************************************************/
25 
26 #include "idevice.h"
27 
28 #include "devicemanager.h"
29 #include "deviceprocesslist.h"
30 #include "idevicefactory.h"
31 
32 #include "../kit.h"
33 #include "../kitinformation.h"
34 #include "../runconfiguration.h"
35 
36 #include <ssh/sshconnection.h>
37 #include <utils/displayname.h>
38 #include <utils/icon.h>
39 #include <utils/portlist.h>
40 #include <utils/qtcassert.h>
41 #include <utils/url.h>
42 
43 #include <QCoreApplication>
44 #include <QStandardPaths>
45 
46 #include <QDateTime>
47 #include <QString>
48 #include <QUuid>
49 
50 /*!
51  * \class ProjectExplorer::IDevice::DeviceAction
52  * \brief The DeviceAction class describes an action that can be run on a device.
53  *
54  * The description consists of a human-readable string that will be displayed
55  * on a button which, when clicked, executes a functor, and the functor itself.
56  * This is typically some sort of dialog or wizard, so \a parent widget is provided.
57  */
58 
59 /*!
60  * \class ProjectExplorer::IDevice
61  * \brief The IDevice class is the base class for all devices.
62  *
63  * The term \e device refers to some host to which files can be deployed or on
64  * which an application can run, for example.
65  * In the typical case, this would be some sort of embedded computer connected in some way to
66  * the PC on which \QC runs. This class itself does not specify a connection
67  * protocol; that
68  * kind of detail is to be added by subclasses.
69  * Devices are managed by a \c DeviceManager.
70  * \sa ProjectExplorer::DeviceManager
71  */
72 
73 /*!
74  * \fn Utils::Id ProjectExplorer::IDevice::invalidId()
75  * A value that no device can ever have as its internal id.
76  */
77 
78 /*!
79  * \fn QString ProjectExplorer::IDevice::displayType() const
80  * Prints a representation of the device's type suitable for displaying to a
81  * user.
82  */
83 
84 /*!
85  * \fn ProjectExplorer::IDeviceWidget *ProjectExplorer::IDevice::createWidget()
86  * Creates a widget that displays device information not part of the IDevice base class.
87  *        The widget can also be used to let the user change these attributes.
88  */
89 
90 /*!
91  * \fn void ProjectExplorer::IDevice::addDeviceAction(const DeviceAction &deviceAction)
92  * Adds an actions that can be run on this device.
93  * These actions will be available in the \gui Devices options page.
94  */
95 
96 /*!
97  * \fn ProjectExplorer::IDevice::Ptr ProjectExplorer::IDevice::clone() const
98  * Creates an identical copy of a device object.
99  */
100 
101 using namespace Utils;
102 
newId()103 static Utils::Id newId()
104 {
105     return Utils::Id::fromString(QUuid::createUuid().toString());
106 }
107 
108 namespace ProjectExplorer {
109 
110 const char DisplayNameKey[] = "Name";
111 const char TypeKey[] = "OsType";
112 const char IdKey[] = "InternalId";
113 const char OriginKey[] = "Origin";
114 const char MachineTypeKey[] = "Type";
115 const char VersionKey[] = "Version";
116 const char ExtraDataKey[] = "ExtraData";
117 
118 // Connection
119 const char HostKey[] = "Host";
120 const char SshPortKey[] = "SshPort";
121 const char PortsSpecKey[] = "FreePortsSpec";
122 const char UserNameKey[] = "Uname";
123 const char AuthKey[] = "Authentication";
124 const char KeyFileKey[] = "KeyFile";
125 const char TimeoutKey[] = "Timeout";
126 const char HostKeyCheckingKey[] = "HostKeyChecking";
127 
128 const char DebugServerKey[] = "DebugServerKey";
129 const char QmlRuntimeKey[] = "QmlsceneKey";
130 
131 using AuthType = QSsh::SshConnectionParameters::AuthenticationType;
132 const AuthType DefaultAuthType = QSsh::SshConnectionParameters::AuthenticationTypeAll;
133 const IDevice::MachineType DefaultMachineType = IDevice::Hardware;
134 
135 const int DefaultTimeout = 10;
136 
137 namespace Internal {
138 class IDevicePrivate
139 {
140 public:
141     IDevicePrivate() = default;
142 
143     Utils::DisplayName displayName;
144     QString displayType;
145     Utils::Id type;
146     IDevice::Origin origin = IDevice::AutoDetected;
147     Utils::Id id;
148     IDevice::DeviceState deviceState = IDevice::DeviceStateUnknown;
149     IDevice::MachineType machineType = IDevice::Hardware;
150     Utils::OsType osType = Utils::OsTypeOther;
151     int version = 0; // This is used by devices that have been added by the SDK.
152 
153     QSsh::SshConnectionParameters sshParameters;
154     Utils::PortList freePorts;
155     QString debugServerPath;
156     QString qmlRunCommand;
157     bool emptyCommandAllowed = false;
158 
159     QList<Utils::Icon> deviceIcons;
160     QList<IDevice::DeviceAction> deviceActions;
161     QVariantMap extraData;
162     IDevice::OpenTerminal openTerminal;
163 };
164 } // namespace Internal
165 
DeviceTester(QObject * parent)166 DeviceTester::DeviceTester(QObject *parent) : QObject(parent) { }
167 
IDevice()168 IDevice::IDevice() : d(new Internal::IDevicePrivate)
169 {
170 }
171 
setOpenTerminal(const IDevice::OpenTerminal & openTerminal)172 void IDevice::setOpenTerminal(const IDevice::OpenTerminal &openTerminal)
173 {
174     d->openTerminal = openTerminal;
175 }
176 
setupId(Origin origin,Utils::Id id)177 void IDevice::setupId(Origin origin, Utils::Id id)
178 {
179     d->origin = origin;
180     QTC_CHECK(origin == ManuallyAdded || id.isValid());
181     d->id = id.isValid() ? id : newId();
182 }
183 
canOpenTerminal() const184 bool IDevice::canOpenTerminal() const
185 {
186     return bool(d->openTerminal);
187 }
188 
openTerminal(const Utils::Environment & env,const QString & workingDir) const189 void IDevice::openTerminal(const Utils::Environment &env, const QString &workingDir) const
190 {
191     QTC_ASSERT(canOpenTerminal(), return);
192     d->openTerminal(env, workingDir);
193 }
194 
isEmptyCommandAllowed() const195 bool IDevice::isEmptyCommandAllowed() const
196 {
197     return d->emptyCommandAllowed;
198 }
199 
setAllowEmptyCommand(bool allow)200 void IDevice::setAllowEmptyCommand(bool allow)
201 {
202     d->emptyCommandAllowed = allow;
203 }
204 
isAnyUnixDevice() const205 bool IDevice::isAnyUnixDevice() const
206 {
207     return d->osType == OsTypeLinux || d->osType == OsTypeMac || d->osType == OsTypeOtherUnix;
208 }
209 
mapToGlobalPath(const FilePath & pathOnDevice) const210 FilePath IDevice::mapToGlobalPath(const FilePath &pathOnDevice) const
211 {
212     return pathOnDevice;
213 }
214 
handlesFile(const FilePath & filePath) const215 bool IDevice::handlesFile(const FilePath &filePath) const
216 {
217     Q_UNUSED(filePath);
218     return false;
219 }
220 
isExecutableFile(const FilePath & filePath) const221 bool IDevice::isExecutableFile(const FilePath &filePath) const
222 {
223     Q_UNUSED(filePath);
224     QTC_CHECK(false);
225     return false;
226 }
227 
isReadableFile(const FilePath & filePath) const228 bool IDevice::isReadableFile(const FilePath &filePath) const
229 {
230     Q_UNUSED(filePath);
231     QTC_CHECK(false);
232     return false;
233 }
234 
isWritableFile(const Utils::FilePath & filePath) const235 bool IDevice::isWritableFile(const Utils::FilePath &filePath) const
236 {
237     Q_UNUSED(filePath);
238     QTC_CHECK(false);
239     return false;
240 }
241 
isReadableDirectory(const FilePath & filePath) const242 bool IDevice::isReadableDirectory(const FilePath &filePath) const
243 {
244     Q_UNUSED(filePath);
245     QTC_CHECK(false);
246     return false;
247 }
248 
isWritableDirectory(const FilePath & filePath) const249 bool IDevice::isWritableDirectory(const FilePath &filePath) const
250 {
251     Q_UNUSED(filePath);
252     QTC_CHECK(false);
253     return false;
254 }
255 
isFile(const FilePath & filePath) const256 bool IDevice::isFile(const FilePath &filePath) const
257 {
258     Q_UNUSED(filePath);
259     QTC_CHECK(false);
260     return false;
261 }
262 
isDirectory(const FilePath & filePath) const263 bool IDevice::isDirectory(const FilePath &filePath) const
264 {
265     Q_UNUSED(filePath);
266     QTC_CHECK(false);
267     return false;
268 }
269 
ensureWritableDirectory(const FilePath & filePath) const270 bool IDevice::ensureWritableDirectory(const FilePath &filePath) const
271 {
272     if (isWritableDirectory(filePath))
273         return true;
274     return createDirectory(filePath);
275 }
276 
ensureExistingFile(const FilePath & filePath) const277 bool IDevice::ensureExistingFile(const FilePath &filePath) const
278 {
279     Q_UNUSED(filePath);
280     QTC_CHECK(false);
281     return false;
282 }
283 
createDirectory(const FilePath & filePath) const284 bool IDevice::createDirectory(const FilePath &filePath) const
285 {
286     Q_UNUSED(filePath);
287     QTC_CHECK(false);
288     return false;
289 }
290 
exists(const FilePath & filePath) const291 bool IDevice::exists(const FilePath &filePath) const
292 {
293     Q_UNUSED(filePath);
294     QTC_CHECK(false);
295     return false;
296 }
297 
removeFile(const FilePath & filePath) const298 bool IDevice::removeFile(const FilePath &filePath) const
299 {
300     Q_UNUSED(filePath);
301     QTC_CHECK(false);
302     return false;
303 }
304 
removeRecursively(const FilePath & filePath) const305 bool IDevice::removeRecursively(const FilePath &filePath) const
306 {
307     Q_UNUSED(filePath);
308     QTC_CHECK(false);
309     return false;
310 }
311 
copyFile(const FilePath & filePath,const FilePath & target) const312 bool IDevice::copyFile(const FilePath &filePath, const FilePath &target) const
313 {
314     Q_UNUSED(filePath);
315     Q_UNUSED(target);
316     QTC_CHECK(false);
317     return false;
318 }
319 
renameFile(const FilePath & filePath,const FilePath & target) const320 bool IDevice::renameFile(const FilePath &filePath, const FilePath &target) const
321 {
322     Q_UNUSED(filePath);
323     Q_UNUSED(target);
324     QTC_CHECK(false);
325     return false;
326 }
327 
searchExecutableInPath(const QString & fileName) const328 FilePath IDevice::searchExecutableInPath(const QString &fileName) const
329 {
330     FilePaths paths;
331     for (const FilePath &path : systemEnvironment().path())
332         paths.append(mapToGlobalPath(path));
333     return searchExecutable(fileName, paths);
334 }
335 
searchExecutable(const QString & fileName,const FilePaths & dirs) const336 FilePath IDevice::searchExecutable(const QString &fileName, const FilePaths &dirs) const
337 {
338     for (FilePath dir : dirs) {
339         if (!handlesFile(dir)) // Allow device-local dirs to be used.
340             dir = mapToGlobalPath(dir);
341         QTC_CHECK(handlesFile(dir));
342         const FilePath candidate = dir / fileName;
343         if (isExecutableFile(candidate))
344             return candidate;
345     }
346 
347     return {};
348 }
349 
symLinkTarget(const FilePath & filePath) const350 FilePath IDevice::symLinkTarget(const FilePath &filePath) const
351 {
352     Q_UNUSED(filePath);
353     QTC_CHECK(false);
354     return {};
355 }
356 
directoryEntries(const FilePath & filePath,const QStringList & nameFilters,QDir::Filters filters,QDir::SortFlags sort) const357 QList<FilePath> IDevice::directoryEntries(const FilePath &filePath,
358                                           const QStringList &nameFilters,
359                                           QDir::Filters filters,
360                                           QDir::SortFlags sort) const
361 {
362     Q_UNUSED(filePath);
363     Q_UNUSED(nameFilters);
364     Q_UNUSED(filters);
365     Q_UNUSED(sort);
366     QTC_CHECK(false);
367     return {};
368 }
369 
fileContents(const FilePath & filePath,qint64 limit,qint64 offset) const370 QByteArray IDevice::fileContents(const FilePath &filePath, qint64 limit, qint64 offset) const
371 {
372     Q_UNUSED(filePath);
373     Q_UNUSED(limit);
374     Q_UNUSED(offset);
375     QTC_CHECK(false);
376     return {};
377 }
378 
writeFileContents(const FilePath & filePath,const QByteArray & data) const379 bool IDevice::writeFileContents(const FilePath &filePath, const QByteArray &data) const
380 {
381     Q_UNUSED(filePath);
382     Q_UNUSED(data);
383     QTC_CHECK(false);
384     return {};
385 }
386 
lastModified(const FilePath & filePath) const387 QDateTime IDevice::lastModified(const FilePath &filePath) const
388 {
389     Q_UNUSED(filePath);
390     return {};
391 }
392 
permissions(const Utils::FilePath & filePath) const393 QFileDevice::Permissions IDevice::permissions(const Utils::FilePath &filePath) const
394 {
395     Q_UNUSED(filePath);
396     QTC_CHECK(false);
397     return {};
398 }
399 
runProcess(QtcProcess & process) const400 void IDevice::runProcess(QtcProcess &process) const
401 {
402     Q_UNUSED(process);
403     QTC_CHECK(false);
404 }
405 
systemEnvironment() const406 Environment IDevice::systemEnvironment() const
407 {
408     QTC_CHECK(false);
409     return Environment::systemEnvironment();
410 }
411 
412 IDevice::~IDevice() = default;
413 
414 /*!
415     Specifies a free-text name for the device to be displayed in GUI elements.
416 */
417 
displayName() const418 QString IDevice::displayName() const
419 {
420     return d->displayName.value();
421 }
422 
setDisplayName(const QString & name)423 void IDevice::setDisplayName(const QString &name)
424 {
425     d->displayName.setValue(name);
426 }
427 
setDefaultDisplayName(const QString & name)428 void IDevice::setDefaultDisplayName(const QString &name)
429 {
430     d->displayName.setDefaultValue(name);
431 }
432 
displayType() const433 QString IDevice::displayType() const
434 {
435     return d->displayType;
436 }
437 
setDisplayType(const QString & type)438 void IDevice::setDisplayType(const QString &type)
439 {
440     d->displayType = type;
441 }
442 
setOsType(Utils::OsType osType)443 void IDevice::setOsType(Utils::OsType osType)
444 {
445     d->osType = osType;
446 }
447 
deviceInformation() const448 IDevice::DeviceInfo IDevice::deviceInformation() const
449 {
450     const QString key = QCoreApplication::translate("ProjectExplorer::IDevice", "Device");
451     return DeviceInfo() << IDevice::DeviceInfoItem(key, deviceStateToString());
452 }
453 
454 /*!
455     Identifies the type of the device. Devices with the same type share certain
456     abilities. This attribute is immutable.
457 
458     \sa ProjectExplorer::IDeviceFactory
459  */
460 
type() const461 Utils::Id IDevice::type() const
462 {
463     return d->type;
464 }
465 
setType(Utils::Id type)466 void IDevice::setType(Utils::Id type)
467 {
468     d->type = type;
469 }
470 
471 /*!
472     Returns \c true if the device has been added via some sort of auto-detection
473     mechanism. Devices that are not auto-detected can only ever be created
474     interactively from the \gui Options page. This attribute is immutable.
475 
476     \sa DeviceSettingsWidget
477 */
478 
isAutoDetected() const479 bool IDevice::isAutoDetected() const
480 {
481     return d->origin == AutoDetected;
482 }
483 
484 /*!
485     Identifies the device. If an id is given when constructing a device then
486     this id is used. Otherwise, a UUID is generated and used to identity the
487     device.
488 
489     \sa ProjectExplorer::DeviceManager::findInactiveAutoDetectedDevice()
490 */
491 
id() const492 Utils::Id IDevice::id() const
493 {
494     return d->id;
495 }
496 
497 /*!
498     Tests whether a device can be compatible with the given kit. The default
499     implementation will match the device type specified in the kit against
500     the device's own type.
501 */
isCompatibleWith(const Kit * k) const502 bool IDevice::isCompatibleWith(const Kit *k) const
503 {
504     return DeviceTypeKitAspect::deviceTypeId(k) == type();
505 }
506 
addDeviceAction(const DeviceAction & deviceAction)507 void IDevice::addDeviceAction(const DeviceAction &deviceAction)
508 {
509     d->deviceActions.append(deviceAction);
510 }
511 
deviceActions() const512 const QList<IDevice::DeviceAction> IDevice::deviceActions() const
513 {
514     return d->deviceActions;
515 }
516 
portsGatheringMethod() const517 PortsGatheringMethod::Ptr IDevice::portsGatheringMethod() const
518 {
519     return PortsGatheringMethod::Ptr();
520 }
521 
createProcessListModel(QObject * parent) const522 DeviceProcessList *IDevice::createProcessListModel(QObject *parent) const
523 {
524     Q_UNUSED(parent)
525     QTC_ASSERT(false, qDebug("This should not have been called..."); return nullptr);
526     return nullptr;
527 }
528 
createDeviceTester() const529 DeviceTester *IDevice::createDeviceTester() const
530 {
531     QTC_ASSERT(false, qDebug("This should not have been called..."));
532     return nullptr;
533 }
534 
osType() const535 Utils::OsType IDevice::osType() const
536 {
537     return d->osType;
538 }
539 
createProcess(QObject *) const540 DeviceProcess *IDevice::createProcess(QObject * /* parent */) const
541 {
542     QTC_CHECK(false);
543     return nullptr;
544 }
545 
environmentFetcher() const546 DeviceEnvironmentFetcher::Ptr IDevice::environmentFetcher() const
547 {
548     return DeviceEnvironmentFetcher::Ptr();
549 }
550 
deviceState() const551 IDevice::DeviceState IDevice::deviceState() const
552 {
553     return d->deviceState;
554 }
555 
setDeviceState(const IDevice::DeviceState state)556 void IDevice::setDeviceState(const IDevice::DeviceState state)
557 {
558     if (d->deviceState == state)
559         return;
560     d->deviceState = state;
561 }
562 
typeFromMap(const QVariantMap & map)563 Utils::Id IDevice::typeFromMap(const QVariantMap &map)
564 {
565     return Utils::Id::fromSetting(map.value(QLatin1String(TypeKey)));
566 }
567 
idFromMap(const QVariantMap & map)568 Utils::Id IDevice::idFromMap(const QVariantMap &map)
569 {
570     return Utils::Id::fromSetting(map.value(QLatin1String(IdKey)));
571 }
572 
573 /*!
574     Restores a device object from a serialized state as written by toMap().
575     If subclasses override this to restore additional state, they must call the
576     base class implementation.
577 */
578 
fromMap(const QVariantMap & map)579 void IDevice::fromMap(const QVariantMap &map)
580 {
581     d->type = typeFromMap(map);
582     d->displayName.fromMap(map, DisplayNameKey);
583     d->id = Utils::Id::fromSetting(map.value(QLatin1String(IdKey)));
584     if (!d->id.isValid())
585         d->id = newId();
586     d->origin = static_cast<Origin>(map.value(QLatin1String(OriginKey), ManuallyAdded).toInt());
587 
588     d->sshParameters.setHost(map.value(QLatin1String(HostKey)).toString());
589     d->sshParameters.setPort(map.value(QLatin1String(SshPortKey), 22).toInt());
590     d->sshParameters.setUserName(map.value(QLatin1String(UserNameKey)).toString());
591 
592     // Pre-4.9, the authentication enum used to have more values
593     const int storedAuthType = map.value(QLatin1String(AuthKey), DefaultAuthType).toInt();
594     const bool outdatedAuthType = storedAuthType
595             > QSsh::SshConnectionParameters::AuthenticationTypeSpecificKey;
596     d->sshParameters.authenticationType = outdatedAuthType
597             ? QSsh::SshConnectionParameters::AuthenticationTypeAll
598             : static_cast<AuthType>(storedAuthType);
599 
600     d->sshParameters.privateKeyFile = map.value(QLatin1String(KeyFileKey), defaultPrivateKeyFilePath()).toString();
601     d->sshParameters.timeout = map.value(QLatin1String(TimeoutKey), DefaultTimeout).toInt();
602     d->sshParameters.hostKeyCheckingMode = static_cast<QSsh::SshHostKeyCheckingMode>
603             (map.value(QLatin1String(HostKeyCheckingKey), QSsh::SshHostKeyCheckingNone).toInt());
604 
605     QString portsSpec = map.value(PortsSpecKey).toString();
606     if (portsSpec.isEmpty())
607         portsSpec = "10000-10100";
608     d->freePorts = Utils::PortList::fromString(portsSpec);
609     d->machineType = static_cast<MachineType>(map.value(QLatin1String(MachineTypeKey), DefaultMachineType).toInt());
610     d->version = map.value(QLatin1String(VersionKey), 0).toInt();
611 
612     d->debugServerPath = map.value(QLatin1String(DebugServerKey)).toString();
613     d->qmlRunCommand = map.value(QLatin1String(QmlRuntimeKey)).toString();
614     d->extraData = map.value(ExtraDataKey).toMap();
615 }
616 
617 /*!
618     Serializes a device object, for example to save it to a file.
619     If subclasses override this function to save additional state, they must
620     call the base class implementation.
621 */
622 
toMap() const623 QVariantMap IDevice::toMap() const
624 {
625     QVariantMap map;
626     d->displayName.toMap(map, DisplayNameKey);
627     map.insert(QLatin1String(TypeKey), d->type.toString());
628     map.insert(QLatin1String(IdKey), d->id.toSetting());
629     map.insert(QLatin1String(OriginKey), d->origin);
630 
631     map.insert(QLatin1String(MachineTypeKey), d->machineType);
632     map.insert(QLatin1String(HostKey), d->sshParameters.host());
633     map.insert(QLatin1String(SshPortKey), d->sshParameters.port());
634     map.insert(QLatin1String(UserNameKey), d->sshParameters.userName());
635     map.insert(QLatin1String(AuthKey), d->sshParameters.authenticationType);
636     map.insert(QLatin1String(KeyFileKey), d->sshParameters.privateKeyFile);
637     map.insert(QLatin1String(TimeoutKey), d->sshParameters.timeout);
638     map.insert(QLatin1String(HostKeyCheckingKey), d->sshParameters.hostKeyCheckingMode);
639 
640     map.insert(QLatin1String(PortsSpecKey), d->freePorts.toString());
641     map.insert(QLatin1String(VersionKey), d->version);
642 
643     map.insert(QLatin1String(DebugServerKey), d->debugServerPath);
644     map.insert(QLatin1String(QmlRuntimeKey), d->qmlRunCommand);
645     map.insert(ExtraDataKey, d->extraData);
646 
647     return map;
648 }
649 
clone() const650 IDevice::Ptr IDevice::clone() const
651 {
652     IDeviceFactory *factory = IDeviceFactory::find(d->type);
653     QTC_ASSERT(factory, return {});
654     IDevice::Ptr device = factory->construct();
655     QTC_ASSERT(device, return {});
656     device->d->deviceState = d->deviceState;
657     device->d->deviceActions = d->deviceActions;
658     device->d->deviceIcons = d->deviceIcons;
659     // Os type is only set in the constructor, always to the same value.
660     // But make sure we notice if that changes in the future (which it shouldn't).
661     QTC_CHECK(device->d->osType == d->osType);
662     device->d->osType = d->osType;
663     device->fromMap(toMap());
664     return device;
665 }
666 
deviceStateToString() const667 QString IDevice::deviceStateToString() const
668 {
669     const char context[] = "ProjectExplorer::IDevice";
670     switch (d->deviceState) {
671     case IDevice::DeviceReadyToUse: return QCoreApplication::translate(context, "Ready to use");
672     case IDevice::DeviceConnected: return QCoreApplication::translate(context, "Connected");
673     case IDevice::DeviceDisconnected: return QCoreApplication::translate(context, "Disconnected");
674     case IDevice::DeviceStateUnknown: return QCoreApplication::translate(context, "Unknown");
675     default: return QCoreApplication::translate(context, "Invalid");
676     }
677 }
678 
sshParameters() const679 QSsh::SshConnectionParameters IDevice::sshParameters() const
680 {
681     return d->sshParameters;
682 }
683 
setSshParameters(const QSsh::SshConnectionParameters & sshParameters)684 void IDevice::setSshParameters(const QSsh::SshConnectionParameters &sshParameters)
685 {
686     d->sshParameters = sshParameters;
687 }
688 
toolControlChannel(const ControlChannelHint &) const689 QUrl IDevice::toolControlChannel(const ControlChannelHint &) const
690 {
691     QUrl url;
692     url.setScheme(Utils::urlTcpScheme());
693     url.setHost(d->sshParameters.host());
694     return url;
695 }
696 
setFreePorts(const Utils::PortList & freePorts)697 void IDevice::setFreePorts(const Utils::PortList &freePorts)
698 {
699     d->freePorts = freePorts;
700 }
701 
freePorts() const702 Utils::PortList IDevice::freePorts() const
703 {
704     return d->freePorts;
705 }
706 
machineType() const707 IDevice::MachineType IDevice::machineType() const
708 {
709     return d->machineType;
710 }
711 
setMachineType(MachineType machineType)712 void IDevice::setMachineType(MachineType machineType)
713 {
714     d->machineType = machineType;
715 }
716 
debugServerPath() const717 QString IDevice::debugServerPath() const
718 {
719     return d->debugServerPath;
720 }
721 
setDebugServerPath(const QString & path)722 void IDevice::setDebugServerPath(const QString &path)
723 {
724     d->debugServerPath = path;
725 }
726 
qmlRunCommand() const727 QString IDevice::qmlRunCommand() const
728 {
729     return d->qmlRunCommand;
730 }
731 
setQmlRunCommand(const QString & path)732 void IDevice::setQmlRunCommand(const QString &path)
733 {
734     d->qmlRunCommand = path;
735 }
736 
setExtraData(Utils::Id kind,const QVariant & data)737 void IDevice::setExtraData(Utils::Id kind, const QVariant &data)
738 {
739     d->extraData.insert(kind.toString(), data);
740 }
741 
extraData(Utils::Id kind) const742 QVariant IDevice::extraData(Utils::Id kind) const
743 {
744     return d->extraData.value(kind.toString());
745 }
746 
version() const747 int IDevice::version() const
748 {
749     return d->version;
750 }
751 
defaultPrivateKeyFilePath()752 QString IDevice::defaultPrivateKeyFilePath()
753 {
754     return QStandardPaths::writableLocation(QStandardPaths::HomeLocation)
755         + QLatin1String("/.ssh/id_rsa");
756 }
757 
defaultPublicKeyFilePath()758 QString IDevice::defaultPublicKeyFilePath()
759 {
760     return defaultPrivateKeyFilePath() + QLatin1String(".pub");
761 }
762 
setDebuggerCommand(const QString & cmd)763 void DeviceProcessSignalOperation::setDebuggerCommand(const QString &cmd)
764 {
765     m_debuggerCommand = cmd;
766 }
767 
768 DeviceProcessSignalOperation::DeviceProcessSignalOperation() = default;
769 
770 DeviceEnvironmentFetcher::DeviceEnvironmentFetcher() = default;
771 
772 } // namespace ProjectExplorer
773