diff options
author | Bramastyo Harimukti <bramastyo.harimukti.santoso@pelagicore.com> | 2019-05-16 10:38:19 +0200 |
---|---|---|
committer | Bramastyo Harimukti Santoso <bramastyo.harimukti.santoso@pelagicore.com> | 2019-05-16 09:23:21 +0000 |
commit | cef6b1e9b20e24c966c3408fcdadee92f07a81a6 (patch) | |
tree | e0f5560db7bfd16662b60f020d15302dc2310fdc /src/remotesettings | |
parent | 0275cfa4d765afcf1b4a4f7888534b3bd5eb7457 (diff) |
[middleware] rename dataprovider back to remotesettings
- as discussed, it is better to keep "remotesettings" than having
an intermediate name for 5.13 release
Change-Id: I37fd3f21dc5faf8dbad98b38674f6ed711617069
Reviewed-by: Kavindra Palaraja <kpalaraja@luxoft.com>
Reviewed-by: Egor Nemtsev <enemtsev@luxoft.com>
Diffstat (limited to 'src/remotesettings')
25 files changed, 1846 insertions, 0 deletions
diff --git a/src/remotesettings/app/ClusterPage.qml b/src/remotesettings/app/ClusterPage.qml new file mode 100644 index 00000000..ef719acc --- /dev/null +++ b/src/remotesettings/app/ClusterPage.qml @@ -0,0 +1,485 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Neptune 3 IVI UI. +** +** $QT_BEGIN_LICENSE:GPL-QTAS$ +** Commercial License Usage +** Licensees holding valid commercial Qt Automotive Suite 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 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** 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. +** +** $QT_END_LICENSE$ +** +** SPDX-License-Identifier: GPL-3.0 +** +****************************************************************************/ +import QtQuick 2.8 +import QtQuick.Controls 2.2 +import QtQuick.Layouts 1.3 + + +Flickable { + id: root + flickableDirection: Flickable.VerticalFlick + contentHeight: baseLayout.height + + property bool simulationEnabled: false + + ScrollIndicator.vertical: ScrollIndicator { } + + ColumnLayout { + id: baseLayout + enabled: instrumentCluster.isInitialized && client.connected + spacing: 20 + anchors.centerIn: parent + + RowLayout { + spacing: sc(10) + Layout.alignment: Qt.AlignHCenter + + // speed Field + Dial { + id: speedDial + from: 0 + to: 260 + stepSize: 1.0 + value: instrumentCluster.speed + onMoved: instrumentCluster.speed = value + + Label { + text: qsTr("Speed:") + anchors.bottom: speedDial.verticalCenter + anchors.horizontalCenter: speedDial.horizontalCenter + } + + Label { + id: speedLabel + text: Math.round(speedDial.value) + anchors.top: speedDial.verticalCenter + anchors.horizontalCenter: speedDial.horizontalCenter + } + } + + // ePower Field + Dial { + id: ePowerDial + from: -25 + to: 100 + stepSize: 1.0 + value: instrumentCluster.ePower + onMoved: instrumentCluster.ePower = value + + Label { + text: qsTr("ePower:") + anchors.bottom: ePowerDial.verticalCenter + anchors.horizontalCenter: ePowerDial.horizontalCenter + } + + Label { + id: ePowerLabel + text: Math.round(ePowerDial.value) + anchors.top: ePowerDial.verticalCenter + anchors.horizontalCenter: ePowerDial.horizontalCenter + } + } + } + + GridLayout { + Layout.alignment: Qt.AlignHCenter + columns: root.width < sc(100) ? 2 : 4 + + // speedLimit Field + Label { + text: qsTr("Speed limit:") + } + Slider { + id: speedLimitSlider + value: instrumentCluster.speedLimit + from: 0.0 + stepSize: 1.0 + to: 120.0 + onValueChanged: if (pressed) { instrumentCluster.speedLimit = value } + } + + // speedCruise Field + Label { + text: qsTr("Cruise speed:") + } + Slider { + id: speedCruiseSlider + value: instrumentCluster.speedCruise + from: 0.0 + stepSize: 1.0 + to: 120.0 + onValueChanged: if (pressed) { instrumentCluster.speedCruise = value } + } + + // driveTrainState field + Label { + text: qsTr("Gear:") + } + + ComboBox { + id: driveTrainStateComboBox + model: [qsTr("P"), qsTr("N"), qsTr("D"), qsTr("R")] + currentIndex: instrumentCluster.driveTrainState + onActivated: instrumentCluster.driveTrainState = currentIndex + } + Label { + text: qsTr("Navigation Mode:") + } + CheckBox { + checked: uiSettings.navigationMode + onClicked: uiSettings.navigationMode = checked + } + + Label { + text: qsTr("Simulation Mode:") + } + CheckBox { + checked: root.simulationEnabled + onClicked: root.simulationEnabled = !root.simulationEnabled + } + + Label { + text: qsTr("Hide Gauges:") + } + CheckBox { + checked: uiSettings.hideGauges + onClicked: uiSettings.hideGauges = checked + } + + Label { + text: qsTr("Flat Gauges:") + } + CheckBox { + checked: uiSettings.flatGauges + onClicked: uiSettings.flatGauges = checked + } + + /*! + Outside Temperature + */ + Label { + text: qsTr("Outside temperature: " + outsideTemperature.value.toFixed(1).padStart(6) + " °C") + } + Slider { + id: outsideTemperature + value: instrumentCluster.outsideTemperatureCelsius + from: -100 + stepSize: 0.5 + to: 100.0 + onValueChanged: if (pressed) { instrumentCluster.outsideTemperatureCelsius = value } + } + + /*! + Mileage in km + */ + Label { + text: qsTr("Mileage km") + } + Slider { + id: mileageKm + value: instrumentCluster.mileageKm + from: 0 + stepSize: 0.5 + to: 9E6 + onValueChanged: if (pressed) { instrumentCluster.mileageKm = value } + } + + /*! + DrivingMode field + */ + Label { + text: qsTr("Driving mode:") + } + + ComboBox { + id: driveingModeComboBox + model: [qsTr("Normal"), qsTr("ECO"), qsTr("Sport")] + currentIndex: instrumentCluster.drivingMode + onActivated: instrumentCluster.drivingMode = currentIndex + } + + /*! + Driving mode range Field + */ + Label { + text: qsTr("Driving mode range:") + } + Dial { + id: drivingModeRangeDial + from: 0 + to: 1000 + stepSize: 1.0 + value: instrumentCluster.drivingModeRangeKm + onMoved: instrumentCluster.drivingModeRangeKm = value + + + + Label { + text: Math.round(parent.value) + anchors.top: parent.verticalCenter + anchors.horizontalCenter: parent.horizontalCenter + } + } + + /*! + ECO mode range Field + */ + Label { + text: qsTr("ECO mode range:") + } + Dial { + id: ecoModeRangeDial + from: 0 + to: 500 + stepSize: 1.0 + value: instrumentCluster.drivingModeECORangeKm + onMoved: instrumentCluster.drivingModeECORangeKm = value + + + + Label { + text: Math.round(parent.value) + anchors.top: parent.verticalCenter + anchors.horizontalCenter: parent.horizontalCenter + } + } + + /*! + Route progress + */ + Label { + text: qsTr("Route progress, %:") + } + + Dial { + id: routeProgressDial + from: 0 + to: 1.0 + stepSize: 0.01 + value: instrumentCluster.navigationProgressPercents + onMoved: instrumentCluster.navigationProgressPercents = value + + + + Label { + text: Math.round(parent.value * 100.0) + anchors.top: parent.verticalCenter + anchors.horizontalCenter: parent.horizontalCenter + } + } + + /*! + Route distance + */ + Label { + text: qsTr("Route distance, km") + } + Slider { + id: routeDistance + value: instrumentCluster.navigationRouteDistanceKm + from: 0 + stepSize: 0.5 + to: 25000 + onValueChanged: if (pressed) { instrumentCluster.navigationRouteDistanceKm = value } + } + + Timer { + interval: 1000 + running: root.simulationEnabled + repeat: true + property int speedChange: 10 + onTriggered: { + if (instrumentCluster.speed > 140) { + speedChange = -10; + } + if (instrumentCluster.speed < 20) { + speedChange = 10; + } + instrumentCluster.speed += speedChange; + + if (instrumentCluster.ePower < 80) { + instrumentCluster.ePower = instrumentCluster.ePower + 2; + } else { + instrumentCluster.ePower = 0.0; + } + + if (instrumentCluster.speedCruise < 100) { + instrumentCluster.speedCruise = instrumentCluster.speedCruise + 10; + } else { + instrumentCluster.speedCruise = 0; + } + + if (instrumentCluster.mileageKm < 100000) { + instrumentCluster.mileageKm = instrumentCluster.mileageKm + Math.random(100) + } else { + instrumentCluster.mileageKm = 0 + } + + if (instrumentCluster.drivingModeRangeKm < 1000) { + instrumentCluster.drivingModeRangeKm = instrumentCluster.mileageKm + Math.random(20) + } else { + instrumentCluster.drivingModeRangeKm = 0 + } + + if (instrumentCluster.navigationProgressPercents < 1.0) { + instrumentCluster.navigationProgressPercents = instrumentCluster.navigationProgressPercents + + 0.01 + } else { + instrumentCluster.navigationProgressPercents = 0.0 + } + + if (instrumentCluster.navigationRouteDistanceKm < 130.0) { + instrumentCluster.navigationRouteDistanceKm = instrumentCluster.navigationRouteDistanceKm + + Math.random(10) + } else { + instrumentCluster.navigationRouteDistanceKm = 0.0 + } + } + } + } + + GridLayout { + Layout.alignment: Qt.AlignHCenter + columns: root.width < sc(100) ? 2 : 4 + + // lowBeamHeadlight Field + Label { + text: qsTr("Low beam headlight:") + } + CheckBox { + id: lowBeamHeadlightCheckbox + checked: instrumentCluster.lowBeamHeadlight + onClicked: instrumentCluster.lowBeamHeadlight = checked + } + + // highBeamHeadlight Field + Label { + text: qsTr("High beam headlight:") + } + CheckBox { + id: highBeamHeadlightCheckbox + checked: instrumentCluster.highBeamHeadlight + onClicked: instrumentCluster.highBeamHeadlight = checked + } + + // fogLight Field + Label { + text: qsTr("Fog light:") + } + CheckBox { + id: fogLightCheckbox + checked: instrumentCluster.fogLight + onClicked: instrumentCluster.fogLight = checked + } + + // stabilityControl Field + Label { + text: qsTr("Stability control:") + } + CheckBox { + id: stabilityControlCheckbox + checked: instrumentCluster.stabilityControl + onClicked: instrumentCluster.stabilityControl = checked + } + + // leftTurn Field + Label { + text: qsTr("Left turn:") + } + CheckBox { + id: leftTurnCheckbox + checked: instrumentCluster.leftTurn + onClicked: instrumentCluster.leftTurn = checked + } + + // rightTurn Field + Label { + text: qsTr("Right turn:") + } + CheckBox { + id: rightTurnCheckbox + checked: instrumentCluster.rightTurn + onClicked: instrumentCluster.rightTurn = checked + } + + // seatBeltNotFastened Field + Label { + text: qsTr("Seat belt not fastened:") + } + CheckBox { + id: seatBeltNotFastenedCheckbox + checked: instrumentCluster.seatBeltNotFastened + onClicked: instrumentCluster.seatBeltNotFastened = checked + } + + // ABSFailure Field + Label { + text: qsTr("ABS failure:") + } + CheckBox { + id: absFailureCheckbox + checked: instrumentCluster.ABSFailure + onClicked: instrumentCluster.ABSFailure = checked + } + + // parkBrake Field + Label { + text: qsTr("Park brake:") + } + CheckBox { + id: parkBrakeCheckbox + checked: instrumentCluster.parkBrake + onClicked: instrumentCluster.parkBrake = checked + } + + // tyrePressureLow Field + Label { + text: qsTr("Tyre pressure low:") + } + CheckBox { + id: tyrePressureLowCheckbox + checked: instrumentCluster.tyrePressureLow + onClicked: instrumentCluster.tyrePressureLow = checked + } + + // brakeFailure Field + Label { + text: qsTr("Brake failure:") + } + CheckBox { + id: brakeFailureCheckBox + checked: instrumentCluster.brakeFailure + onClicked: instrumentCluster.brakeFailure = checked + } + + // airbagFailure Field + Label { + text: qsTr("Airbag failure:") + } + CheckBox { + id: airbagFailureCheckBox + checked: instrumentCluster.airbagFailure + onClicked: instrumentCluster.airbagFailure = checked + } + } + } +} diff --git a/src/remotesettings/app/ConnectionDialog.qml b/src/remotesettings/app/ConnectionDialog.qml new file mode 100644 index 00000000..a4ca82a1 --- /dev/null +++ b/src/remotesettings/app/ConnectionDialog.qml @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Neptune 3 IVI UI. +** +** $QT_BEGIN_LICENSE:GPL-QTAS$ +** Commercial License Usage +** Licensees holding valid commercial Qt Automotive Suite 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 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** 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. +** +** $QT_END_LICENSE$ +** +** SPDX-License-Identifier: GPL-3.0 +** +****************************************************************************/ +import QtQuick 2.7 +import QtQuick.Controls 2.2 +import QtQuick.Layouts 1.3 + +Dialog { + id: connectionDialog + property string url + property string statusText + property var lastUrls + modal: true + + signal accepted(bool accepted) + + contentItem: Frame { + implicitWidth: 340 + implicitHeight: 240 + ColumnLayout { + anchors.fill: parent + + Label { + text: qsTr("Connection settings") + Layout.alignment: Qt.AlignCenter + } + + ColumnLayout { + Layout.fillWidth: true + Layout.alignment: Qt.AlignLeft + + Label { + text: qsTr("Server URL") + } + + ComboBox { + id: urlCombo + Layout.fillWidth: true + editable: true + editText: url + model: lastUrls + onEditTextChanged: url=editText + } + } + + + RowLayout { + spacing: sc(10) + Layout.fillWidth: true + Layout.alignment: Qt.AlignHCenter + + Button { + text: qsTr("Connect") + onClicked: connectionDialog.accepted(true) + } + + Button { + text: qsTr("Cancel") + onClicked: connectionDialog.accepted(false) + } + } + } + } +} diff --git a/src/remotesettings/app/SettingsPage.qml b/src/remotesettings/app/SettingsPage.qml new file mode 100644 index 00000000..17c82c97 --- /dev/null +++ b/src/remotesettings/app/SettingsPage.qml @@ -0,0 +1,145 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Neptune 3 IVI UI. +** +** $QT_BEGIN_LICENSE:GPL-QTAS$ +** Commercial License Usage +** Licensees holding valid commercial Qt Automotive Suite 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 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** 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. +** +** $QT_END_LICENSE$ +** +** SPDX-License-Identifier: GPL-3.0 +** +****************************************************************************/ +import QtQuick 2.8 +import QtQuick.Controls 2.2 +import QtQuick.Layouts 1.3 + + +Flickable { + id: root + flickableDirection: Flickable.VerticalFlick + contentHeight: baseLayout.height + + ScrollIndicator.vertical: ScrollIndicator { } + + GridLayout { + id: baseLayout + columns: 2 + enabled: uiSettings.isInitialized && client.connected + anchors.centerIn: parent + + // Language Field + Label { + text: qsTr("Language:") + } + ComboBox { + id: languageComboBox + model: uiSettings.languages + currentIndex: uiSettings.languages.indexOf(uiSettings.language) + onActivated: uiSettings.language = currentText + } + + // 24h format Field + Label { + text: qsTr("24h time format:") + } + CheckBox { + checked: uiSettings.twentyFourHourTimeFormat + onToggled: uiSettings.twentyFourHourTimeFormat = checked + } + + // right hand drive mode + Label { + text: qsTr("Right-to-left mode:") + } + CheckBox { + checked: uiSettings.rtlMode + onToggled: uiSettings.rtlMode = checked + } + + // Volume Field + Label { + text: qsTr("Volume:") + } + Slider { + id: volumeSlider + value: uiSettings.volume + from: 0.0 + to: 1.0 + onMoved: uiSettings.volume = value + } + + // Balance Field + Label { + text: qsTr("Balance:") + } + Slider { + id: balanceSlider + value: uiSettings.balance + from: 1.0 + to: -1.0 + onValueChanged: if (pressed) { uiSettings.balance = value } + } + + // Mute Field + Label { + text: qsTr("Mute:") + } + CheckBox { + id: muteCheckbox + checked: uiSettings.muted + onClicked: uiSettings.muted = checked + } + + // Theme Field + Label { + text: qsTr("Theme:") + } + + ComboBox { + id: themeComboBox + model: [qsTr("Light"), qsTr("Dark")] + currentIndex: uiSettings.theme + onActivated: uiSettings.theme = currentIndex + } + + // Door 1 Field + Label { + text: qsTr("Door 1:") + } + CheckBox { + id: door1OpenCheckbox + checked: uiSettings.door1Open + onClicked: uiSettings.door1Open = checked + } + + // Door 2 Field + Label { + text: qsTr("Door 2:") + } + CheckBox { + id: door2OpenCheckbox + checked: uiSettings.door2Open + onClicked: uiSettings.door2Open = checked + } + } +} diff --git a/src/remotesettings/app/SystemUIPage.qml b/src/remotesettings/app/SystemUIPage.qml new file mode 100644 index 00000000..6353caff --- /dev/null +++ b/src/remotesettings/app/SystemUIPage.qml @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Neptune 3 IVI UI. +** +** $QT_BEGIN_LICENSE:GPL-QTAS$ +** Commercial License Usage +** Licensees holding valid commercial Qt Automotive Suite 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 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** 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. +** +** $QT_END_LICENSE$ +** +** SPDX-License-Identifier: GPL-3.0 +** +****************************************************************************/ +import QtQuick 2.8 +import QtQuick.Controls 2.2 +import QtQuick.Layouts 1.3 + +Flickable { + id: root + flickableDirection: Flickable.VerticalFlick + contentHeight: baseLayout.height + + ScrollIndicator.vertical: ScrollIndicator { } + + ColumnLayout { + id: baseLayout + enabled: systemUI.isInitialized && client.connected + anchors.centerIn: parent + + Button { + text: qsTr("Show Next Application IC Window"); + onClicked: { + // This is a hack. See the documentation of this property for details + systemUI.applicationICWindowSwitchCount = systemUI.applicationICWindowSwitchCount + 1 + } + } + } +} + diff --git a/src/remotesettings/app/app.pro b/src/remotesettings/app/app.pro new file mode 100644 index 00000000..9639c5c6 --- /dev/null +++ b/src/remotesettings/app/app.pro @@ -0,0 +1,43 @@ +TARGET = neptune-companion-app +DESTDIR = $$BUILD_DIR +QT += quick ivicore +CONFIG += c++11 +CONFIG -= app_bundle + +include($$SOURCE_DIR/config.pri) + +LIBS += -L$$LIB_DESTDIR -l$$qtLibraryTarget(remotesettings) + +INCLUDEPATH += $$OUT_PWD/../frontend + +SOURCES += main.cpp \ + client.cpp + +RESOURCES += qml.qrc \ + app.qrc + +target.path = $$INSTALL_PREFIX/neptune3 +INSTALLS += target + +QMAKE_RPATHDIR += $$QMAKE_REL_RPATH_BASE/$$relative_path($$INSTALL_PREFIX/neptune3/lib, $$INSTALL_PREFIX/neptune3/) + +#needed for the android deployment to include additional qml plugins +QML_IMPORT_PATH += $$BUILD_DIR/imports_shared_cpp + +android { +#This is used to tell the deployment tool to include these additional +#libs to the apk. This library (libQt5RemoteObjects) is not directly used by the +#app itself, but by the backend plugin. + ANDROID_EXTRA_LIBS = $$[QT_INSTALL_LIBS]/libQt5RemoteObjects.so + +#In case we have some other than QML plugins to include to the apk, this is the +#variable to use. In this case we use it to include the Qtivi backend plugin, +#which is expected to be found under directory "qtivi". For this to work, the +#built plugin has then to be found under "$$BUILD_DIR/plugins/qtivi/". +#There is a line in the backend plugin's .pro file that places the plugin under +#"$$BUILD_DIR/plugins/" when building for android + ANDROID_EXTRA_PLUGINS = $$BUILD_DIR/plugins/ +} + +HEADERS += \ + client.h diff --git a/src/remotesettings/app/app.qrc b/src/remotesettings/app/app.qrc new file mode 100644 index 00000000..e257dfd6 --- /dev/null +++ b/src/remotesettings/app/app.qrc @@ -0,0 +1,5 @@ +<RCC> + <qresource prefix="/"> + <file>server.conf</file> + </qresource> +</RCC> diff --git a/src/remotesettings/app/client.cpp b/src/remotesettings/app/client.cpp new file mode 100644 index 00000000..8209e245 --- /dev/null +++ b/src/remotesettings/app/client.cpp @@ -0,0 +1,201 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Neptune 3 IVI UI. +** +** $QT_BEGIN_LICENSE:GPL-QTAS$ +** Commercial License Usage +** Licensees holding valid commercial Qt Automotive Suite 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 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** 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. +** +** $QT_END_LICENSE$ +** +** SPDX-License-Identifier: GPL-3.0 +** +****************************************************************************/ +#include "client.h" + +Q_LOGGING_CATEGORY(dataProviderApp, "dataProvider.App") + +const QString Client::settingsLastUrlsPrefix = QStringLiteral("lastUrls"); +const QString Client::settingsLastUrlsItem = QStringLiteral("url"); +const int Client::numOfUrlsStored = 5; +const int Client::timeoutToleranceMS = 1000; +const int Client::reconnectionIntervalMS = 3000; +const QString Client::defaultUrl = QStringLiteral("tcp://127.0.0.1:9999"); + +Client::Client(QObject *parent) : QObject(parent), + m_connected(false), + m_timedOut(false), + m_settings(QStringLiteral("Pelagicore"), QStringLiteral("NeptuneControlApp")) +{ + setStatus(tr("Not connected")); + connect(&m_connectionMonitoringTimer, &QTimer::timeout, this, &Client::onCMTimeout); + connect(&m_connectionMonitoring, &ConnectionMonitoring::counterChanged, + this, &Client::onCMCounterChanged); + connect(&m_connectionMonitoring, &QIviAbstractFeature::isInitializedChanged, + this, &Client::updateConnectionStatus); + connect(&m_connectionMonitoring, &QIviAbstractFeature::errorChanged, + this, &Client::updateConnectionStatus); + connect(&m_reconnectionTimer, &QTimer::timeout, this, &Client::onReconnectionTimeout); + readSettings(); + m_connectionMonitoringTimer.setSingleShot(true); + m_reconnectionTimer.setSingleShot(false); +} + +Client::~Client() +{ +} + +QUrl Client::serverUrl() const +{ + return m_serverUrl; +} + +QString Client::status() const +{ + return m_status; +} + +QStringList Client::lastUrls() const +{ + if (m_lastUrls.isEmpty()) + return {defaultUrl}; + return m_lastUrls; +} + +bool Client::connected() const +{ + return m_connected; +} + +void Client::connectToServer(const QString &serverUrl) +{ + QUrl url(serverUrl); + if (!url.isValid()) { + setStatus(tr("Invalid URL: %1").arg(url.toString())); + return; + } + + if (url==m_serverUrl && connected()) + return; + + QString configPath(QStringLiteral("./server.conf")); + if (qEnvironmentVariableIsSet("SERVER_CONF_PATH")) + configPath = QString::fromLocal8Bit(qgetenv("SERVER_CONF_PATH")); + + QSettings settings(configPath, QSettings::IniFormat); + settings.beginGroup(QStringLiteral("settings")); + settings.setValue(QStringLiteral("Registry"), serverUrl); + settings.sync(); + + m_connectionMonitoring.setServiceObject(nullptr); + m_connectionMonitoring.startAutoDiscovery(); + + setStatus(tr("Connecting to %1...").arg(url.toString())); + updateLastUrls(url.toString()); + + if (m_serverUrl!=url) { + m_serverUrl=url; + emit serverUrlChanged(m_serverUrl); + m_reconnectionTimer.stop(); + } +} + +void Client::updateConnectionStatus() +{ + bool c = m_connectionMonitoring.isInitialized() && + m_connectionMonitoring.error()==QIviAbstractFeature::NoError && + !m_timedOut; + if (c == m_connected) + return; + m_connected = c; + emit connectedChanged(m_connected); + if (m_connected) { + setStatus(tr("Connected to %1").arg(serverUrl().toString())); + m_reconnectionTimer.stop(); + } else { + setStatus(tr("Disconnected")); + if (m_timedOut) { + qCWarning(dataProviderApp) << "Server heartbeat timed out."; + m_reconnectionTimer.start(reconnectionIntervalMS); + } + } +} + +void Client::onCMCounterChanged() +{ + m_connectionMonitoringTimer.start(m_connectionMonitoring.intervalMS()+ + timeoutToleranceMS); + if (m_timedOut) { + m_timedOut = false; + updateConnectionStatus(); + } +} + +void Client::onCMTimeout() +{ + m_timedOut = true; + updateConnectionStatus(); +} + +void Client::onReconnectionTimeout() +{ + connectToServer(serverUrl().toString()); +} + +void Client::setStatus(const QString &status) +{ + if (status==m_status) + return; + m_status=status; + qCWarning(dataProviderApp) << "Client status: " << status; + emit statusChanged(m_status); +} + +void Client::readSettings() +{ + int size=m_settings.beginReadArray(settingsLastUrlsPrefix); + for (int i=0; i<size; i++) { + m_settings.setArrayIndex(i); + m_lastUrls.append(m_settings.value(settingsLastUrlsItem).toString()); + } + m_settings.endArray(); + emit lastUrlsChanged(m_lastUrls); +} + +void Client::writeSettings() +{ + m_settings.beginWriteArray(settingsLastUrlsPrefix); + for (int i=0; i<m_lastUrls.size(); i++) { + m_settings.setArrayIndex(i); + m_settings.setValue(settingsLastUrlsItem, m_lastUrls.at(i)); + } + m_settings.endArray(); +} + +void Client::updateLastUrls(const QString &url) +{ + m_lastUrls.removeOne(url); + m_lastUrls.push_front(url); + while (m_lastUrls.size() > numOfUrlsStored) + m_lastUrls.pop_back(); + writeSettings(); + emit lastUrlsChanged(m_lastUrls); +} diff --git a/src/remotesettings/app/client.h b/src/remotesettings/app/client.h new file mode 100644 index 00000000..92ac2c1d --- /dev/null +++ b/src/remotesettings/app/client.h @@ -0,0 +1,103 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Neptune 3 IVI UI. +** +** $QT_BEGIN_LICENSE:GPL-QTAS$ +** Commercial License Usage +** Licensees holding valid commercial Qt Automotive Suite 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 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** 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. +** +** $QT_END_LICENSE$ +** +** SPDX-License-Identifier: GPL-3.0 +** +****************************************************************************/ +#ifndef CLIENT_H +#define CLIENT_H + +#include <QObject> +#include <QSettings> +#include <QTimer> +#include <QLoggingCategory> +#include <QUrl> +#include "connectionmonitoring.h" + +Q_DECLARE_LOGGING_CATEGORY(dataProviderApp) + +class Client : public QObject +{ + Q_OBJECT + Q_PROPERTY(QUrl serverUrl READ serverUrl NOTIFY serverUrlChanged) + Q_PROPERTY(QString status READ status NOTIFY statusChanged) + Q_PROPERTY(QStringList lastUrls READ lastUrls NOTIFY lastUrlsChanged) + Q_PROPERTY(bool connected READ connected NOTIFY connectedChanged) + + static const QString settingsLastUrlsPrefix; + static const QString settingsLastUrlsItem; + static const int numOfUrlsStored; + static const int timeoutToleranceMS; + static const int reconnectionIntervalMS; + +public: + static const QString defaultUrl; + + explicit Client(QObject *parent = nullptr); + ~Client(); + + QUrl serverUrl() const; + QString status() const; + QStringList lastUrls() const; + bool connected() const; + +signals: + void serverUrlChanged(const QUrl &url); + void statusChanged(const QString &status); + void lastUrlsChanged(const QStringList &lastUrls); + void connectedChanged(bool connected); + +public slots: + void connectToServer(const QString &url); + +protected slots: + void updateConnectionStatus(); + void onCMCounterChanged(); + void onCMTimeout(); + void onReconnectionTimeout(); + +private: + void setStatus(const QString &status); + void readSettings(); + void writeSettings(); + void updateLastUrls(const QString &url); + + QUrl m_serverUrl; + QStringList m_lastUrls; + bool m_connected; + bool m_timedOut; + QString m_status; + QSettings m_settings; + + ConnectionMonitoring m_connectionMonitoring; + + QTimer m_connectionMonitoringTimer; + QTimer m_reconnectionTimer; +}; + +#endif // CLIENT_H diff --git a/src/remotesettings/app/main.cpp b/src/remotesettings/app/main.cpp new file mode 100644 index 00000000..367ed72c --- /dev/null +++ b/src/remotesettings/app/main.cpp @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Neptune 3 IVI UI. +** +** $QT_BEGIN_LICENSE:GPL-QTAS$ +** Commercial License Usage +** Licensees holding valid commercial Qt Automotive Suite 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 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** 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. +** +** $QT_END_LICENSE$ +** +** SPDX-License-Identifier: GPL-3.0 +** +****************************************************************************/ +#include <QGuiApplication> +#include <QQmlApplicationEngine> +#include <QQmlContext> +#include <QDir> +#include "client.h" + +int main(int argc, char *argv[]) +{ + QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); + QGuiApplication app(argc, argv); + + Client client; + + QQmlApplicationEngine engine; + engine.addImportPath(QDir::currentPath()+QStringLiteral("/imports_shared/")); + engine.rootContext()->setContextProperty(QStringLiteral("client"), &client); + engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); + if (engine.rootObjects().isEmpty()) + return -1; + + return app.exec(); +} diff --git a/src/remotesettings/app/main.qml b/src/remotesettings/app/main.qml new file mode 100644 index 00000000..8b43441d --- /dev/null +++ b/src/remotesettings/app/main.qml @@ -0,0 +1,159 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Neptune 3 IVI UI. +** +** $QT_BEGIN_LICENSE:GPL-QTAS$ +** Commercial License Usage +** Licensees holding valid commercial Qt Automotive Suite 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 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** 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. +** +** $QT_END_LICENSE$ +** +** SPDX-License-Identifier: GPL-3.0 +** +****************************************************************************/ +import QtQuick 2.7 +import QtQuick.Controls 2.2 +import QtQuick.Layouts 1.3 +import QtIvi 1.0 +import shared.com.pelagicore.remotesettings 1.0 +import shared.com.pelagicore.drivedata 1.0 + +import QtQuick.Window 2.3 + +ApplicationWindow { + id: root + + visible: true + width: 1280 + height: 800 + title: qsTr("Settings app") + + function sc(value) { + return value * Screen.pixelDensity; + } + + Component.onCompleted: { + connectionDialog.open() + } + + UISettings { + id: uiSettings + } + + InstrumentCluster { + id: instrumentCluster + } + + ConnectionMonitoring { + id: connectionMonitoring + } + + SystemUI { + id: systemUI + } + + ConnectionDialog { + id: connectionDialog + statusText: client.status + lastUrls: client.lastUrls + + x: (parent.width-width) /2 + y: (parent.height-height) /2 + + onAccepted: { + if (accepted) { + client.connectToServer(url); + uiSettings.setServiceObject(null); + instrumentCluster.setServiceObject(null); + systemUI.setServiceObject(null); + uiSettings.startAutoDiscovery(); + instrumentCluster.startAutoDiscovery(); + systemUI.startAutoDiscovery(); + } + connectionDialog.close(); + } + + Connections { + target: client + onServerUrlChanged: { + if (client.serverUrl.toString().length) + connectionDialog.url = client.serverUrl.toString(); + else + connectionDialog.url = defaultUrl; + } + } + + Connections { + target: client + onConnectedChanged: { + if (client.connected) + connectionDialog.close(); + } + } + + } + + header: ToolBar { + leftPadding: 8 + rightPadding: 8 + RowLayout { + anchors.fill: parent + Label { + text: client.status + } + Item { + Layout.fillWidth: true + } + + ToolButton { + text: qsTr("Connect...") + onClicked: connectionDialog.open() + } + } + } + + StackLayout { + id: stack + anchors.fill: parent + anchors.margins: 16 + SettingsPage {} + ClusterPage {} + SystemUIPage {} + } + + footer: TabBar { + TabButton { + text: uiSettings.isInitialized && client.connected ? + qsTr("Settings") : qsTr("Settings (Offline)") + onClicked: stack.currentIndex = 0 + } + TabButton { + text: instrumentCluster.isInitialized && client.connected ? + qsTr("Cluster") : qsTr("Cluster (Offline)") + onClicked: stack.currentIndex = 1 + } + TabButton { + text: systemUI.isInitialized && client.connected ? + qsTr("System UI") : qsTr("System UI (Offline)") + onClicked: stack.currentIndex = 2 + } + } +} diff --git a/src/remotesettings/app/qml.qrc b/src/remotesettings/app/qml.qrc new file mode 100644 index 00000000..ec50876c --- /dev/null +++ b/src/remotesettings/app/qml.qrc @@ -0,0 +1,10 @@ +<RCC> + <qresource prefix="/"> + <file>main.qml</file> + <file>qtquickcontrols2.conf</file> + <file>ClusterPage.qml</file> + <file>ConnectionDialog.qml</file> + <file>SettingsPage.qml</file> + <file>SystemUIPage.qml</file> + </qresource> +</RCC> diff --git a/src/remotesettings/app/qtquickcontrols2.conf b/src/remotesettings/app/qtquickcontrols2.conf new file mode 100644 index 00000000..ce3af5ce --- /dev/null +++ b/src/remotesettings/app/qtquickcontrols2.conf @@ -0,0 +1,15 @@ +; This file can be edited to change the style of the application +; See Styling Qt Quick Controls 2 in the documentation for details: +; http://doc.qt.io/qt-5/qtquickcontrols2-styles.html + +[Controls] +Style=Material + +[Universal] +Theme=Light +;Accent=Steel + +[Material] +Theme=Light +Accent=#FA9E54 +Primary=#FA9E54 diff --git a/src/remotesettings/app/server.conf b/src/remotesettings/app/server.conf new file mode 100644 index 00000000..a1e6baa6 --- /dev/null +++ b/src/remotesettings/app/server.conf @@ -0,0 +1,2 @@ +[settings] +Registry=tcp://10.10.1.76:9999 diff --git a/src/remotesettings/backend/backend.pro b/src/remotesettings/backend/backend.pro new file mode 100644 index 00000000..18d6ca26 --- /dev/null +++ b/src/remotesettings/backend/backend.pro @@ -0,0 +1,32 @@ +TEMPLATE=lib +TARGET = $$qtLibraryTarget(remotesettings_backend_qtro) +CONFIG += ivigenerator plugin + +QT_FOR_CONFIG += ivicore +!qtConfig(ivigenerator): error("No ivigenerator available: Make sure QtIvi is installed and configured correctly") + +include($$SOURCE_DIR/config.pri) + +LIBS += -L$$LIB_DESTDIR -l$$qtLibraryTarget(remotesettings) +DESTDIR = $$BUILD_DIR/qtivi + +#needed for the android deployment to work +android: DESTDIR = $$BUILD_DIR/plugins/qtivi + +CONFIG += warn_off +INCLUDEPATH += $$OUT_PWD/../frontend +PLUGIN_TYPE = qtivi +PLUGIN_EXTENDS = qtivi +PLUGIN_CLASS_NAME = IviSettingsBackendInterface + +QT += core ivicore + +QFACE_FORMAT = backend_qtro +QFACE_SOURCES = ../remotesettings.qface + +DEPENDPATH += $$OUT_PWD/../backend + +QMAKE_RPATHDIR += $$QMAKE_REL_RPATH_BASE/$$relative_path($$INSTALL_PREFIX/neptune3/lib, $$INSTALL_PREFIX/neptune3/qtivi) + +target.path = $$INSTALL_PREFIX/neptune3/qtivi +INSTALLS += target diff --git a/src/remotesettings/backend_simulation/backend_simulation.pro b/src/remotesettings/backend_simulation/backend_simulation.pro new file mode 100644 index 00000000..b5ba75c7 --- /dev/null +++ b/src/remotesettings/backend_simulation/backend_simulation.pro @@ -0,0 +1,32 @@ +TEMPLATE=lib +TARGET = $$qtLibraryTarget(remotesettings_backend_simulation) +CONFIG += ivigenerator plugin + +QT_FOR_CONFIG += ivicore +!qtConfig(ivigenerator): error("No ivigenerator available: Make sure QtIvi is installed and configured correctly") + +include($$SOURCE_DIR/config.pri) + +LIBS += -L$$LIB_DESTDIR -l$$qtLibraryTarget(remotesettings) +DESTDIR = $$BUILD_DIR/qtivi + +#needed for the android deployment to work +android: DESTDIR = $$BUILD_DIR/plugins/qtivi + +CONFIG += warn_off +INCLUDEPATH += $$OUT_PWD/../frontend +PLUGIN_TYPE = qtivi +PLUGIN_EXTENDS = qtivi +PLUGIN_CLASS_NAME = IviSettingsBackendInterface + +QT += core ivicore + +QFACE_FORMAT = backend_simulator +QFACE_SOURCES = ../remotesettings.qface + +DEPENDPATH += $$OUT_PWD/../backend + +QMAKE_RPATHDIR += $$QMAKE_REL_RPATH_BASE/$$relative_path($$INSTALL_PREFIX/neptune3/lib, $$INSTALL_PREFIX/neptune3/qtivi) + +target.path = $$INSTALL_PREFIX/neptune3/qtivi +INSTALLS += target diff --git a/src/remotesettings/frontend/frontend.pro b/src/remotesettings/frontend/frontend.pro new file mode 100644 index 00000000..ef2f653c --- /dev/null +++ b/src/remotesettings/frontend/frontend.pro @@ -0,0 +1,22 @@ +TARGET = $$qtLibraryTarget(remotesettings) +TEMPLATE = lib +CONFIG += ivigenerator +DESTDIR = $$LIB_DESTDIR + +QT_FOR_CONFIG += ivicore +!qtConfig(ivigenerator): error("No ivigenerator available: Make sure QtIvi is installed and configured correctly") + +macos: QMAKE_SONAME_PREFIX = @rpath + +include($$SOURCE_DIR/config.pri) + +DEFINES += QT_BUILD_REMOTESETTINGS_LIB +QT += ivicore ivicore-private qml + +QFACE_SOURCES = ../remotesettings.qface + +DEPENDPATH += $$OUT_PWD/../frontend + +target.path = $$INSTALL_PREFIX/neptune3/lib +win32:target.path = $$INSTALL_PREFIX/neptune3/ +INSTALLS += target diff --git a/src/remotesettings/qml_plugin/plugin.cpp b/src/remotesettings/qml_plugin/plugin.cpp new file mode 100644 index 00000000..9bc8bb21 --- /dev/null +++ b/src/remotesettings/qml_plugin/plugin.cpp @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Neptune 3 IVI UI. +** +** $QT_BEGIN_LICENSE:GPL-QTAS$ +** Commercial License Usage +** Licensees holding valid commercial Qt Automotive Suite 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 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** 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. +** +** $QT_END_LICENSE$ +** +** SPDX-License-Identifier: GPL-3.0 +** +****************************************************************************/ +#include <QtQml/qqmlextensionplugin.h> +#include <qqml.h> + +#include "remotesettingsmodule.h" + +QT_BEGIN_NAMESPACE + +class RemoteSettingsPlugin : public QQmlExtensionPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid) +public: + virtual void registerTypes(const char *uri) override + { + Q_ASSERT(QLatin1String(uri) == QLatin1String("shared.com.pelagicore.remotesettings")); + + RemoteSettingsModule::registerQmlTypes(uri, 1, 0); + } +}; + +QT_END_NAMESPACE + +#include "plugin.moc" diff --git a/src/remotesettings/qml_plugin/qml_plugin.pro b/src/remotesettings/qml_plugin/qml_plugin.pro new file mode 100644 index 00000000..9ac0b76f --- /dev/null +++ b/src/remotesettings/qml_plugin/qml_plugin.pro @@ -0,0 +1,16 @@ +TEMPLATE = lib +CONFIG += plugin +TARGET = remotesettingsplugin +QT += qml +LIBS += -L$$LIB_DESTDIR -l$$qtLibraryTarget(remotesettings) +INCLUDEPATH += $$OUT_PWD/../frontend + +include($$SOURCE_DIR/config.pri) + +SOURCES += \ + plugin.cpp + +uri = com.pelagicore.remotesettings +load(qmlplugin) + +QMAKE_RPATHDIR += $$QMAKE_REL_RPATH_BASE/$$relative_path($$INSTALL_PREFIX/neptune3/lib, $$installPath) diff --git a/src/remotesettings/qml_plugin/qmldir b/src/remotesettings/qml_plugin/qmldir new file mode 100644 index 00000000..61ab26a1 --- /dev/null +++ b/src/remotesettings/qml_plugin/qmldir @@ -0,0 +1,3 @@ +module shared.com.pelagicore.remotesettings +plugin remotesettingsplugin +classname RemoteSettingsPlugin diff --git a/src/remotesettings/remotesettings-server/main.cpp b/src/remotesettings/remotesettings-server/main.cpp new file mode 100644 index 00000000..fc88014b --- /dev/null +++ b/src/remotesettings/remotesettings-server/main.cpp @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Neptune 3 IVI UI. +** +** $QT_BEGIN_LICENSE:GPL-QTAS$ +** Commercial License Usage +** Licensees holding valid commercial Qt Automotive Suite 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 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** 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. +** +** $QT_END_LICENSE$ +** +** SPDX-License-Identifier: GPL-3.0 +** +****************************************************************************/ +#include <QCoreApplication> +#include <QDir> +#include <QLockFile> + +#include "server.h" + +int main(int argc, char *argv[]) +{ + QCoreApplication a(argc, argv); + + // single instance guard + QLockFile lockFile(QStringLiteral("%1/NeptuneRemoteSettingsServer.lock").arg(QDir::tempPath())); + if (!lockFile.tryLock(100)) { + qCritical("Neptune RemoteSettingsServer already running, aborting..."); + return EXIT_FAILURE; + } + + Server s; + s.start(); + + return a.exec(); +} diff --git a/src/remotesettings/remotesettings-server/remotesettings-server.pro b/src/remotesettings/remotesettings-server/remotesettings-server.pro new file mode 100644 index 00000000..9c0f6904 --- /dev/null +++ b/src/remotesettings/remotesettings-server/remotesettings-server.pro @@ -0,0 +1,36 @@ +QT -= gui + +CONFIG += c++11 console +macos: CONFIG -= app_bundle +CONFIG += ivigenerator + +QT_FOR_CONFIG += ivicore +!qtConfig(ivigenerator): error("No ivigenerator available: Make sure QtIvi is installed and configured correctly") + +include($$SOURCE_DIR/config.pri) + +QFACE_FORMAT = server_qtro +QFACE_SOURCES = ../remotesettings.qface + +SOURCES += \ + main.cpp\ + server.cpp + +HEADERS += \ + server.h + +DEPENDPATH += $$OUT_PWD/../server + +LIBS += -L$$LIB_DESTDIR -l$$qtLibraryTarget(remotesettings) + +INCLUDEPATH += $$OUT_PWD/../frontend + +QMAKE_RPATHDIR += $$QMAKE_REL_RPATH_BASE/$$relative_path($$INSTALL_PREFIX/neptune3/lib, $$INSTALL_PREFIX/neptune3) + +DISTFILES += + +TARGET = remotesettings-server +DESTDIR = $$BUILD_DIR + +target.path = $$INSTALL_PREFIX/neptune3 +INSTALLS += target diff --git a/src/remotesettings/remotesettings-server/server.cpp b/src/remotesettings/remotesettings-server/server.cpp new file mode 100644 index 00000000..4b6cc4a0 --- /dev/null +++ b/src/remotesettings/remotesettings-server/server.cpp @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Neptune 3 IVI UI. +** +** $QT_BEGIN_LICENSE:GPL-QTAS$ +** Commercial License Usage +** Licensees holding valid commercial Qt Automotive Suite 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 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** 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. +** +** $QT_END_LICENSE$ +** +** SPDX-License-Identifier: GPL-3.0 +** +****************************************************************************/ +#include "server.h" +#include <QCoreApplication> + +Q_LOGGING_CATEGORY(remoteSettingsServer, "remoteSettings.server") + +Server::Server(QObject *parent) : QObject(parent) +{ + connect(QCoreApplication::instance(),&QCoreApplication::aboutToQuit, + this,&Server::onAboutToQuit); + +} + +void Server::start() +{ + m_UISettingsService.reset(new UISettingsSimpleSource()); + Core::instance()->host()->enableRemoting(m_UISettingsService.data(), "RemoteSettings.UISettings"); + qCDebug(remoteSettingsServer) << "register service at: RemoteSettings.UISettings"; + + m_systemUIService.reset(new SystemUISimpleSource()); + Core::instance()->host()->enableRemoting(m_systemUIService.data(), "RemoteSettings.SystemUI"); + qCDebug(remoteSettingsServer) << "register service at: RemoteSettings.SystemUI"; + + m_connectionMonitoringService.reset(new ConnectionMonitoringSimpleSource()); + Core::instance()->host()->enableRemoting(m_connectionMonitoringService.data(), "RemoteSettings.ConnectionMonitoring"); + qCDebug(remoteSettingsServer) << "register service at: RemoteSettings.ConnectionMonitoring"; + + initConnectionMonitoring(); +} + +void Server::onROError(QRemoteObjectNode::ErrorCode code) +{ + qCWarning(remoteSettingsServer) << "Remote objects error, code:" << code; +} + +void Server::onAboutToQuit() +{ +} + +void Server::onTimeout() +{ + m_connectionMonitoringService->setCounter( + m_connectionMonitoringService->counter() + 1); +} + +void Server::initConnectionMonitoring() +{ + m_connectionMonitoringService->setIntervalMS(2000); + connect(&m_heartBeatTimer, &QTimer::timeout, this, &Server::onTimeout); + m_heartBeatTimer.setSingleShot(false); + m_heartBeatTimer.start(m_connectionMonitoringService->intervalMS()); +} diff --git a/src/remotesettings/remotesettings-server/server.h b/src/remotesettings/remotesettings-server/server.h new file mode 100644 index 00000000..243bdced --- /dev/null +++ b/src/remotesettings/remotesettings-server/server.h @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Luxoft Sweden AB +** Copyright (C) 2018 Pelagicore AG +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Neptune 3 IVI UI. +** +** $QT_BEGIN_LICENSE:GPL-QTAS$ +** Commercial License Usage +** Licensees holding valid commercial Qt Automotive Suite 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 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** 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. +** +** $QT_END_LICENSE$ +** +** SPDX-License-Identifier: GPL-3.0 +** +****************************************************************************/ +#ifndef SERVER_H +#define SERVER_H + +#include <QObject> +#include <QSettings> +#include <QTimer> + +#include "core.h" +#include "rep_uisettings_source.h" +#include "rep_systemui_source.h" +#include "rep_connectionmonitoring_source.h" + +Q_DECLARE_LOGGING_CATEGORY(remoteSettingsServer) + +class Server : public QObject +{ + Q_OBJECT +public: + explicit Server(QObject *parent = nullptr); + + void start(); + +public slots: + void onROError(QRemoteObjectNode::ErrorCode code); + void onAboutToQuit(); + +protected slots: + void onTimeout(); + +protected: + QScopedPointer<UISettingsSimpleSource> m_UISettingsService; + QScopedPointer<SystemUISimpleSource> m_systemUIService; + QScopedPointer<ConnectionMonitoringSimpleSource> m_connectionMonitoringService; + + void initConnectionMonitoring(); + +private: + QTimer m_heartBeatTimer; +}; + +#endif // SERVER_H diff --git a/src/remotesettings/remotesettings.pro b/src/remotesettings/remotesettings.pro new file mode 100644 index 00000000..038b3e11 --- /dev/null +++ b/src/remotesettings/remotesettings.pro @@ -0,0 +1,20 @@ +TEMPLATE = subdirs + +SUBDIRS += \ + frontend \ + backend_simulation \ + qml_plugin \ + +# Don't build the production backend on android and ios, only use the simulation backend +!android:!ios:SUBDIRS += \ + remotesettings-server \ + app \ + backend \ + +backend_simulation.depends = frontend +backend.depends = frontend +server.depends = frontend +app.depends = frontend +qml_plugin.depends = frontend + +OTHER_FILES += remotesettings.qface diff --git a/src/remotesettings/remotesettings.qface b/src/remotesettings/remotesettings.qface new file mode 100644 index 00000000..80766514 --- /dev/null +++ b/src/remotesettings/remotesettings.qface @@ -0,0 +1,54 @@ +module RemoteSettings 1.0 + +interface UISettings { + string language; + list<string> languages; + + bool twentyFourHourTimeFormat; + + /** + * 0 is muted and 1.0 is max + */ + real volume; + bool muted; + /* + * -1.0 left and +1.0 right and 0 is centered + */ + real balance; + + int theme; + string accentColor; + + bool rtlMode; + + bool door1Open; + bool door2Open; + + /* + * Whether the instrument cluster should be in navigation mode + * in this mode its gauges etc will be reshaped to give more room + * for the maps navigation content being displayed behind it + */ + bool navigationMode; + + /** Whether both gauges should be hidden or not */ + bool hideGauges; + bool flatGauges; +} + +interface SystemUI { + /* + * Incrementing this value will make sysui switch to display the next + * available application instrument cluster window. + * + * This is a hack. What we really need here is just a plain signal that + * could be emitted on demand. So that's not really storing a setting + * but serving as plain RPC. + */ + int applicationICWindowSwitchCount +} + +interface ConnectionMonitoring { + int intervalMS; + int counter; +} |