aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/boot2qt
diff options
context:
space:
mode:
authorhjk <hjk@qt.io>2019-06-04 14:22:35 +0200
committerhjk <hjk@qt.io>2019-06-07 06:22:45 +0000
commit5942b82490985008af9ac10b3b2ed0e060d5dba5 (patch)
treeebda5bd21b93ef1d8b8f1195f5896b388f52b8d8 /src/plugins/boot2qt
parent0c74f6cc21ae7fccfd844efdd9365e72fa507a23 (diff)
Add support for Boot2Qt
A plugin for communication with Boot2Qt devices. Task-number: QTCREATORBUG-21808 Change-Id: I61f4a9451c2fe8ff4e1108e07db2e72e8c613c43 Reviewed-by: Kari Oikarinen <kari.oikarinen@qt.io> Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
Diffstat (limited to 'src/plugins/boot2qt')
-rw-r--r--src/plugins/boot2qt/Boot2Qt.json.in23
-rw-r--r--src/plugins/boot2qt/boot2qt.pro49
-rw-r--r--src/plugins/boot2qt/boot2qt.qbs72
-rw-r--r--src/plugins/boot2qt/boot2qt_dependencies.pri8
-rw-r--r--src/plugins/boot2qt/device-detection/device-detection.pri13
-rw-r--r--src/plugins/boot2qt/device-detection/devicedetector.cpp149
-rw-r--r--src/plugins/boot2qt/device-detection/devicedetector.h60
-rw-r--r--src/plugins/boot2qt/device-detection/hostmessages.cpp147
-rw-r--r--src/plugins/boot2qt/device-detection/hostmessages.h65
-rw-r--r--src/plugins/boot2qt/device-detection/qdbdevicetracker.cpp87
-rw-r--r--src/plugins/boot2qt/device-detection/qdbdevicetracker.h63
-rw-r--r--src/plugins/boot2qt/device-detection/qdbmessagetracker.cpp88
-rw-r--r--src/plugins/boot2qt/device-detection/qdbmessagetracker.h56
-rw-r--r--src/plugins/boot2qt/device-detection/qdbwatcher.cpp165
-rw-r--r--src/plugins/boot2qt/device-detection/qdbwatcher.h76
-rw-r--r--src/plugins/boot2qt/deviceapplicationobserver.cpp123
-rw-r--r--src/plugins/boot2qt/deviceapplicationobserver.h71
-rw-r--r--src/plugins/boot2qt/images/qdbdevice.pngbin0 -> 378 bytes
-rw-r--r--src/plugins/boot2qt/images/qdbdevice@2x.pngbin0 -> 706 bytes
-rw-r--r--src/plugins/boot2qt/images/qdbdevicesmall.pngbin0 -> 260 bytes
-rw-r--r--src/plugins/boot2qt/images/qdbdevicesmall@2x.pngbin0 -> 442 bytes
-rw-r--r--src/plugins/boot2qt/qdb.qrc8
-rw-r--r--src/plugins/boot2qt/qdb_global.h34
-rw-r--r--src/plugins/boot2qt/qdbconstants.h47
-rw-r--r--src/plugins/boot2qt/qdbdeployconfigurationfactory.cpp60
-rw-r--r--src/plugins/boot2qt/qdbdeployconfigurationfactory.h40
-rw-r--r--src/plugins/boot2qt/qdbdeploystepfactory.cpp56
-rw-r--r--src/plugins/boot2qt/qdbdeploystepfactory.h46
-rw-r--r--src/plugins/boot2qt/qdbdevice.cpp149
-rw-r--r--src/plugins/boot2qt/qdbdevice.h76
-rw-r--r--src/plugins/boot2qt/qdbdevicedebugsupport.cpp223
-rw-r--r--src/plugins/boot2qt/qdbdevicedebugsupport.h87
-rw-r--r--src/plugins/boot2qt/qdbdeviceprocess.cpp52
-rw-r--r--src/plugins/boot2qt/qdbdeviceprocess.h47
-rw-r--r--src/plugins/boot2qt/qdbdevicewizard.cpp113
-rw-r--r--src/plugins/boot2qt/qdbdevicewizard.h55
-rw-r--r--src/plugins/boot2qt/qdbdevicewizardsettingspage.ui73
-rw-r--r--src/plugins/boot2qt/qdbmakedefaultappservice.cpp126
-rw-r--r--src/plugins/boot2qt/qdbmakedefaultappservice.h61
-rw-r--r--src/plugins/boot2qt/qdbmakedefaultappstep.cpp158
-rw-r--r--src/plugins/boot2qt/qdbmakedefaultappstep.h61
-rw-r--r--src/plugins/boot2qt/qdbplugin.cpp240
-rw-r--r--src/plugins/boot2qt/qdbplugin.h51
-rw-r--r--src/plugins/boot2qt/qdbqtversion.cpp47
-rw-r--r--src/plugins/boot2qt/qdbqtversion.h44
-rw-r--r--src/plugins/boot2qt/qdbrunconfiguration.cpp141
-rw-r--r--src/plugins/boot2qt/qdbrunconfiguration.h62
-rw-r--r--src/plugins/boot2qt/qdbstopapplicationservice.cpp123
-rw-r--r--src/plugins/boot2qt/qdbstopapplicationservice.h61
-rw-r--r--src/plugins/boot2qt/qdbstopapplicationstep.cpp73
-rw-r--r--src/plugins/boot2qt/qdbstopapplicationstep.h54
-rw-r--r--src/plugins/boot2qt/qdbutils.cpp138
-rw-r--r--src/plugins/boot2qt/qdbutils.h56
53 files changed, 3977 insertions, 0 deletions
diff --git a/src/plugins/boot2qt/Boot2Qt.json.in b/src/plugins/boot2qt/Boot2Qt.json.in
new file mode 100644
index 0000000000..82fe1b0008
--- /dev/null
+++ b/src/plugins/boot2qt/Boot2Qt.json.in
@@ -0,0 +1,23 @@
+{
+ \"Name\" : \"Boot2Qt\",
+ \"Version\" : \"$$QTCREATOR_VERSION\",
+ \"CompatVersion\" : \"$$QTCREATOR_COMPAT_VERSION\",
+ \"Revision\" : \"$$QTC_PLUGIN_REVISION\",
+ \"DisabledByDefault\" : true,
+ \"Experimental\" : true,
+ \"Vendor\" : \"The Qt Company Ltd\",
+ \"Copyright\" : \"(C) $$QTCREATOR_COPYRIGHT_YEAR The Qt Company Ltd\",
+ \"License\" : [ \"Commercial Usage\",
+ \"\",
+ \"Licensees holding valid Qt Commercial licenses may use this plugin in accordance with the Qt Commercial License Agreement provided with the Software or, alternatively, in accordance with the terms contained in a written agreement between you and The Qt Company.\",
+ \"\",
+ \"GNU General Public License Usage\",
+ \"\",
+ \"Alternatively, this plugin may be used under the terms of the GNU General Public License version 3 as published by the Free Software Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT included in the packaging of this plugin. Please review the following information to ensure the GNU General Public License requirements will be met: https://www.gnu.org/licenses/gpl-3.0.html.\"
+],
+
+ \"Category\" : \"Device Support\",
+ \"Description\" : \"Support for the Boot2Qt Device access using the Qt Debug Bridge.\",
+ \"Url\" : \"http://www.qt.io\",
+ $$dependencyList
+}
diff --git a/src/plugins/boot2qt/boot2qt.pro b/src/plugins/boot2qt/boot2qt.pro
new file mode 100644
index 0000000000..1111ce88c9
--- /dev/null
+++ b/src/plugins/boot2qt/boot2qt.pro
@@ -0,0 +1,49 @@
+DEFINES += BOOT2QT_LIBRARY
+QT += network
+
+include(../../qtcreatorplugin.pri)
+include(boot2qt_dependencies.pri)
+
+include(device-detection/device-detection.pri)
+
+HEADERS += \
+ qdbutils.h \
+ deviceapplicationobserver.h \
+ qdbdevice.h \
+ qdbqtversion.h \
+ qdbdeployconfigurationfactory.h \
+ qdbdevicewizard.h \
+ qdbrunconfiguration.h \
+ qdbmakedefaultappstep.h \
+ qdbmakedefaultappservice.h \
+ qdbstopapplicationstep.h \
+ qdbstopapplicationservice.h \
+ qdbdeploystepfactory.h \
+ qdbdevicedebugsupport.h \
+ qdbconstants.h \
+ qdb_global.h \
+ qdbplugin.h \
+ qdbdeviceprocess.h
+
+SOURCES += \
+ qdbutils.cpp \
+ deviceapplicationobserver.cpp \
+ qdbdevice.cpp \
+ qdbqtversion.cpp \
+ qdbdeployconfigurationfactory.cpp \
+ qdbdevicewizard.cpp \
+ qdbrunconfiguration.cpp \
+ qdbmakedefaultappstep.cpp \
+ qdbmakedefaultappservice.cpp \
+ qdbstopapplicationstep.cpp \
+ qdbstopapplicationservice.cpp \
+ qdbdeploystepfactory.cpp \
+ qdbdevicedebugsupport.cpp \
+ qdbdeviceprocess.cpp \
+ qdbplugin.cpp \
+
+FORMS += \
+ qdbdevicewizardsettingspage.ui
+
+RESOURCES += \
+ qdb.qrc
diff --git a/src/plugins/boot2qt/boot2qt.qbs b/src/plugins/boot2qt/boot2qt.qbs
new file mode 100644
index 0000000000..8369c86aaf
--- /dev/null
+++ b/src/plugins/boot2qt/boot2qt.qbs
@@ -0,0 +1,72 @@
+import qbs
+
+QtcPlugin {
+ name: "Boot2Qt"
+
+ Depends { name: "Core" }
+ Depends { name: "Debugger" }
+ Depends { name: "ProjectExplorer" }
+ Depends { name: "QmlDebug" }
+ Depends { name: "QtSupport" }
+ Depends { name: "RemoteLinux" }
+ Depends { name: "Utils" }
+
+ cpp.defines: base.concat("BOOT2QT_LIBRARY")
+
+ Group {
+ name: "General"
+ files: [
+ "qdb.qrc",
+ "qdbutils.cpp",
+ "qdbutils.h",
+ "deviceapplicationobserver.cpp",
+ "deviceapplicationobserver.h",
+ "qdbconstants.h",
+ "qdb_global.h",
+ "qdbdeployconfigurationfactory.cpp",
+ "qdbdeployconfigurationfactory.h",
+ "qdbdeploystepfactory.cpp",
+ "qdbdeploystepfactory.h",
+ "qdbdevice.cpp",
+ "qdbdevice.h",
+ "qdbdevicedebugsupport.cpp",
+ "qdbdevicedebugsupport.h",
+ "qdbdeviceprocess.cpp",
+ "qdbdeviceprocess.h",
+ "qdbdevicewizard.cpp",
+ "qdbdevicewizard.h",
+ "qdbdevicewizardsettingspage.ui",
+ "qdbmakedefaultappservice.cpp",
+ "qdbmakedefaultappservice.h",
+ "qdbmakedefaultappstep.cpp",
+ "qdbmakedefaultappstep.h",
+ "qdbplugin.cpp",
+ "qdbplugin.h",
+ "qdbstopapplicationservice.cpp",
+ "qdbstopapplicationservice.h",
+ "qdbstopapplicationstep.cpp",
+ "qdbstopapplicationstep.h",
+ "qdbqtversion.cpp",
+ "qdbqtversion.h",
+ "qdbrunconfiguration.cpp",
+ "qdbrunconfiguration.h",
+ ]
+ }
+
+ Group {
+ name: "Device Detection"
+ prefix: "device-detection/"
+ files: [
+ "devicedetector.cpp",
+ "devicedetector.h",
+ "hostmessages.cpp",
+ "hostmessages.h",
+ "qdbdevicetracker.cpp",
+ "qdbdevicetracker.h",
+ "qdbwatcher.h",
+ "qdbwatcher.cpp",
+ "qdbmessagetracker.cpp",
+ "qdbmessagetracker.h",
+ ]
+ }
+}
diff --git a/src/plugins/boot2qt/boot2qt_dependencies.pri b/src/plugins/boot2qt/boot2qt_dependencies.pri
new file mode 100644
index 0000000000..ea2f583ed9
--- /dev/null
+++ b/src/plugins/boot2qt/boot2qt_dependencies.pri
@@ -0,0 +1,8 @@
+QTC_PLUGIN_NAME = Boot2Qt
+QTC_PLUGIN_DEPENDS += \
+ coreplugin \
+ debugger \
+ projectexplorer \
+ qtsupport \
+ remotelinux
+
diff --git a/src/plugins/boot2qt/device-detection/device-detection.pri b/src/plugins/boot2qt/device-detection/device-detection.pri
new file mode 100644
index 0000000000..6ba0c35152
--- /dev/null
+++ b/src/plugins/boot2qt/device-detection/device-detection.pri
@@ -0,0 +1,13 @@
+HEADERS += \
+ $$PWD/devicedetector.h \
+ $$PWD/hostmessages.h \
+ $$PWD/qdbdevicetracker.h \
+ $$PWD/qdbmessagetracker.h \
+ $$PWD/qdbwatcher.h \
+
+SOURCES += \
+ $$PWD/devicedetector.cpp \
+ $$PWD/hostmessages.cpp \
+ $$PWD/qdbdevicetracker.cpp \
+ $$PWD/qdbmessagetracker.cpp \
+ $$PWD/qdbwatcher.cpp \
diff --git a/src/plugins/boot2qt/device-detection/devicedetector.cpp b/src/plugins/boot2qt/device-detection/devicedetector.cpp
new file mode 100644
index 0000000000..89dbb60e2f
--- /dev/null
+++ b/src/plugins/boot2qt/device-detection/devicedetector.cpp
@@ -0,0 +1,149 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "devicedetector.h"
+
+#include "../qdbutils.h"
+#include "../qdbconstants.h"
+#include "../qdbdevice.h"
+
+#include <projectexplorer/devicesupport/devicemanager.h>
+#include <utils/qtcassert.h>
+
+#include <QHash>
+#include <QObject>
+
+using namespace ProjectExplorer;
+
+namespace Qdb {
+namespace Internal {
+
+static bool isAutodetectedQdbDevice(const IDevice::ConstPtr &device)
+{
+ return device
+ && device->type() == Qdb::Constants::QdbLinuxOsType
+ && device->isAutoDetected();
+}
+
+DeviceDetector::DeviceDetector()
+{
+}
+
+DeviceDetector::~DeviceDetector()
+{
+ stop();
+}
+
+void DeviceDetector::start()
+{
+ QTC_ASSERT(m_state == Inactive, return);
+
+ connect(&m_deviceTracker, &QdbDeviceTracker::deviceEvent,
+ this, &DeviceDetector::handleDeviceEvent);
+ connect(&m_deviceTracker, &QdbDeviceTracker::trackerError,
+ this, &DeviceDetector::handleTrackerError);
+
+ resetDevices();
+ m_state = WaitingForDeviceUpdates;
+ m_deviceTracker.start();
+ m_messageTracker.start();
+}
+
+void DeviceDetector::stop()
+{
+ m_messageTracker.stop();
+
+ switch (m_state) {
+ case WaitingForDeviceUpdates:
+ m_deviceTracker.stop();
+ resetDevices();
+ break;
+ case Inactive:
+ break;
+ }
+ m_state = Inactive;
+}
+
+void DeviceDetector::handleDeviceEvent(QdbDeviceTracker::DeviceEventType eventType,
+ const QMap<QString, QString> &info)
+{
+ const QString serial = info.value("serial");
+ if (serial.isEmpty()) {
+ showMessage("Error: Did not get a serial number in a device event from QDB", false);
+ return;
+ }
+
+ const Core::Id deviceId = Constants::QdbHardwareDevicePrefix.withSuffix(':' + serial);
+ const auto messagePrefix = tr("Device \"%1\" %2").arg(serial);
+ DeviceManager * const dm = DeviceManager::instance();
+
+ if (eventType == QdbDeviceTracker::NewDevice) {
+ const QString name = tr("Qt Debug Bridge device %1").arg(serial);
+ QdbDevice::Ptr device = QdbDevice::create();
+ device->setupId(IDevice::AutoDetected, deviceId);
+ device->setDisplayName(name);
+ device->setType(Qdb::Constants::QdbLinuxOsType);
+ device->setMachineType(IDevice::Hardware);
+
+ const QString ipAddress = info["ipAddress"];
+ device->setupDefaultNetworkSettings(ipAddress);
+
+ IDevice::DeviceState state;
+ if (ipAddress.isEmpty())
+ state = IDevice::DeviceConnected;
+ else
+ state = IDevice::DeviceReadyToUse;
+ device->setDeviceState(state);
+
+ dm->addDevice(device);
+
+ if (state == IDevice::DeviceConnected)
+ showMessage(messagePrefix.arg("connected, waiting for IP"), false);
+ else
+ showMessage(messagePrefix.arg("is ready to use at ").append(ipAddress), false);
+ } else if (eventType == QdbDeviceTracker::DisconnectedDevice) {
+ dm->setDeviceState(deviceId, IDevice::DeviceDisconnected);
+ showMessage(messagePrefix.arg("disconnected"), false);
+ }
+}
+
+void DeviceDetector::handleTrackerError(const QString &errorMessage)
+{
+ showMessage(tr("Device detection error: %1").arg(errorMessage), true);
+ stop();
+}
+
+void DeviceDetector::resetDevices()
+{
+ DeviceManager * const dm = DeviceManager::instance();
+ for (int i = 0; i < dm->deviceCount(); ++i) {
+ const IDevice::ConstPtr device = dm->deviceAt(i);
+ if (isAutodetectedQdbDevice(device))
+ dm->setDeviceState(device->id(), IDevice::DeviceDisconnected);
+ }
+}
+
+} // namespace Internal
+} // namespace Qdb
diff --git a/src/plugins/boot2qt/device-detection/devicedetector.h b/src/plugins/boot2qt/device-detection/devicedetector.h
new file mode 100644
index 0000000000..c5c85c30da
--- /dev/null
+++ b/src/plugins/boot2qt/device-detection/devicedetector.h
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "../qdbdevice.h"
+#include "qdbdevicetracker.h"
+#include "qdbmessagetracker.h"
+
+namespace Qdb {
+namespace Internal {
+
+class DeviceDetector : public QObject
+{
+ Q_OBJECT
+
+public:
+ DeviceDetector();
+ ~DeviceDetector();
+
+ void start();
+ void stop();
+
+private:
+ void handleDeviceEvent(QdbDeviceTracker::DeviceEventType eventType,
+ const QMap<QString, QString> &info);
+ void handleTrackerError(const QString &errorMessage);
+ void resetDevices();
+
+ enum State { Inactive, WaitingForDeviceUpdates };
+
+ State m_state = Inactive;
+ QdbDeviceTracker m_deviceTracker;
+ QdbMessageTracker m_messageTracker;
+};
+
+} // namespace Internal
+} // namespace Qdb
diff --git a/src/plugins/boot2qt/device-detection/hostmessages.cpp b/src/plugins/boot2qt/device-detection/hostmessages.cpp
new file mode 100644
index 0000000000..a5ff0e4168
--- /dev/null
+++ b/src/plugins/boot2qt/device-detection/hostmessages.cpp
@@ -0,0 +1,147 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "hostmessages.h"
+
+#include <utils/qtcassert.h>
+
+const QString responseField = "response";
+const QString requestField = "request";
+const QString versionField = "_version";
+
+void setVersionField(QJsonObject &obj)
+{
+ obj[versionField] = qdbHostMessageVersion;
+}
+
+bool checkHostMessageVersion(const QJsonObject &obj)
+{
+ return obj[versionField].toInt() == qdbHostMessageVersion;
+}
+
+QByteArray createRequest(const RequestType &type)
+{
+ QJsonObject obj;
+ setVersionField(obj);
+ obj[requestField] = requestTypeString(type);
+ return QJsonDocument{obj}.toJson(QJsonDocument::Compact).append('\n');
+}
+
+RequestType requestType(const QJsonObject &obj)
+{
+ const auto fieldValue = obj[requestField];
+ if (fieldValue == requestTypeString(RequestType::Devices))
+ return RequestType::Devices;
+ if (fieldValue == requestTypeString(RequestType::WatchDevices))
+ return RequestType::WatchDevices;
+ if (fieldValue == requestTypeString(RequestType::StopServer))
+ return RequestType::StopServer;
+ if (fieldValue == requestTypeString(RequestType::Messages))
+ return RequestType::Messages;
+ if (fieldValue == requestTypeString(RequestType::WatchMessages))
+ return RequestType::WatchMessages;
+ if (fieldValue == requestTypeString(RequestType::MessagesAndClear))
+ return RequestType::MessagesAndClear;
+
+ return RequestType::Unknown;
+}
+
+QString requestTypeString(const RequestType &type)
+{
+ switch (type) {
+ case RequestType::Devices:
+ return QStringLiteral("devices");
+ case RequestType::WatchDevices:
+ return QStringLiteral("watch-devices");
+ case RequestType::StopServer:
+ return QStringLiteral("stop-server");
+ case RequestType::Messages:
+ return QStringLiteral("messages");
+ case RequestType::WatchMessages:
+ return QStringLiteral("watch-messages");
+ case RequestType::MessagesAndClear:
+ return QStringLiteral("messages-and-clear");
+ case RequestType::Unknown:
+ break;
+ }
+ QTC_ASSERT(false, return QString());
+}
+
+QJsonObject initializeResponse(const ResponseType &type)
+{
+ QJsonObject obj;
+ setVersionField(obj);
+ obj[responseField] = responseTypeString(type);
+ return obj;
+}
+
+ResponseType responseType(const QJsonObject &obj)
+{
+ const auto fieldValue = obj[responseField];
+ if (fieldValue == responseTypeString(ResponseType::Devices))
+ return ResponseType::Devices;
+ if (fieldValue == responseTypeString(ResponseType::NewDevice))
+ return ResponseType::NewDevice;
+ if (fieldValue == responseTypeString(ResponseType::DisconnectedDevice))
+ return ResponseType::DisconnectedDevice;
+ if (fieldValue == responseTypeString(ResponseType::Stopping))
+ return ResponseType::Stopping;
+ if (fieldValue == responseTypeString(ResponseType::Messages))
+ return ResponseType::Messages;
+ if (fieldValue == responseTypeString(ResponseType::InvalidRequest))
+ return ResponseType::InvalidRequest;
+ if (fieldValue == responseTypeString(ResponseType::UnsupportedVersion))
+ return ResponseType::UnsupportedVersion;
+
+ return ResponseType::Unknown;
+}
+
+QString responseTypeString(const ResponseType &type)
+{
+ switch (type) {
+ case ResponseType::Devices:
+ return QStringLiteral("devices");
+ case ResponseType::NewDevice:
+ return QStringLiteral("new-device");
+ case ResponseType::DisconnectedDevice:
+ return QStringLiteral("disconnected-device");
+ case ResponseType::Stopping:
+ return QStringLiteral("stopping");
+ case ResponseType::Messages:
+ return QStringLiteral("messages");
+ case ResponseType::InvalidRequest:
+ return QStringLiteral("invalid-request");
+ case ResponseType::UnsupportedVersion:
+ return QStringLiteral("unsupported-version");
+ case ResponseType::Unknown:
+ break;
+ }
+ QTC_ASSERT(false, return QString());
+}
+
+QByteArray serialiseResponse(const QJsonObject &obj)
+{
+ return QJsonDocument{obj}.toJson(QJsonDocument::Compact).append('\n');
+}
diff --git a/src/plugins/boot2qt/device-detection/hostmessages.h b/src/plugins/boot2qt/device-detection/hostmessages.h
new file mode 100644
index 0000000000..5191d2c058
--- /dev/null
+++ b/src/plugins/boot2qt/device-detection/hostmessages.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <QtCore/qbytearray.h>
+#include <QtCore/qjsondocument.h>
+#include <QtCore/qjsonobject.h>
+
+const int qdbHostMessageVersion = 1;
+bool checkHostMessageVersion(const QJsonObject &obj);
+
+enum class RequestType
+{
+ Unknown = 0,
+ Devices,
+ WatchDevices,
+ StopServer,
+ WatchMessages,
+ Messages,
+ MessagesAndClear,
+};
+
+QByteArray createRequest(const RequestType &type);
+RequestType requestType(const QJsonObject &obj);
+QString requestTypeString(const RequestType &type);
+
+enum class ResponseType
+{
+ Unknown = 0,
+ Devices,
+ NewDevice,
+ DisconnectedDevice,
+ Stopping,
+ InvalidRequest,
+ UnsupportedVersion,
+ Messages,
+};
+
+QJsonObject initializeResponse(const ResponseType &type);
+ResponseType responseType(const QJsonObject &obj);
+QString responseTypeString(const ResponseType &type);
+QByteArray serialiseResponse(const QJsonObject &obj);
diff --git a/src/plugins/boot2qt/device-detection/qdbdevicetracker.cpp b/src/plugins/boot2qt/device-detection/qdbdevicetracker.cpp
new file mode 100644
index 0000000000..8ec5ec655a
--- /dev/null
+++ b/src/plugins/boot2qt/device-detection/qdbdevicetracker.cpp
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "qdbdevicetracker.h"
+#include "qdbwatcher.h"
+
+#include "../qdbutils.h"
+#include "hostmessages.h"
+
+#include <QJsonDocument>
+#include <QJsonObject>
+
+namespace Qdb {
+namespace Internal {
+
+QdbDeviceTracker::QdbDeviceTracker(QObject *parent)
+ : QObject(parent)
+{
+ m_qdbWatcher = new QdbWatcher(this);
+ connect(m_qdbWatcher, &QdbWatcher::incomingMessage, this, &QdbDeviceTracker::handleWatchMessage);
+ connect(m_qdbWatcher, &QdbWatcher::watcherError, this, &QdbDeviceTracker::trackerError);
+}
+void QdbDeviceTracker::start()
+{
+ m_qdbWatcher->start(RequestType::WatchDevices);
+}
+
+void QdbDeviceTracker::stop()
+{
+ m_qdbWatcher->stop();
+}
+
+void QdbDeviceTracker::handleWatchMessage(const QJsonDocument &document)
+{
+ const auto type = responseType(document.object());
+ if (type != ResponseType::NewDevice && type != ResponseType::DisconnectedDevice) {
+ stop();
+ const QString message =
+ tr("Shutting down device discovery due to unexpected response: %1");
+ emit trackerError(message.arg(QString::fromUtf8(document.toJson())));
+ return;
+ }
+
+ DeviceEventType eventType = type == ResponseType::NewDevice ? NewDevice
+ : DisconnectedDevice;
+ QVariantMap variantInfo = document.object().toVariantMap();
+ QMap<QString, QString> info;
+
+ switch (eventType) {
+ case NewDevice:
+ {
+ const QVariantMap deviceInfo = variantInfo["device"].value<QVariantMap>();
+ for (auto iter = deviceInfo.begin(); iter != deviceInfo.end(); ++iter)
+ info[iter.key()] = iter.value().toString();
+ }
+ break;
+ case DisconnectedDevice:
+ info["serial"] = variantInfo["serial"].toString();
+ break;
+ }
+ emit deviceEvent(eventType, info);
+}
+
+} // namespace Internal
+} // namespace Qdb
diff --git a/src/plugins/boot2qt/device-detection/qdbdevicetracker.h b/src/plugins/boot2qt/device-detection/qdbdevicetracker.h
new file mode 100644
index 0000000000..197cb7abbc
--- /dev/null
+++ b/src/plugins/boot2qt/device-detection/qdbdevicetracker.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+#include <QObject>
+#include <QMap>
+
+namespace Qdb {
+namespace Internal {
+
+class QdbWatcher;
+
+class QdbDeviceTracker : public QObject
+{
+ Q_OBJECT
+public:
+ QdbDeviceTracker(QObject *parent = nullptr);
+
+ enum DeviceEventType
+ {
+ NewDevice,
+ DisconnectedDevice
+ };
+
+ void start();
+ void stop();
+
+private slots:
+ void handleWatchMessage(const QJsonDocument &document);
+
+signals:
+ void deviceEvent(DeviceEventType eventType, QMap<QString, QString> info);
+ void trackerError(QString errorMessage);
+
+private:
+ QdbWatcher *m_qdbWatcher = nullptr;
+
+};
+
+} // namespace Internal
+} // namespace Qdb
diff --git a/src/plugins/boot2qt/device-detection/qdbmessagetracker.cpp b/src/plugins/boot2qt/device-detection/qdbmessagetracker.cpp
new file mode 100644
index 0000000000..3e9bc558d0
--- /dev/null
+++ b/src/plugins/boot2qt/device-detection/qdbmessagetracker.cpp
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "qdbmessagetracker.h"
+#include "qdbwatcher.h"
+
+#include "../qdbutils.h"
+#include "hostmessages.h"
+
+#include <QJsonDocument>
+#include <QJsonObject>
+#include <QJsonArray>
+
+namespace Qdb {
+namespace Internal {
+
+QdbMessageTracker::QdbMessageTracker(QObject *parent)
+ : QObject(parent)
+{
+ m_qdbWatcher = new QdbWatcher(this);
+ connect(m_qdbWatcher, &QdbWatcher::incomingMessage, this, &QdbMessageTracker::handleWatchMessage);
+ // Errors are not handled because showing the messages is just a helpful addition for the users
+ // but not critical.
+}
+
+void QdbMessageTracker::start()
+{
+ m_qdbWatcher->start(RequestType::WatchMessages);
+}
+
+void QdbMessageTracker::stop()
+{
+ m_qdbWatcher->stop();
+}
+
+void QdbMessageTracker::handleWatchMessage(const QJsonDocument &document)
+{
+ const auto type = responseType(document.object());
+ if (type != ResponseType::Messages) {
+ stop();
+ const QString message =
+ tr("Shutting down message reception due to unexpected response: %1");
+ emit trackerError(message.arg(QString::fromUtf8(document.toJson())));
+ return;
+ }
+
+ for (const auto &i : document.object().value(QLatin1String("messages")).toArray()) {
+ // There is an additional interger field "type" available allowing future
+ // filtering and handling messages regarding of their type.
+ const auto message = i.toObject().value(QLatin1String("text")).toString();
+
+ // In case the issues reported from qdb server are permanent the messages
+ // will reappear every second annoying the user. A cache will check
+ // if the message was already displayed.
+ for (auto i = m_messageCache.firstIndex(); i < m_messageCache.lastIndex(); ++i) {
+ if (m_messageCache.at(i) == message)
+ return;
+ }
+
+ m_messageCache.append(message);
+ showMessage(tr("Qdb message: %1").arg(message), true);
+ }
+}
+
+} // namespace Internal
+} // namespace Qdb
diff --git a/src/plugins/boot2qt/device-detection/qdbmessagetracker.h b/src/plugins/boot2qt/device-detection/qdbmessagetracker.h
new file mode 100644
index 0000000000..a6a2ae7e1c
--- /dev/null
+++ b/src/plugins/boot2qt/device-detection/qdbmessagetracker.h
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+#include <QObject>
+#include <QContiguousCache>
+
+namespace Qdb {
+namespace Internal {
+
+class QdbWatcher;
+
+class QdbMessageTracker : public QObject
+{
+ Q_OBJECT
+public:
+ QdbMessageTracker(QObject *parent = nullptr);
+
+ void start();
+ void stop();
+
+signals:
+ void trackerError(QString errorMessage);
+
+private slots:
+ void handleWatchMessage(const QJsonDocument &document);
+
+private:
+ QdbWatcher *m_qdbWatcher = nullptr;
+ QContiguousCache<QString> m_messageCache = QContiguousCache<QString>(10);
+};
+
+} // namespace Internal
+} // namespace Qdb
diff --git a/src/plugins/boot2qt/device-detection/qdbwatcher.cpp b/src/plugins/boot2qt/device-detection/qdbwatcher.cpp
new file mode 100644
index 0000000000..e5a9b5c2ef
--- /dev/null
+++ b/src/plugins/boot2qt/device-detection/qdbwatcher.cpp
@@ -0,0 +1,165 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "qdbwatcher.h"
+
+#include "../qdbutils.h"
+#include "hostmessages.h"
+
+#include <utils/fileutils.h>
+
+#include <QFile>
+#include <QProcess>
+#include <QTimer>
+
+namespace Qdb {
+namespace Internal {
+
+const int startupDelay = 500; // time in ms to wait for host server startup before retrying
+const QString qdbSocketName = "qdb.socket";
+
+QMutex QdbWatcher::s_startMutex;
+bool QdbWatcher::s_startedServer = false;
+
+QdbWatcher::QdbWatcher(QObject *parent)
+ : QObject(parent)
+ , m_requestType(RequestType::Unknown)
+{
+}
+
+QdbWatcher::~QdbWatcher()
+{
+ stop();
+}
+
+void QdbWatcher::start(RequestType requestType)
+{
+ m_requestType = requestType;
+ startPrivate();
+}
+
+void QdbWatcher::startPrivate()
+{
+ m_socket = std::unique_ptr<QLocalSocket>(new QLocalSocket());
+ connect(m_socket.get(), &QLocalSocket::connected,
+ this, &QdbWatcher::handleWatchConnection);
+ connect(m_socket.get(), static_cast<void (QLocalSocket::*)
+ (QLocalSocket::LocalSocketError)>(&QLocalSocket::error),
+ this, &QdbWatcher::handleWatchError);
+ m_socket->connectToServer(qdbSocketName);
+}
+
+void QdbWatcher::stop()
+{
+ m_shuttingDown = true;
+ if (m_socket)
+ m_socket->disconnectFromServer();
+}
+
+void QdbWatcher::handleWatchConnection()
+{
+ m_retried = false;
+ {
+ QMutexLocker lock(&s_startMutex);
+ s_startedServer = false;
+ }
+ connect(m_socket.get(), &QIODevice::readyRead, this, &QdbWatcher::handleWatchMessage);
+ m_socket->write(createRequest(m_requestType));
+}
+
+void QdbWatcher::handleWatchError(QLocalSocket::LocalSocketError error)
+{
+ if (m_shuttingDown)
+ return;
+
+ if (error == QLocalSocket::PeerClosedError) {
+ retry();
+ return;
+ }
+
+ if (error != QLocalSocket::ServerNotFoundError
+ && error != QLocalSocket::ConnectionRefusedError) {
+ stop();
+ emit watcherError(tr("Unexpected QLocalSocket error: %1")
+ .arg(m_socket->errorString()));
+ return;
+ }
+
+ if (m_retried) {
+ stop();
+ emit watcherError(tr("Could not connect to QDB host server even after trying to start it"));
+ return;
+ }
+ retry();
+}
+
+void QdbWatcher::handleWatchMessage()
+{
+ while (m_socket->bytesAvailable() > 0) {
+ const QByteArray responseBytes = m_socket->readLine();
+ const auto document = QJsonDocument::fromJson(responseBytes);
+ if (document.isNull()) {
+ const QString message =
+ tr("Invalid JSON response received from QDB server: %1");
+ emit watcherError(message.arg(QString::fromUtf8(responseBytes)));
+ return;
+ }
+ emit incomingMessage(document);
+ }
+}
+
+void QdbWatcher::forkHostServer()
+{
+ Utils::FilePath qdbFilePath = findTool(QdbTool::Qdb);
+ QFile executable(qdbFilePath.toString());
+ if (!executable.exists()) {
+ const QString message = tr("Could not find QDB host server executable. "
+ "You can set the location with environment variable %1.")
+ .arg(QLatin1String(overridingEnvironmentVariable(QdbTool::Qdb)));
+ showMessage(message, true);
+ return;
+ }
+ if (QProcess::startDetached(qdbFilePath.toString(), {"server"}))
+ showMessage(tr("QDB host server started"), false);
+ else
+ showMessage(tr("Could not start QDB host server in %1").arg(qdbFilePath.toString()), true);
+}
+
+void QdbWatcher::retry()
+{
+ m_retried = true;
+ {
+ QMutexLocker lock(&s_startMutex);
+ if (!s_startedServer) {
+ showMessage(tr("Starting QDB host server"), false);
+ forkHostServer();
+ s_startedServer = true;
+ }
+ }
+ QTimer::singleShot(startupDelay, this, &QdbWatcher::startPrivate);
+}
+
+} // namespace Internal
+} // namespace Qdb
diff --git a/src/plugins/boot2qt/device-detection/qdbwatcher.h b/src/plugins/boot2qt/device-detection/qdbwatcher.h
new file mode 100644
index 0000000000..713c18e997
--- /dev/null
+++ b/src/plugins/boot2qt/device-detection/qdbwatcher.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <QLocalSocket>
+#include <QMutex>
+#include <QObject>
+
+#include <memory>
+
+enum class RequestType;
+QT_BEGIN_NAMESPACE
+class QJsonDocument;
+QT_END_NAMESPACE
+
+namespace Qdb {
+namespace Internal {
+
+class QdbWatcher : public QObject
+{
+ Q_OBJECT
+public:
+ QdbWatcher(QObject *parent = nullptr);
+ virtual ~QdbWatcher();
+ void stop();
+ void start(RequestType requestType);
+
+signals:
+ void incomingMessage(const QJsonDocument &);
+ void watcherError(const QString &);
+
+private:
+ void startPrivate();
+
+private:
+ void handleWatchConnection();
+ void handleWatchError(QLocalSocket::LocalSocketError error);
+ void handleWatchMessage();
+ static void forkHostServer();
+ void retry();
+
+ static QMutex s_startMutex;
+ static bool s_startedServer;
+
+ std::unique_ptr<QLocalSocket> m_socket = nullptr;
+ bool m_shuttingDown = false;
+ bool m_retried = false;
+ RequestType m_requestType;
+};
+
+} // namespace Internal
+} // namespace Qdb
+
diff --git a/src/plugins/boot2qt/deviceapplicationobserver.cpp b/src/plugins/boot2qt/deviceapplicationobserver.cpp
new file mode 100644
index 0000000000..2faf717b5c
--- /dev/null
+++ b/src/plugins/boot2qt/deviceapplicationobserver.cpp
@@ -0,0 +1,123 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "deviceapplicationobserver.h"
+
+#include "qdbutils.h"
+
+#include <projectexplorer/runcontrol.h>
+
+#include <utils/qtcassert.h>
+#include <utils/qtcprocess.h>
+
+using namespace ProjectExplorer;
+
+namespace Qdb {
+namespace Internal {
+
+DeviceApplicationObserver::DeviceApplicationObserver(QObject *parent)
+ : QObject(parent), m_appRunner(new ApplicationLauncher(this))
+{
+ connect(m_appRunner, &ApplicationLauncher::remoteStdout, this,
+ &DeviceApplicationObserver::handleStdout);
+ connect(m_appRunner, &ApplicationLauncher::remoteStderr, this,
+ &DeviceApplicationObserver::handleStderr);
+ connect(m_appRunner, &ApplicationLauncher::reportError, this,
+ &DeviceApplicationObserver::handleError);
+ connect(m_appRunner, &ApplicationLauncher::finished, this,
+ &DeviceApplicationObserver::handleFinished);
+}
+
+void DeviceApplicationObserver::start(const IDevice::ConstPtr &device,
+ const QList<Command> &commands)
+{
+ QTC_ASSERT(device, return);
+ m_device = device;
+ m_commandsToRun = commands;
+ runNext();
+}
+
+void DeviceApplicationObserver::runNext()
+{
+ if (m_commandsToRun.isEmpty()) {
+ showMessage(tr("Commands on device '%1' finished successfully.")
+ .arg(m_device->displayName()));
+ deleteLater();
+ return;
+ }
+ const Command c = m_commandsToRun.takeFirst();
+ m_stdout.clear();
+ m_stderr.clear();
+
+ Runnable r;
+ r.executable = c.binary;
+ r.commandLineArguments = Utils::QtcProcess::joinArgs(c.arguments);
+ m_appRunner->start(r, m_device);
+ showMessage(tr("Starting command '%1 %2' on device '%3'.")
+ .arg(r.executable, r.commandLineArguments, m_device->displayName()));
+}
+
+void DeviceApplicationObserver::handleStdout(const QString &data)
+{
+ m_stdout += data;
+}
+
+void DeviceApplicationObserver::handleStderr(const QString &data)
+{
+ m_stderr += data;
+}
+
+void DeviceApplicationObserver::handleError(const QString &message)
+{
+ m_error = message;
+}
+
+void DeviceApplicationObserver::handleFinished(bool success)
+{
+ if (success && (m_stdout.contains("fail") || m_stdout.contains("error")
+ || m_stdout.contains("not found"))) {
+ success = false; // adb does not forward exit codes and all stderr goes to stdout.
+ }
+ if (!success) {
+ QString errorString;
+ if (!m_error.isEmpty()) {
+ errorString = tr("Command failed on device '%1': %2").arg(m_device->displayName(),
+ m_error);
+ } else {
+ errorString = tr("Command failed on device '%1'.").arg(m_device->displayName());
+ }
+ showMessage(errorString, true);
+ if (!m_stdout.isEmpty())
+ showMessage(tr("stdout was: '%1'").arg(m_stdout));
+ if (!m_stderr.isEmpty())
+ showMessage(tr("stderr was: '%1'").arg(m_stderr));
+ deleteLater();
+ return;
+ }
+ runNext();
+}
+
+} // namespace Internal
+} // namespace Qdb
diff --git a/src/plugins/boot2qt/deviceapplicationobserver.h b/src/plugins/boot2qt/deviceapplicationobserver.h
new file mode 100644
index 0000000000..f82abbb3b4
--- /dev/null
+++ b/src/plugins/boot2qt/deviceapplicationobserver.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <projectexplorer/devicesupport/idevice.h>
+
+#include <QStringList>
+
+namespace ProjectExplorer { class ApplicationLauncher; }
+
+namespace Qdb {
+namespace Internal {
+
+class Command {
+public:
+ Command(const QString &bin, const QStringList &args = QStringList())
+ : binary(bin), arguments(args) {}
+
+ QString binary;
+ QStringList arguments;
+};
+
+class DeviceApplicationObserver : public QObject
+{
+ Q_OBJECT
+public:
+ explicit DeviceApplicationObserver(QObject *parent = 0);
+
+ // Once all commands have finished, this object will delete itself.
+ void start(const ProjectExplorer::IDevice::ConstPtr &device, const QList<Command> &commands);
+
+private:
+ void handleStdout(const QString &data);
+ void handleStderr(const QString &data);
+ void handleError(const QString &message);
+ void handleFinished(bool success);
+ void runNext();
+
+ QString m_stdout;
+ QString m_stderr;
+ QList<Command> m_commandsToRun;
+ ProjectExplorer::ApplicationLauncher * const m_appRunner;
+ ProjectExplorer::IDevice::ConstPtr m_device;
+ QString m_error;
+};
+
+} // namespace Internal
+} // namespace Qdb
diff --git a/src/plugins/boot2qt/images/qdbdevice.png b/src/plugins/boot2qt/images/qdbdevice.png
new file mode 100644
index 0000000000..760dde9777
--- /dev/null
+++ b/src/plugins/boot2qt/images/qdbdevice.png
Binary files differ
diff --git a/src/plugins/boot2qt/images/qdbdevice@2x.png b/src/plugins/boot2qt/images/qdbdevice@2x.png
new file mode 100644
index 0000000000..62ffbdad02
--- /dev/null
+++ b/src/plugins/boot2qt/images/qdbdevice@2x.png
Binary files differ
diff --git a/src/plugins/boot2qt/images/qdbdevicesmall.png b/src/plugins/boot2qt/images/qdbdevicesmall.png
new file mode 100644
index 0000000000..d15d6de6ca
--- /dev/null
+++ b/src/plugins/boot2qt/images/qdbdevicesmall.png
Binary files differ
diff --git a/src/plugins/boot2qt/images/qdbdevicesmall@2x.png b/src/plugins/boot2qt/images/qdbdevicesmall@2x.png
new file mode 100644
index 0000000000..38409af9ee
--- /dev/null
+++ b/src/plugins/boot2qt/images/qdbdevicesmall@2x.png
Binary files differ
diff --git a/src/plugins/boot2qt/qdb.qrc b/src/plugins/boot2qt/qdb.qrc
new file mode 100644
index 0000000000..2855671b05
--- /dev/null
+++ b/src/plugins/boot2qt/qdb.qrc
@@ -0,0 +1,8 @@
+<RCC>
+ <qresource prefix="/qdb">
+ <file>images/qdbdevice.png</file>
+ <file>images/qdbdevice@2x.png</file>
+ <file>images/qdbdevicesmall.png</file>
+ <file>images/qdbdevicesmall@2x.png</file>
+ </qresource>
+</RCC>
diff --git a/src/plugins/boot2qt/qdb_global.h b/src/plugins/boot2qt/qdb_global.h
new file mode 100644
index 0000000000..e17acae85f
--- /dev/null
+++ b/src/plugins/boot2qt/qdb_global.h
@@ -0,0 +1,34 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <QtGlobal>
+
+#if defined(BOOT2QT_LIBRARY)
+# define QDBPLUGINSHARED_EXPORT Q_DECL_EXPORT
+#else
+# define QDBPLUGINSHARED_EXPORT Q_DECL_IMPORT
+#endif
diff --git a/src/plugins/boot2qt/qdbconstants.h b/src/plugins/boot2qt/qdbconstants.h
new file mode 100644
index 0000000000..9d9093f4a1
--- /dev/null
+++ b/src/plugins/boot2qt/qdbconstants.h
@@ -0,0 +1,47 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <coreplugin/id.h>
+
+namespace Qdb {
+namespace Constants {
+
+const char QdbLinuxOsType[] = "QdbLinuxOsType";
+
+const char QdbDeployConfigurationId[] = "Qt4ProjectManager.Qdb.QdbDeployConfiguration";
+
+const Core::Id QdbHardwareDevicePrefix = "QdbHardwareDevice";
+const char AppcontrollerFilepath[] = "/usr/bin/appcontroller";
+const char QdbRunConfigurationPrefix[] = "QdbLinuxRunConfiguration:";
+
+} // namespace Constants
+
+namespace Internal {
+enum VmState { VmReady, VmNotReady, VmShutDown };
+}
+
+} // namespace Qdb
diff --git a/src/plugins/boot2qt/qdbdeployconfigurationfactory.cpp b/src/plugins/boot2qt/qdbdeployconfigurationfactory.cpp
new file mode 100644
index 0000000000..c033b6b101
--- /dev/null
+++ b/src/plugins/boot2qt/qdbdeployconfigurationfactory.cpp
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "qdbdeployconfigurationfactory.h"
+
+#include "qdbconstants.h"
+#include "qdbstopapplicationstep.h"
+
+#include <projectexplorer/deploymentdataview.h>
+#include <projectexplorer/kitinformation.h>
+#include <projectexplorer/project.h>
+#include <projectexplorer/target.h>
+
+#include <remotelinux/remotelinuxcheckforfreediskspacestep.h>
+#include <remotelinux/genericdirectuploadstep.h>
+#include <remotelinux/remotelinuxdeployconfiguration.h>
+
+using namespace ProjectExplorer;
+using namespace RemoteLinux;
+
+namespace Qdb {
+namespace Internal {
+
+QdbDeployConfigurationFactory::QdbDeployConfigurationFactory()
+{
+ setConfigBaseId(Constants::QdbDeployConfigurationId);
+ addSupportedTargetDeviceType(Constants::QdbLinuxOsType);
+ setDefaultDisplayName(QCoreApplication::translate("Qdb::Internal::QdbDeployConfiguration",
+ "Deploy to Boot2Qt target"));
+ setUseDeploymentDataView();
+
+ addInitialStep(RemoteLinuxCheckForFreeDiskSpaceStep::stepId());
+ addInitialStep(QdbStopApplicationStep::stepId());
+ addInitialStep(GenericDirectUploadStep::stepId());
+}
+
+} // namespace Internal
+} // namespace Qdb
diff --git a/src/plugins/boot2qt/qdbdeployconfigurationfactory.h b/src/plugins/boot2qt/qdbdeployconfigurationfactory.h
new file mode 100644
index 0000000000..90fd93f239
--- /dev/null
+++ b/src/plugins/boot2qt/qdbdeployconfigurationfactory.h
@@ -0,0 +1,40 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <projectexplorer/deployconfiguration.h>
+
+namespace Qdb {
+namespace Internal {
+
+class QdbDeployConfigurationFactory : public ProjectExplorer::DeployConfigurationFactory
+{
+public:
+ QdbDeployConfigurationFactory();
+};
+
+} // namespace Internal
+} // namespace Qdb
diff --git a/src/plugins/boot2qt/qdbdeploystepfactory.cpp b/src/plugins/boot2qt/qdbdeploystepfactory.cpp
new file mode 100644
index 0000000000..a39b3e5b86
--- /dev/null
+++ b/src/plugins/boot2qt/qdbdeploystepfactory.cpp
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "qdbdeploystepfactory.h"
+
+#include "qdbconstants.h"
+#include "qdbmakedefaultappstep.h"
+#include "qdbstopapplicationstep.h"
+
+#include <projectexplorer/buildsteplist.h>
+#include <projectexplorer/projectexplorerconstants.h>
+#include <projectexplorer/target.h>
+
+namespace Qdb {
+namespace Internal {
+
+QdbMakeDefaultAppStepFactory::QdbMakeDefaultAppStepFactory()
+{
+ registerStep<QdbMakeDefaultAppStep>(QdbMakeDefaultAppStep::stepId());
+ setDisplayName(QdbMakeDefaultAppStep::stepDisplayName());
+ setSupportedDeviceType(Constants::QdbLinuxOsType);
+ setSupportedStepList(ProjectExplorer::Constants::BUILDSTEPS_DEPLOY);
+}
+
+QdbStopApplicationStepFactory::QdbStopApplicationStepFactory()
+{
+ registerStep<QdbStopApplicationStep>(QdbStopApplicationStep::stepId());
+ setDisplayName(QdbStopApplicationStep::stepDisplayName());
+ setSupportedDeviceType(Constants::QdbLinuxOsType);
+ setSupportedStepList(ProjectExplorer::Constants::BUILDSTEPS_DEPLOY);
+}
+
+} // namespace Internal
+} // namespace Qdb
diff --git a/src/plugins/boot2qt/qdbdeploystepfactory.h b/src/plugins/boot2qt/qdbdeploystepfactory.h
new file mode 100644
index 0000000000..fada4a8478
--- /dev/null
+++ b/src/plugins/boot2qt/qdbdeploystepfactory.h
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <projectexplorer/buildstep.h>
+
+namespace Qdb {
+namespace Internal {
+
+class QdbMakeDefaultAppStepFactory : public ProjectExplorer::BuildStepFactory
+{
+public:
+ QdbMakeDefaultAppStepFactory();
+};
+
+class QdbStopApplicationStepFactory : public ProjectExplorer::BuildStepFactory
+{
+public:
+ QdbStopApplicationStepFactory();
+};
+
+} // namespace Internal
+} // namespace Qdb
diff --git a/src/plugins/boot2qt/qdbdevice.cpp b/src/plugins/boot2qt/qdbdevice.cpp
new file mode 100644
index 0000000000..9fd5595593
--- /dev/null
+++ b/src/plugins/boot2qt/qdbdevice.cpp
@@ -0,0 +1,149 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "qdbdevice.h"
+
+#include "qdbutils.h"
+#include "deviceapplicationobserver.h"
+#include "qdbconstants.h"
+#include "qdbdeviceprocess.h"
+#include "qdbdevicedebugsupport.h"
+#include "qdbdevicewizard.h"
+
+#include <coreplugin/icore.h>
+
+#include <ssh/sshconnection.h>
+#include <utils/portlist.h>
+
+using namespace ProjectExplorer;
+
+namespace Qdb {
+namespace Internal {
+
+QdbDevice::QdbDevice()
+{
+ addDeviceAction({tr("Reboot Device"), [](const IDevice::Ptr &device, QWidget *) {
+ QList<Command> commands{Command("reboot")};
+ (new DeviceApplicationObserver)->start(device, commands);
+ }});
+
+ addDeviceAction({tr("Restore Default App"), [](const IDevice::Ptr &device, QWidget *) {
+ QList<Command> commands{Command(appControllerFilePath(), QStringList{"--remove-default"})};
+ (new DeviceApplicationObserver)->start(device, commands);
+ }});
+}
+
+QString QdbDevice::displayType() const
+{
+ return tr("Boot2Qt Device");
+}
+
+ProjectExplorer::IDeviceWidget *QdbDevice::createWidget()
+{
+ ProjectExplorer::IDeviceWidget *w = RemoteLinux::LinuxDevice::createWidget();
+
+ return w;
+}
+
+ProjectExplorer::DeviceProcess *QdbDevice::createProcess(QObject *parent) const
+{
+ return new QdbDeviceProcess(sharedFromThis(), parent);
+}
+
+void QdbDevice::setSerialNumber(const QString &serial)
+{
+ m_serialNumber = serial;
+}
+
+QString QdbDevice::serialNumber() const
+{
+ return m_serialNumber;
+}
+
+void QdbDevice::fromMap(const QVariantMap &map)
+{
+ ProjectExplorer::IDevice::fromMap(map);
+ setSerialNumber(map.value("Qdb.SerialNumber").toString());
+}
+
+QVariantMap QdbDevice::toMap() const
+{
+ QVariantMap map = ProjectExplorer::IDevice::toMap();
+ map.insert("Qdb.SerialNumber", serialNumber());
+ return map;
+}
+
+void QdbDevice::setupDefaultNetworkSettings(const QString &host)
+{
+ setFreePorts(Utils::PortList::fromString("10000-10100"));
+
+ QSsh::SshConnectionParameters parameters = sshParameters();
+ parameters.setHost(host);
+ parameters.setUserName("root");
+ parameters.setPort(22);
+ parameters.timeout = 10;
+ parameters.authenticationType = QSsh::SshConnectionParameters::AuthenticationTypeAll;
+ setSshParameters(parameters);
+}
+
+std::function<ProjectExplorer::RunWorker *(ProjectExplorer::RunControl *)>
+ QdbDevice::workerCreator(Core::Id id) const
+{
+ if (id == "PerfRecorder") {
+ return [](ProjectExplorer::RunControl *runControl) {
+ return new QdbDevicePerfProfilerSupport(runControl);
+ };
+ }
+ return {};
+}
+
+
+// Device factory
+
+static IDevice::Ptr createDevice(QdbDeviceWizard::DeviceType deviceType)
+{
+ QdbDeviceWizard wizard(deviceType, Core::ICore::mainWindow());
+
+ if (wizard.exec() != QDialog::Accepted)
+ return IDevice::Ptr();
+ return wizard.device();
+}
+
+QdbLinuxDeviceFactory::QdbLinuxDeviceFactory()
+ : IDeviceFactory(Constants::QdbLinuxOsType)
+{
+ setDisplayName(tr("Boot2Qt Device"));
+ setCombinedIcon(":/qdb/images/qdbdevicesmall.png", ":/qdb/images/qdbdevice.png");
+ setCanCreate(true);
+ setConstructionFunction(&QdbDevice::create);
+}
+
+IDevice::Ptr QdbLinuxDeviceFactory::create() const
+{
+ return createDevice(QdbDeviceWizard::HardwareDevice);
+}
+
+} // namespace Internal
+} // namespace Qdb
diff --git a/src/plugins/boot2qt/qdbdevice.h b/src/plugins/boot2qt/qdbdevice.h
new file mode 100644
index 0000000000..db0ff76aea
--- /dev/null
+++ b/src/plugins/boot2qt/qdbdevice.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "qdbconstants.h"
+#include <projectexplorer/kit.h>
+#include <remotelinux/linuxdevice.h>
+
+namespace Qdb {
+namespace Internal {
+
+class QdbDevice : public RemoteLinux::LinuxDevice
+{
+public:
+ typedef QSharedPointer<QdbDevice> Ptr;
+ typedef QSharedPointer<const QdbDevice> ConstPtr;
+
+ static Ptr create() { return Ptr(new QdbDevice); }
+
+ QString displayType() const final;
+ ProjectExplorer::IDeviceWidget *createWidget() final;
+
+ ProjectExplorer::DeviceProcess *createProcess(QObject *parent) const final;
+
+ void setSerialNumber(const QString &serial);
+ QString serialNumber() const;
+
+ void fromMap(const QVariantMap &map) final;
+ QVariantMap toMap() const final;
+
+ void setupDefaultNetworkSettings(const QString &host);
+
+ std::function<ProjectExplorer::RunWorker *(ProjectExplorer::RunControl *)>
+ workerCreator(Core::Id id) const override;
+
+private:
+ QdbDevice();
+
+ QString m_serialNumber;
+};
+
+class QdbLinuxDeviceFactory : public ProjectExplorer::IDeviceFactory
+{
+ Q_OBJECT
+public:
+ QdbLinuxDeviceFactory();
+
+private:
+ ProjectExplorer::IDevice::Ptr create() const final;
+};
+
+} // namespace Internal
+} // namespace Qdb
diff --git a/src/plugins/boot2qt/qdbdevicedebugsupport.cpp b/src/plugins/boot2qt/qdbdevicedebugsupport.cpp
new file mode 100644
index 0000000000..31bcb2b3db
--- /dev/null
+++ b/src/plugins/boot2qt/qdbdevicedebugsupport.cpp
@@ -0,0 +1,223 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "qdbdevicedebugsupport.h"
+
+#include "qdbconstants.h"
+#include "qdbdevice.h"
+#include "qdbrunconfiguration.h"
+
+#include <debugger/debuggerruncontrol.h>
+
+#include <ssh/sshconnection.h>
+
+#include <utils/algorithm.h>
+#include <utils/url.h>
+
+using namespace Debugger;
+using namespace ProjectExplorer;
+using namespace Utils;
+using namespace Qdb::Internal;
+
+namespace Qdb {
+
+class QdbDeviceInferiorRunner : public RunWorker
+{
+public:
+ QdbDeviceInferiorRunner(RunControl *runControl,
+ bool usePerf, bool useGdbServer, bool useQmlServer,
+ QmlDebug::QmlDebugServicesPreset qmlServices)
+ : RunWorker(runControl),
+ m_usePerf(usePerf), m_useGdbServer(useGdbServer), m_useQmlServer(useQmlServer),
+ m_qmlServices(qmlServices)
+ {
+ setId("QdbDebuggeeRunner");
+
+ connect(&m_launcher, &ApplicationLauncher::remoteProcessStarted,
+ this, &RunWorker::reportStarted);
+ connect(&m_launcher, &ApplicationLauncher::finished,
+ this, &RunWorker::reportStopped);
+ connect(&m_launcher, &ApplicationLauncher::appendMessage,
+ this, &RunWorker::appendMessage);
+ connect(&m_launcher, &ApplicationLauncher::remoteStdout,
+ this, [this](const QString &out) { appendMessage(out, StdOutFormat); });
+ connect(&m_launcher, &ApplicationLauncher::remoteStderr,
+ this, [this](const QString &out) { appendMessage(out, StdErrFormat); });
+
+ m_portsGatherer = new GdbServerPortsGatherer(runControl);
+ m_portsGatherer->setUseGdbServer(useGdbServer || usePerf);
+ m_portsGatherer->setUseQmlServer(useQmlServer);
+ addStartDependency(m_portsGatherer);
+ }
+
+ Port perfPort() const { return m_portsGatherer->gdbServerPort(); }
+ QUrl gdbServer() const { return m_portsGatherer->gdbServer(); }
+ Port qmlServerPort() const { return m_portsGatherer->qmlServerPort(); }
+ QUrl qmlServer() const { return m_portsGatherer->qmlServer(); }
+
+ void start() override
+ {
+ const int perfPort = m_portsGatherer->gdbServerPort().number();
+ const int gdbServerPort = m_portsGatherer->gdbServerPort().number();
+ const int qmlServerPort = m_portsGatherer->qmlServerPort().number();
+
+ int lowerPort = 0;
+ int upperPort = 0;
+
+ Runnable r = runnable();
+
+ QString args;
+ if (m_useGdbServer) {
+ args.append(" --debug-gdb");
+ lowerPort = upperPort = gdbServerPort;
+ }
+ if (m_useQmlServer) {
+ args.append(" --debug-qml --qml-debug-services ");
+ args.append(QmlDebug::qmlDebugServices(m_qmlServices));
+ lowerPort = upperPort = qmlServerPort;
+ }
+ if (m_useGdbServer && m_useQmlServer) {
+ if (gdbServerPort + 1 != qmlServerPort) {
+ reportFailure("Need adjacent free ports for combined C++/QML debugging");
+ return;
+ }
+ lowerPort = gdbServerPort;
+ upperPort = qmlServerPort;
+ }
+ if (m_usePerf) {
+ if (auto perfSettings = runControl()->settings("Analyzer.Perf.Settings")) {
+ QStringList perfRecordArgs = perfSettings
+ ->property("perfRecordArguments").toStringList();
+ args.append(QString::fromLatin1(" --profile-perf %1").arg(
+ Utils::transform(perfRecordArgs, [](QString arg) {
+ return arg.replace(',', ",,");
+ }).join(',')));
+ }
+ lowerPort = upperPort = perfPort;
+ }
+ args.append(QString(" --port-range %1-%2 ").arg(lowerPort).arg(upperPort));
+ args.append(r.executable);
+ args.append(" ");
+ args.append(r.commandLineArguments);
+
+ r.commandLineArguments = args;
+ r.executable = Constants::AppcontrollerFilepath;
+
+ m_launcher.start(r, device());
+ }
+
+ void stop() override { m_launcher.stop(); }
+
+private:
+ Debugger::GdbServerPortsGatherer *m_portsGatherer = nullptr;
+ bool m_usePerf;
+ bool m_useGdbServer;
+ bool m_useQmlServer;
+ QmlDebug::QmlDebugServicesPreset m_qmlServices;
+ ApplicationLauncher m_launcher;
+};
+
+
+// QdbDeviceDebugSupport
+
+QdbDeviceDebugSupport::QdbDeviceDebugSupport(RunControl *runControl)
+ : Debugger::DebuggerRunTool(runControl)
+{
+ setId("QdbDeviceDebugSupport");
+
+ m_debuggee = new QdbDeviceInferiorRunner(runControl, false, isCppDebugging(), isQmlDebugging(),
+ QmlDebug::QmlDebuggerServices);
+ addStartDependency(m_debuggee);
+
+ m_debuggee->addStopDependency(this);
+}
+
+void QdbDeviceDebugSupport::start()
+{
+ setStartMode(Debugger::AttachToRemoteServer);
+ setCloseMode(KillAndExitMonitorAtClose);
+ setRemoteChannel(m_debuggee->gdbServer());
+ setQmlServer(m_debuggee->qmlServer());
+ setUseContinueInsteadOfRun(true);
+ setContinueAfterAttach(true);
+ addSolibSearchDir("%{sysroot}/system/lib");
+
+ DebuggerRunTool::start();
+}
+
+void QdbDeviceDebugSupport::stop()
+{
+ // Do nothing unusual. The launcher will die as result of (gdb) kill.
+ DebuggerRunTool::stop();
+}
+
+
+// QdbDeviceQmlProfilerSupport
+
+QdbDeviceQmlToolingSupport::QdbDeviceQmlToolingSupport(RunControl *runControl,
+ QmlDebug::QmlDebugServicesPreset services)
+ : RunWorker(runControl)
+{
+ setId("QdbDeviceQmlToolingSupport");
+
+ m_runner = new QdbDeviceInferiorRunner(runControl, false, false, true, services);
+ addStartDependency(m_runner);
+ addStopDependency(m_runner);
+
+ m_worker = runControl->createWorker(runControl->runMode());
+ m_worker->addStartDependency(this);
+ addStopDependency(m_worker);
+}
+
+void QdbDeviceQmlToolingSupport::start()
+{
+ m_worker->recordData("QmlServerUrl", m_runner->qmlServer());
+ reportStarted();
+}
+
+// QdbDevicePerfProfilerSupport
+
+QdbDevicePerfProfilerSupport::QdbDevicePerfProfilerSupport(RunControl *runControl)
+ : RunWorker(runControl)
+{
+ setId("QdbDevicePerfProfilerSupport");
+
+ m_profilee = new QdbDeviceInferiorRunner(runControl, true, false, false,
+ QmlDebug::NoQmlDebugServices);
+ addStartDependency(m_profilee);
+ addStopDependency(m_profilee);
+}
+
+void QdbDevicePerfProfilerSupport::start()
+{
+ QUrl url;
+ url.setScheme(Utils::urlTcpScheme());
+ url.setHost(device()->sshParameters().host());
+ url.setPort(m_profilee->perfPort().number());
+ runControl()->setProperty("PerfConnection", url);
+ reportStarted();
+}
+
+} // namespace Qdb
diff --git a/src/plugins/boot2qt/qdbdevicedebugsupport.h b/src/plugins/boot2qt/qdbdevicedebugsupport.h
new file mode 100644
index 0000000000..0f07b20f48
--- /dev/null
+++ b/src/plugins/boot2qt/qdbdevicedebugsupport.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <debugger/debuggerruncontrol.h>
+#include <qmldebug/qmldebugcommandlinearguments.h>
+
+namespace Qdb {
+
+class QdbDeviceInferiorRunner;
+
+class QdbDeviceDebugSupport : public Debugger::DebuggerRunTool
+{
+public:
+ QdbDeviceDebugSupport(ProjectExplorer::RunControl *runControl);
+
+private:
+ void start();
+ void stop();
+
+ QdbDeviceInferiorRunner *m_debuggee = nullptr;
+};
+
+class QdbDeviceQmlToolingSupport : public ProjectExplorer::RunWorker
+{
+public:
+ QdbDeviceQmlToolingSupport(ProjectExplorer::RunControl *runControl,
+ QmlDebug::QmlDebugServicesPreset services);
+
+private:
+ void start() override;
+
+ QdbDeviceInferiorRunner *m_runner = nullptr;
+ ProjectExplorer::RunWorker *m_worker = nullptr;
+};
+
+class QdbDeviceQmlProfilerSupport : public QdbDeviceQmlToolingSupport
+{
+public:
+ QdbDeviceQmlProfilerSupport(ProjectExplorer::RunControl *runControl) :
+ QdbDeviceQmlToolingSupport(runControl, QmlDebug::QmlProfilerServices)
+ {}
+};
+
+class QdbDeviceQmlPreviewSupport : public QdbDeviceQmlToolingSupport
+{
+public:
+ QdbDeviceQmlPreviewSupport(ProjectExplorer::RunControl *runControl) :
+ QdbDeviceQmlToolingSupport(runControl, QmlDebug::QmlPreviewServices)
+ {}
+};
+
+class QdbDevicePerfProfilerSupport : public ProjectExplorer::RunWorker
+{
+public:
+ QdbDevicePerfProfilerSupport(ProjectExplorer::RunControl *runControl);
+
+private:
+ void start() override;
+
+ QdbDeviceInferiorRunner *m_profilee = nullptr;
+};
+
+} // namespace Qdb
diff --git a/src/plugins/boot2qt/qdbdeviceprocess.cpp b/src/plugins/boot2qt/qdbdeviceprocess.cpp
new file mode 100644
index 0000000000..2a5901dbad
--- /dev/null
+++ b/src/plugins/boot2qt/qdbdeviceprocess.cpp
@@ -0,0 +1,52 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "qdbdeviceprocess.h"
+
+#include "qdbconstants.h"
+
+#include <projectexplorer/runcontrol.h>
+
+
+namespace Qdb {
+namespace Internal {
+
+QdbDeviceProcess::QdbDeviceProcess(const QSharedPointer<const ProjectExplorer::IDevice> &device, QObject *parent)
+ : RemoteLinux::LinuxDeviceProcess(device, parent),
+ m_stopRunner(new ProjectExplorer::ApplicationLauncher(this))
+{
+}
+
+void QdbDeviceProcess::terminate()
+{
+ ProjectExplorer::Runnable r;
+ r.executable = Constants::AppcontrollerFilepath;
+ r.commandLineArguments = QStringLiteral("--stop");
+
+ m_stopRunner->start(r, device());
+}
+
+} // namespace Internal
+} // namespace Qdb
diff --git a/src/plugins/boot2qt/qdbdeviceprocess.h b/src/plugins/boot2qt/qdbdeviceprocess.h
new file mode 100644
index 0000000000..c4e4afccf5
--- /dev/null
+++ b/src/plugins/boot2qt/qdbdeviceprocess.h
@@ -0,0 +1,47 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <projectexplorer/applicationlauncher.h>
+#include <remotelinux/linuxdeviceprocess.h>
+
+namespace Qdb {
+namespace Internal {
+
+class QdbDeviceProcess : public RemoteLinux::LinuxDeviceProcess
+{
+public:
+ QdbDeviceProcess(const QSharedPointer<const ProjectExplorer::IDevice> &device,
+ QObject *parent = 0);
+
+ void terminate() override;
+
+private:
+ ProjectExplorer::ApplicationLauncher *m_stopRunner;
+};
+
+} // namespace Internal
+} // namespace Qdb
diff --git a/src/plugins/boot2qt/qdbdevicewizard.cpp b/src/plugins/boot2qt/qdbdevicewizard.cpp
new file mode 100644
index 0000000000..165732084c
--- /dev/null
+++ b/src/plugins/boot2qt/qdbdevicewizard.cpp
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "qdbdevicewizard.h"
+#include "ui_qdbdevicewizardsettingspage.h"
+
+#include "qdbconstants.h"
+#include "qdbdevice.h"
+
+#include <utils/qtcassert.h>
+
+#include <QString>
+#include <QWizardPage>
+
+namespace {
+enum PageId { SettingsPageId };
+} // anonymous namespace
+
+namespace Qdb {
+namespace Internal {
+
+class QdbSettingsPage : public QWizardPage
+{
+ Q_OBJECT
+public:
+ QdbSettingsPage(QdbDeviceWizard::DeviceType deviceType, QWidget *parent = 0)
+ : QWizardPage(parent), m_deviceType(deviceType)
+ {
+ m_ui.setupUi(this);
+ setTitle(tr("Device Settings"));
+ connect(m_ui.nameLineEdit, &QLineEdit::textChanged, this, &QWizardPage::completeChanged);
+ connect(m_ui.addressLineEdit, &QLineEdit::textChanged,
+ this, &QWizardPage::completeChanged);
+ }
+
+ QdbDeviceWizard::DeviceType deviceType() const { return m_deviceType; }
+ QString deviceName() const { return m_ui.nameLineEdit->text().trimmed(); }
+ QString deviceAddress() const { return m_ui.addressLineEdit->text().trimmed(); }
+
+private:
+ bool isComplete() const final {
+ return !deviceName().isEmpty() && !deviceAddress().isEmpty();
+ }
+
+ QdbDeviceWizard::DeviceType m_deviceType;
+ Ui::QdbDeviceWizardSettingsPage m_ui;
+};
+
+class QdbDeviceWizard::DeviceWizardPrivate
+{
+public:
+ DeviceWizardPrivate(DeviceType deviceType)
+ : settingsPage(deviceType)
+ {
+
+ }
+
+ QdbSettingsPage settingsPage;
+};
+
+QdbDeviceWizard::QdbDeviceWizard(DeviceType deviceType, QWidget *parent)
+ : QWizard(parent), d(new DeviceWizardPrivate(deviceType))
+{
+ setWindowTitle(tr("Boot2Qt Network Device Setup"));
+ d->settingsPage.setCommitPage(true);
+ setPage(SettingsPageId, &d->settingsPage);
+}
+
+QdbDeviceWizard::~QdbDeviceWizard()
+{
+ delete d;
+}
+
+ProjectExplorer::IDevice::Ptr QdbDeviceWizard::device()
+{
+ QdbDevice::Ptr device = QdbDevice::create();
+
+ device->setDisplayName(d->settingsPage.deviceName());
+ device->setupId(ProjectExplorer::IDevice::ManuallyAdded, Core::Id());
+ device->setType(Constants::QdbLinuxOsType);
+ device->setMachineType(ProjectExplorer::IDevice::Hardware);
+
+ device->setupDefaultNetworkSettings(d->settingsPage.deviceAddress());
+
+ return device;
+}
+
+} // namespace Internal
+} // namespace Qdb
+
+#include "qdbdevicewizard.moc"
diff --git a/src/plugins/boot2qt/qdbdevicewizard.h b/src/plugins/boot2qt/qdbdevicewizard.h
new file mode 100644
index 0000000000..5191c8cedf
--- /dev/null
+++ b/src/plugins/boot2qt/qdbdevicewizard.h
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <projectexplorer/devicesupport/idevice.h>
+
+#include <QWizard>
+
+namespace Qdb {
+namespace Internal {
+
+class QdbDeviceWizard : public QWizard
+{
+ Q_OBJECT
+public:
+ enum DeviceType
+ {
+ HardwareDevice
+ };
+
+ QdbDeviceWizard(DeviceType deviceType, QWidget *parent = 0);
+ ~QdbDeviceWizard();
+
+ ProjectExplorer::IDevice::Ptr device();
+
+private:
+ class DeviceWizardPrivate;
+ DeviceWizardPrivate * const d;
+};
+
+} // namespace Internal
+} // namespace Qdb
diff --git a/src/plugins/boot2qt/qdbdevicewizardsettingspage.ui b/src/plugins/boot2qt/qdbdevicewizardsettingspage.ui
new file mode 100644
index 0000000000..2aefa42fbf
--- /dev/null
+++ b/src/plugins/boot2qt/qdbdevicewizardsettingspage.ui
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Qdb::Internal::QdbDeviceWizardSettingsPage</class>
+ <widget class="QWizardPage" name="Qdb::Internal::QdbDeviceWizardSettingsPage">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>669</width>
+ <height>308</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>WizardPage</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <layout class="QFormLayout" name="formLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="nameLabel">
+ <property name="text">
+ <string>Device name:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLineEdit" name="nameLineEdit">
+ <property name="placeholderText">
+ <string>A short, free-text description</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="addressLabel">
+ <property name="text">
+ <string>Device address:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="addressLineEdit">
+ <property name="placeholderText">
+ <string>Host name or IP address</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QLabel" name="usbWarningLabel">
+ <property name="text">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Note:&lt;/span&gt; Do not use this wizard for devices connected via USB.&lt;br/&gt;Those will be auto-detected.&lt;/p&gt;&lt;p&gt;The connectivity to the device is tested after finishing.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/plugins/boot2qt/qdbmakedefaultappservice.cpp b/src/plugins/boot2qt/qdbmakedefaultappservice.cpp
new file mode 100644
index 0000000000..fc7212b910
--- /dev/null
+++ b/src/plugins/boot2qt/qdbmakedefaultappservice.cpp
@@ -0,0 +1,126 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "qdbmakedefaultappservice.h"
+
+#include "qdbconstants.h"
+#include "qdbrunconfiguration.h"
+
+#include <ssh/sshremoteprocessrunner.h>
+#include <projectexplorer/target.h>
+#include <projectexplorer/runconfigurationaspects.h>
+
+namespace Qdb {
+namespace Internal {
+
+class QdbMakeDefaultAppServicePrivate
+{
+public:
+ bool makeDefault;
+ QSsh::SshRemoteProcessRunner *processRunner;
+};
+
+QdbMakeDefaultAppService::QdbMakeDefaultAppService(QObject *parent)
+ : AbstractRemoteLinuxDeployService(parent),
+ d(new QdbMakeDefaultAppServicePrivate)
+{
+ d->processRunner = 0;
+ d->makeDefault = true;
+}
+
+QdbMakeDefaultAppService::~QdbMakeDefaultAppService()
+{
+ cleanup();
+ delete d;
+}
+
+void QdbMakeDefaultAppService::setMakeDefault(bool makeDefault)
+{
+ d->makeDefault = makeDefault;
+}
+
+void QdbMakeDefaultAppService::handleStdErr()
+{
+ emit stdErrData(QString::fromUtf8(d->processRunner->readAllStandardError()));
+}
+
+void QdbMakeDefaultAppService::handleProcessFinished(const QString &error)
+{
+ if (!error.isEmpty()) {
+ emit errorMessage(tr("Remote process failed: %1").arg(error));
+ stopDeployment();
+ return;
+ }
+
+ QByteArray processOutput = d->processRunner->readAllStandardOutput();
+
+ if (d->makeDefault)
+ emit progressMessage(tr("Application made as the default one."));
+ else
+ emit progressMessage(tr("Reset the default application."));
+
+ stopDeployment();
+}
+
+void QdbMakeDefaultAppService::doDeploy()
+{
+ d->processRunner = new QSsh::SshRemoteProcessRunner;
+ connect(d->processRunner, &QSsh::SshRemoteProcessRunner::processClosed,
+ this, &QdbMakeDefaultAppService::handleProcessFinished);
+ connect(d->processRunner, &QSsh::SshRemoteProcessRunner::readyReadStandardError,
+ this, &QdbMakeDefaultAppService::handleStdErr);
+
+ QString remoteExe;
+
+ if (ProjectExplorer::RunConfiguration *rc = target()->activeRunConfiguration()) {
+ if (auto exeAspect = rc->aspect<ProjectExplorer::ExecutableAspect>())
+ remoteExe = exeAspect->executable().toString();
+ }
+
+ QString command = Constants::AppcontrollerFilepath;
+ command += d->makeDefault && !remoteExe.isEmpty() ? QStringLiteral(" --make-default ") + remoteExe
+ : QStringLiteral(" --remove-default");
+
+ d->processRunner->run(command, deviceConfiguration()->sshParameters());
+}
+
+void QdbMakeDefaultAppService::stopDeployment()
+{
+ cleanup();
+ handleDeploymentDone();
+}
+
+void QdbMakeDefaultAppService::cleanup()
+{
+ if (d->processRunner) {
+ disconnect(d->processRunner, 0, this, 0);
+ d->processRunner->cancel();
+ delete d->processRunner;
+ d->processRunner = 0;
+ }
+}
+
+} // namespace Internal
+} // namespace Qdb
diff --git a/src/plugins/boot2qt/qdbmakedefaultappservice.h b/src/plugins/boot2qt/qdbmakedefaultappservice.h
new file mode 100644
index 0000000000..75c78144a3
--- /dev/null
+++ b/src/plugins/boot2qt/qdbmakedefaultappservice.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <remotelinux/abstractremotelinuxdeployservice.h>
+
+namespace Qdb {
+namespace Internal {
+
+class QdbMakeDefaultAppServicePrivate;
+
+class QdbMakeDefaultAppService : public RemoteLinux::AbstractRemoteLinuxDeployService
+{
+ Q_OBJECT
+public:
+ QdbMakeDefaultAppService(QObject *parent = 0);
+ ~QdbMakeDefaultAppService();
+ void setMakeDefault(bool makeDefault);
+
+private slots:
+ void handleStdErr();
+ void handleProcessFinished(const QString &error);
+
+private:
+ bool isDeploymentNecessary() const { return true; }
+ void doDeviceSetup() { handleDeviceSetupDone(true); }
+ void stopDeviceSetup() { handleDeviceSetupDone(false); }
+
+ void doDeploy();
+ void stopDeployment();
+
+ void cleanup();
+
+ QdbMakeDefaultAppServicePrivate * const d;
+};
+
+} // namespace Internal
+} // namespace Qdb
diff --git a/src/plugins/boot2qt/qdbmakedefaultappstep.cpp b/src/plugins/boot2qt/qdbmakedefaultappstep.cpp
new file mode 100644
index 0000000000..db65267238
--- /dev/null
+++ b/src/plugins/boot2qt/qdbmakedefaultappstep.cpp
@@ -0,0 +1,158 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "qdbmakedefaultappstep.h"
+
+#include "qdbmakedefaultappservice.h"
+
+#include <QRadioButton>
+#include <QVBoxLayout>
+
+namespace Qdb {
+namespace Internal {
+
+class QdbMakeDefaultAppStepPrivate
+{
+public:
+ QdbMakeDefaultAppService deployService;
+ bool makeDefault;
+};
+
+class QdbConfigWidget : public ProjectExplorer::BuildStepConfigWidget
+{
+ Q_OBJECT
+public:
+ QdbConfigWidget(QdbMakeDefaultAppStep *step)
+ : BuildStepConfigWidget(step)
+ {
+ QVBoxLayout * const mainLayout = new QVBoxLayout(this);
+ mainLayout->setMargin(0);
+
+ m_makeDefaultBtn.setText(tr("Set this application to start by default"));
+ m_resetDefaultBtn.setText(tr("Reset default application"));
+
+ if (step->makeDefault())
+ m_makeDefaultBtn.setChecked(true);
+ else
+ m_resetDefaultBtn.setChecked(true);
+
+ mainLayout->addWidget(&m_makeDefaultBtn);
+ mainLayout->addWidget(&m_resetDefaultBtn);
+
+ connect(&m_makeDefaultBtn, &QRadioButton::clicked,
+ this, &QdbConfigWidget::handleMakeDefault);
+ connect(&m_resetDefaultBtn, &QRadioButton::clicked,
+ this, &QdbConfigWidget::handleResetDefault);
+ }
+
+private:
+ Q_SLOT void handleMakeDefault() {
+ QdbMakeDefaultAppStep *step =
+ qobject_cast<QdbMakeDefaultAppStep *>(this->step());
+ step->setMakeDefault(true);
+ }
+
+ Q_SLOT void handleResetDefault() {
+ QdbMakeDefaultAppStep *step =
+ qobject_cast<QdbMakeDefaultAppStep *>(this->step());
+ step->setMakeDefault(false);
+ }
+
+ QRadioButton m_makeDefaultBtn;
+ QRadioButton m_resetDefaultBtn;
+};
+
+QdbMakeDefaultAppStep::QdbMakeDefaultAppStep(ProjectExplorer::BuildStepList *bsl)
+ : AbstractRemoteLinuxDeployStep(bsl, stepId())
+{
+ d = new QdbMakeDefaultAppStepPrivate;
+ setDefaultDisplayName(stepDisplayName());
+
+}
+
+QdbMakeDefaultAppStep::~QdbMakeDefaultAppStep()
+{
+ delete d;
+}
+
+Core::Id QdbMakeDefaultAppStep::stepId()
+{
+ return "Qdb.MakeDefaultAppStep";
+}
+
+RemoteLinux::CheckResult QdbMakeDefaultAppStep::initInternal()
+{
+ d->deployService.setMakeDefault(d->makeDefault);
+ return deployService()->isDeploymentPossible();
+}
+
+RemoteLinux::AbstractRemoteLinuxDeployService *QdbMakeDefaultAppStep::deployService() const
+{
+ return &d->deployService;
+}
+
+ProjectExplorer::BuildStepConfigWidget *QdbMakeDefaultAppStep::createConfigWidget()
+{
+ return new QdbConfigWidget(this);
+}
+
+QString QdbMakeDefaultAppStep::stepDisplayName()
+{
+ return QStringLiteral("Change default application");
+}
+
+void QdbMakeDefaultAppStep::setMakeDefault(bool makeDefault)
+{
+ d->makeDefault = makeDefault;
+}
+
+bool QdbMakeDefaultAppStep::makeDefault() const
+{
+ return d->makeDefault;
+}
+
+static QString makeDefaultKey()
+{
+ return QLatin1String("QdbMakeDefaultDeployStep.MakeDefault");
+}
+
+bool QdbMakeDefaultAppStep::fromMap(const QVariantMap &map)
+{
+ if (!AbstractRemoteLinuxDeployStep::fromMap(map))
+ return false;
+ d->makeDefault = map.value(makeDefaultKey()).toBool();
+ return true;
+}
+
+QVariantMap QdbMakeDefaultAppStep::toMap() const
+{
+ QVariantMap map = AbstractRemoteLinuxDeployStep::toMap();
+ map.insert(makeDefaultKey(), d->makeDefault);
+ return map;
+}
+} // namespace Internal
+} // namespace Qdb
+
+#include "qdbmakedefaultappstep.moc"
diff --git a/src/plugins/boot2qt/qdbmakedefaultappstep.h b/src/plugins/boot2qt/qdbmakedefaultappstep.h
new file mode 100644
index 0000000000..9e04f78f46
--- /dev/null
+++ b/src/plugins/boot2qt/qdbmakedefaultappstep.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <remotelinux/abstractremotelinuxdeploystep.h>
+
+namespace Qdb {
+namespace Internal {
+
+class QdbMakeDefaultAppStepPrivate;
+
+class QdbMakeDefaultAppStep : public RemoteLinux::AbstractRemoteLinuxDeployStep
+{
+ Q_OBJECT
+
+public:
+ explicit QdbMakeDefaultAppStep(ProjectExplorer::BuildStepList *bsl);
+
+ ~QdbMakeDefaultAppStep() override;
+ static Core::Id stepId();
+ static QString stepDisplayName();
+
+ void setMakeDefault(bool makeDefault);
+ bool makeDefault() const;
+
+protected:
+ RemoteLinux::CheckResult initInternal() override;
+ RemoteLinux::AbstractRemoteLinuxDeployService *deployService() const override;
+ ProjectExplorer::BuildStepConfigWidget *createConfigWidget() override;
+ bool fromMap(const QVariantMap &map) override;
+ QVariantMap toMap() const override;
+
+private:
+ QdbMakeDefaultAppStepPrivate *d;
+};
+
+} // namespace Internal
+} // namespace Qdb
diff --git a/src/plugins/boot2qt/qdbplugin.cpp b/src/plugins/boot2qt/qdbplugin.cpp
new file mode 100644
index 0000000000..e726118eb1
--- /dev/null
+++ b/src/plugins/boot2qt/qdbplugin.cpp
@@ -0,0 +1,240 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "qdbplugin.h"
+
+#include "device-detection/devicedetector.h"
+#include "qdbdeployconfigurationfactory.h"
+#include "qdbdeploystepfactory.h"
+#include "qdbdevicedebugsupport.h"
+#include "qdbqtversion.h"
+#include "qdbrunconfiguration.h"
+#include "qdbutils.h"
+
+#include <coreplugin/actionmanager/actioncontainer.h>
+#include <coreplugin/actionmanager/actionmanager.h>
+#include <coreplugin/icore.h>
+
+#include <projectexplorer/devicesupport/devicemanager.h>
+#include <projectexplorer/kitinformation.h>
+#include <projectexplorer/kitmanager.h>
+#include <projectexplorer/target.h>
+
+#include <qtsupport/qtversionfactory.h>
+
+#include <remotelinux/remotelinuxcheckforfreediskspacestep.h>
+#include <remotelinux/genericdirectuploadstep.h>
+
+#include <utils/hostosinfo.h>
+#include <utils/fileutils.h>
+
+#include <QAction>
+#include <QFileInfo>
+#include <QProcess>
+
+using namespace ProjectExplorer;
+
+namespace Qdb {
+namespace Internal {
+
+static Utils::FilePath flashWizardFilePath()
+{
+ return findTool(QdbTool::FlashingWizard);
+}
+
+static void startFlashingWizard()
+{
+ const QString filePath = flashWizardFilePath().toUserOutput();
+ if (Utils::HostOsInfo::isWindowsHost()) {
+ if (QProcess::startDetached(QLatin1String("explorer.exe"), {filePath}))
+ return;
+ } else if (QProcess::startDetached(filePath)) {
+ return;
+ }
+ const QString message =
+ QCoreApplication::translate("Qdb", "Flash wizard \"%1\" failed to start.");
+ showMessage(message.arg(filePath), true);
+}
+
+void registerFlashAction(QObject *parentForAction)
+{
+ if (isFlashActionDisabled())
+ return;
+ const Utils::FilePath fileName = flashWizardFilePath();
+ if (!fileName.exists()) {
+ const QString message =
+ QCoreApplication::translate("Qdb", "Flash wizard executable \"%1\" not found.");
+ showMessage(message.arg(fileName.toString()));
+ return;
+ }
+
+ const char flashActionId[] = "Qdb.FlashAction";
+ if (Core::ActionManager::command(flashActionId))
+ return; // The action has already been registered.
+
+ Core::ActionContainer *toolsContainer =
+ Core::ActionManager::actionContainer(Core::Constants::M_TOOLS);
+ toolsContainer->insertGroup(Core::Constants::G_TOOLS_OPTIONS,
+ flashActionId);
+
+ Core::Context globalContext(Core::Constants::C_GLOBAL);
+
+ const QString actionText = QCoreApplication::translate("Qdb", "Flash Boot to Qt Device");
+ QAction *flashAction = new QAction(actionText, parentForAction);
+ Core::Command *flashCommand = Core::ActionManager::registerAction(flashAction,
+ flashActionId,
+ globalContext);
+ QObject::connect(flashAction, &QAction::triggered, startFlashingWizard);
+ toolsContainer->addAction(flashCommand, flashActionId);
+}
+
+class QdbQtVersionFactory : public QtSupport::QtVersionFactory
+{
+public:
+ QdbQtVersionFactory()
+ {
+ setQtVersionCreator([] { return new QdbQtVersion; });
+ setSupportedType("Qdb.EmbeddedLinuxQt");
+ setPriority(99);
+ setRestrictionChecker([](const SetupData &setup) {
+ return setup.platforms.contains("boot2qt");
+ });
+ }
+};
+
+class QdbDeviceRunSupport : public SimpleTargetRunner
+{
+public:
+ QdbDeviceRunSupport(RunControl *runControl)
+ : SimpleTargetRunner(runControl)
+ {}
+
+ void start() final
+ {
+ Runnable r = runnable();
+ r.commandLineArguments = r.executable + ' ' + r.commandLineArguments;
+ r.executable = Constants::AppcontrollerFilepath;
+ setRunnable(r);
+ SimpleTargetRunner::start();
+ }
+};
+
+template <class Step>
+class QdbDeployStepFactory : public ProjectExplorer::BuildStepFactory
+{
+public:
+ QdbDeployStepFactory()
+ {
+ registerStep<Step>(Step::stepId());
+ setDisplayName(Step::displayName());
+ setSupportedConfiguration(Constants::QdbDeployConfigurationId);
+ setSupportedStepList(ProjectExplorer::Constants::BUILDSTEPS_DEPLOY);
+ }
+};
+
+class QdbPluginPrivate : public QObject
+{
+public:
+ void setupDeviceDetection();
+
+ QdbLinuxDeviceFactory m_qdbDeviceFactory;
+ QdbQtVersionFactory m_qtVersionFactory;
+ QdbDeployConfigurationFactory m_deployConfigFactory;
+ QdbRunConfigurationFactory m_runConfigFactory;
+ QdbStopApplicationStepFactory m_stopApplicationStepFactory;
+ QdbMakeDefaultAppStepFactory m_makeDefaultAppStepFactory;
+
+ QdbDeployStepFactory<RemoteLinux::RemoteLinuxCheckForFreeDiskSpaceStep>
+ m_checkForFreeDiskSpaceStepFactory;
+ QdbDeployStepFactory<RemoteLinux::GenericDirectUploadStep>
+ m_directUploadStepFactory;
+
+ DeviceDetector m_deviceDetector;
+};
+
+QdbPlugin::~QdbPlugin()
+{
+ delete d;
+}
+
+bool QdbPlugin::initialize(const QStringList &arguments, QString *errorString)
+{
+ Q_UNUSED(arguments)
+ Q_UNUSED(errorString)
+
+ d = new QdbPluginPrivate;
+
+ auto constraint = [](RunConfiguration *runConfiguration) {
+ const Core::Id devType = DeviceTypeKitAspect::deviceTypeId(
+ runConfiguration->target()->kit());
+
+ if (devType != Qdb::Constants::QdbLinuxOsType)
+ return false;
+
+ const Core::Id id = runConfiguration->id();
+ return runConfiguration->isEnabled()
+ && (id.name().startsWith(Constants::QdbRunConfigurationPrefix)
+ || id.name().startsWith("QmlProjectManager.QmlRunConfiguration"));
+ };
+
+ RunControl::registerWorker<QdbDeviceRunSupport>
+ (ProjectExplorer::Constants::NORMAL_RUN_MODE, constraint);
+ RunControl::registerWorker<QdbDeviceDebugSupport>
+ (ProjectExplorer::Constants::DEBUG_RUN_MODE, constraint);
+ RunControl::registerWorker<QdbDeviceQmlProfilerSupport>
+ (ProjectExplorer::Constants::QML_PROFILER_RUN_MODE, constraint);
+ RunControl::registerWorker<QdbDeviceQmlPreviewSupport>
+ (ProjectExplorer::Constants::QML_PREVIEW_RUN_MODE, constraint);
+
+ registerFlashAction(this);
+
+ return true;
+}
+
+void QdbPlugin::extensionsInitialized()
+{
+ DeviceManager * const dm = DeviceManager::instance();
+ if (dm->isLoaded()) {
+ d->setupDeviceDetection();
+ } else {
+ connect(dm, &DeviceManager::devicesLoaded,
+ d, &QdbPluginPrivate::setupDeviceDetection);
+ }
+}
+
+ExtensionSystem::IPlugin::ShutdownFlag QdbPlugin::aboutToShutdown()
+{
+ d->m_deviceDetector.stop();
+
+ return SynchronousShutdown;
+}
+
+void QdbPluginPrivate::setupDeviceDetection()
+{
+ m_deviceDetector.start();
+}
+
+} // Internal
+} // Qdb
diff --git a/src/plugins/boot2qt/qdbplugin.h b/src/plugins/boot2qt/qdbplugin.h
new file mode 100644
index 0000000000..2f1611fa60
--- /dev/null
+++ b/src/plugins/boot2qt/qdbplugin.h
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <extensionsystem/iplugin.h>
+
+namespace Qdb {
+namespace Internal {
+
+class QdbPlugin : public ExtensionSystem::IPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "Boot2Qt.json")
+
+public:
+ QdbPlugin() = default;
+ ~QdbPlugin() final;
+
+private:
+ bool initialize(const QStringList &arguments, QString *errorString) final;
+ void extensionsInitialized() final;
+ ShutdownFlag aboutToShutdown() final;
+
+ class QdbPluginPrivate *d = nullptr;
+};
+
+} // namespace Internal
+} // namespace Qdb
diff --git a/src/plugins/boot2qt/qdbqtversion.cpp b/src/plugins/boot2qt/qdbqtversion.cpp
new file mode 100644
index 0000000000..ea62199106
--- /dev/null
+++ b/src/plugins/boot2qt/qdbqtversion.cpp
@@ -0,0 +1,47 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "qdbqtversion.h"
+
+#include "qdbconstants.h"
+
+#include <coreplugin/id.h>
+
+namespace Qdb {
+namespace Internal {
+
+QString QdbQtVersion::description() const
+{
+ return QCoreApplication::translate("QtVersion", "Boot2Qt", "Qt version is used for Boot2Qt development");
+}
+
+QSet<Core::Id> QdbQtVersion::targetDeviceTypes() const
+{
+ return {Core::Id(Constants::QdbLinuxOsType)};
+
+}
+
+} // namespace Internal
+} // namespace Qdb
diff --git a/src/plugins/boot2qt/qdbqtversion.h b/src/plugins/boot2qt/qdbqtversion.h
new file mode 100644
index 0000000000..ac95a70701
--- /dev/null
+++ b/src/plugins/boot2qt/qdbqtversion.h
@@ -0,0 +1,44 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <qtsupport/baseqtversion.h>
+
+namespace Qdb {
+namespace Internal {
+
+class QdbQtVersion : public QtSupport::BaseQtVersion
+{
+public:
+ QdbQtVersion() = default;
+ ~QdbQtVersion() = default;
+
+ QString description() const final;
+ QSet<Core::Id> targetDeviceTypes() const final;
+};
+
+} // namespace Internal
+} // namespace Qdb
diff --git a/src/plugins/boot2qt/qdbrunconfiguration.cpp b/src/plugins/boot2qt/qdbrunconfiguration.cpp
new file mode 100644
index 0000000000..4f998511a2
--- /dev/null
+++ b/src/plugins/boot2qt/qdbrunconfiguration.cpp
@@ -0,0 +1,141 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "qdbrunconfiguration.h"
+
+#include "qdbconstants.h"
+
+#include <projectexplorer/buildtargetinfo.h>
+#include <projectexplorer/deploymentdata.h>
+#include <projectexplorer/project.h>
+#include <projectexplorer/runconfigurationaspects.h>
+#include <projectexplorer/target.h>
+
+#include <qtsupport/qtoutputformatter.h>
+
+#include <remotelinux/remotelinuxenvironmentaspect.h>
+
+using namespace ProjectExplorer;
+using namespace Utils;
+
+namespace Qdb {
+namespace Internal {
+
+// FullCommandLineAspect
+
+FullCommandLineAspect::FullCommandLineAspect(RunConfiguration *rc)
+{
+ setLabelText(QdbRunConfiguration::tr("Full command line:"));
+
+ auto exeAspect = rc->aspect<ExecutableAspect>();
+ auto argumentsAspect = rc->aspect<ArgumentsAspect>();
+
+ auto updateCommandLine = [this, rc, exeAspect, argumentsAspect] {
+ const QString usedExecutable = exeAspect->executable().toString();
+ const QString args = argumentsAspect->arguments(rc->macroExpander());
+ setValue(QString(Constants::AppcontrollerFilepath)
+ + ' ' + usedExecutable + ' ' + args);
+ };
+
+ connect(argumentsAspect, &ArgumentsAspect::argumentsChanged, this, updateCommandLine);
+ connect(exeAspect, &ExecutableAspect::changed, this, updateCommandLine);
+ updateCommandLine();
+}
+
+// QdbRunConfiguration
+
+QdbRunConfiguration::QdbRunConfiguration(Target *target, Core::Id id)
+ : RunConfiguration(target, id)
+{
+ auto exeAspect = addAspect<ExecutableAspect>();
+ exeAspect->setSettingsKey("QdbRunConfig.RemoteExecutable");
+ exeAspect->setLabelText(tr("Executable on device:"));
+ exeAspect->setExecutablePathStyle(OsTypeLinux);
+ exeAspect->setPlaceHolderText(tr("Remote path not set"));
+ exeAspect->makeOverridable("QdbRunConfig.AlternateRemoteExecutable",
+ "QdbRunCofig.UseAlternateRemoteExecutable");
+
+ auto symbolsAspect = addAspect<SymbolFileAspect>();
+ symbolsAspect->setSettingsKey("QdbRunConfig.LocalExecutable");
+ symbolsAspect->setLabelText(tr("Executable on host:"));
+ symbolsAspect->setDisplayStyle(SymbolFileAspect::LabelDisplay);
+
+ addAspect<RemoteLinux::RemoteLinuxEnvironmentAspect>(target);
+ addAspect<ArgumentsAspect>();
+ addAspect<WorkingDirectoryAspect>();
+ addAspect<FullCommandLineAspect>(this);
+
+ setOutputFormatter<QtSupport::QtOutputFormatter>();
+
+ connect(target, &Target::deploymentDataChanged,
+ this, &QdbRunConfiguration::updateTargetInformation);
+ connect(target, &Target::applicationTargetsChanged,
+ this, &QdbRunConfiguration::updateTargetInformation);
+ connect(target, &Target::kitChanged,
+ this, &QdbRunConfiguration::updateTargetInformation);
+ connect(target->project(), &Project::parsingFinished,
+ this, &QdbRunConfiguration::updateTargetInformation);
+
+ setDefaultDisplayName(tr("Run on Boot2Qt Device"));
+}
+
+ProjectExplorer::RunConfiguration::ConfigurationState QdbRunConfiguration::ensureConfigured(QString *errorMessage)
+{
+ QString remoteExecutable = aspect<ExecutableAspect>()->executable().toString();
+ if (remoteExecutable.isEmpty()) {
+ if (errorMessage) {
+ *errorMessage = tr("The remote executable must be set "
+ "in order to run on a Boot2Qt device.");
+ }
+ return UnConfigured;
+ }
+ return Configured;
+}
+
+void QdbRunConfiguration::updateTargetInformation()
+{
+ BuildTargetInfo bti = buildTargetInfo();
+ QString localExecutable = bti.targetFilePath.toString();
+ DeployableFile depFile = target()->deploymentData().deployableForLocalFile(localExecutable);
+
+ aspect<ExecutableAspect>()->setExecutable(FilePath::fromString(depFile.remoteFilePath()));
+ aspect<SymbolFileAspect>()->setValue(localExecutable);
+}
+
+QString QdbRunConfiguration::defaultDisplayName() const
+{
+ return RunConfigurationFactory::decoratedTargetName(buildKey(), target());
+}
+
+// QdbRunConfigurationFactory
+
+QdbRunConfigurationFactory::QdbRunConfigurationFactory()
+{
+ registerRunConfiguration<QdbRunConfiguration>(Qdb::Constants::QdbRunConfigurationPrefix);
+ addSupportedTargetDeviceType(Constants::QdbLinuxOsType);
+}
+
+} // namespace Internal
+} // namespace Qdb
diff --git a/src/plugins/boot2qt/qdbrunconfiguration.h b/src/plugins/boot2qt/qdbrunconfiguration.h
new file mode 100644
index 0000000000..0099c63b5e
--- /dev/null
+++ b/src/plugins/boot2qt/qdbrunconfiguration.h
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <projectexplorer/runconfigurationaspects.h>
+
+namespace Qdb {
+namespace Internal {
+
+class FullCommandLineAspect : public ProjectExplorer::BaseStringAspect
+{
+ Q_OBJECT
+
+public:
+ explicit FullCommandLineAspect(ProjectExplorer::RunConfiguration *rc);
+};
+
+class QdbRunConfiguration : public ProjectExplorer::RunConfiguration
+{
+ Q_OBJECT
+
+public:
+ QdbRunConfiguration(ProjectExplorer::Target *target, Core::Id id);
+
+ ConfigurationState ensureConfigured(QString *errorMessage) override;
+
+private:
+ void updateTargetInformation();
+ QString defaultDisplayName() const;
+};
+
+class QdbRunConfigurationFactory : public ProjectExplorer::RunConfigurationFactory
+{
+public:
+ QdbRunConfigurationFactory();
+};
+
+} // namespace Internal
+} // namespace Qdb
diff --git a/src/plugins/boot2qt/qdbstopapplicationservice.cpp b/src/plugins/boot2qt/qdbstopapplicationservice.cpp
new file mode 100644
index 0000000000..e39e3d005a
--- /dev/null
+++ b/src/plugins/boot2qt/qdbstopapplicationservice.cpp
@@ -0,0 +1,123 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "qdbstopapplicationservice.h"
+
+#include "qdbconstants.h"
+
+#include <projectexplorer/applicationlauncher.h>
+#include <projectexplorer/kitinformation.h>
+#include <projectexplorer/runcontrol.h>
+#include <projectexplorer/target.h>
+
+namespace Qdb {
+namespace Internal {
+
+class QdbStopApplicationServicePrivate
+{
+public:
+ ProjectExplorer::ApplicationLauncher applicationLauncher;
+ QString errorOutput;
+};
+
+QdbStopApplicationService::QdbStopApplicationService(QObject *parent)
+ : AbstractRemoteLinuxDeployService(parent),
+ d(new QdbStopApplicationServicePrivate)
+{
+
+}
+
+QdbStopApplicationService::~QdbStopApplicationService()
+{
+ cleanup();
+ delete d;
+}
+
+void QdbStopApplicationService::handleProcessFinished(bool success)
+{
+ const auto failureMessage = tr("Could not check and possibly stop running application.");
+ if (!success) {
+ emit errorMessage(failureMessage);
+ stopDeployment();
+ return;
+ }
+
+ if (d->errorOutput.contains("Could not connect: Connection refused")) {
+ emit progressMessage(tr("Checked that there is no running application."));
+ } else if (!d->errorOutput.isEmpty()) {
+ emit stdErrData(d->errorOutput);
+ emit errorMessage(failureMessage);
+ } else {
+ emit progressMessage(tr("Stopped the running application."));
+ }
+
+ stopDeployment();
+}
+
+void QdbStopApplicationService::handleStderr(const QString &output)
+{
+ d->errorOutput.append(output);
+}
+
+void QdbStopApplicationService::handleStdout(const QString &output)
+{
+ emit stdOutData(output);
+}
+
+void QdbStopApplicationService::doDeploy()
+{
+ connect(&d->applicationLauncher, &ProjectExplorer::ApplicationLauncher::reportError,
+ this, &QdbStopApplicationService::stdErrData);
+ connect(&d->applicationLauncher, &ProjectExplorer::ApplicationLauncher::remoteStderr,
+ this, &QdbStopApplicationService::handleStderr);
+ connect(&d->applicationLauncher, &ProjectExplorer::ApplicationLauncher::remoteStdout,
+ this, &QdbStopApplicationService::handleStdout);
+ connect(&d->applicationLauncher, &ProjectExplorer::ApplicationLauncher::finished,
+ this, &QdbStopApplicationService::handleProcessFinished);
+ connect(&d->applicationLauncher, &ProjectExplorer::ApplicationLauncher::reportProgress,
+ this, &QdbStopApplicationService::stdOutData);
+
+ ProjectExplorer::Runnable runnable;
+ runnable.executable = Constants::AppcontrollerFilepath;
+ runnable.commandLineArguments = QStringLiteral("--stop");
+ runnable.workingDirectory = QStringLiteral("/usr/bin");
+
+ d->applicationLauncher.start(runnable,
+ ProjectExplorer::DeviceKitAspect::device(target()->kit()));
+}
+
+void QdbStopApplicationService::stopDeployment()
+{
+ cleanup();
+ handleDeploymentDone();
+}
+
+void QdbStopApplicationService::cleanup()
+{
+ d->applicationLauncher.disconnect(this);
+}
+
+} // namespace Internal
+} // namespace Qdb
diff --git a/src/plugins/boot2qt/qdbstopapplicationservice.h b/src/plugins/boot2qt/qdbstopapplicationservice.h
new file mode 100644
index 0000000000..19dbc1f585
--- /dev/null
+++ b/src/plugins/boot2qt/qdbstopapplicationservice.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <remotelinux/abstractremotelinuxdeployservice.h>
+
+namespace Qdb {
+namespace Internal {
+
+class QdbStopApplicationServicePrivate;
+
+class QdbStopApplicationService : public RemoteLinux::AbstractRemoteLinuxDeployService
+{
+ Q_OBJECT
+public:
+ QdbStopApplicationService(QObject *parent = 0);
+ ~QdbStopApplicationService();
+
+private slots:
+ void handleProcessFinished(bool success);
+ void handleStderr(const QString &output);
+ void handleStdout(const QString &output);
+
+private:
+ bool isDeploymentNecessary() const final { return true; }
+ void doDeviceSetup() final { handleDeviceSetupDone(true); }
+ void stopDeviceSetup() final { handleDeviceSetupDone(false); }
+
+ void doDeploy() final;
+ void stopDeployment() final;
+
+ void cleanup();
+
+ QdbStopApplicationServicePrivate * const d;
+};
+
+} // namespace Internal
+} // namespace Qdb
diff --git a/src/plugins/boot2qt/qdbstopapplicationstep.cpp b/src/plugins/boot2qt/qdbstopapplicationstep.cpp
new file mode 100644
index 0000000000..982211189b
--- /dev/null
+++ b/src/plugins/boot2qt/qdbstopapplicationstep.cpp
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "qdbstopapplicationstep.h"
+
+#include "qdbstopapplicationservice.h"
+
+namespace Qdb {
+namespace Internal {
+
+class QdbStopApplicationStepPrivate
+{
+public:
+ QdbStopApplicationService deployService;
+};
+
+QdbStopApplicationStep::QdbStopApplicationStep(ProjectExplorer::BuildStepList *bsl)
+ : AbstractRemoteLinuxDeployStep(bsl, stepId())
+{
+ d = new QdbStopApplicationStepPrivate;
+ setDefaultDisplayName(stepDisplayName());
+ setWidgetExpandedByDefault(false);
+}
+
+QdbStopApplicationStep::~QdbStopApplicationStep()
+{
+ delete d;
+}
+
+Core::Id QdbStopApplicationStep::stepId()
+{
+ return "Qdb.StopApplicationStep";
+}
+
+RemoteLinux::CheckResult QdbStopApplicationStep::initInternal()
+{
+ return deployService()->isDeploymentPossible();
+}
+
+RemoteLinux::AbstractRemoteLinuxDeployService *QdbStopApplicationStep::deployService() const
+{
+ return &d->deployService;
+}
+
+QString QdbStopApplicationStep::stepDisplayName()
+{
+ return tr("Stop already running application");
+}
+
+} // namespace Internal
+} // namespace Qdb
diff --git a/src/plugins/boot2qt/qdbstopapplicationstep.h b/src/plugins/boot2qt/qdbstopapplicationstep.h
new file mode 100644
index 0000000000..b9d1d6e3e8
--- /dev/null
+++ b/src/plugins/boot2qt/qdbstopapplicationstep.h
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <remotelinux/abstractremotelinuxdeploystep.h>
+
+namespace Qdb {
+namespace Internal {
+
+class QdbStopApplicationStepPrivate;
+
+class QdbStopApplicationStep : public RemoteLinux::AbstractRemoteLinuxDeployStep
+{
+ Q_OBJECT
+public:
+ explicit QdbStopApplicationStep(ProjectExplorer::BuildStepList *bsl);
+
+ ~QdbStopApplicationStep() final;
+ static Core::Id stepId();
+ static QString stepDisplayName();
+
+protected:
+ RemoteLinux::CheckResult initInternal() final;
+ RemoteLinux::AbstractRemoteLinuxDeployService *deployService() const final;
+
+private:
+ QdbStopApplicationStepPrivate *d;
+};
+
+} // namespace Internal
+} // namespace Qdb
diff --git a/src/plugins/boot2qt/qdbutils.cpp b/src/plugins/boot2qt/qdbutils.cpp
new file mode 100644
index 0000000000..8ba78928e0
--- /dev/null
+++ b/src/plugins/boot2qt/qdbutils.cpp
@@ -0,0 +1,138 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "qdbutils.h"
+
+#include <coreplugin/icore.h>
+#include <coreplugin/messagemanager.h>
+#include <utils/hostosinfo.h>
+#include <utils/fileutils.h>
+#include <utils/qtcassert.h>
+
+#include <QDir>
+
+namespace Qdb {
+namespace Internal {
+
+static QString executableBaseName(QdbTool tool)
+{
+ switch (tool) {
+ case QdbTool::Adb:
+ return QLatin1String("adb");
+ case QdbTool::FlashingWizard:
+ return QLatin1String("b2qt-flashing-wizard");
+ case QdbTool::Qdb:
+ return QLatin1String("qdb");
+ }
+ QTC_CHECK(false);
+ return QString();
+}
+
+QString appControllerFilePath()
+{
+ return QLatin1String("appcontroller");
+}
+
+Utils::FilePath findTool(QdbTool tool, PathSource *source)
+{
+ QString filePath = QString::fromLocal8Bit(qgetenv(overridingEnvironmentVariable(tool)));
+ if (source)
+ *source = PathSource::Environment;
+
+ if (filePath.isEmpty()) {
+ QSettings * const settings = Core::ICore::settings();
+ settings->beginGroup(settingsGroupKey());
+ filePath = settings->value(settingsKey(tool)).toString();
+ settings->endGroup();
+ if (source)
+ *source = PathSource::Settings;
+ }
+
+ if (filePath.isEmpty()) {
+ filePath = Utils::HostOsInfo::withExecutableSuffix(
+ QCoreApplication::applicationDirPath()
+#ifdef Q_OS_MACOS
+ + QLatin1String("/../../../Tools/b2qt/")
+#else
+ + QLatin1String("/../../b2qt/")
+#endif
+ + executableBaseName(tool));
+ if (source)
+ *source = PathSource::Fallback;
+ }
+
+ return Utils::FilePath::fromString(QDir::cleanPath(filePath));
+}
+
+bool isFlashActionDisabled()
+{
+ QSettings * const settings = Core::ICore::settings();
+ settings->beginGroup(settingsGroupKey());
+ bool disabled = settings->value("flashActionDisabled", false).toBool();
+ settings->endGroup();
+ return disabled;
+}
+
+const char *overridingEnvironmentVariable(QdbTool tool)
+{
+ switch (tool) {
+ case QdbTool::Adb:
+ return "BOOT2QT_ADB_FILEPATH";
+ case QdbTool::FlashingWizard:
+ return "BOOT2QT_FLASHWIZARD_FILEPATH";
+ case QdbTool::Qdb:
+ return "BOOT2QT_QDB_FILEPATH";
+ }
+ QTC_ASSERT(false, return "");
+}
+
+void showMessage(const QString &message, bool important)
+{
+ const QString fullMessage = QCoreApplication::translate("Boot2Qt", "Boot2Qt: %1").arg(message);
+ const Core::MessageManager::PrintToOutputPaneFlags flags = important
+ ? Core::MessageManager::ModeSwitch : Core::MessageManager::Silent;
+ Core::MessageManager::write(fullMessage, flags);
+}
+
+QString settingsGroupKey()
+{
+ return QLatin1String("Boot2Qt");
+}
+
+QString settingsKey(QdbTool tool)
+{
+ switch (tool) {
+ case QdbTool::Adb:
+ return QLatin1String("adbFilePath");
+ case QdbTool::FlashingWizard:
+ return QLatin1String("flashingWizardFilePath");
+ case QdbTool::Qdb:
+ return QLatin1String("qdbFilePath");
+ }
+ QTC_ASSERT(false, return QString());
+}
+
+} // namespace Internal
+} // namespace Qdb
diff --git a/src/plugins/boot2qt/qdbutils.h b/src/plugins/boot2qt/qdbutils.h
new file mode 100644
index 0000000000..a67930fbec
--- /dev/null
+++ b/src/plugins/boot2qt/qdbutils.h
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <utils/fileutils.h>
+
+#include <qglobal.h>
+
+namespace Qdb {
+namespace Internal {
+
+enum class QdbTool {
+ Adb,
+ FlashingWizard,
+ Qdb
+};
+
+enum class PathSource {
+ Environment,
+ Settings,
+ Fallback
+};
+
+QString appControllerFilePath();
+Utils::FilePath findTool(QdbTool tool, PathSource *source = nullptr);
+bool isFlashActionDisabled();
+const char *overridingEnvironmentVariable(QdbTool tool);
+void showMessage(const QString &message, bool important = false);
+QString settingsGroupKey();
+QString settingsKey(QdbTool tool);
+
+} // namespace Internal
+} // namespace Qdb