From 21ff97fe8aa682a9bc137aeae390260412d9f9c3 Mon Sep 17 00:00:00 2001 From: "michal.szwaj" Date: Mon, 19 Mar 2018 20:58:40 +0100 Subject: [PATCH 01/13] Remove Main class --- include/f1x/openauto/autoapp/App.hpp | 2 +- include/f1x/openauto/autoapp/Main.hpp | 57 -------------------------- src/autoapp/App.cpp | 2 +- src/autoapp/Main.cpp | 58 --------------------------- src/autoapp/autoapp.cpp | 48 ++++++++++++++-------- 5 files changed, 33 insertions(+), 134 deletions(-) delete mode 100644 include/f1x/openauto/autoapp/Main.hpp delete mode 100644 src/autoapp/Main.cpp diff --git a/include/f1x/openauto/autoapp/App.hpp b/include/f1x/openauto/autoapp/App.hpp index f31e2d5..461743d 100644 --- a/include/f1x/openauto/autoapp/App.hpp +++ b/include/f1x/openauto/autoapp/App.hpp @@ -38,7 +38,7 @@ public: App(boost::asio::io_service& ioService, projection::IAndroidAutoEntityFactory& androidAutoEntityFactory, aasdk::usb::IUSBHub::Pointer usbHub, aasdk::usb::IConnectedAccessoriesEnumerator::Pointer connectedAccessoriesEnumerator); - void start(); + void waitForUSBDevice(); void stop(); void onAndroidAutoQuit() override; diff --git a/include/f1x/openauto/autoapp/Main.hpp b/include/f1x/openauto/autoapp/Main.hpp deleted file mode 100644 index 4cb6746..0000000 --- a/include/f1x/openauto/autoapp/Main.hpp +++ /dev/null @@ -1,57 +0,0 @@ -/* -* This file is part of openauto project. -* Copyright (C) 2018 f1x.studio (Michal Szwaj) -* -* openauto is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 3 of the License, or -* (at your option) any later version. - -* openauto is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with openauto. If not, see . -*/ - -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace f1x -{ -namespace openauto -{ -namespace autoapp -{ - -class Main -{ -public: - Main(aasdk::usb::IUSBWrapper& usbWrapper, boost::asio::io_service& ioService, configuration::IConfiguration::Pointer configuration); - - void start(); - void stop(); - -private: - aasdk::usb::IUSBWrapper& usbWrapper_; - boost::asio::io_service& ioService_; - aasdk::usb::AccessoryModeQueryFactory queryFactory_; - aasdk::usb::AccessoryModeQueryChainFactory queryChainFactory_; - projection::ServiceFactory serviceFactory_; - projection::AndroidAutoEntityFactory androidAutoEntityFactory_; - autoapp::App::Pointer app_; -}; - -} -} -} diff --git a/src/autoapp/App.cpp b/src/autoapp/App.cpp index 73a7b3d..7b00e07 100644 --- a/src/autoapp/App.cpp +++ b/src/autoapp/App.cpp @@ -39,7 +39,7 @@ App::App(boost::asio::io_service& ioService, projection::IAndroidAutoEntityFacto } -void App::start() +void App::waitForUSBDevice() { strand_.dispatch([this, self = this->shared_from_this()]() { this->waitForDevice(); diff --git a/src/autoapp/Main.cpp b/src/autoapp/Main.cpp deleted file mode 100644 index 84ea91e..0000000 --- a/src/autoapp/Main.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/* -* This file is part of openauto project. -* Copyright (C) 2018 f1x.studio (Michal Szwaj) -* -* openauto is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 3 of the License, or -* (at your option) any later version. - -* openauto is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with openauto. If not, see . -*/ - -#include -#include -#include -#include - -namespace f1x -{ -namespace openauto -{ -namespace autoapp -{ - -Main::Main(aasdk::usb::IUSBWrapper& usbWrapper, boost::asio::io_service& ioService, configuration::IConfiguration::Pointer configuration) - : usbWrapper_(usbWrapper) - , ioService_(ioService) - , queryFactory_(usbWrapper_, ioService_) - , queryChainFactory_(usbWrapper_, ioService_, queryFactory_) - , serviceFactory_(ioService_, configuration) - , androidAutoEntityFactory_(usbWrapper_, ioService_, configuration, serviceFactory_) -{ - auto usbHub(std::make_shared(usbWrapper_, ioService_, queryChainFactory_)); - auto ConnectedAccessoriesEnumerator(std::make_shared(usbWrapper_, ioService_, queryChainFactory_)); - - app_ = std::make_shared(ioService_, androidAutoEntityFactory_, - std::move(usbHub), std::move(ConnectedAccessoriesEnumerator)); -} - -void Main::start() -{ - app_->start(); -} - -void Main::stop() -{ - app_->stop(); -} - -} -} -} diff --git a/src/autoapp/autoapp.cpp b/src/autoapp/autoapp.cpp index 4b4b4b5..6a2e3e9 100644 --- a/src/autoapp/autoapp.cpp +++ b/src/autoapp/autoapp.cpp @@ -18,10 +18,18 @@ #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include #include -#include #include namespace aasdk = f1x::aasdk; @@ -66,35 +74,41 @@ int main(int argc, char* argv[]) return 1; } - QApplication qApplication(argc, argv); boost::asio::io_service ioService; boost::asio::io_service::work work(ioService); + std::vector threadPool; + startUSBWorkers(ioService, usbContext, threadPool); + startIOServiceWorkers(ioService, threadPool); + QApplication qApplication(argc, argv); autoapp::ui::MainWindow mainWindow; mainWindow.setWindowFlags(Qt::WindowStaysOnTopHint); - mainWindow.showFullScreen(); auto configuration = std::make_shared(); autoapp::ui::SettingsWindow settingsWindow(configuration); settingsWindow.setWindowFlags(Qt::WindowStaysOnTopHint); - qApplication.setOverrideCursor(Qt::BlankCursor); - bool cursorVisible = false; - QObject::connect(&mainWindow, &autoapp::ui::MainWindow::toggleCursor, [&cursorVisible, &qApplication]() { - cursorVisible = !cursorVisible; - qApplication.setOverrideCursor(cursorVisible ? Qt::ArrowCursor : Qt::BlankCursor); - }); - - aasdk::usb::USBWrapper usbWrapper(usbContext); - autoapp::Main main(usbWrapper, ioService, configuration); - QObject::connect(&mainWindow, &autoapp::ui::MainWindow::exit, []() { std::exit(0); }); QObject::connect(&mainWindow, &autoapp::ui::MainWindow::openSettings, &settingsWindow, &autoapp::ui::SettingsWindow::showFullScreen); - std::vector threadPool; - startUSBWorkers(ioService, usbContext, threadPool); - startIOServiceWorkers(ioService, threadPool); - main.start(); + qApplication.setOverrideCursor(Qt::BlankCursor); + QObject::connect(&mainWindow, &autoapp::ui::MainWindow::toggleCursor, [&qApplication]() { + const auto cursor = qApplication.overrideCursor()->shape() == Qt::BlankCursor ? Qt::ArrowCursor : Qt::BlankCursor; + qApplication.setOverrideCursor(cursor); + }); + + mainWindow.showFullScreen(); + + aasdk::usb::USBWrapper usbWrapper(usbContext); + aasdk::usb::AccessoryModeQueryFactory queryFactory(usbWrapper, ioService); + aasdk::usb::AccessoryModeQueryChainFactory queryChainFactory(usbWrapper, ioService, queryFactory); + autoapp::projection::ServiceFactory serviceFactory(ioService, configuration); + autoapp::projection::AndroidAutoEntityFactory androidAutoEntityFactory(usbWrapper, ioService, configuration, serviceFactory); + + auto usbHub(std::make_shared(usbWrapper, ioService, queryChainFactory)); + auto ConnectedAccessoriesEnumerator(std::make_shared(usbWrapper, ioService, queryChainFactory)); + auto app = std::make_shared(ioService, androidAutoEntityFactory, std::move(usbHub), std::move(ConnectedAccessoriesEnumerator)); + app->waitForUSBDevice(); auto result = qApplication.exec(); std::for_each(threadPool.begin(), threadPool.end(), std::bind(&std::thread::join, std::placeholders::_1)); From 2ecdd83e76b417f1200e0c11278a0b1ce349e82b Mon Sep 17 00:00:00 2001 From: "michal.szwaj" Date: Mon, 19 Mar 2018 21:34:32 +0100 Subject: [PATCH 02/13] Implement creating of tcp AA entity --- include/f1x/openauto/autoapp/App.hpp | 8 +++- .../Projection/AndroidAutoEntityFactory.hpp | 6 +-- .../Projection/IAndroidAutoEntityFactory.hpp | 4 +- src/autoapp/App.cpp | 46 +++++++++++++++++-- .../Projection/AndroidAutoEntityFactory.cpp | 12 ++--- src/autoapp/autoapp.cpp | 6 ++- 6 files changed, 60 insertions(+), 22 deletions(-) diff --git a/include/f1x/openauto/autoapp/App.hpp b/include/f1x/openauto/autoapp/App.hpp index 461743d..5bbdbe2 100644 --- a/include/f1x/openauto/autoapp/App.hpp +++ b/include/f1x/openauto/autoapp/App.hpp @@ -20,6 +20,9 @@ #include #include +#include +#include +#include #include #include @@ -35,10 +38,11 @@ class App: public projection::IAndroidAutoEntityEventHandler, public std::enable public: typedef std::shared_ptr Pointer; - App(boost::asio::io_service& ioService, projection::IAndroidAutoEntityFactory& androidAutoEntityFactory, + App(boost::asio::io_service& ioService, aasdk::usb::USBWrapper& usbWrapper, aasdk::tcp::ITCPWrapper& tcpWrapper, projection::IAndroidAutoEntityFactory& androidAutoEntityFactory, aasdk::usb::IUSBHub::Pointer usbHub, aasdk::usb::IConnectedAccessoriesEnumerator::Pointer connectedAccessoriesEnumerator); void waitForUSBDevice(); + void start(aasdk::tcp::ITCPEndpoint::SocketPointer socket); void stop(); void onAndroidAutoQuit() override; @@ -51,6 +55,8 @@ private: void onUSBHubError(const aasdk::error::Error& error); boost::asio::io_service& ioService_; + aasdk::usb::USBWrapper& usbWrapper_; + aasdk::tcp::ITCPWrapper& tcpWrapper_; boost::asio::io_service::strand strand_; projection::IAndroidAutoEntityFactory& androidAutoEntityFactory_; aasdk::usb::IUSBHub::Pointer usbHub_; diff --git a/include/f1x/openauto/autoapp/Projection/AndroidAutoEntityFactory.hpp b/include/f1x/openauto/autoapp/Projection/AndroidAutoEntityFactory.hpp index 1df64dc..73b8696 100644 --- a/include/f1x/openauto/autoapp/Projection/AndroidAutoEntityFactory.hpp +++ b/include/f1x/openauto/autoapp/Projection/AndroidAutoEntityFactory.hpp @@ -36,18 +36,16 @@ namespace projection class AndroidAutoEntityFactory: public IAndroidAutoEntityFactory { public: - AndroidAutoEntityFactory(aasdk::usb::IUSBWrapper& usbWrapper, - boost::asio::io_service& ioService, + AndroidAutoEntityFactory(boost::asio::io_service& ioService, configuration::IConfiguration::Pointer configuration, IServiceFactory& serviceFactory); - IAndroidAutoEntity::Pointer create(aasdk::usb::DeviceHandle deviceHandle) override; + IAndroidAutoEntity::Pointer create(aasdk::usb::IAOAPDevice::Pointer aoapDevice) override; IAndroidAutoEntity::Pointer create(aasdk::tcp::ITCPEndpoint::Pointer tcpEndpoint) override; private: IAndroidAutoEntity::Pointer create(aasdk::transport::ITransport::Pointer transport); - aasdk::usb::IUSBWrapper& usbWrapper_; boost::asio::io_service& ioService_; configuration::IConfiguration::Pointer configuration_; IServiceFactory& serviceFactory_; diff --git a/include/f1x/openauto/autoapp/Projection/IAndroidAutoEntityFactory.hpp b/include/f1x/openauto/autoapp/Projection/IAndroidAutoEntityFactory.hpp index 945c247..f9f37c3 100644 --- a/include/f1x/openauto/autoapp/Projection/IAndroidAutoEntityFactory.hpp +++ b/include/f1x/openauto/autoapp/Projection/IAndroidAutoEntityFactory.hpp @@ -19,7 +19,7 @@ #pragma once #include -#include +#include #include namespace f1x @@ -36,7 +36,7 @@ class IAndroidAutoEntityFactory public: virtual ~IAndroidAutoEntityFactory() = default; - virtual IAndroidAutoEntity::Pointer create(aasdk::usb::DeviceHandle deviceHandle) = 0; + virtual IAndroidAutoEntity::Pointer create(aasdk::usb::IAOAPDevice::Pointer aoapDevice) = 0; virtual IAndroidAutoEntity::Pointer create(aasdk::tcp::ITCPEndpoint::Pointer tcpEndpoint) = 0; }; diff --git a/src/autoapp/App.cpp b/src/autoapp/App.cpp index 7b00e07..441b4d6 100644 --- a/src/autoapp/App.cpp +++ b/src/autoapp/App.cpp @@ -17,6 +17,8 @@ */ #include +#include +#include #include #include @@ -27,9 +29,11 @@ namespace openauto namespace autoapp { -App::App(boost::asio::io_service& ioService, projection::IAndroidAutoEntityFactory& androidAutoEntityFactory, +App::App(boost::asio::io_service& ioService, aasdk::usb::USBWrapper& usbWrapper, aasdk::tcp::ITCPWrapper& tcpWrapper, projection::IAndroidAutoEntityFactory& androidAutoEntityFactory, aasdk::usb::IUSBHub::Pointer usbHub, aasdk::usb::IConnectedAccessoriesEnumerator::Pointer connectedAccessoriesEnumerator) : ioService_(ioService) + , usbWrapper_(usbWrapper) + , tcpWrapper_(tcpWrapper) , strand_(ioService_) , androidAutoEntityFactory_(androidAutoEntityFactory) , usbHub_(std::move(usbHub)) @@ -47,6 +51,35 @@ void App::waitForUSBDevice() }); } +void App::start(aasdk::tcp::ITCPEndpoint::SocketPointer socket) +{ + strand_.dispatch([this, self = this->shared_from_this(), socket = std::move(socket)]() mutable { + if(androidAutoEntity_ == nullptr) + { + try + { + usbHub_->cancel(); + connectedAccessoriesEnumerator_->cancel(); + + auto tcpEndpoint(std::make_shared(tcpWrapper_, std::move(socket))); + androidAutoEntity_ = androidAutoEntityFactory_.create(std::move(tcpEndpoint)); + androidAutoEntity_->start(*this); + } + catch(const aasdk::error::Error& error) + { + OPENAUTO_LOG(error) << "[App] TCP AndroidAutoEntity create error: " << error.what(); + + androidAutoEntity_.reset(); + this->waitForDevice(); + } + } + else + { + OPENAUTO_LOG(warning) << "[App] android auto entity is still running."; + } + }); +} + void App::stop() { strand_.dispatch([this, self = this->shared_from_this()]() { @@ -69,12 +102,15 @@ void App::aoapDeviceHandler(aasdk::usb::DeviceHandle deviceHandle) { try { - androidAutoEntity_ = androidAutoEntityFactory_.create(std::move(deviceHandle)); + connectedAccessoriesEnumerator_->cancel(); + + auto aoapDevice(aasdk::usb::AOAPDevice::create(usbWrapper_, ioService_, deviceHandle)); + androidAutoEntity_ = androidAutoEntityFactory_.create(std::move(aoapDevice)); androidAutoEntity_->start(*this); } catch(const aasdk::error::Error& error) { - OPENAUTO_LOG(error) << "[App] AndroidAutoEntity create error: " << error.what(); + OPENAUTO_LOG(error) << "[App] USB AndroidAutoEntity create error: " << error.what(); androidAutoEntity_.reset(); this->waitForDevice(); @@ -128,8 +164,8 @@ void App::onUSBHubError(const aasdk::error::Error& error) { OPENAUTO_LOG(error) << "[App] usb hub error: " << error.what(); - if(error.getCode() == aasdk::error::ErrorCode::OPERATION_ABORTED || - error.getCode() == aasdk::error::ErrorCode::OPERATION_IN_PROGRESS) + if(error.getCode() != aasdk::error::ErrorCode::OPERATION_ABORTED && + error.getCode() != aasdk::error::ErrorCode::OPERATION_IN_PROGRESS) { this->waitForDevice(); } diff --git a/src/autoapp/Projection/AndroidAutoEntityFactory.cpp b/src/autoapp/Projection/AndroidAutoEntityFactory.cpp index cc31fae..0eb6942 100644 --- a/src/autoapp/Projection/AndroidAutoEntityFactory.cpp +++ b/src/autoapp/Projection/AndroidAutoEntityFactory.cpp @@ -33,23 +33,19 @@ namespace autoapp namespace projection { -AndroidAutoEntityFactory::AndroidAutoEntityFactory(aasdk::usb::IUSBWrapper& usbWrapper, - boost::asio::io_service& ioService, +AndroidAutoEntityFactory::AndroidAutoEntityFactory(boost::asio::io_service& ioService, configuration::IConfiguration::Pointer configuration, IServiceFactory& serviceFactory) - : usbWrapper_(usbWrapper) - , ioService_(ioService) + : ioService_(ioService) , configuration_(std::move(configuration)) , serviceFactory_(serviceFactory) { } -IAndroidAutoEntity::Pointer AndroidAutoEntityFactory::create(aasdk::usb::DeviceHandle deviceHandle) +IAndroidAutoEntity::Pointer AndroidAutoEntityFactory::create(aasdk::usb::IAOAPDevice::Pointer aoapDevice) { - auto aoapDevice(aasdk::usb::AOAPDevice::create(usbWrapper_, ioService_, deviceHandle)); - auto transport(std::make_shared(ioService_, aoapDevice)); - + auto transport(std::make_shared(ioService_, std::move(aoapDevice))); return create(std::move(transport)); } diff --git a/src/autoapp/autoapp.cpp b/src/autoapp/autoapp.cpp index 6a2e3e9..d88863a 100644 --- a/src/autoapp/autoapp.cpp +++ b/src/autoapp/autoapp.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -99,15 +100,16 @@ int main(int argc, char* argv[]) mainWindow.showFullScreen(); + aasdk::tcp::TCPWrapper tcpWrapper; aasdk::usb::USBWrapper usbWrapper(usbContext); aasdk::usb::AccessoryModeQueryFactory queryFactory(usbWrapper, ioService); aasdk::usb::AccessoryModeQueryChainFactory queryChainFactory(usbWrapper, ioService, queryFactory); autoapp::projection::ServiceFactory serviceFactory(ioService, configuration); - autoapp::projection::AndroidAutoEntityFactory androidAutoEntityFactory(usbWrapper, ioService, configuration, serviceFactory); + autoapp::projection::AndroidAutoEntityFactory androidAutoEntityFactory(ioService, configuration, serviceFactory); auto usbHub(std::make_shared(usbWrapper, ioService, queryChainFactory)); auto ConnectedAccessoriesEnumerator(std::make_shared(usbWrapper, ioService, queryChainFactory)); - auto app = std::make_shared(ioService, androidAutoEntityFactory, std::move(usbHub), std::move(ConnectedAccessoriesEnumerator)); + auto app = std::make_shared(ioService, usbWrapper, tcpWrapper, androidAutoEntityFactory, std::move(usbHub), std::move(ConnectedAccessoriesEnumerator)); app->waitForUSBDevice(); auto result = qApplication.exec(); From 3819f5e75289bb89573871f414ee9d67c9e0ef80 Mon Sep 17 00:00:00 2001 From: "michal.szwaj" Date: Mon, 19 Mar 2018 21:45:12 +0100 Subject: [PATCH 03/13] Close socket when entity is still running --- src/autoapp/App.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/autoapp/App.cpp b/src/autoapp/App.cpp index 441b4d6..b3f92a0 100644 --- a/src/autoapp/App.cpp +++ b/src/autoapp/App.cpp @@ -75,6 +75,7 @@ void App::start(aasdk::tcp::ITCPEndpoint::SocketPointer socket) } else { + tcpWrapper_.close(*socket); OPENAUTO_LOG(warning) << "[App] android auto entity is still running."; } }); From 69d6cf835ba0959d705aa62904a2acc270848e67 Mon Sep 17 00:00:00 2001 From: "michal.szwaj" Date: Wed, 21 Mar 2018 19:38:20 +0100 Subject: [PATCH 04/13] Draft of Connect dialog --- .../f1x/openauto/autoapp/UI/ConnectDialog.hpp | 33 +++++ .../f1x/openauto/autoapp/UI/MainWindow.hpp | 1 + src/autoapp/UI/ConnectDialog.cpp | 28 ++++ src/autoapp/UI/MainWindow.cpp | 1 + src/autoapp/UI/connectdialog.ui | 120 ++++++++++++++++++ src/autoapp/UI/mainwindow.ui | 50 +++++--- src/autoapp/UI/settingswindow.ui | 2 +- src/autoapp/autoapp.cpp | 9 +- 8 files changed, 221 insertions(+), 23 deletions(-) create mode 100644 include/f1x/openauto/autoapp/UI/ConnectDialog.hpp create mode 100644 src/autoapp/UI/ConnectDialog.cpp create mode 100644 src/autoapp/UI/connectdialog.ui diff --git a/include/f1x/openauto/autoapp/UI/ConnectDialog.hpp b/include/f1x/openauto/autoapp/UI/ConnectDialog.hpp new file mode 100644 index 0000000..db90ca4 --- /dev/null +++ b/include/f1x/openauto/autoapp/UI/ConnectDialog.hpp @@ -0,0 +1,33 @@ +#pragma once + +#include + +namespace Ui { +class ConnectDialog; +} + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace ui +{ + +class ConnectDialog : public QDialog +{ + Q_OBJECT + +public: + explicit ConnectDialog(QWidget *parent = nullptr); + ~ConnectDialog() override; + +private: + Ui::ConnectDialog *ui; +}; + +} +} +} +} diff --git a/include/f1x/openauto/autoapp/UI/MainWindow.hpp b/include/f1x/openauto/autoapp/UI/MainWindow.hpp index 2c82330..b7e2354 100644 --- a/include/f1x/openauto/autoapp/UI/MainWindow.hpp +++ b/include/f1x/openauto/autoapp/UI/MainWindow.hpp @@ -46,6 +46,7 @@ signals: void exit(); void openSettings(); void toggleCursor(); + void openConnectDialog(); private: Ui::MainWindow* ui_; diff --git a/src/autoapp/UI/ConnectDialog.cpp b/src/autoapp/UI/ConnectDialog.cpp new file mode 100644 index 0000000..b663f51 --- /dev/null +++ b/src/autoapp/UI/ConnectDialog.cpp @@ -0,0 +1,28 @@ +#include +#include "ui_connectdialog.h" + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace ui +{ + +ConnectDialog::ConnectDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::ConnectDialog) +{ + ui->setupUi(this); +} + +ConnectDialog::~ConnectDialog() +{ + delete ui; +} + +} +} +} +} diff --git a/src/autoapp/UI/MainWindow.cpp b/src/autoapp/UI/MainWindow.cpp index 8569c06..49954f8 100644 --- a/src/autoapp/UI/MainWindow.cpp +++ b/src/autoapp/UI/MainWindow.cpp @@ -37,6 +37,7 @@ MainWindow::MainWindow(QWidget *parent) connect(ui_->pushButtonSettings, &QPushButton::clicked, this, &MainWindow::openSettings); connect(ui_->pushButtonExit, &QPushButton::clicked, this, &MainWindow::exit); connect(ui_->pushButtonToggleCursor, &QPushButton::clicked, this, &MainWindow::toggleCursor); + connect(ui_->pushButtonWirelessConnection, &QPushButton::clicked, this, &MainWindow::openConnectDialog); } MainWindow::~MainWindow() diff --git a/src/autoapp/UI/connectdialog.ui b/src/autoapp/UI/connectdialog.ui new file mode 100644 index 0000000..ba7b6ee --- /dev/null +++ b/src/autoapp/UI/connectdialog.ui @@ -0,0 +1,120 @@ + + + ConnectDialog + + + + 0 + 0 + 301 + 389 + + + + Connect to device + + + + + 10 + 10 + 281 + 61 + + + + IP Address + + + + + 10 + 30 + 261 + 25 + + + + + + + + 10 + 80 + 281 + 181 + + + + Recent + + + + + 10 + 30 + 261 + 141 + + + + + + + + 60 + 260 + 221 + 81 + + + + <html><head/><body><p><span style=" font-style:italic;">In order to use wireless mode you must enable head unit server in developer settings.</span></p></body></html> + + + true + + + + + + 20 + 290 + 21 + 21 + + + + <html><head/><body><p><img src=":/ico_info.png"/></p></body></html> + + + + + + 100 + 340 + 89 + 41 + + + + Cancel + + + + + + 200 + 340 + 89 + 41 + + + + Connect + + + + + + diff --git a/src/autoapp/UI/mainwindow.ui b/src/autoapp/UI/mainwindow.ui index 8bf5291..7432822 100644 --- a/src/autoapp/UI/mainwindow.ui +++ b/src/autoapp/UI/mainwindow.ui @@ -48,7 +48,7 @@ color: rgb(238, 238, 236); 630 - 340 + 370 161 41 @@ -67,7 +67,7 @@ color: rgb(238, 238, 236); 630 - 390 + 420 161 41 @@ -79,7 +79,7 @@ color: rgb(238, 238, 236); false - + 340 @@ -92,11 +92,11 @@ color: rgb(238, 238, 236); <html><head/><body><p><span style=" font-style:italic; color:#eeeeec;">Plug in your device to start AndroidAuto (tm).</span></p></body></html> - + 10 - 410 + 440 271 21 @@ -167,20 +167,20 @@ color: rgb(238, 238, 236); 220 - 376 + 400 21 - 21 + 31 <html><head/><body><p><img src=":/ico_info.png"/></p></body></html> - + 250 - 370 + 400 361 31 @@ -193,7 +193,7 @@ color: rgb(238, 238, 236); 630 - 290 + 270 161 41 @@ -208,21 +208,31 @@ color: rgb(238, 238, 236); false - - - - - 0 - 0 - 800 - 22 - - + + + + 630 + 320 + 161 + 41 + + + + Wireless connection + + + false + + + false + + pushButtonToggleCursor + pushButtonWirelessConnection pushButtonSettings pushButtonExit diff --git a/src/autoapp/UI/settingswindow.ui b/src/autoapp/UI/settingswindow.ui index 63ad7a2..b066a78 100644 --- a/src/autoapp/UI/settingswindow.ui +++ b/src/autoapp/UI/settingswindow.ui @@ -23,7 +23,7 @@ - Form + Settings background-color: rgb(46, 52, 54); diff --git a/src/autoapp/autoapp.cpp b/src/autoapp/autoapp.cpp index d88863a..f063a2d 100644 --- a/src/autoapp/autoapp.cpp +++ b/src/autoapp/autoapp.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include namespace aasdk = f1x::aasdk; @@ -89,8 +90,12 @@ int main(int argc, char* argv[]) autoapp::ui::SettingsWindow settingsWindow(configuration); settingsWindow.setWindowFlags(Qt::WindowStaysOnTopHint); + autoapp::ui::ConnectDialog connectDialog; + connectDialog.setWindowFlags(Qt::Window | Qt::WindowStaysOnTopHint); + QObject::connect(&mainWindow, &autoapp::ui::MainWindow::exit, []() { std::exit(0); }); QObject::connect(&mainWindow, &autoapp::ui::MainWindow::openSettings, &settingsWindow, &autoapp::ui::SettingsWindow::showFullScreen); + QObject::connect(&mainWindow, &autoapp::ui::MainWindow::openConnectDialog, &connectDialog, &autoapp::ui::ConnectDialog::exec); qApplication.setOverrideCursor(Qt::BlankCursor); QObject::connect(&mainWindow, &autoapp::ui::MainWindow::toggleCursor, [&qApplication]() { @@ -108,8 +113,8 @@ int main(int argc, char* argv[]) autoapp::projection::AndroidAutoEntityFactory androidAutoEntityFactory(ioService, configuration, serviceFactory); auto usbHub(std::make_shared(usbWrapper, ioService, queryChainFactory)); - auto ConnectedAccessoriesEnumerator(std::make_shared(usbWrapper, ioService, queryChainFactory)); - auto app = std::make_shared(ioService, usbWrapper, tcpWrapper, androidAutoEntityFactory, std::move(usbHub), std::move(ConnectedAccessoriesEnumerator)); + auto connectedAccessoriesEnumerator(std::make_shared(usbWrapper, ioService, queryChainFactory)); + auto app = std::make_shared(ioService, usbWrapper, tcpWrapper, androidAutoEntityFactory, std::move(usbHub), std::move(connectedAccessoriesEnumerator)); app->waitForUSBDevice(); auto result = qApplication.exec(); From 7c31bafa10b583cb7cc84e4aaed0ac6b5104b987 Mon Sep 17 00:00:00 2001 From: "michal.szwaj" Date: Wed, 21 Mar 2018 23:51:31 +0100 Subject: [PATCH 05/13] Implement connecting to the device --- .../f1x/openauto/autoapp/UI/ConnectDialog.hpp | 17 +++++++- src/autoapp/UI/ConnectDialog.cpp | 42 ++++++++++++++++--- src/autoapp/autoapp.cpp | 11 +++-- 3 files changed, 60 insertions(+), 10 deletions(-) diff --git a/include/f1x/openauto/autoapp/UI/ConnectDialog.hpp b/include/f1x/openauto/autoapp/UI/ConnectDialog.hpp index db90ca4..c0b0c42 100644 --- a/include/f1x/openauto/autoapp/UI/ConnectDialog.hpp +++ b/include/f1x/openauto/autoapp/UI/ConnectDialog.hpp @@ -1,6 +1,8 @@ #pragma once #include +#include +#include namespace Ui { class ConnectDialog; @@ -20,11 +22,22 @@ class ConnectDialog : public QDialog Q_OBJECT public: - explicit ConnectDialog(QWidget *parent = nullptr); + explicit ConnectDialog(boost::asio::io_service& ioService, aasdk::tcp::ITCPWrapper& tcpWrapper, QWidget *parent = nullptr); ~ConnectDialog() override; +signals: + void connectToDevice(const QString& ipAddress); + void connected(aasdk::tcp::ITCPEndpoint::SocketPointer socket); + void connectionFailed(); + +private slots: + void onConnectButtonClicked(); + void onConnectionFailed(); + private: - Ui::ConnectDialog *ui; + boost::asio::io_service& ioService_; + aasdk::tcp::ITCPWrapper& tcpWrapper_; + Ui::ConnectDialog *ui_; }; } diff --git a/src/autoapp/UI/ConnectDialog.cpp b/src/autoapp/UI/ConnectDialog.cpp index b663f51..54337b6 100644 --- a/src/autoapp/UI/ConnectDialog.cpp +++ b/src/autoapp/UI/ConnectDialog.cpp @@ -1,3 +1,4 @@ +#include #include #include "ui_connectdialog.h" @@ -10,16 +11,47 @@ namespace autoapp namespace ui { -ConnectDialog::ConnectDialog(QWidget *parent) : - QDialog(parent), - ui(new Ui::ConnectDialog) +ConnectDialog::ConnectDialog(boost::asio::io_service& ioService, aasdk::tcp::ITCPWrapper& tcpWrapper, QWidget *parent) + : QDialog(parent) + , ioService_(ioService) + , tcpWrapper_(tcpWrapper) + , ui_(new Ui::ConnectDialog) { - ui->setupUi(this); + qRegisterMetaType("aasdk::tcp::ITCPEndpoint::SocketPointer"); + + ui_->setupUi(this); + connect(ui_->pushButtonCancel, &QPushButton::clicked, this, &ConnectDialog::close); + connect(ui_->pushButtonConnect, &QPushButton::clicked, this, &ConnectDialog::onConnectButtonClicked); + connect(this, &ConnectDialog::connectionFailed, this, &ConnectDialog::onConnectionFailed); } ConnectDialog::~ConnectDialog() { - delete ui; + delete ui_; +} + +void ConnectDialog::onConnectButtonClicked() +{ + const auto& ipAddress = ui_->lineEditIPAddress->text().toStdString(); + auto socket = std::make_shared(ioService_); + + // !ec means no error + if(!tcpWrapper_.connect(*socket, ipAddress, 5277)) + { + emit connected(socket); + this->close(); + } + else + { + emit connectionFailed(); + } +} + +void ConnectDialog::onConnectionFailed() +{ + QMessageBox errorMessage(QMessageBox::Critical, "Error", "Connection failed.", QMessageBox::Ok); + errorMessage.setWindowFlags(Qt::WindowStaysOnTopHint); + errorMessage.exec(); } } diff --git a/src/autoapp/autoapp.cpp b/src/autoapp/autoapp.cpp index f063a2d..0c238cf 100644 --- a/src/autoapp/autoapp.cpp +++ b/src/autoapp/autoapp.cpp @@ -90,8 +90,9 @@ int main(int argc, char* argv[]) autoapp::ui::SettingsWindow settingsWindow(configuration); settingsWindow.setWindowFlags(Qt::WindowStaysOnTopHint); - autoapp::ui::ConnectDialog connectDialog; - connectDialog.setWindowFlags(Qt::Window | Qt::WindowStaysOnTopHint); + aasdk::tcp::TCPWrapper tcpWrapper; + autoapp::ui::ConnectDialog connectDialog(ioService, tcpWrapper); + connectDialog.setWindowFlags(Qt::WindowStaysOnTopHint); QObject::connect(&mainWindow, &autoapp::ui::MainWindow::exit, []() { std::exit(0); }); QObject::connect(&mainWindow, &autoapp::ui::MainWindow::openSettings, &settingsWindow, &autoapp::ui::SettingsWindow::showFullScreen); @@ -105,7 +106,6 @@ int main(int argc, char* argv[]) mainWindow.showFullScreen(); - aasdk::tcp::TCPWrapper tcpWrapper; aasdk::usb::USBWrapper usbWrapper(usbContext); aasdk::usb::AccessoryModeQueryFactory queryFactory(usbWrapper, ioService); aasdk::usb::AccessoryModeQueryChainFactory queryChainFactory(usbWrapper, ioService, queryFactory); @@ -115,6 +115,11 @@ int main(int argc, char* argv[]) auto usbHub(std::make_shared(usbWrapper, ioService, queryChainFactory)); auto connectedAccessoriesEnumerator(std::make_shared(usbWrapper, ioService, queryChainFactory)); auto app = std::make_shared(ioService, usbWrapper, tcpWrapper, androidAutoEntityFactory, std::move(usbHub), std::move(connectedAccessoriesEnumerator)); + + QObject::connect(&connectDialog, &autoapp::ui::ConnectDialog::connected, [&app](auto socket) { + app->start(std::move(socket)); + }); + app->waitForUSBDevice(); auto result = qApplication.exec(); From f77cbca8766d9b43844b41eea491817acc1c6c5f Mon Sep 17 00:00:00 2001 From: "michal.szwaj" Date: Thu, 22 Mar 2018 16:33:23 +0100 Subject: [PATCH 06/13] Indicate connection progress --- .../f1x/openauto/autoapp/UI/ConnectDialog.hpp | 4 +- src/autoapp/UI/ConnectDialog.cpp | 38 +++++++++++---- src/autoapp/UI/connectdialog.ui | 47 +++++++++++++++++-- src/autoapp/autoapp.cpp | 2 +- 4 files changed, 74 insertions(+), 17 deletions(-) diff --git a/include/f1x/openauto/autoapp/UI/ConnectDialog.hpp b/include/f1x/openauto/autoapp/UI/ConnectDialog.hpp index c0b0c42..a1d348b 100644 --- a/include/f1x/openauto/autoapp/UI/ConnectDialog.hpp +++ b/include/f1x/openauto/autoapp/UI/ConnectDialog.hpp @@ -27,12 +27,14 @@ public: signals: void connectToDevice(const QString& ipAddress); - void connected(aasdk::tcp::ITCPEndpoint::SocketPointer socket); + void connectionSucceed(aasdk::tcp::ITCPEndpoint::SocketPointer socket); void connectionFailed(); private slots: void onConnectButtonClicked(); void onConnectionFailed(); + void onConnectionSucceed(); + void setControlsEnabledStatus(bool status); private: boost::asio::io_service& ioService_; diff --git a/src/autoapp/UI/ConnectDialog.cpp b/src/autoapp/UI/ConnectDialog.cpp index 54337b6..9849052 100644 --- a/src/autoapp/UI/ConnectDialog.cpp +++ b/src/autoapp/UI/ConnectDialog.cpp @@ -22,6 +22,7 @@ ConnectDialog::ConnectDialog(boost::asio::io_service& ioService, aasdk::tcp::ITC ui_->setupUi(this); connect(ui_->pushButtonCancel, &QPushButton::clicked, this, &ConnectDialog::close); connect(ui_->pushButtonConnect, &QPushButton::clicked, this, &ConnectDialog::onConnectButtonClicked); + connect(this, &ConnectDialog::connectionSucceed, this, &ConnectDialog::onConnectionSucceed); connect(this, &ConnectDialog::connectionFailed, this, &ConnectDialog::onConnectionFailed); } @@ -32,28 +33,45 @@ ConnectDialog::~ConnectDialog() void ConnectDialog::onConnectButtonClicked() { + this->setControlsEnabledStatus(false); + const auto& ipAddress = ui_->lineEditIPAddress->text().toStdString(); auto socket = std::make_shared(ioService_); + tcpWrapper_.asyncConnect(*socket, ipAddress, 5277, [this, socket](auto ec) mutable { + if(!ec) + { + emit connectionSucceed(std::move(socket)); + this->close(); + } + else + { + emit connectionFailed(); + } + }); +} - // !ec means no error - if(!tcpWrapper_.connect(*socket, ipAddress, 5277)) - { - emit connected(socket); - this->close(); - } - else - { - emit connectionFailed(); - } +void ConnectDialog::onConnectionSucceed() +{ + this->setControlsEnabledStatus(true); } void ConnectDialog::onConnectionFailed() { + this->setControlsEnabledStatus(true); + QMessageBox errorMessage(QMessageBox::Critical, "Error", "Connection failed.", QMessageBox::Ok); errorMessage.setWindowFlags(Qt::WindowStaysOnTopHint); errorMessage.exec(); } +void ConnectDialog::setControlsEnabledStatus(bool status) +{ + ui_->pushButtonConnect->setVisible(status); + ui_->pushButtonCancel->setEnabled(status); + ui_->lineEditIPAddress->setEnabled(status); + ui_->listViewRecent->setEnabled(status); +} + } } } diff --git a/src/autoapp/UI/connectdialog.ui b/src/autoapp/UI/connectdialog.ui index ba7b6ee..a9adb5d 100644 --- a/src/autoapp/UI/connectdialog.ui +++ b/src/autoapp/UI/connectdialog.ui @@ -59,7 +59,7 @@ - + 60 @@ -91,9 +91,9 @@ - 100 + 40 340 - 89 + 121 41 @@ -104,9 +104,9 @@ - 200 + 170 340 - 89 + 121 41 @@ -114,6 +114,43 @@ Connect + + + + 170 + 340 + 121 + 41 + + + + 0 + + + 0 + + + + + + 188 + 350 + 91 + 20 + + + + Connecting... + + + groupBoxIPAddress + groupBoxRecent + labelHeadUnitServerInfo + labelCopyrightsInfoIcon + pushButtonCancel + progressBarConnect + labelConnecting + pushButtonConnect diff --git a/src/autoapp/autoapp.cpp b/src/autoapp/autoapp.cpp index 0c238cf..81fe3cd 100644 --- a/src/autoapp/autoapp.cpp +++ b/src/autoapp/autoapp.cpp @@ -116,7 +116,7 @@ int main(int argc, char* argv[]) auto connectedAccessoriesEnumerator(std::make_shared(usbWrapper, ioService, queryChainFactory)); auto app = std::make_shared(ioService, usbWrapper, tcpWrapper, androidAutoEntityFactory, std::move(usbHub), std::move(connectedAccessoriesEnumerator)); - QObject::connect(&connectDialog, &autoapp::ui::ConnectDialog::connected, [&app](auto socket) { + QObject::connect(&connectDialog, &autoapp::ui::ConnectDialog::connectionSucceed, [&app](auto socket) { app->start(std::move(socket)); }); From 991f31bc771b0271492fe6ff9931a49b6e1073cb Mon Sep 17 00:00:00 2001 From: "michal.szwaj" Date: Thu, 22 Mar 2018 17:12:37 +0100 Subject: [PATCH 07/13] Handle invalid IP address --- .../f1x/openauto/autoapp/UI/ConnectDialog.hpp | 5 ++- src/autoapp/UI/ConnectDialog.cpp | 37 ++++++++++++------- 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/include/f1x/openauto/autoapp/UI/ConnectDialog.hpp b/include/f1x/openauto/autoapp/UI/ConnectDialog.hpp index a1d348b..fe654ca 100644 --- a/include/f1x/openauto/autoapp/UI/ConnectDialog.hpp +++ b/include/f1x/openauto/autoapp/UI/ConnectDialog.hpp @@ -28,13 +28,14 @@ public: signals: void connectToDevice(const QString& ipAddress); void connectionSucceed(aasdk::tcp::ITCPEndpoint::SocketPointer socket); - void connectionFailed(); + void connectionFailed(const QString& message); private slots: void onConnectButtonClicked(); - void onConnectionFailed(); + void onConnectionFailed(const QString& message); void onConnectionSucceed(); void setControlsEnabledStatus(bool status); + void connectHandler(const boost::system::error_code& ec, aasdk::tcp::ITCPEndpoint::SocketPointer socket); private: boost::asio::io_service& ioService_; diff --git a/src/autoapp/UI/ConnectDialog.cpp b/src/autoapp/UI/ConnectDialog.cpp index 9849052..69a2e02 100644 --- a/src/autoapp/UI/ConnectDialog.cpp +++ b/src/autoapp/UI/ConnectDialog.cpp @@ -37,17 +37,28 @@ void ConnectDialog::onConnectButtonClicked() const auto& ipAddress = ui_->lineEditIPAddress->text().toStdString(); auto socket = std::make_shared(ioService_); - tcpWrapper_.asyncConnect(*socket, ipAddress, 5277, [this, socket](auto ec) mutable { - if(!ec) - { - emit connectionSucceed(std::move(socket)); - this->close(); - } - else - { - emit connectionFailed(); - } - }); + + try + { + tcpWrapper_.asyncConnect(*socket, ipAddress, 5277, std::bind(&ConnectDialog::connectHandler, this, std::placeholders::_1, socket)); + } + catch(const boost::system::system_error& se) + { + emit connectionFailed(QString(se.what())); + } +} + +void ConnectDialog::connectHandler(const boost::system::error_code& ec, aasdk::tcp::ITCPEndpoint::SocketPointer socket) +{ + if(!ec) + { + emit connectionSucceed(std::move(socket)); + this->close(); + } + else + { + emit connectionFailed(QString::fromStdString(ec.message())); + } } void ConnectDialog::onConnectionSucceed() @@ -55,11 +66,11 @@ void ConnectDialog::onConnectionSucceed() this->setControlsEnabledStatus(true); } -void ConnectDialog::onConnectionFailed() +void ConnectDialog::onConnectionFailed(const QString& message) { this->setControlsEnabledStatus(true); - QMessageBox errorMessage(QMessageBox::Critical, "Error", "Connection failed.", QMessageBox::Ok); + QMessageBox errorMessage(QMessageBox::Critical, "Connect error", message, QMessageBox::Ok); errorMessage.setWindowFlags(Qt::WindowStaysOnTopHint); errorMessage.exec(); } From 42c15ec0097b82a3edf1059fed8072399b63b534 Mon Sep 17 00:00:00 2001 From: "michal.szwaj" Date: Thu, 22 Mar 2018 17:16:56 +0100 Subject: [PATCH 08/13] Remove status bar --- src/autoapp/UI/mainwindow.ui | 1 - 1 file changed, 1 deletion(-) diff --git a/src/autoapp/UI/mainwindow.ui b/src/autoapp/UI/mainwindow.ui index 7432822..6da956e 100644 --- a/src/autoapp/UI/mainwindow.ui +++ b/src/autoapp/UI/mainwindow.ui @@ -228,7 +228,6 @@ color: rgb(238, 238, 236); - pushButtonToggleCursor From 258a6a3c59e8118e7c3f72bc52cadc3bbcb16d68 Mon Sep 17 00:00:00 2001 From: "michal.szwaj" Date: Sun, 25 Mar 2018 01:29:36 +0100 Subject: [PATCH 09/13] Impelemnt recent list --- .../Configuration/IRecentAddressesList.hpp | 46 ++++++++ .../Configuration/RecentAddressesList.hpp | 57 ++++++++++ .../f1x/openauto/autoapp/UI/ConnectDialog.hpp | 16 ++- .../Configuration/RecentAddressesList.cpp | 106 ++++++++++++++++++ src/autoapp/UI/ConnectDialog.cpp | 32 +++++- 5 files changed, 248 insertions(+), 9 deletions(-) create mode 100644 include/f1x/openauto/autoapp/Configuration/IRecentAddressesList.hpp create mode 100644 include/f1x/openauto/autoapp/Configuration/RecentAddressesList.hpp create mode 100644 src/autoapp/Configuration/RecentAddressesList.cpp diff --git a/include/f1x/openauto/autoapp/Configuration/IRecentAddressesList.hpp b/include/f1x/openauto/autoapp/Configuration/IRecentAddressesList.hpp new file mode 100644 index 0000000..88213de --- /dev/null +++ b/include/f1x/openauto/autoapp/Configuration/IRecentAddressesList.hpp @@ -0,0 +1,46 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#pragma once + +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace configuration +{ + +class IRecentAddressesList +{ +public: + typedef std::deque RecentAddresses; + + virtual void read() = 0; + virtual void insertAddress(const std::string& address) = 0; + virtual RecentAddresses getList() const = 0; +}; + +} +} +} +} diff --git a/include/f1x/openauto/autoapp/Configuration/RecentAddressesList.hpp b/include/f1x/openauto/autoapp/Configuration/RecentAddressesList.hpp new file mode 100644 index 0000000..3c12591 --- /dev/null +++ b/include/f1x/openauto/autoapp/Configuration/RecentAddressesList.hpp @@ -0,0 +1,57 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#pragma once + +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace configuration +{ + +class RecentAddressesList: public IRecentAddressesList +{ +public: + RecentAddressesList(size_t maxListSize); + + void read() override; + void insertAddress(const std::string& address) override; + RecentAddresses getList() const override; + +private: + void load(); + void save(); + + size_t maxListSize_; + RecentAddresses list_; + + static const std::string cConfigFileName; + static const std::string cRecentEntiresCount; + static const std::string cRecentEntryPrefix; +}; + +} +} +} +} diff --git a/include/f1x/openauto/autoapp/UI/ConnectDialog.hpp b/include/f1x/openauto/autoapp/UI/ConnectDialog.hpp index fe654ca..5395bef 100644 --- a/include/f1x/openauto/autoapp/UI/ConnectDialog.hpp +++ b/include/f1x/openauto/autoapp/UI/ConnectDialog.hpp @@ -1,8 +1,10 @@ #pragma once #include +#include #include #include +#include namespace Ui { class ConnectDialog; @@ -22,25 +24,31 @@ class ConnectDialog : public QDialog Q_OBJECT public: - explicit ConnectDialog(boost::asio::io_service& ioService, aasdk::tcp::ITCPWrapper& tcpWrapper, QWidget *parent = nullptr); + explicit ConnectDialog(boost::asio::io_service& ioService, aasdk::tcp::ITCPWrapper& tcpWrapper, openauto::autoapp::configuration::IRecentAddressesList& recentAddressesList, QWidget *parent = nullptr); ~ConnectDialog() override; signals: void connectToDevice(const QString& ipAddress); - void connectionSucceed(aasdk::tcp::ITCPEndpoint::SocketPointer socket); + void connectionSucceed(aasdk::tcp::ITCPEndpoint::SocketPointer socket, std::string ipAddress); void connectionFailed(const QString& message); private slots: void onConnectButtonClicked(); void onConnectionFailed(const QString& message); - void onConnectionSucceed(); + void onConnectionSucceed(aasdk::tcp::ITCPEndpoint::SocketPointer socket, std::string ipAddress); void setControlsEnabledStatus(bool status); - void connectHandler(const boost::system::error_code& ec, aasdk::tcp::ITCPEndpoint::SocketPointer socket); + void connectHandler(const boost::system::error_code& ec, std::string ipAddress, aasdk::tcp::ITCPEndpoint::SocketPointer socket); private: + void insertIpAddress(std::string ipAddress); + void loadRecentList(); + boost::asio::io_service& ioService_; aasdk::tcp::ITCPWrapper& tcpWrapper_; + openauto::autoapp::configuration::IRecentAddressesList& recentAddressesList_; Ui::ConnectDialog *ui_; + QStringListModel recentAddressesModel_; + QStringList recentAddressesModelList_; }; } diff --git a/src/autoapp/Configuration/RecentAddressesList.cpp b/src/autoapp/Configuration/RecentAddressesList.cpp new file mode 100644 index 0000000..7d8af3e --- /dev/null +++ b/src/autoapp/Configuration/RecentAddressesList.cpp @@ -0,0 +1,106 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#include +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace configuration +{ + +const std::string RecentAddressesList::cConfigFileName = "openauto_wifi_recent.ini"; +const std::string RecentAddressesList::cRecentEntiresCount = "Recent.EntiresCount"; +const std::string RecentAddressesList::cRecentEntryPrefix = "Recent.Entry_"; + +RecentAddressesList::RecentAddressesList(size_t maxListSize) + : maxListSize_(maxListSize) +{ + +} + +void RecentAddressesList::read() +{ + this->load(); +} + +void RecentAddressesList::insertAddress(const std::string& address) +{ + list_.push_front(address); + this->save(); +} + +RecentAddressesList::RecentAddresses RecentAddressesList::getList() const +{ + return list_; +} + +void RecentAddressesList::load() +{ + boost::property_tree::ptree iniConfig; + + try + { + boost::property_tree::ini_parser::read_ini(cConfigFileName, iniConfig); + + const auto listSize = std::min(maxListSize_, iniConfig.get(cRecentEntiresCount, 0)); + + for(size_t i = 0; i < listSize; ++i) + { + const auto key = cRecentEntryPrefix + std::to_string(i); + const auto address = iniConfig.get(key, RecentAddresses::value_type()); + + if(!address.empty()) + { + list_.push_back(address); + } + } + } + catch(const boost::property_tree::ini_parser_error& e) + { + OPENAUTO_LOG(warning) << "[RecentAddressesList] failed to read configuration file: " << cConfigFileName + << ", error: " << e.what() + << ". Empty list will be used."; + } +} + +void RecentAddressesList::save() +{ + boost::property_tree::ptree iniConfig; + + const auto entiresCount = std::min(maxListSize_, list_.size()); + iniConfig.put(cRecentEntiresCount, entiresCount); + + for(size_t i = 0; i < entiresCount; ++i) + { + const auto key = cRecentEntryPrefix + std::to_string(i); + iniConfig.put(key, list_.at(i)); + } + + boost::property_tree::ini_parser::write_ini(cConfigFileName, iniConfig); +} + +} +} +} +} diff --git a/src/autoapp/UI/ConnectDialog.cpp b/src/autoapp/UI/ConnectDialog.cpp index 69a2e02..1a510cd 100644 --- a/src/autoapp/UI/ConnectDialog.cpp +++ b/src/autoapp/UI/ConnectDialog.cpp @@ -11,10 +11,11 @@ namespace autoapp namespace ui { -ConnectDialog::ConnectDialog(boost::asio::io_service& ioService, aasdk::tcp::ITCPWrapper& tcpWrapper, QWidget *parent) +ConnectDialog::ConnectDialog(boost::asio::io_service& ioService, aasdk::tcp::ITCPWrapper& tcpWrapper, openauto::autoapp::configuration::IRecentAddressesList& recentAddressesList, QWidget *parent) : QDialog(parent) , ioService_(ioService) , tcpWrapper_(tcpWrapper) + , recentAddressesList_(recentAddressesList) , ui_(new Ui::ConnectDialog) { qRegisterMetaType("aasdk::tcp::ITCPEndpoint::SocketPointer"); @@ -24,6 +25,9 @@ ConnectDialog::ConnectDialog(boost::asio::io_service& ioService, aasdk::tcp::ITC connect(ui_->pushButtonConnect, &QPushButton::clicked, this, &ConnectDialog::onConnectButtonClicked); connect(this, &ConnectDialog::connectionSucceed, this, &ConnectDialog::onConnectionSucceed); connect(this, &ConnectDialog::connectionFailed, this, &ConnectDialog::onConnectionFailed); + + recentAddressesModel_.setStringList(recentAddressesModelList_); + ui_->listViewRecent->setModel(&recentAddressesModel_); } ConnectDialog::~ConnectDialog() @@ -40,7 +44,7 @@ void ConnectDialog::onConnectButtonClicked() try { - tcpWrapper_.asyncConnect(*socket, ipAddress, 5277, std::bind(&ConnectDialog::connectHandler, this, std::placeholders::_1, socket)); + tcpWrapper_.asyncConnect(*socket, ipAddress, 5277, std::bind(&ConnectDialog::connectHandler, this, std::placeholders::_1, ipAddress, socket)); } catch(const boost::system::system_error& se) { @@ -48,11 +52,11 @@ void ConnectDialog::onConnectButtonClicked() } } -void ConnectDialog::connectHandler(const boost::system::error_code& ec, aasdk::tcp::ITCPEndpoint::SocketPointer socket) +void ConnectDialog::connectHandler(const boost::system::error_code& ec, std::string ipAddress, aasdk::tcp::ITCPEndpoint::SocketPointer socket) { if(!ec) { - emit connectionSucceed(std::move(socket)); + emit connectionSucceed(std::move(socket), ipAddress); this->close(); } else @@ -61,8 +65,9 @@ void ConnectDialog::connectHandler(const boost::system::error_code& ec, aasdk::t } } -void ConnectDialog::onConnectionSucceed() +void ConnectDialog::onConnectionSucceed(aasdk::tcp::ITCPEndpoint::SocketPointer, std::string ipAddress) { + this->insertIpAddress(ipAddress); this->setControlsEnabledStatus(true); } @@ -83,6 +88,23 @@ void ConnectDialog::setControlsEnabledStatus(bool status) ui_->listViewRecent->setEnabled(status); } +void ConnectDialog::loadRecentList() +{ + recentAddressesModelList_.clear(); + const auto& configList = recentAddressesList_.getList(); + + for(const auto& element : configList) + { + recentAddressesModelList_.append(QString::fromStdString(element)); + } +} + +void ConnectDialog::insertIpAddress(std::string ipAddress) +{ + recentAddressesList_.insertAddress(ipAddress); + this->loadRecentList(); +} + } } } From f01f057b68720b806c63b186d04a1d8fd2c8374b Mon Sep 17 00:00:00 2001 From: "michal.szwaj" Date: Sun, 25 Mar 2018 01:58:38 +0100 Subject: [PATCH 10/13] Load recent addresses list --- include/f1x/openauto/autoapp/UI/ConnectDialog.hpp | 11 +++++------ src/autoapp/UI/ConnectDialog.cpp | 15 +++++++++------ src/autoapp/autoapp.cpp | 6 +++++- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/include/f1x/openauto/autoapp/UI/ConnectDialog.hpp b/include/f1x/openauto/autoapp/UI/ConnectDialog.hpp index 5395bef..dcb3326 100644 --- a/include/f1x/openauto/autoapp/UI/ConnectDialog.hpp +++ b/include/f1x/openauto/autoapp/UI/ConnectDialog.hpp @@ -29,26 +29,25 @@ public: signals: void connectToDevice(const QString& ipAddress); - void connectionSucceed(aasdk::tcp::ITCPEndpoint::SocketPointer socket, std::string ipAddress); + void connectionSucceed(aasdk::tcp::ITCPEndpoint::SocketPointer socket, const std::string& ipAddress); void connectionFailed(const QString& message); private slots: void onConnectButtonClicked(); void onConnectionFailed(const QString& message); - void onConnectionSucceed(aasdk::tcp::ITCPEndpoint::SocketPointer socket, std::string ipAddress); - void setControlsEnabledStatus(bool status); - void connectHandler(const boost::system::error_code& ec, std::string ipAddress, aasdk::tcp::ITCPEndpoint::SocketPointer socket); + void onConnectionSucceed(aasdk::tcp::ITCPEndpoint::SocketPointer socket, const std::string& ipAddress); private: - void insertIpAddress(std::string ipAddress); + void insertIpAddress(const std::string& ipAddress); void loadRecentList(); + void setControlsEnabledStatus(bool status); + void connectHandler(const boost::system::error_code& ec, const std::string& ipAddress, aasdk::tcp::ITCPEndpoint::SocketPointer socket); boost::asio::io_service& ioService_; aasdk::tcp::ITCPWrapper& tcpWrapper_; openauto::autoapp::configuration::IRecentAddressesList& recentAddressesList_; Ui::ConnectDialog *ui_; QStringListModel recentAddressesModel_; - QStringList recentAddressesModelList_; }; } diff --git a/src/autoapp/UI/ConnectDialog.cpp b/src/autoapp/UI/ConnectDialog.cpp index 1a510cd..5e43c17 100644 --- a/src/autoapp/UI/ConnectDialog.cpp +++ b/src/autoapp/UI/ConnectDialog.cpp @@ -19,6 +19,7 @@ ConnectDialog::ConnectDialog(boost::asio::io_service& ioService, aasdk::tcp::ITC , ui_(new Ui::ConnectDialog) { qRegisterMetaType("aasdk::tcp::ITCPEndpoint::SocketPointer"); + qRegisterMetaType("std::string"); ui_->setupUi(this); connect(ui_->pushButtonCancel, &QPushButton::clicked, this, &ConnectDialog::close); @@ -26,8 +27,8 @@ ConnectDialog::ConnectDialog(boost::asio::io_service& ioService, aasdk::tcp::ITC connect(this, &ConnectDialog::connectionSucceed, this, &ConnectDialog::onConnectionSucceed); connect(this, &ConnectDialog::connectionFailed, this, &ConnectDialog::onConnectionFailed); - recentAddressesModel_.setStringList(recentAddressesModelList_); ui_->listViewRecent->setModel(&recentAddressesModel_); + this->loadRecentList(); } ConnectDialog::~ConnectDialog() @@ -52,7 +53,7 @@ void ConnectDialog::onConnectButtonClicked() } } -void ConnectDialog::connectHandler(const boost::system::error_code& ec, std::string ipAddress, aasdk::tcp::ITCPEndpoint::SocketPointer socket) +void ConnectDialog::connectHandler(const boost::system::error_code& ec, const std::string& ipAddress, aasdk::tcp::ITCPEndpoint::SocketPointer socket) { if(!ec) { @@ -65,7 +66,7 @@ void ConnectDialog::connectHandler(const boost::system::error_code& ec, std::str } } -void ConnectDialog::onConnectionSucceed(aasdk::tcp::ITCPEndpoint::SocketPointer, std::string ipAddress) +void ConnectDialog::onConnectionSucceed(aasdk::tcp::ITCPEndpoint::SocketPointer, const std::string& ipAddress) { this->insertIpAddress(ipAddress); this->setControlsEnabledStatus(true); @@ -90,16 +91,18 @@ void ConnectDialog::setControlsEnabledStatus(bool status) void ConnectDialog::loadRecentList() { - recentAddressesModelList_.clear(); + QStringList stringList; const auto& configList = recentAddressesList_.getList(); for(const auto& element : configList) { - recentAddressesModelList_.append(QString::fromStdString(element)); + stringList.append(QString::fromStdString(element)); } + + recentAddressesModel_.setStringList(stringList); } -void ConnectDialog::insertIpAddress(std::string ipAddress) +void ConnectDialog::insertIpAddress(const std::string& ipAddress) { recentAddressesList_.insertAddress(ipAddress); this->loadRecentList(); diff --git a/src/autoapp/autoapp.cpp b/src/autoapp/autoapp.cpp index 81fe3cd..4d0d846 100644 --- a/src/autoapp/autoapp.cpp +++ b/src/autoapp/autoapp.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -90,8 +91,11 @@ int main(int argc, char* argv[]) autoapp::ui::SettingsWindow settingsWindow(configuration); settingsWindow.setWindowFlags(Qt::WindowStaysOnTopHint); + autoapp::configuration::RecentAddressesList recentAddressesList(5); + recentAddressesList.read(); + aasdk::tcp::TCPWrapper tcpWrapper; - autoapp::ui::ConnectDialog connectDialog(ioService, tcpWrapper); + autoapp::ui::ConnectDialog connectDialog(ioService, tcpWrapper, recentAddressesList); connectDialog.setWindowFlags(Qt::WindowStaysOnTopHint); QObject::connect(&mainWindow, &autoapp::ui::MainWindow::exit, []() { std::exit(0); }); From 9db15b953e070d2ff7377b9d130e4cc64ce7659b Mon Sep 17 00:00:00 2001 From: "michal.szwaj" Date: Sun, 25 Mar 2018 03:13:23 +0200 Subject: [PATCH 11/13] Implement selection of recent address --- include/f1x/openauto/autoapp/UI/ConnectDialog.hpp | 1 + src/autoapp/Configuration/RecentAddressesList.cpp | 7 +++++-- src/autoapp/UI/ConnectDialog.cpp | 11 +++++++++++ src/autoapp/UI/connectdialog.ui | 3 +++ 4 files changed, 20 insertions(+), 2 deletions(-) diff --git a/include/f1x/openauto/autoapp/UI/ConnectDialog.hpp b/include/f1x/openauto/autoapp/UI/ConnectDialog.hpp index dcb3326..9e944aa 100644 --- a/include/f1x/openauto/autoapp/UI/ConnectDialog.hpp +++ b/include/f1x/openauto/autoapp/UI/ConnectDialog.hpp @@ -36,6 +36,7 @@ private slots: void onConnectButtonClicked(); void onConnectionFailed(const QString& message); void onConnectionSucceed(aasdk::tcp::ITCPEndpoint::SocketPointer socket, const std::string& ipAddress); + void onRecentAddressClicked(const QModelIndex& index); private: void insertIpAddress(const std::string& ipAddress); diff --git a/src/autoapp/Configuration/RecentAddressesList.cpp b/src/autoapp/Configuration/RecentAddressesList.cpp index 7d8af3e..ebfa2d1 100644 --- a/src/autoapp/Configuration/RecentAddressesList.cpp +++ b/src/autoapp/Configuration/RecentAddressesList.cpp @@ -46,8 +46,11 @@ void RecentAddressesList::read() void RecentAddressesList::insertAddress(const std::string& address) { - list_.push_front(address); - this->save(); + if(std::find(list_.begin(), list_.end(), address) != list_.end()) + { + list_.push_front(address); + this->save(); + } } RecentAddressesList::RecentAddresses RecentAddressesList::getList() const diff --git a/src/autoapp/UI/ConnectDialog.cpp b/src/autoapp/UI/ConnectDialog.cpp index 5e43c17..127e216 100644 --- a/src/autoapp/UI/ConnectDialog.cpp +++ b/src/autoapp/UI/ConnectDialog.cpp @@ -24,6 +24,7 @@ ConnectDialog::ConnectDialog(boost::asio::io_service& ioService, aasdk::tcp::ITC ui_->setupUi(this); connect(ui_->pushButtonCancel, &QPushButton::clicked, this, &ConnectDialog::close); connect(ui_->pushButtonConnect, &QPushButton::clicked, this, &ConnectDialog::onConnectButtonClicked); + connect(ui_->listViewRecent, &QListView::clicked, this, &ConnectDialog::onRecentAddressClicked); connect(this, &ConnectDialog::connectionSucceed, this, &ConnectDialog::onConnectionSucceed); connect(this, &ConnectDialog::connectionFailed, this, &ConnectDialog::onConnectionFailed); @@ -81,6 +82,16 @@ void ConnectDialog::onConnectionFailed(const QString& message) errorMessage.exec(); } +void ConnectDialog::onRecentAddressClicked(const QModelIndex& index) +{ + const auto& recentAddressesList = recentAddressesList_.getList(); + + if(static_cast(index.row()) <= recentAddressesList.size()) + { + ui_->lineEditIPAddress->setText(QString::fromStdString(recentAddressesList.at(index.row()))); + } +} + void ConnectDialog::setControlsEnabledStatus(bool status) { ui_->pushButtonConnect->setVisible(status); diff --git a/src/autoapp/UI/connectdialog.ui b/src/autoapp/UI/connectdialog.ui index a9adb5d..445e962 100644 --- a/src/autoapp/UI/connectdialog.ui +++ b/src/autoapp/UI/connectdialog.ui @@ -57,6 +57,9 @@ 141 + + QAbstractItemView::NoEditTriggers + From 9c529421227905da53870945357d344f39342f81 Mon Sep 17 00:00:00 2001 From: "michal.szwaj" Date: Sun, 25 Mar 2018 03:17:16 +0200 Subject: [PATCH 12/13] Fix condition of adding address to the recent list --- src/autoapp/Configuration/RecentAddressesList.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/autoapp/Configuration/RecentAddressesList.cpp b/src/autoapp/Configuration/RecentAddressesList.cpp index ebfa2d1..3e19214 100644 --- a/src/autoapp/Configuration/RecentAddressesList.cpp +++ b/src/autoapp/Configuration/RecentAddressesList.cpp @@ -46,7 +46,7 @@ void RecentAddressesList::read() void RecentAddressesList::insertAddress(const std::string& address) { - if(std::find(list_.begin(), list_.end(), address) != list_.end()) + if(std::find(list_.begin(), list_.end(), address) == list_.end()) { list_.push_front(address); this->save(); From 50c2a437fa867a884a9a3a39ccfce27ce70d80ed Mon Sep 17 00:00:00 2001 From: "michal.szwaj" Date: Sun, 25 Mar 2018 03:31:51 +0200 Subject: [PATCH 13/13] Replace last recent address with newer one --- src/autoapp/Configuration/RecentAddressesList.cpp | 13 ++++++++++--- src/autoapp/autoapp.cpp | 2 +- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/autoapp/Configuration/RecentAddressesList.cpp b/src/autoapp/Configuration/RecentAddressesList.cpp index 3e19214..c29fdcf 100644 --- a/src/autoapp/Configuration/RecentAddressesList.cpp +++ b/src/autoapp/Configuration/RecentAddressesList.cpp @@ -46,11 +46,18 @@ void RecentAddressesList::read() void RecentAddressesList::insertAddress(const std::string& address) { - if(std::find(list_.begin(), list_.end(), address) == list_.end()) + if(std::find(list_.begin(), list_.end(), address) != list_.end()) { - list_.push_front(address); - this->save(); + return; } + + if(list_.size() >= maxListSize_) + { + list_.pop_back(); + } + + list_.push_front(address); + this->save(); } RecentAddressesList::RecentAddresses RecentAddressesList::getList() const diff --git a/src/autoapp/autoapp.cpp b/src/autoapp/autoapp.cpp index 4d0d846..8c2565c 100644 --- a/src/autoapp/autoapp.cpp +++ b/src/autoapp/autoapp.cpp @@ -91,7 +91,7 @@ int main(int argc, char* argv[]) autoapp::ui::SettingsWindow settingsWindow(configuration); settingsWindow.setWindowFlags(Qt::WindowStaysOnTopHint); - autoapp::configuration::RecentAddressesList recentAddressesList(5); + autoapp::configuration::RecentAddressesList recentAddressesList(7); recentAddressesList.read(); aasdk::tcp::TCPWrapper tcpWrapper;