diff --git a/CMakeLists.txt b/CMakeLists.txt
index 773c1438..fc87b2e5 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -32,6 +32,7 @@ find_package(libusb-1.0 REQUIRED)
find_package(Qt5 COMPONENTS Multimedia MultimediaWidgets Bluetooth)
find_package(Protobuf REQUIRED)
find_package(OpenSSL REQUIRED)
+find_package(rtaudio REQUIRED)
if(WIN32)
set(WINSOCK2_LIBRARIES "ws2_32")
@@ -54,6 +55,7 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR}
${LIBUSB_1_INCLUDE_DIRS}
${PROTOBUF_INCLUDE_DIR}
${OPENSSL_INCLUDE_DIR}
+ ${RTAUDIO_INCLUDE_DIRS}
${AASDK_PROTO_INCLUDE_DIRS}
${AASDK_INCLUDE_DIRS}
${BCM_HOST_INCLUDE_DIRS}
@@ -62,10 +64,13 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR}
link_directories(${CMAKE_LIBRARY_OUTPUT_DIRECTORY})
+set(common_include_directory ${include_directory}/f1x/openauto/Common)
+
set(autoapp_sources_directory ${sources_directory}/autoapp)
-file(GLOB_RECURSE source_files ${autoapp_sources_directory}/*.ui ${autoapp_sources_directory}/*.cpp ${include_directory}/*.hpp ${resources_directory}/*.qrc)
+set(autoapp_include_directory ${include_directory}/f1x/openauto/autoapp)
+file(GLOB_RECURSE autoapp_source_files ${autoapp_sources_directory}/*.ui ${autoapp_sources_directory}/*.cpp ${autoapp_include_directory}/*.hpp ${common_include_directory}/*.hpp ${resources_directory}/*.qrc)
-add_executable(autoapp ${source_files})
+add_executable(autoapp ${autoapp_source_files})
target_link_libraries(autoapp
${Boost_LIBRARIES}
@@ -77,5 +82,19 @@ target_link_libraries(autoapp
${BCM_HOST_LIBRARIES}
${ILCLIENT_LIBRARIES}
${WINSOCK2_LIBRARIES}
+ ${RTAUDIO_LIBRARIES}
${AASDK_PROTO_LIBRARIES}
${AASDK_LIBRARIES})
+
+set(btservice_sources_directory ${sources_directory}/btservice)
+set(btservice_include_directory ${include_directory}/f1x/openauto/btservice)
+file(GLOB_RECURSE btservice_source_files ${btservice_sources_directory}/*.cpp ${btservice_include_directory}/*.hpp ${common_include_directory}/*.hpp)
+
+add_executable(btservice ${btservice_source_files})
+
+target_link_libraries(btservice
+ ${Boost_LIBRARIES}
+ ${Qt5Bluetooth_LIBRARIES}
+ ${Qt5MultimediaWidgets_LIBRARIES}
+ ${PROTOBUF_LIBRARIES}
+ ${AASDK_PROTO_LIBRARIES})
diff --git a/Readme.md b/Readme.md
index aaf92178..2deb2ebb 100644
--- a/Readme.md
+++ b/Readme.md
@@ -22,6 +22,8 @@ OpenAuto is an AndroidAuto(tm) headunit emulator based on aasdk library and Qt l
- Touchscreen and buttons input
- Bluetooth
- Automatic launch after device hotplug
+ - Automatic detection of connected Android devices
+ - Wireless (WiFi) mode via head unit server (must be enabled in hidden developer settings)
- User-friendly settings
### Supported platforms
@@ -42,6 +44,7 @@ Copyrights (c) 2018 f1x.studio (Michal Szwaj)
- [Boost libraries](http://www.boost.org/)
- [Qt libraries](https://www.qt.io/)
- [CMake](https://cmake.org/)
+ - [RtAudio](https://www.music.mcgill.ca/~gary/rtaudio/playback.html)
- Broadcom ilclient from RaspberryPI 3 firmware
- OpenMAX IL API
diff --git a/cmake_modules/Findrtaudio.cmake b/cmake_modules/Findrtaudio.cmake
new file mode 100644
index 00000000..60b9384c
--- /dev/null
+++ b/cmake_modules/Findrtaudio.cmake
@@ -0,0 +1,70 @@
+#
+# 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 .
+#
+
+if (RTAUDIO_LIBRARIES AND RTAUDIO_INCLUDE_DIRS)
+ # in cache already
+ set(RTAUDIO_FOUND TRUE)
+else (RTAUDIO_LIBRARIES AND RTAUDIO_INCLUDE_DIRS)
+ find_path(RTAUDIO_INCLUDE_DIR
+ NAMES
+ RtAudio.h
+ PATHS
+ /usr/include
+ /usr/local/include
+ /opt/local/include
+ /sw/include
+ PATH_SUFFIXES
+ rtaudio
+ )
+
+ find_library(RTAUDIO_LIBRARY
+ NAMES
+ rtaudio
+ PATHS
+ /usr/lib
+ /usr/local/lib
+ /opt/local/lib
+ /sw/lib
+ )
+
+ set(RTAUDIO_INCLUDE_DIRS
+ ${RTAUDIO_INCLUDE_DIR}
+ )
+ set(RTAUDIO_LIBRARIES
+ ${RTAUDIO_LIBRARY}
+)
+
+ if (RTAUDIO_INCLUDE_DIRS AND RTAUDIO_LIBRARIES)
+ set(RTAUDIO_FOUND TRUE)
+ endif (RTAUDIO_INCLUDE_DIRS AND RTAUDIO_LIBRARIES)
+
+ if (RTAUDIO_FOUND)
+ if (NOT rtaudio_FIND_QUIETLY)
+ message(STATUS "Found rtaudio:")
+ message(STATUS " - Includes: ${RTAUDIO_INCLUDE_DIRS}")
+ message(STATUS " - Libraries: ${RTAUDIO_LIBRARIES}")
+ endif (NOT rtaudio_FIND_QUIETLY)
+ else (RTAUDIO_FOUND)
+ if (rtaudio_FIND_REQUIRED)
+ message(FATAL_ERROR "Could not find rtaudio")
+ endif (rtaudio_FIND_REQUIRED)
+ endif (RTAUDIO_FOUND)
+
+ mark_as_advanced(RTAUDIO_INCLUDE_DIRS RTAUDIO_LIBRARIES)
+
+endif (RTAUDIO_LIBRARIES AND RTAUDIO_INCLUDE_DIRS)
diff --git a/include/f1x/openauto/Common/Log.hpp b/include/f1x/openauto/Common/Log.hpp
index f0f544a5..42159617 100644
--- a/include/f1x/openauto/Common/Log.hpp
+++ b/include/f1x/openauto/Common/Log.hpp
@@ -20,4 +20,4 @@
#include
-#define OPENAUTO_LOG(severity) BOOST_LOG_TRIVIAL(severity) << "[AaApp] "
+#define OPENAUTO_LOG(severity) BOOST_LOG_TRIVIAL(severity) << "[OpenAuto] "
diff --git a/include/f1x/openauto/autoapp/USB/USBApp.hpp b/include/f1x/openauto/autoapp/App.hpp
similarity index 60%
rename from include/f1x/openauto/autoapp/USB/USBApp.hpp
rename to include/f1x/openauto/autoapp/App.hpp
index 76c6955e..5bbdbe2c 100644
--- a/include/f1x/openauto/autoapp/USB/USBApp.hpp
+++ b/include/f1x/openauto/autoapp/App.hpp
@@ -19,6 +19,10 @@
#pragma once
#include
+#include
+#include
+#include
+#include
#include
#include
@@ -28,31 +32,35 @@ namespace openauto
{
namespace autoapp
{
-namespace usb
-{
-class USBApp: public projection::IAndroidAutoEntityEventHandler, public std::enable_shared_from_this
+class App: public projection::IAndroidAutoEntityEventHandler, public std::enable_shared_from_this
{
public:
- typedef std::shared_ptr Pointer;
+ typedef std::shared_ptr Pointer;
- USBApp(boost::asio::io_service& ioService, projection::IAndroidAutoEntityFactory& androidAutoEntityFactory, aasdk::usb::IUSBHub::Pointer usbHub);
+ 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 start();
+ void waitForUSBDevice();
+ void start(aasdk::tcp::ITCPEndpoint::SocketPointer socket);
void stop();
void onAndroidAutoQuit() override;
private:
- using std::enable_shared_from_this::shared_from_this;
+ using std::enable_shared_from_this::shared_from_this;
+ void enumerateDevices();
void waitForDevice();
void aoapDeviceHandler(aasdk::usb::DeviceHandle deviceHandle);
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_;
+ aasdk::usb::IConnectedAccessoriesEnumerator::Pointer connectedAccessoriesEnumerator_;
projection::IAndroidAutoEntity::Pointer androidAutoEntity_;
bool isStopped_;
};
@@ -60,4 +68,3 @@ class USBApp: public projection::IAndroidAutoEntityEventHandler, public std::ena
}
}
}
-}
diff --git a/include/f1x/openauto/autoapp/Configuration/AudioOutputBackendType.hpp b/include/f1x/openauto/autoapp/Configuration/AudioOutputBackendType.hpp
new file mode 100644
index 00000000..e954874a
--- /dev/null
+++ b/include/f1x/openauto/autoapp/Configuration/AudioOutputBackendType.hpp
@@ -0,0 +1,39 @@
+/*
+* 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
+
+namespace f1x
+{
+namespace openauto
+{
+namespace autoapp
+{
+namespace configuration
+{
+
+enum class AudioOutputBackendType
+{
+ RTAUDIO,
+ QT
+};
+
+}
+}
+}
+}
diff --git a/include/f1x/openauto/autoapp/Configuration/Configuration.hpp b/include/f1x/openauto/autoapp/Configuration/Configuration.hpp
index 2498977e..f4a0649c 100644
--- a/include/f1x/openauto/autoapp/Configuration/Configuration.hpp
+++ b/include/f1x/openauto/autoapp/Configuration/Configuration.hpp
@@ -52,6 +52,8 @@ class Configuration: public IConfiguration
void setScreenDPI(size_t value) override;
void setOMXLayerIndex(int32_t value) override;
int32_t getOMXLayerIndex() const override;
+ void setVideoMargins(QRect value) override;
+ QRect getVideoMargins() const override;
bool getTouchscreenEnabled() const override;
void setTouchscreenEnabled(bool value) override;
@@ -67,6 +69,8 @@ class Configuration: public IConfiguration
void setMusicAudioChannelEnabled(bool value) override;
bool speechAudioChannelEnabled() const override;
void setSpeechAudioChannelEnabled(bool value) override;
+ AudioOutputBackendType getAudioOutputBackendType() const override;
+ void setAudioOutputBackendType(AudioOutputBackendType value) override;
private:
void readButtonCodes(boost::property_tree::ptree& iniConfig);
@@ -79,12 +83,14 @@ class Configuration: public IConfiguration
aasdk::proto::enums::VideoResolution::Enum videoResolution_;
size_t screenDPI_;
int32_t omxLayerIndex_;
+ QRect videoMargins_;
bool enableTouchscreen_;
ButtonCodes buttonCodes_;
BluetoothAdapterType bluetoothAdapterType_;
std::string bluetoothRemoteAdapterAddress_;
bool musicAudioChannelEnabled_;
bool speechAudiochannelEnabled_;
+ AudioOutputBackendType audioOutputBackendType_;
static const std::string cConfigFileName;
@@ -95,9 +101,12 @@ class Configuration: public IConfiguration
static const std::string cVideoResolutionKey;
static const std::string cVideoScreenDPIKey;
static const std::string cVideoOMXLayerIndexKey;
+ static const std::string cVideoMarginWidth;
+ static const std::string cVideoMarginHeight;
static const std::string cAudioMusicAudioChannelEnabled;
static const std::string cAudioSpeechAudioChannelEnabled;
+ static const std::string cAudioOutputBackendType;
static const std::string cBluetoothAdapterTypeKey;
static const std::string cBluetoothRemoteAdapterAddressKey;
diff --git a/include/f1x/openauto/autoapp/Configuration/IConfiguration.hpp b/include/f1x/openauto/autoapp/Configuration/IConfiguration.hpp
index 48437f6f..2165a688 100644
--- a/include/f1x/openauto/autoapp/Configuration/IConfiguration.hpp
+++ b/include/f1x/openauto/autoapp/Configuration/IConfiguration.hpp
@@ -19,11 +19,13 @@
#pragma once
#include
+#include
#include
#include
#include
#include
#include
+#include
namespace f1x
{
@@ -59,6 +61,8 @@ class IConfiguration
virtual void setScreenDPI(size_t value) = 0;
virtual void setOMXLayerIndex(int32_t value) = 0;
virtual int32_t getOMXLayerIndex() const = 0;
+ virtual void setVideoMargins(QRect value) = 0;
+ virtual QRect getVideoMargins() const = 0;
virtual bool getTouchscreenEnabled() const = 0;
virtual void setTouchscreenEnabled(bool value) = 0;
@@ -74,6 +78,8 @@ class IConfiguration
virtual void setMusicAudioChannelEnabled(bool value) = 0;
virtual bool speechAudioChannelEnabled() const = 0;
virtual void setSpeechAudioChannelEnabled(bool value) = 0;
+ virtual AudioOutputBackendType getAudioOutputBackendType() const = 0;
+ virtual void setAudioOutputBackendType(AudioOutputBackendType value) = 0;
};
}
diff --git a/src/autoapp/Main.cpp b/include/f1x/openauto/autoapp/Configuration/IRecentAddressesList.hpp
similarity index 60%
rename from src/autoapp/Main.cpp
rename to include/f1x/openauto/autoapp/Configuration/IRecentAddressesList.hpp
index 0f7783a7..88213def 100644
--- a/src/autoapp/Main.cpp
+++ b/include/f1x/openauto/autoapp/Configuration/IRecentAddressesList.hpp
@@ -16,24 +16,31 @@
* along with openauto. If not, see .
*/
-#include
-#include
+#pragma once
-namespace aasdk = f1x::aasdk;
-namespace autoapp = f1x::openauto::autoapp;
+#include
+#include
-int main(int argc, char* argv[])
+namespace f1x
{
- libusb_context* context;
- if(libusb_init(&context) != 0)
- {
- OPENAUTO_LOG(error) << "[OpenAuto] libusb init failed.";
- return 1;
- }
+namespace openauto
+{
+namespace autoapp
+{
+namespace configuration
+{
+
+class IRecentAddressesList
+{
+public:
+ typedef std::deque RecentAddresses;
- autoapp::usb::USBMain main(context);
- auto result = main.exec(argc, argv);
+ virtual void read() = 0;
+ virtual void insertAddress(const std::string& address) = 0;
+ virtual RecentAddresses getList() const = 0;
+};
- libusb_exit(context);
- return result;
+}
+}
+}
}
diff --git a/include/f1x/openauto/autoapp/Configuration/RecentAddressesList.hpp b/include/f1x/openauto/autoapp/Configuration/RecentAddressesList.hpp
new file mode 100644
index 00000000..3c125913
--- /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/Projection/AndroidAutoEntityFactory.hpp b/include/f1x/openauto/autoapp/Projection/AndroidAutoEntityFactory.hpp
index aa3017c2..73b8696b 100644
--- a/include/f1x/openauto/autoapp/Projection/AndroidAutoEntityFactory.hpp
+++ b/include/f1x/openauto/autoapp/Projection/AndroidAutoEntityFactory.hpp
@@ -19,6 +19,7 @@
#pragma once
#include
+#include
#include
#include
#include
@@ -35,15 +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:
- aasdk::usb::IUSBWrapper& usbWrapper_;
+ IAndroidAutoEntity::Pointer create(aasdk::transport::ITransport::Pointer transport);
+
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 ab51c4f1..f9f37c34 100644
--- a/include/f1x/openauto/autoapp/Projection/IAndroidAutoEntityFactory.hpp
+++ b/include/f1x/openauto/autoapp/Projection/IAndroidAutoEntityFactory.hpp
@@ -18,7 +18,8 @@
#pragma once
-#include
+#include
+#include
#include
namespace f1x
@@ -35,7 +36,8 @@ 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/include/f1x/openauto/autoapp/Projection/IAudioOutput.hpp b/include/f1x/openauto/autoapp/Projection/IAudioOutput.hpp
index 383ad280..c41de312 100644
--- a/include/f1x/openauto/autoapp/Projection/IAudioOutput.hpp
+++ b/include/f1x/openauto/autoapp/Projection/IAudioOutput.hpp
@@ -19,6 +19,7 @@
#pragma once
#include
+#include
#include
namespace f1x
@@ -39,7 +40,7 @@ class IAudioOutput
virtual ~IAudioOutput() = default;
virtual bool open() = 0;
- virtual void write(const aasdk::common::DataConstBuffer& buffer) = 0;
+ virtual void write(aasdk::messenger::Timestamp::ValueType timestamp, const aasdk::common::DataConstBuffer& buffer) = 0;
virtual void start() = 0;
virtual void stop() = 0;
virtual void suspend() = 0;
diff --git a/include/f1x/openauto/autoapp/Projection/IVideoOutput.hpp b/include/f1x/openauto/autoapp/Projection/IVideoOutput.hpp
index c1ada0d6..1c483bc1 100644
--- a/include/f1x/openauto/autoapp/Projection/IVideoOutput.hpp
+++ b/include/f1x/openauto/autoapp/Projection/IVideoOutput.hpp
@@ -19,6 +19,7 @@
#pragma once
#include
+#include
#include
#include
#include
@@ -47,6 +48,7 @@ class IVideoOutput
virtual aasdk::proto::enums::VideoFPS::Enum getVideoFPS() const = 0;
virtual aasdk::proto::enums::VideoResolution::Enum getVideoResolution() const = 0;
virtual size_t getScreenDPI() const = 0;
+ virtual QRect getVideoMargins() const = 0;
};
}
diff --git a/include/f1x/openauto/autoapp/Projection/AudioInput.hpp b/include/f1x/openauto/autoapp/Projection/QtAudioInput.hpp
similarity index 92%
rename from include/f1x/openauto/autoapp/Projection/AudioInput.hpp
rename to include/f1x/openauto/autoapp/Projection/QtAudioInput.hpp
index 1dd7db0d..97816eab 100644
--- a/include/f1x/openauto/autoapp/Projection/AudioInput.hpp
+++ b/include/f1x/openauto/autoapp/Projection/QtAudioInput.hpp
@@ -32,11 +32,11 @@ namespace autoapp
namespace projection
{
-class AudioInput: public QObject, public IAudioInput
+class QtAudioInput: public QObject, public IAudioInput
{
Q_OBJECT
public:
- AudioInput(uint32_t channelCount, uint32_t sampleSize, uint32_t sampleRate);
+ QtAudioInput(uint32_t channelCount, uint32_t sampleSize, uint32_t sampleRate);
bool open() override;
bool isActive() const override;
diff --git a/include/f1x/openauto/autoapp/Projection/AudioOutput.hpp b/include/f1x/openauto/autoapp/Projection/QtAudioOutput.hpp
similarity index 86%
rename from include/f1x/openauto/autoapp/Projection/AudioOutput.hpp
rename to include/f1x/openauto/autoapp/Projection/QtAudioOutput.hpp
index 9aa4d413..742dbf8c 100644
--- a/include/f1x/openauto/autoapp/Projection/AudioOutput.hpp
+++ b/include/f1x/openauto/autoapp/Projection/QtAudioOutput.hpp
@@ -32,14 +32,14 @@ namespace autoapp
namespace projection
{
-class AudioOutput: public QObject, public IAudioOutput
+class QtAudioOutput: public QObject, public IAudioOutput
{
Q_OBJECT
public:
- AudioOutput(uint32_t channelCount, uint32_t sampleSize, uint32_t sampleRate);
+ QtAudioOutput(uint32_t channelCount, uint32_t sampleSize, uint32_t sampleRate);
bool open() override;
- void write(const aasdk::common::DataConstBuffer& buffer) override;
+ void write(aasdk::messenger::Timestamp::ValueType, const aasdk::common::DataConstBuffer& buffer) override;
void start() override;
void stop() override;
void suspend() override;
diff --git a/include/f1x/openauto/autoapp/Projection/RtAudioOutput.hpp b/include/f1x/openauto/autoapp/Projection/RtAudioOutput.hpp
new file mode 100644
index 00000000..063d5b34
--- /dev/null
+++ b/include/f1x/openauto/autoapp/Projection/RtAudioOutput.hpp
@@ -0,0 +1,63 @@
+/*
+* 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
+
+namespace f1x
+{
+namespace openauto
+{
+namespace autoapp
+{
+namespace projection
+{
+
+class RtAudioOutput: public IAudioOutput
+{
+public:
+ RtAudioOutput(uint32_t channelCount, uint32_t sampleSize, uint32_t sampleRate);
+ bool open() override;
+ void write(aasdk::messenger::Timestamp::ValueType timestamp, const aasdk::common::DataConstBuffer& buffer) override;
+ void start() override;
+ void stop() override;
+ void suspend() override;
+ uint32_t getSampleSize() const override;
+ uint32_t getChannelCount() const override;
+ uint32_t getSampleRate() const override;
+
+private:
+ void doSuspend();
+ static int audioBufferReadHandler(void* outputBuffer, void* inputBuffer, unsigned int nBufferFrames,
+ double streamTime, RtAudioStreamStatus status, void* userData);
+
+ uint32_t channelCount_;
+ uint32_t sampleSize_;
+ uint32_t sampleRate_;
+ SequentialBuffer audioBuffer_;
+ std::unique_ptr dac_;
+ std::mutex mutex_;
+};
+
+}
+}
+}
+}
diff --git a/include/f1x/openauto/autoapp/Projection/ServiceFactory.hpp b/include/f1x/openauto/autoapp/Projection/ServiceFactory.hpp
index 0d929b66..f7fdbd20 100644
--- a/include/f1x/openauto/autoapp/Projection/ServiceFactory.hpp
+++ b/include/f1x/openauto/autoapp/Projection/ServiceFactory.hpp
@@ -40,6 +40,7 @@ class ServiceFactory: public IServiceFactory
IService::Pointer createVideoService(aasdk::messenger::IMessenger::Pointer messenger);
IService::Pointer createBluetoothService(aasdk::messenger::IMessenger::Pointer messenger);
IService::Pointer createInputService(aasdk::messenger::IMessenger::Pointer messenger);
+ void createAudioServices(ServiceList& serviceList, aasdk::messenger::IMessenger::Pointer messenger);
boost::asio::io_service& ioService_;
configuration::IConfiguration::Pointer configuration_;
diff --git a/include/f1x/openauto/autoapp/Projection/VideoOutput.hpp b/include/f1x/openauto/autoapp/Projection/VideoOutput.hpp
index 7cfac93b..3c67cf6b 100644
--- a/include/f1x/openauto/autoapp/Projection/VideoOutput.hpp
+++ b/include/f1x/openauto/autoapp/Projection/VideoOutput.hpp
@@ -38,6 +38,7 @@ class VideoOutput: public IVideoOutput
aasdk::proto::enums::VideoFPS::Enum getVideoFPS() const override;
aasdk::proto::enums::VideoResolution::Enum getVideoResolution() const override;
size_t getScreenDPI() const override;
+ QRect getVideoMargins() const override;
protected:
configuration::IConfiguration::Pointer configuration_;
diff --git a/include/f1x/openauto/autoapp/UI/ConnectDialog.hpp b/include/f1x/openauto/autoapp/UI/ConnectDialog.hpp
new file mode 100644
index 00000000..9e944aa7
--- /dev/null
+++ b/include/f1x/openauto/autoapp/UI/ConnectDialog.hpp
@@ -0,0 +1,57 @@
+#pragma once
+
+#include
+#include
+#include
+#include
+#include
+
+namespace Ui {
+class ConnectDialog;
+}
+
+namespace f1x
+{
+namespace openauto
+{
+namespace autoapp
+{
+namespace ui
+{
+
+class ConnectDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ 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, 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, const std::string& ipAddress);
+ void onRecentAddressClicked(const QModelIndex& index);
+
+private:
+ 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_;
+};
+
+}
+}
+}
+}
diff --git a/include/f1x/openauto/autoapp/UI/MainWindow.hpp b/include/f1x/openauto/autoapp/UI/MainWindow.hpp
index 2c823309..b7e23545 100644
--- a/include/f1x/openauto/autoapp/UI/MainWindow.hpp
+++ b/include/f1x/openauto/autoapp/UI/MainWindow.hpp
@@ -46,6 +46,7 @@ class MainWindow : public QMainWindow
void exit();
void openSettings();
void toggleCursor();
+ void openConnectDialog();
private:
Ui::MainWindow* ui_;
diff --git a/include/f1x/openauto/autoapp/USB/USBMain.hpp b/include/f1x/openauto/autoapp/USB/USBMain.hpp
deleted file mode 100644
index 481d84bb..00000000
--- a/include/f1x/openauto/autoapp/USB/USBMain.hpp
+++ /dev/null
@@ -1,68 +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
-#include
-
-namespace f1x
-{
-namespace openauto
-{
-namespace autoapp
-{
-namespace usb
-{
-
-class USBMain
-{
-public:
- USBMain(libusb_context* context);
-
- int exec(int argc, char* argv[]);
-
-private:
- typedef std::vector ThreadPool;
-
- void startUSBWorkers();
- void startIOServiceWorkers();
-
- libusb_context* usbContext_;
- aasdk::usb::USBWrapper usbWrapper_;
- boost::asio::io_service ioService_;
- aasdk::usb::AccessoryModeQueryFactory queryFactory_;
- aasdk::usb::AccessoryModeQueryChainFactory queryChainFactory_;
- configuration::IConfiguration::Pointer configuration_;
- projection::ServiceFactory serviceFactory_;
- projection::AndroidAutoEntityFactory androidAutoEntityFactory_;
- autoapp::usb::USBApp::Pointer usbApp_;
- ThreadPool threadPool_;
-};
-
-}
-}
-}
-}
diff --git a/include/f1x/openauto/btservice/AndroidBluetoothServer.hpp b/include/f1x/openauto/btservice/AndroidBluetoothServer.hpp
new file mode 100644
index 00000000..4e159bc5
--- /dev/null
+++ b/include/f1x/openauto/btservice/AndroidBluetoothServer.hpp
@@ -0,0 +1,51 @@
+/*
+* 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
+
+namespace f1x
+{
+namespace openauto
+{
+namespace btservice
+{
+
+class AndroidBluetoothServer: public QObject, public IAndroidBluetoothServer
+{
+ Q_OBJECT
+
+public:
+ AndroidBluetoothServer();
+
+ bool start(const QBluetoothAddress& address, uint16_t portNumber) override;
+
+private slots:
+ void onClientConnected();
+
+private:
+ std::unique_ptr rfcommServer_;
+};
+
+}
+}
+}
diff --git a/include/f1x/openauto/btservice/AndroidBluetoothService.hpp b/include/f1x/openauto/btservice/AndroidBluetoothService.hpp
new file mode 100644
index 00000000..ebbb8609
--- /dev/null
+++ b/include/f1x/openauto/btservice/AndroidBluetoothService.hpp
@@ -0,0 +1,45 @@
+/*
+* 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 btservice
+{
+
+class AndroidBluetoothService: public IAndroidBluetoothService
+{
+public:
+ AndroidBluetoothService(uint16_t portNumber);
+
+ bool registerService(const QBluetoothAddress& bluetoothAddress) override;
+ bool unregisterService() override;
+
+private:
+ QBluetoothServiceInfo serviceInfo_;
+};
+
+}
+}
+}
diff --git a/include/f1x/openauto/btservice/IAndroidBluetoothServer.hpp b/include/f1x/openauto/btservice/IAndroidBluetoothServer.hpp
new file mode 100644
index 00000000..fb109ed9
--- /dev/null
+++ b/include/f1x/openauto/btservice/IAndroidBluetoothServer.hpp
@@ -0,0 +1,40 @@
+/*
+* 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
+
+namespace f1x
+{
+namespace openauto
+{
+namespace btservice
+{
+
+class IAndroidBluetoothServer
+{
+public:
+ virtual ~IAndroidBluetoothServer() = default;
+
+ virtual bool start(const QBluetoothAddress& address, uint16_t portNumber) = 0;
+};
+
+}
+}
+}
diff --git a/include/f1x/openauto/btservice/IAndroidBluetoothService.hpp b/include/f1x/openauto/btservice/IAndroidBluetoothService.hpp
new file mode 100644
index 00000000..71352c9d
--- /dev/null
+++ b/include/f1x/openauto/btservice/IAndroidBluetoothService.hpp
@@ -0,0 +1,41 @@
+/*
+* 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
+
+namespace f1x
+{
+namespace openauto
+{
+namespace btservice
+{
+
+class IAndroidBluetoothService
+{
+public:
+ virtual ~IAndroidBluetoothService() = default;
+
+ virtual bool registerService(const QBluetoothAddress& bluetoothAddress) = 0;
+ virtual bool unregisterService() = 0;
+};
+
+}
+}
+}
diff --git a/src/autoapp/App.cpp b/src/autoapp/App.cpp
new file mode 100644
index 00000000..b3f92a00
--- /dev/null
+++ b/src/autoapp/App.cpp
@@ -0,0 +1,177 @@
+/*
+* 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
+#include
+
+namespace f1x
+{
+namespace openauto
+{
+namespace autoapp
+{
+
+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))
+ , connectedAccessoriesEnumerator_(std::move(connectedAccessoriesEnumerator))
+ , isStopped_(false)
+{
+
+}
+
+void App::waitForUSBDevice()
+{
+ strand_.dispatch([this, self = this->shared_from_this()]() {
+ this->waitForDevice();
+ this->enumerateDevices();
+ });
+}
+
+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
+ {
+ tcpWrapper_.close(*socket);
+ OPENAUTO_LOG(warning) << "[App] android auto entity is still running.";
+ }
+ });
+}
+
+void App::stop()
+{
+ strand_.dispatch([this, self = this->shared_from_this()]() {
+ isStopped_ = true;
+ connectedAccessoriesEnumerator_->cancel();
+ usbHub_->cancel();
+
+ if(androidAutoEntity_ != nullptr)
+ {
+ androidAutoEntity_->stop();
+ }
+ });
+}
+
+void App::aoapDeviceHandler(aasdk::usb::DeviceHandle deviceHandle)
+{
+ OPENAUTO_LOG(info) << "[App] Device connected.";
+
+ if(androidAutoEntity_ == nullptr)
+ {
+ try
+ {
+ 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] USB AndroidAutoEntity create error: " << error.what();
+
+ androidAutoEntity_.reset();
+ this->waitForDevice();
+ }
+ }
+ else
+ {
+ OPENAUTO_LOG(warning) << "[App] android auto entity is still running.";
+ }
+}
+
+void App::enumerateDevices()
+{
+ auto promise = aasdk::usb::IConnectedAccessoriesEnumerator::Promise::defer(strand_);
+ promise->then([this, self = this->shared_from_this()](auto result) {
+ OPENAUTO_LOG(info) << "[App] Devices enumeration result: " << result;
+ },
+ [this, self = this->shared_from_this()](auto e) {
+ OPENAUTO_LOG(error) << "[App] Devices enumeration failed: " << e.what();
+ });
+
+ connectedAccessoriesEnumerator_->enumerate(std::move(promise));
+}
+
+void App::waitForDevice()
+{
+ OPENAUTO_LOG(info) << "[App] Waiting for device...";
+
+ auto promise = aasdk::usb::IUSBHub::Promise::defer(strand_);
+ promise->then(std::bind(&App::aoapDeviceHandler, this->shared_from_this(), std::placeholders::_1),
+ std::bind(&App::onUSBHubError, this->shared_from_this(), std::placeholders::_1));
+ usbHub_->start(std::move(promise));
+}
+
+void App::onAndroidAutoQuit()
+{
+ strand_.dispatch([this, self = this->shared_from_this()]() {
+ OPENAUTO_LOG(info) << "[App] quit.";
+
+ androidAutoEntity_->stop();
+ androidAutoEntity_.reset();
+
+ if(!isStopped_)
+ {
+ this->waitForDevice();
+ }
+ });
+}
+
+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)
+ {
+ this->waitForDevice();
+ }
+}
+
+}
+}
+}
diff --git a/src/autoapp/Configuration/Configuration.cpp b/src/autoapp/Configuration/Configuration.cpp
index c1c42297..0e79129b 100644
--- a/src/autoapp/Configuration/Configuration.cpp
+++ b/src/autoapp/Configuration/Configuration.cpp
@@ -37,9 +37,12 @@ const std::string Configuration::cVideoFPSKey = "Video.FPS";
const std::string Configuration::cVideoResolutionKey = "Video.Resolution";
const std::string Configuration::cVideoScreenDPIKey = "Video.ScreenDPI";
const std::string Configuration::cVideoOMXLayerIndexKey = "Video.OMXLayerIndex";
+const std::string Configuration::cVideoMarginWidth = "Video.MarginWidth";
+const std::string Configuration::cVideoMarginHeight = "Video.MarginHeight";
const std::string Configuration::cAudioMusicAudioChannelEnabled = "Audio.MusicAudioChannelEnabled";
const std::string Configuration::cAudioSpeechAudioChannelEnabled = "Audio.SpeechAudioChannelEnabled";
+const std::string Configuration::cAudioOutputBackendType = "Audio.OutputBackendType";
const std::string Configuration::cBluetoothAdapterTypeKey = "Bluetooth.AdapterType";
const std::string Configuration::cBluetoothRemoteAdapterAddressKey = "Bluetooth.RemoteAdapterAddress";
@@ -87,6 +90,7 @@ void Configuration::load()
screenDPI_ = iniConfig.get(cVideoScreenDPIKey, 140);
omxLayerIndex_ = iniConfig.get(cVideoOMXLayerIndexKey, 1);
+ videoMargins_ = QRect(0, 0, iniConfig.get(cVideoMarginWidth, 0), iniConfig.get(cVideoMarginHeight, 0));
enableTouchscreen_ = iniConfig.get(cInputEnableTouchscreenKey, true);
this->readButtonCodes(iniConfig);
@@ -98,6 +102,7 @@ void Configuration::load()
musicAudioChannelEnabled_ = iniConfig.get(cAudioMusicAudioChannelEnabled, true);
speechAudiochannelEnabled_ = iniConfig.get(cAudioSpeechAudioChannelEnabled, true);
+ audioOutputBackendType_ = static_cast(iniConfig.get(cAudioOutputBackendType, static_cast(AudioOutputBackendType::RTAUDIO)));
}
catch(const boost::property_tree::ini_parser_error& e)
{
@@ -116,12 +121,14 @@ void Configuration::reset()
videoResolution_ = aasdk::proto::enums::VideoResolution::_480p;
screenDPI_ = 140;
omxLayerIndex_ = 1;
+ videoMargins_ = QRect(0, 0, 0, 0);
enableTouchscreen_ = true;
buttonCodes_.clear();
bluetoothAdapterType_ = BluetoothAdapterType::NONE;
bluetoothRemoteAdapterAddress_ = "";
musicAudioChannelEnabled_ = true;
speechAudiochannelEnabled_ = true;
+ audioOutputBackendType_ = AudioOutputBackendType::RTAUDIO;
}
void Configuration::save()
@@ -134,6 +141,8 @@ void Configuration::save()
iniConfig.put(cVideoResolutionKey, static_cast(videoResolution_));
iniConfig.put(cVideoScreenDPIKey, screenDPI_);
iniConfig.put(cVideoOMXLayerIndexKey, omxLayerIndex_);
+ iniConfig.put(cVideoMarginWidth, videoMargins_.width());
+ iniConfig.put(cVideoMarginHeight, videoMargins_.height());
iniConfig.put(cInputEnableTouchscreenKey, enableTouchscreen_);
this->writeButtonCodes(iniConfig);
@@ -143,6 +152,7 @@ void Configuration::save()
iniConfig.put(cAudioMusicAudioChannelEnabled, musicAudioChannelEnabled_);
iniConfig.put(cAudioSpeechAudioChannelEnabled, speechAudiochannelEnabled_);
+ iniConfig.put(cAudioOutputBackendType, static_cast(audioOutputBackendType_));
boost::property_tree::ini_parser::write_ini(cConfigFileName, iniConfig);
}
@@ -206,6 +216,16 @@ int32_t Configuration::getOMXLayerIndex() const
return omxLayerIndex_;
}
+void Configuration::setVideoMargins(QRect value)
+{
+ videoMargins_ = value;
+}
+
+QRect Configuration::getVideoMargins() const
+{
+ return videoMargins_;
+}
+
bool Configuration::getTouchscreenEnabled() const
{
return enableTouchscreen_;
@@ -266,6 +286,16 @@ void Configuration::setSpeechAudioChannelEnabled(bool value)
speechAudiochannelEnabled_ = value;
}
+AudioOutputBackendType Configuration::getAudioOutputBackendType() const
+{
+ return audioOutputBackendType_;
+}
+
+void Configuration::setAudioOutputBackendType(AudioOutputBackendType value)
+{
+ audioOutputBackendType_ = value;
+}
+
void Configuration::readButtonCodes(boost::property_tree::ptree& iniConfig)
{
this->insertButtonCode(iniConfig, cInputPlayButtonKey, aasdk::proto::enums::ButtonCode::PLAY);
diff --git a/src/autoapp/Configuration/RecentAddressesList.cpp b/src/autoapp/Configuration/RecentAddressesList.cpp
new file mode 100644
index 00000000..c29fdcf1
--- /dev/null
+++ b/src/autoapp/Configuration/RecentAddressesList.cpp
@@ -0,0 +1,116 @@
+/*
+* 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)
+{
+ if(std::find(list_.begin(), list_.end(), address) != list_.end())
+ {
+ return;
+ }
+
+ if(list_.size() >= maxListSize_)
+ {
+ list_.pop_back();
+ }
+
+ 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/Projection/AndroidAutoEntityFactory.cpp b/src/autoapp/Projection/AndroidAutoEntityFactory.cpp
index 612b8189..0eb69428 100644
--- a/src/autoapp/Projection/AndroidAutoEntityFactory.cpp
+++ b/src/autoapp/Projection/AndroidAutoEntityFactory.cpp
@@ -19,6 +19,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -32,23 +33,30 @@ 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));
+}
+IAndroidAutoEntity::Pointer AndroidAutoEntityFactory::create(aasdk::tcp::ITCPEndpoint::Pointer tcpEndpoint)
+{
+ auto transport(std::make_shared(ioService_, std::move(tcpEndpoint)));
+ return create(std::move(transport));
+}
+
+IAndroidAutoEntity::Pointer AndroidAutoEntityFactory::create(aasdk::transport::ITransport::Pointer transport)
+{
auto sslWrapper(std::make_shared());
auto cryptor(std::make_shared(std::move(sslWrapper)));
diff --git a/src/autoapp/Projection/AudioService.cpp b/src/autoapp/Projection/AudioService.cpp
index 3e68c11a..d09001fe 100644
--- a/src/autoapp/Projection/AudioService.cpp
+++ b/src/autoapp/Projection/AudioService.cpp
@@ -93,6 +93,12 @@ void AudioService::onChannelOpenRequest(const aasdk::proto::messages::ChannelOpe
OPENAUTO_LOG(info) << "[AudioService] open request"
<< ", channel: " << aasdk::messenger::channelIdToString(channel_->getId())
<< ", priority: " << request.priority();
+
+ OPENAUTO_LOG(debug) << "[AudioService] channel: " << aasdk::messenger::channelIdToString(channel_->getId())
+ << " audio output sample rate: " << audioOutput_->getSampleRate()
+ << ", sample size: " << audioOutput_->getSampleSize()
+ << ", channel count: " << audioOutput_->getChannelCount();
+
const aasdk::proto::enums::Status::Enum status = audioOutput_->open() ? aasdk::proto::enums::Status::OK : aasdk::proto::enums::Status::FAIL;
OPENAUTO_LOG(info) << "[AudioService] open status: " << status
<< ", channel: " << aasdk::messenger::channelIdToString(channel_->getId());
@@ -146,14 +152,9 @@ void AudioService::onAVChannelStopIndication(const aasdk::proto::messages::AVCha
channel_->receive(this->shared_from_this());
}
-void AudioService::onAVMediaWithTimestampIndication(aasdk::messenger::Timestamp::ValueType, const aasdk::common::DataConstBuffer& buffer)
-{
- this->onAVMediaIndication(buffer);
-}
-
-void AudioService::onAVMediaIndication(const aasdk::common::DataConstBuffer& buffer)
+void AudioService::onAVMediaWithTimestampIndication(aasdk::messenger::Timestamp::ValueType timestamp, const aasdk::common::DataConstBuffer& buffer)
{
- audioOutput_->write(buffer);
+ audioOutput_->write(timestamp, buffer);
aasdk::proto::messages::AVMediaAckIndication indication;
indication.set_session(session_);
indication.set_value(1);
@@ -164,6 +165,11 @@ void AudioService::onAVMediaIndication(const aasdk::common::DataConstBuffer& buf
channel_->receive(this->shared_from_this());
}
+void AudioService::onAVMediaIndication(const aasdk::common::DataConstBuffer& buffer)
+{
+ this->onAVMediaWithTimestampIndication(0, buffer);
+}
+
void AudioService::onChannelError(const aasdk::error::Error& e)
{
OPENAUTO_LOG(error) << "[AudioService] channel error: " << e.what()
diff --git a/src/autoapp/Projection/AudioInput.cpp b/src/autoapp/Projection/QtAudioInput.cpp
similarity index 77%
rename from src/autoapp/Projection/AudioInput.cpp
rename to src/autoapp/Projection/QtAudioInput.cpp
index 2fe3fbfb..15584302 100644
--- a/src/autoapp/Projection/AudioInput.cpp
+++ b/src/autoapp/Projection/QtAudioInput.cpp
@@ -17,7 +17,7 @@
*/
#include
-#include
+#include
#include
namespace f1x
@@ -29,7 +29,7 @@ namespace autoapp
namespace projection
{
-AudioInput::AudioInput(uint32_t channelCount, uint32_t sampleSize, uint32_t sampleRate)
+QtAudioInput::QtAudioInput(uint32_t channelCount, uint32_t sampleSize, uint32_t sampleRate)
: ioDevice_(nullptr)
{
qRegisterMetaType("StartPromise::Pointer");
@@ -42,32 +42,32 @@ AudioInput::AudioInput(uint32_t channelCount, uint32_t sampleSize, uint32_t samp
audioFormat_.setSampleType(QAudioFormat::SignedInt);
this->moveToThread(QApplication::instance()->thread());
- connect(this, &AudioInput::startRecording, this, &AudioInput::onStartRecording, Qt::QueuedConnection);
- connect(this, &AudioInput::stopRecording, this, &AudioInput::onStopRecording, Qt::QueuedConnection);
+ connect(this, &QtAudioInput::startRecording, this, &QtAudioInput::onStartRecording, Qt::QueuedConnection);
+ connect(this, &QtAudioInput::stopRecording, this, &QtAudioInput::onStopRecording, Qt::QueuedConnection);
QMetaObject::invokeMethod(this, "createAudioInput", Qt::BlockingQueuedConnection);
}
-void AudioInput::createAudioInput()
+void QtAudioInput::createAudioInput()
{
OPENAUTO_LOG(debug) << "[AudioInput] create.";
audioInput_ = (std::make_unique(QAudioDeviceInfo::defaultInputDevice(), audioFormat_));
}
-bool AudioInput::open()
+bool QtAudioInput::open()
{
std::lock_guard lock(mutex_);
return ioDevice_ == nullptr;
}
-bool AudioInput::isActive() const
+bool QtAudioInput::isActive() const
{
std::lock_guard lock(mutex_);
return ioDevice_ != nullptr;
}
-void AudioInput::read(ReadPromise::Pointer promise)
+void QtAudioInput::read(ReadPromise::Pointer promise)
{
std::lock_guard lock(mutex_);
@@ -85,32 +85,32 @@ void AudioInput::read(ReadPromise::Pointer promise)
}
}
-void AudioInput::start(StartPromise::Pointer promise)
+void QtAudioInput::start(StartPromise::Pointer promise)
{
emit startRecording(std::move(promise));
}
-void AudioInput::stop()
+void QtAudioInput::stop()
{
emit stopRecording();
}
-uint32_t AudioInput::getSampleSize() const
+uint32_t QtAudioInput::getSampleSize() const
{
return audioFormat_.sampleSize();
}
-uint32_t AudioInput::getChannelCount() const
+uint32_t QtAudioInput::getChannelCount() const
{
return audioFormat_.channelCount();
}
-uint32_t AudioInput::getSampleRate() const
+uint32_t QtAudioInput::getSampleRate() const
{
return audioFormat_.sampleRate();
}
-void AudioInput::onStartRecording(StartPromise::Pointer promise)
+void QtAudioInput::onStartRecording(StartPromise::Pointer promise)
{
std::lock_guard lock(mutex_);
@@ -118,7 +118,7 @@ void AudioInput::onStartRecording(StartPromise::Pointer promise)
if(ioDevice_ != nullptr)
{
- connect(ioDevice_, &QIODevice::readyRead, this, &AudioInput::onReadyRead, Qt::QueuedConnection);
+ connect(ioDevice_, &QIODevice::readyRead, this, &QtAudioInput::onReadyRead, Qt::QueuedConnection);
promise->resolve();
}
else
@@ -127,7 +127,7 @@ void AudioInput::onStartRecording(StartPromise::Pointer promise)
}
}
-void AudioInput::onStopRecording()
+void QtAudioInput::onStopRecording()
{
std::lock_guard lock(mutex_);
@@ -147,7 +147,7 @@ void AudioInput::onStopRecording()
audioInput_->stop();
}
-void AudioInput::onReadyRead()
+void QtAudioInput::onReadyRead()
{
std::lock_guard lock(mutex_);
diff --git a/src/autoapp/Projection/AudioOutput.cpp b/src/autoapp/Projection/QtAudioOutput.cpp
similarity index 67%
rename from src/autoapp/Projection/AudioOutput.cpp
rename to src/autoapp/Projection/QtAudioOutput.cpp
index 7b309d5b..dff8049e 100644
--- a/src/autoapp/Projection/AudioOutput.cpp
+++ b/src/autoapp/Projection/QtAudioOutput.cpp
@@ -17,7 +17,7 @@
*/
#include
-#include
+#include
#include
namespace f1x
@@ -29,7 +29,7 @@ namespace autoapp
namespace projection
{
-AudioOutput::AudioOutput(uint32_t channelCount, uint32_t sampleSize, uint32_t sampleRate)
+QtAudioOutput::QtAudioOutput(uint32_t channelCount, uint32_t sampleSize, uint32_t sampleRate)
: playbackStarted_(false)
{
audioFormat_.setChannelCount(channelCount);
@@ -40,63 +40,60 @@ AudioOutput::AudioOutput(uint32_t channelCount, uint32_t sampleSize, uint32_t sa
audioFormat_.setSampleType(QAudioFormat::SignedInt);
this->moveToThread(QApplication::instance()->thread());
- connect(this, &AudioOutput::startPlayback, this, &AudioOutput::onStartPlayback);
- connect(this, &AudioOutput::suspendPlayback, this, &AudioOutput::onSuspendPlayback);
- connect(this, &AudioOutput::stopPlayback, this, &AudioOutput::onStopPlayback);
+ connect(this, &QtAudioOutput::startPlayback, this, &QtAudioOutput::onStartPlayback);
+ connect(this, &QtAudioOutput::suspendPlayback, this, &QtAudioOutput::onSuspendPlayback);
+ connect(this, &QtAudioOutput::stopPlayback, this, &QtAudioOutput::onStopPlayback);
QMetaObject::invokeMethod(this, "createAudioOutput", Qt::BlockingQueuedConnection);
}
-void AudioOutput::createAudioOutput()
+void QtAudioOutput::createAudioOutput()
{
- OPENAUTO_LOG(debug) << "[AudioOutput] create.";
+ OPENAUTO_LOG(debug) << "[QtAudioOutput] create.";
audioOutput_ = std::make_unique(QAudioDeviceInfo::defaultOutputDevice(), audioFormat_);
-
- // Default volume level (max) produces crackles
- audioOutput_->setVolume(static_cast(0.90));
}
-bool AudioOutput::open()
+bool QtAudioOutput::open()
{
return audioBuffer_.open(QIODevice::ReadWrite);
}
-void AudioOutput::write(const aasdk::common::DataConstBuffer& buffer)
+void QtAudioOutput::write(aasdk::messenger::Timestamp::ValueType, const aasdk::common::DataConstBuffer& buffer)
{
audioBuffer_.write(reinterpret_cast(buffer.cdata), buffer.size);
}
-void AudioOutput::start()
+void QtAudioOutput::start()
{
emit startPlayback();
}
-void AudioOutput::stop()
+void QtAudioOutput::stop()
{
emit stopPlayback();
}
-void AudioOutput::suspend()
+void QtAudioOutput::suspend()
{
emit suspendPlayback();
}
-uint32_t AudioOutput::getSampleSize() const
+uint32_t QtAudioOutput::getSampleSize() const
{
return audioFormat_.sampleSize();
}
-uint32_t AudioOutput::getChannelCount() const
+uint32_t QtAudioOutput::getChannelCount() const
{
return audioFormat_.channelCount();
}
-uint32_t AudioOutput::getSampleRate() const
+uint32_t QtAudioOutput::getSampleRate() const
{
return audioFormat_.sampleRate();
}
-void AudioOutput::onStartPlayback()
+void QtAudioOutput::onStartPlayback()
{
if(!playbackStarted_)
{
@@ -109,12 +106,12 @@ void AudioOutput::onStartPlayback()
}
}
-void AudioOutput::onSuspendPlayback()
+void QtAudioOutput::onSuspendPlayback()
{
audioOutput_->suspend();
}
-void AudioOutput::onStopPlayback()
+void QtAudioOutput::onStopPlayback()
{
if(playbackStarted_)
{
diff --git a/src/autoapp/Projection/RtAudioOutput.cpp b/src/autoapp/Projection/RtAudioOutput.cpp
new file mode 100644
index 00000000..139cd51a
--- /dev/null
+++ b/src/autoapp/Projection/RtAudioOutput.cpp
@@ -0,0 +1,156 @@
+/*
+* 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
+
+namespace f1x
+{
+namespace openauto
+{
+namespace autoapp
+{
+namespace projection
+{
+
+RtAudioOutput::RtAudioOutput(uint32_t channelCount, uint32_t sampleSize, uint32_t sampleRate)
+ : channelCount_(channelCount)
+ , sampleSize_(sampleSize)
+ , sampleRate_(sampleRate)
+{
+ std::vector apis;
+ RtAudio::getCompiledApi(apis);
+ dac_ = std::find(apis.begin(), apis.end(), RtAudio::LINUX_PULSE) == apis.end() ? std::make_unique() : std::make_unique(RtAudio::LINUX_PULSE);
+}
+
+bool RtAudioOutput::open()
+{
+ std::lock_guard lock(mutex_);
+
+ if(dac_->getDeviceCount() > 0)
+ {
+ RtAudio::StreamParameters parameters;
+ parameters.deviceId = dac_->getDefaultOutputDevice();
+ parameters.nChannels = channelCount_;
+ parameters.firstChannel = 0;
+
+ try
+ {
+ RtAudio::StreamOptions streamOptions;
+ streamOptions.flags = RTAUDIO_MINIMIZE_LATENCY | RTAUDIO_SCHEDULE_REALTIME;
+ uint32_t bufferFrames = sampleRate_ == 16000 ? 1024 : 2048; //according to the observation of audio packets
+ dac_->openStream(¶meters, nullptr, RTAUDIO_SINT16, sampleRate_, &bufferFrames, &RtAudioOutput::audioBufferReadHandler, static_cast(this), &streamOptions);
+ return audioBuffer_.open(QIODevice::ReadWrite);
+ }
+ catch(const RtAudioError& e)
+ {
+ OPENAUTO_LOG(error) << "[RtAudioOutput] Failed to open audio output, what: " << e.what();
+ }
+ }
+ else
+ {
+ OPENAUTO_LOG(error) << "[RtAudioOutput] No output devices found.";
+ }
+
+ return false;
+}
+
+void RtAudioOutput::write(aasdk::messenger::Timestamp::ValueType timestamp, const aasdk::common::DataConstBuffer& buffer)
+{
+ audioBuffer_.write(reinterpret_cast(buffer.cdata), buffer.size);
+}
+
+void RtAudioOutput::start()
+{
+ std::lock_guard lock(mutex_);
+
+ if(dac_->isStreamOpen() && !dac_->isStreamRunning())
+ {
+ try
+ {
+ dac_->startStream();
+ }
+ catch(const RtAudioError& e)
+ {
+ OPENAUTO_LOG(error) << "[RtAudioOutput] Failed to start audio output, what: " << e.what();
+ }
+ }
+}
+
+void RtAudioOutput::stop()
+{
+ std::lock_guard lock(mutex_);
+
+ this->doSuspend();
+
+ if(dac_->isStreamOpen())
+ {
+ dac_->closeStream();
+ }
+}
+
+void RtAudioOutput::suspend()
+{
+ //not needed
+}
+
+uint32_t RtAudioOutput::getSampleSize() const
+{
+ return sampleSize_;
+}
+
+uint32_t RtAudioOutput::getChannelCount() const
+{
+ return channelCount_;
+}
+
+uint32_t RtAudioOutput::getSampleRate() const
+{
+ return sampleRate_;
+}
+
+void RtAudioOutput::doSuspend()
+{
+ if(dac_->isStreamOpen() && dac_->isStreamRunning())
+ {
+ try
+ {
+ dac_->stopStream();
+ }
+ catch(const RtAudioError& e)
+ {
+ OPENAUTO_LOG(error) << "[RtAudioOutput] Failed to suspend audio output, what: " << e.what();
+ }
+ }
+}
+
+int RtAudioOutput::audioBufferReadHandler(void* outputBuffer, void* inputBuffer, unsigned int nBufferFrames,
+ double streamTime, RtAudioStreamStatus status, void* userData)
+{
+ RtAudioOutput* self = static_cast(userData);
+ std::lock_guardmutex_)> lock(self->mutex_);
+
+ const auto bufferSize = nBufferFrames * (self->sampleSize_ / 8) * self->channelCount_;
+ self->audioBuffer_.read(reinterpret_cast(outputBuffer), bufferSize);
+ return 0;
+}
+
+}
+}
+}
+}
diff --git a/src/autoapp/Projection/SequentialBuffer.cpp b/src/autoapp/Projection/SequentialBuffer.cpp
index bd90a453..a0a5632a 100644
--- a/src/autoapp/Projection/SequentialBuffer.cpp
+++ b/src/autoapp/Projection/SequentialBuffer.cpp
@@ -55,7 +55,8 @@ qint64 SequentialBuffer::readData(char *data, qint64 maxlen)
const auto len = std::min(maxlen, data_.size());
std::copy(data_.begin(), data_.begin() + len, data);
- data_.erase(data_.begin(), data_.begin() + len);
+ data_.erase_begin(len);
+
return len;
}
diff --git a/src/autoapp/Projection/ServiceFactory.cpp b/src/autoapp/Projection/ServiceFactory.cpp
index ade1e386..d10ddff6 100644
--- a/src/autoapp/Projection/ServiceFactory.cpp
+++ b/src/autoapp/Projection/ServiceFactory.cpp
@@ -32,8 +32,9 @@
#include
#include
#include
-#include
-#include
+#include
+#include
+#include
#include
#include
#include
@@ -59,24 +60,9 @@ ServiceList ServiceFactory::create(aasdk::messenger::IMessenger::Pointer messeng
{
ServiceList serviceList;
- IAudioInput::Pointer audioInput(new AudioInput(1, 16, 16000), std::bind(&QObject::deleteLater, std::placeholders::_1));
+ IAudioInput::Pointer audioInput(new QtAudioInput(1, 16, 16000), std::bind(&QObject::deleteLater, std::placeholders::_1));
serviceList.emplace_back(std::make_shared(ioService_, messenger, std::move(audioInput)));
-
- if(configuration_->musicAudioChannelEnabled())
- {
- IAudioOutput::Pointer mediaAudioOutput(new AudioOutput(2, 16, 48000), std::bind(&QObject::deleteLater, std::placeholders::_1));
- serviceList.emplace_back(std::make_shared(ioService_, messenger, std::move(mediaAudioOutput)));
- }
-
- if(configuration_->speechAudioChannelEnabled())
- {
- IAudioOutput::Pointer speechAudioOutput(new AudioOutput(1, 16, 16000), std::bind(&QObject::deleteLater, std::placeholders::_1));
- serviceList.emplace_back(std::make_shared(ioService_, messenger, std::move(speechAudioOutput)));
- }
-
- IAudioOutput::Pointer systemAudioOutput(new AudioOutput(1, 16, 16000), std::bind(&QObject::deleteLater, std::placeholders::_1));
- serviceList.emplace_back(std::make_shared(ioService_, messenger, std::move(systemAudioOutput)));
-
+ this->createAudioServices(serviceList, messenger);
serviceList.emplace_back(std::make_shared(ioService_, messenger));
serviceList.emplace_back(this->createVideoService(messenger));
serviceList.emplace_back(this->createBluetoothService(messenger));
@@ -141,6 +127,33 @@ IService::Pointer ServiceFactory::createInputService(aasdk::messenger::IMessenge
return std::make_shared(ioService_, messenger, std::move(inputDevice));
}
+void ServiceFactory::createAudioServices(ServiceList& serviceList, aasdk::messenger::IMessenger::Pointer messenger)
+{
+ if(configuration_->musicAudioChannelEnabled())
+ {
+ auto mediaAudioOutput = configuration_->getAudioOutputBackendType() == configuration::AudioOutputBackendType::RTAUDIO ?
+ std::make_shared(2, 16, 48000) :
+ IAudioOutput::Pointer(new QtAudioOutput(2, 16, 48000), std::bind(&QObject::deleteLater, std::placeholders::_1));
+
+ serviceList.emplace_back(std::make_shared(ioService_, messenger, std::move(mediaAudioOutput)));
+ }
+
+ if(configuration_->speechAudioChannelEnabled())
+ {
+ auto speechAudioOutput = configuration_->getAudioOutputBackendType() == configuration::AudioOutputBackendType::RTAUDIO ?
+ std::make_shared(1, 16, 16000) :
+ IAudioOutput::Pointer(new QtAudioOutput(1, 16, 16000), std::bind(&QObject::deleteLater, std::placeholders::_1));
+
+ serviceList.emplace_back(std::make_shared(ioService_, messenger, std::move(speechAudioOutput)));
+ }
+
+ auto systemAudioOutput = configuration_->getAudioOutputBackendType() == configuration::AudioOutputBackendType::RTAUDIO ?
+ std::make_shared(1, 16, 16000) :
+ IAudioOutput::Pointer(new QtAudioOutput(1, 16, 16000), std::bind(&QObject::deleteLater, std::placeholders::_1));
+
+ serviceList.emplace_back(std::make_shared(ioService_, messenger, std::move(systemAudioOutput)));
+}
+
}
}
}
diff --git a/src/autoapp/Projection/VideoOutput.cpp b/src/autoapp/Projection/VideoOutput.cpp
index 1b0c4e4d..dca398df 100644
--- a/src/autoapp/Projection/VideoOutput.cpp
+++ b/src/autoapp/Projection/VideoOutput.cpp
@@ -48,6 +48,11 @@ size_t VideoOutput::getScreenDPI() const
return configuration_->getScreenDPI();
}
+QRect VideoOutput::getVideoMargins() const
+{
+ return configuration_->getVideoMargins();
+}
+
}
}
}
diff --git a/src/autoapp/Projection/VideoService.cpp b/src/autoapp/Projection/VideoService.cpp
index 251e0379..b419d4a4 100644
--- a/src/autoapp/Projection/VideoService.cpp
+++ b/src/autoapp/Projection/VideoService.cpp
@@ -144,8 +144,10 @@ void VideoService::fillFeatures(aasdk::proto::messages::ServiceDiscoveryResponse
auto* videoConfig1 = videoChannel->add_video_configs();
videoConfig1->set_video_resolution(videoOutput_->getVideoResolution());
videoConfig1->set_video_fps(videoOutput_->getVideoFPS());
- videoConfig1->set_margin_height(0);
- videoConfig1->set_margin_width(0);
+
+ const auto& videoMargins = videoOutput_->getVideoMargins();
+ videoConfig1->set_margin_height(videoMargins.height());
+ videoConfig1->set_margin_width(videoMargins.width());
videoConfig1->set_dpi(videoOutput_->getScreenDPI());
}
diff --git a/src/autoapp/UI/ConnectDialog.cpp b/src/autoapp/UI/ConnectDialog.cpp
new file mode 100644
index 00000000..127e2165
--- /dev/null
+++ b/src/autoapp/UI/ConnectDialog.cpp
@@ -0,0 +1,125 @@
+#include
+#include
+#include "ui_connectdialog.h"
+
+namespace f1x
+{
+namespace openauto
+{
+namespace autoapp
+{
+namespace ui
+{
+
+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");
+ qRegisterMetaType("std::string");
+
+ 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);
+
+ ui_->listViewRecent->setModel(&recentAddressesModel_);
+ this->loadRecentList();
+}
+
+ConnectDialog::~ConnectDialog()
+{
+ delete ui_;
+}
+
+void ConnectDialog::onConnectButtonClicked()
+{
+ this->setControlsEnabledStatus(false);
+
+ const auto& ipAddress = ui_->lineEditIPAddress->text().toStdString();
+ auto socket = std::make_shared(ioService_);
+
+ try
+ {
+ tcpWrapper_.asyncConnect(*socket, ipAddress, 5277, std::bind(&ConnectDialog::connectHandler, this, std::placeholders::_1, ipAddress, socket));
+ }
+ catch(const boost::system::system_error& se)
+ {
+ emit connectionFailed(QString(se.what()));
+ }
+}
+
+void ConnectDialog::connectHandler(const boost::system::error_code& ec, const std::string& ipAddress, aasdk::tcp::ITCPEndpoint::SocketPointer socket)
+{
+ if(!ec)
+ {
+ emit connectionSucceed(std::move(socket), ipAddress);
+ this->close();
+ }
+ else
+ {
+ emit connectionFailed(QString::fromStdString(ec.message()));
+ }
+}
+
+void ConnectDialog::onConnectionSucceed(aasdk::tcp::ITCPEndpoint::SocketPointer, const std::string& ipAddress)
+{
+ this->insertIpAddress(ipAddress);
+ this->setControlsEnabledStatus(true);
+}
+
+void ConnectDialog::onConnectionFailed(const QString& message)
+{
+ this->setControlsEnabledStatus(true);
+
+ QMessageBox errorMessage(QMessageBox::Critical, "Connect error", message, QMessageBox::Ok);
+ errorMessage.setWindowFlags(Qt::WindowStaysOnTopHint);
+ 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);
+ ui_->pushButtonCancel->setEnabled(status);
+ ui_->lineEditIPAddress->setEnabled(status);
+ ui_->listViewRecent->setEnabled(status);
+}
+
+void ConnectDialog::loadRecentList()
+{
+ QStringList stringList;
+ const auto& configList = recentAddressesList_.getList();
+
+ for(const auto& element : configList)
+ {
+ stringList.append(QString::fromStdString(element));
+ }
+
+ recentAddressesModel_.setStringList(stringList);
+}
+
+void ConnectDialog::insertIpAddress(const std::string& ipAddress)
+{
+ recentAddressesList_.insertAddress(ipAddress);
+ this->loadRecentList();
+}
+
+}
+}
+}
+}
diff --git a/src/autoapp/UI/MainWindow.cpp b/src/autoapp/UI/MainWindow.cpp
index 8569c06f..49954f81 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/SettingsWindow.cpp b/src/autoapp/UI/SettingsWindow.cpp
index dd55a570..5f64b3e8 100644
--- a/src/autoapp/UI/SettingsWindow.cpp
+++ b/src/autoapp/UI/SettingsWindow.cpp
@@ -73,6 +73,10 @@ void SettingsWindow::onSave()
configuration_->setScreenDPI(static_cast(ui_->horizontalSliderScreenDPI->value()));
configuration_->setOMXLayerIndex(ui_->spinBoxOmxLayerIndex->value());
+
+ QRect videoMargins(0, 0, ui_->spinBoxVideoMarginWidth->value(), ui_->spinBoxVideoMarginHeight->value());
+ configuration_->setVideoMargins(std::move(videoMargins));
+
configuration_->setTouchscreenEnabled(ui_->checkBoxEnableTouchscreen->isChecked());
this->saveButtonCheckBoxes();
@@ -93,6 +97,7 @@ void SettingsWindow::onSave()
configuration_->setMusicAudioChannelEnabled(ui_->checkBoxMusicAudioChannel->isChecked());
configuration_->setSpeechAudioChannelEnabled(ui_->checkBoxSpeechAudioChannel->isChecked());
+ configuration_->setAudioOutputBackendType(ui_->radioButtonRtAudio->isChecked() ? configuration::AudioOutputBackendType::RTAUDIO : configuration::AudioOutputBackendType::QT);
configuration_->save();
this->close();
@@ -130,6 +135,10 @@ void SettingsWindow::load()
ui_->horizontalSliderScreenDPI->setValue(static_cast(configuration_->getScreenDPI()));
ui_->spinBoxOmxLayerIndex->setValue(configuration_->getOMXLayerIndex());
+ const auto& videoMargins = configuration_->getVideoMargins();
+ ui_->spinBoxVideoMarginWidth->setValue(videoMargins.width());
+ ui_->spinBoxVideoMarginHeight->setValue(videoMargins.height());
+
ui_->checkBoxEnableTouchscreen->setChecked(configuration_->getTouchscreenEnabled());
this->loadButtonCheckBoxes();
@@ -141,6 +150,10 @@ void SettingsWindow::load()
ui_->checkBoxMusicAudioChannel->setChecked(configuration_->musicAudioChannelEnabled());
ui_->checkBoxSpeechAudioChannel->setChecked(configuration_->speechAudioChannelEnabled());
+
+ const auto& audioOutputBackendType = configuration_->getAudioOutputBackendType();
+ ui_->radioButtonRtAudio->setChecked(audioOutputBackendType == configuration::AudioOutputBackendType::RTAUDIO);
+ ui_->radioButtonQtAudio->setChecked(audioOutputBackendType == configuration::AudioOutputBackendType::QT);
}
void SettingsWindow::loadButtonCheckBoxes()
diff --git a/src/autoapp/UI/connectdialog.ui b/src/autoapp/UI/connectdialog.ui
new file mode 100644
index 00000000..445e962c
--- /dev/null
+++ b/src/autoapp/UI/connectdialog.ui
@@ -0,0 +1,160 @@
+
+
+ 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
+
+
+
+ QAbstractItemView::NoEditTriggers
+
+
+
+
+
+
+ 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>
+
+
+
+
+
+ 40
+ 340
+ 121
+ 41
+
+
+
+ Cancel
+
+
+
+
+
+ 170
+ 340
+ 121
+ 41
+
+
+
+ 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/UI/mainwindow.ui b/src/autoapp/UI/mainwindow.ui
index 8bf52917..6da956e8 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,30 @@ color: rgb(238, 238, 236);
false
+
+
+
+ 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 11e6ad49..40284871 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);
@@ -260,48 +260,6 @@ color: rgb(238, 238, 236);
-
-
-
- 20
- 390
- 531
- 31
-
-
-
- 400
-
-
- Qt::Horizontal
-
-
-
-
-
- 20
- 360
- 91
- 17
-
-
-
- Screen DPI
-
-
-
-
-
- 570
- 380
- 41
- 51
-
-
-
- 400
-
-
@@ -312,7 +270,7 @@ color: rgb(238, 238, 236);
- OMX Layer index
+ Display
@@ -363,6 +321,100 @@ color: rgb(238, 238, 236);
+
+
+
+ 200
+ 40
+ 101
+ 21
+
+
+
+ Margin width:
+
+
+
+
+
+ 310
+ 30
+ 71
+ 41
+
+
+
+ 99999
+
+
+
+
+
+ 410
+ 40
+ 111
+ 21
+
+
+
+ Margin height:
+
+
+
+
+
+ 520
+ 30
+ 71
+ 41
+
+
+
+ 99999
+
+
+
+
+
+
+ 0
+ 360
+ 621
+ 81
+
+
+
+ Screen DPI
+
+
+
+
+ 570
+ 40
+ 41
+ 31
+
+
+
+ 400
+
+
+
+
+
+ 20
+ 40
+ 531
+ 31
+
+
+
+ 400
+
+
+ Qt::Horizontal
+
+
@@ -434,6 +486,45 @@ color: rgb(238, 238, 236);
+
+
+
+ 0
+ 130
+ 621
+ 61
+
+
+
+ Output backend
+
+
+
+
+ 10
+ 30
+ 112
+ 23
+
+
+
+ RT audio
+
+
+
+
+
+ 140
+ 30
+ 112
+ 23
+
+
+
+ Qt
+
+
+
@@ -912,9 +1003,13 @@ color: rgb(238, 238, 236);
radioButton720p
radioButton1080p
spinBoxOmxLayerIndex
+ spinBoxVideoMarginWidth
+ spinBoxVideoMarginHeight
horizontalSliderScreenDPI
checkBoxMusicAudioChannel
checkBoxSpeechAudioChannel
+ radioButtonRtAudio
+ radioButtonQtAudio
checkBoxEnableTouchscreen
listWidgetButtons
checkBoxPlayButton
diff --git a/src/autoapp/USB/USBApp.cpp b/src/autoapp/USB/USBApp.cpp
deleted file mode 100644
index 7f1af9a9..00000000
--- a/src/autoapp/USB/USBApp.cpp
+++ /dev/null
@@ -1,126 +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
-
-namespace f1x
-{
-namespace openauto
-{
-namespace autoapp
-{
-namespace usb
-{
-
-USBApp::USBApp(boost::asio::io_service& ioService, projection::IAndroidAutoEntityFactory& androidAutoEntityFactory, aasdk::usb::IUSBHub::Pointer usbHub)
- : ioService_(ioService)
- , strand_(ioService_)
- , androidAutoEntityFactory_(androidAutoEntityFactory)
- , usbHub_(std::move(usbHub))
- , isStopped_(false)
-{
-
-}
-
-void USBApp::start()
-{
- strand_.dispatch([this, self = this->shared_from_this()]() {
- this->waitForDevice();
- });
-}
-
-void USBApp::stop()
-{
- strand_.dispatch([this, self = this->shared_from_this()]() {
- isStopped_ = true;
- usbHub_->cancel();
-
- if(androidAutoEntity_ != nullptr)
- {
- androidAutoEntity_->stop();
- }
- });
-}
-
-void USBApp::aoapDeviceHandler(aasdk::usb::DeviceHandle deviceHandle)
-{
- OPENAUTO_LOG(info) << "[USBApp] Device connected.";
-
- if(androidAutoEntity_ == nullptr)
- {
- try
- {
- androidAutoEntity_ = androidAutoEntityFactory_.create(std::move(deviceHandle));
- androidAutoEntity_->start(*this);
- }
- catch(const aasdk::error::Error& error)
- {
- OPENAUTO_LOG(error) << "[USBApp] AndroidAutoEntity create error: " << error.what();
-
- androidAutoEntity_.reset();
- this->waitForDevice();
- }
- }
- else
- {
- OPENAUTO_LOG(warning) << "[USBApp] android auto entity is still running.";
- }
-}
-
-void USBApp::waitForDevice()
-{
- OPENAUTO_LOG(info) << "[USBApp] Waiting for device...";
-
- auto promise = aasdk::usb::IUSBHub::Promise::defer(strand_);
- promise->then(std::bind(&USBApp::aoapDeviceHandler, this->shared_from_this(), std::placeholders::_1),
- std::bind(&USBApp::onUSBHubError, this->shared_from_this(), std::placeholders::_1));
- usbHub_->start(std::move(promise));
-}
-
-void USBApp::onAndroidAutoQuit()
-{
- strand_.dispatch([this, self = this->shared_from_this()]() {
- OPENAUTO_LOG(info) << "[USBApp] quit.";
-
- androidAutoEntity_->stop();
- androidAutoEntity_.reset();
-
- if(!isStopped_)
- {
- this->waitForDevice();
- }
- });
-}
-
-void USBApp::onUSBHubError(const aasdk::error::Error& error)
-{
- OPENAUTO_LOG(error) << "[USBApp] usb hub error: " << error.what();
-
- if(error.getCode() == aasdk::error::ErrorCode::OPERATION_ABORTED ||
- error.getCode() == aasdk::error::ErrorCode::OPERATION_IN_PROGRESS)
- {
- this->waitForDevice();
- }
-}
-
-}
-}
-}
-}
diff --git a/src/autoapp/USB/USBMain.cpp b/src/autoapp/USB/USBMain.cpp
deleted file mode 100644
index 42429204..00000000
--- a/src/autoapp/USB/USBMain.cpp
+++ /dev/null
@@ -1,114 +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
-#include
-#include
-#include
-
-namespace f1x
-{
-namespace openauto
-{
-namespace autoapp
-{
-namespace usb
-{
-
-USBMain::USBMain(libusb_context* context)
- : usbContext_(context)
- , usbWrapper_(usbContext_)
- , queryFactory_(usbWrapper_, ioService_)
- , queryChainFactory_(usbWrapper_, ioService_, queryFactory_)
- , configuration_(std::make_shared())
- , serviceFactory_(ioService_, configuration_)
- , androidAutoEntityFactory_(usbWrapper_, ioService_, configuration_, serviceFactory_)
-{
- aasdk::usb::IUSBHub::Pointer usbHub(std::make_shared(usbWrapper_, ioService_, queryChainFactory_));
- usbApp_ = std::make_shared(ioService_, androidAutoEntityFactory_, std::move(usbHub));
-}
-
-int USBMain::exec(int argc, char* argv[])
-{
- QApplication qApplication(argc, argv);
-
- ui::MainWindow mainWindow;
- mainWindow.setWindowFlags(Qt::WindowStaysOnTopHint);
-
- ui::SettingsWindow settingsWindow(configuration_);
- settingsWindow.setWindowFlags(Qt::WindowStaysOnTopHint);
-
- QObject::connect(&mainWindow, &ui::MainWindow::exit, []() { std::exit(0); });
- QObject::connect(&mainWindow, &ui::MainWindow::openSettings, &settingsWindow, &ui::SettingsWindow::showFullScreen);
-
- qApplication.setOverrideCursor(Qt::BlankCursor);
- bool cursorVisible = false;
- QObject::connect(&mainWindow, &ui::MainWindow::toggleCursor, [&cursorVisible, &qApplication]() {
- cursorVisible = !cursorVisible;
- qApplication.setOverrideCursor(cursorVisible ? Qt::ArrowCursor : Qt::BlankCursor);
- });
-
- mainWindow.showFullScreen();
-
- boost::asio::io_service::work work(ioService_);
- this->startIOServiceWorkers();
- this->startUSBWorkers();
- usbApp_->start();
-
- auto result = qApplication.exec();
- std::for_each(threadPool_.begin(), threadPool_.end(), std::bind(&std::thread::join, std::placeholders::_1));
- return result;
-}
-
-void USBMain::startUSBWorkers()
-{
- auto usbWorker = [this]() {
- timeval libusbEventTimeout{180, 0};
-
- while(!ioService_.stopped())
- {
- libusb_handle_events_timeout_completed(usbContext_, &libusbEventTimeout, nullptr);
- }
- };
- threadPool_.emplace_back(usbWorker);
- threadPool_.emplace_back(usbWorker);
- threadPool_.emplace_back(usbWorker);
- threadPool_.emplace_back(usbWorker);
-}
-
-void USBMain::startIOServiceWorkers()
-{
- auto ioServiceWorker = [this]() {
- while(!ioService_.stopped())
- {
- ioService_.run();
- }
- };
- threadPool_.emplace_back(ioServiceWorker);
- threadPool_.emplace_back(ioServiceWorker);
- threadPool_.emplace_back(ioServiceWorker);
- threadPool_.emplace_back(ioServiceWorker);
-}
-
-}
-}
-}
-}
diff --git a/src/autoapp/autoapp.cpp b/src/autoapp/autoapp.cpp
new file mode 100644
index 00000000..8c2565c0
--- /dev/null
+++ b/src/autoapp/autoapp.cpp
@@ -0,0 +1,134 @@
+/*
+* 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
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace aasdk = f1x::aasdk;
+namespace autoapp = f1x::openauto::autoapp;
+using ThreadPool = std::vector;
+
+void startUSBWorkers(boost::asio::io_service& ioService, libusb_context* usbContext, ThreadPool& threadPool)
+{
+ auto usbWorker = [&ioService, usbContext]() {
+ timeval libusbEventTimeout{180, 0};
+
+ while(!ioService.stopped())
+ {
+ libusb_handle_events_timeout_completed(usbContext, &libusbEventTimeout, nullptr);
+ }
+ };
+
+ threadPool.emplace_back(usbWorker);
+ threadPool.emplace_back(usbWorker);
+ threadPool.emplace_back(usbWorker);
+ threadPool.emplace_back(usbWorker);
+}
+
+void startIOServiceWorkers(boost::asio::io_service& ioService, ThreadPool& threadPool)
+{
+ auto ioServiceWorker = [&ioService]() {
+ ioService.run();
+ };
+
+ threadPool.emplace_back(ioServiceWorker);
+ threadPool.emplace_back(ioServiceWorker);
+ threadPool.emplace_back(ioServiceWorker);
+ threadPool.emplace_back(ioServiceWorker);
+}
+
+int main(int argc, char* argv[])
+{
+ libusb_context* usbContext;
+ if(libusb_init(&usbContext) != 0)
+ {
+ OPENAUTO_LOG(error) << "[OpenAuto] libusb init failed.";
+ return 1;
+ }
+
+ 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);
+
+ auto configuration = std::make_shared();
+ autoapp::ui::SettingsWindow settingsWindow(configuration);
+ settingsWindow.setWindowFlags(Qt::WindowStaysOnTopHint);
+
+ autoapp::configuration::RecentAddressesList recentAddressesList(7);
+ recentAddressesList.read();
+
+ aasdk::tcp::TCPWrapper tcpWrapper;
+ autoapp::ui::ConnectDialog connectDialog(ioService, tcpWrapper, recentAddressesList);
+ 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);
+ QObject::connect(&mainWindow, &autoapp::ui::MainWindow::openConnectDialog, &connectDialog, &autoapp::ui::ConnectDialog::exec);
+
+ 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(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));
+
+ QObject::connect(&connectDialog, &autoapp::ui::ConnectDialog::connectionSucceed, [&app](auto socket) {
+ app->start(std::move(socket));
+ });
+
+ app->waitForUSBDevice();
+
+ auto result = qApplication.exec();
+ std::for_each(threadPool.begin(), threadPool.end(), std::bind(&std::thread::join, std::placeholders::_1));
+
+ libusb_exit(usbContext);
+ return result;
+}
diff --git a/src/btservice/AndroidBluetoothServer.cpp b/src/btservice/AndroidBluetoothServer.cpp
new file mode 100644
index 00000000..c827e2b6
--- /dev/null
+++ b/src/btservice/AndroidBluetoothServer.cpp
@@ -0,0 +1,56 @@
+/*
+* 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
+
+namespace f1x
+{
+namespace openauto
+{
+namespace btservice
+{
+
+AndroidBluetoothServer::AndroidBluetoothServer()
+ : rfcommServer_(std::make_unique(QBluetoothServiceInfo::RfcommProtocol, this))
+{
+ connect(rfcommServer_.get(), &QBluetoothServer::newConnection, this, &AndroidBluetoothServer::onClientConnected);
+}
+
+bool AndroidBluetoothServer::start(const QBluetoothAddress& address, uint16_t portNumber)
+{
+ return rfcommServer_->listen(address, portNumber);
+}
+
+void AndroidBluetoothServer::onClientConnected()
+{
+ auto socket = rfcommServer_->nextPendingConnection();
+
+ if(socket != nullptr)
+ {
+ OPENAUTO_LOG(info) << "[AndroidBluetoothServer] rfcomm client connected, peer name: " << socket->peerName().toStdString();
+ }
+ else
+ {
+ OPENAUTO_LOG(error) << "[AndroidBluetoothServer] received null socket during client connection.";
+ }
+}
+
+}
+}
+}
diff --git a/src/btservice/AndroidBluetoothService.cpp b/src/btservice/AndroidBluetoothService.cpp
new file mode 100644
index 00000000..f178662f
--- /dev/null
+++ b/src/btservice/AndroidBluetoothService.cpp
@@ -0,0 +1,71 @@
+/*
+* 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
+
+namespace f1x
+{
+namespace openauto
+{
+namespace btservice
+{
+
+AndroidBluetoothService::AndroidBluetoothService(uint16_t portNumber)
+{
+ //"4de17a00-52cb-11e6-bdf4-0800200c9a66";
+ //"669a0c20-0008-f4bd-e611-cb52007ae14d";
+ const QBluetoothUuid serviceUuid(QLatin1String("4de17a00-52cb-11e6-bdf4-0800200c9a66"));
+
+ QBluetoothServiceInfo::Sequence classId;
+ classId << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::SerialPort));
+ serviceInfo_.setAttribute(QBluetoothServiceInfo::BluetoothProfileDescriptorList, classId);
+ classId.prepend(QVariant::fromValue(serviceUuid));
+ serviceInfo_.setAttribute(QBluetoothServiceInfo::ServiceClassIds, classId);
+ serviceInfo_.setAttribute(QBluetoothServiceInfo::ServiceName, "OpenAuto Bluetooth Service");
+ serviceInfo_.setAttribute(QBluetoothServiceInfo::ServiceDescription, "AndroidAuto WiFi projection automatic setup");
+ serviceInfo_.setAttribute(QBluetoothServiceInfo::ServiceProvider, "f1xstudio.com");
+ serviceInfo_.setServiceUuid(serviceUuid);
+
+ QBluetoothServiceInfo::Sequence publicBrowse;
+ publicBrowse << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::PublicBrowseGroup));
+ serviceInfo_.setAttribute(QBluetoothServiceInfo::BrowseGroupList, publicBrowse);
+
+ QBluetoothServiceInfo::Sequence protocolDescriptorList;
+ QBluetoothServiceInfo::Sequence protocol;
+ protocol << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::L2cap));
+ protocolDescriptorList.append(QVariant::fromValue(protocol));
+ protocol.clear();
+ protocol << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::Rfcomm))
+ << QVariant::fromValue(quint16(portNumber));
+ protocolDescriptorList.append(QVariant::fromValue(protocol));
+ serviceInfo_.setAttribute(QBluetoothServiceInfo::ProtocolDescriptorList, protocolDescriptorList);
+}
+
+bool AndroidBluetoothService::registerService(const QBluetoothAddress& bluetoothAddress)
+{
+ return serviceInfo_.registerService(bluetoothAddress);
+}
+
+bool AndroidBluetoothService::unregisterService()
+{
+ return serviceInfo_.unregisterService();
+}
+
+}
+}
+}
diff --git a/src/btservice/btservice.cpp b/src/btservice/btservice.cpp
new file mode 100644
index 00000000..e759c81c
--- /dev/null
+++ b/src/btservice/btservice.cpp
@@ -0,0 +1,58 @@
+/*
+* 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 btservice = f1x::openauto::btservice;
+
+int main(int argc, char* argv[])
+{
+ QApplication qApplication(argc, argv);
+
+ const QBluetoothAddress address;
+ const uint16_t portNumber = 5000;
+
+ btservice::AndroidBluetoothServer androidBluetoothServer;
+ if(!androidBluetoothServer.start(address, portNumber))
+ {
+ OPENAUTO_LOG(error) << "[btservice] Server start failed.";
+ return 2;
+ }
+
+ OPENAUTO_LOG(info) << "[btservice] Listening for connections, address: " << address.toString().toStdString()
+ << ", port: " << portNumber;
+
+ btservice::AndroidBluetoothService androidBluetoothService(portNumber);
+ if(!androidBluetoothService.registerService(address))
+ {
+ OPENAUTO_LOG(error) << "[btservice] Service registration failed.";
+ return 1;
+ }
+ else
+ {
+ OPENAUTO_LOG(info) << "[btservice] Service registered, port: " << portNumber;
+ }
+
+ qApplication.exec();
+ androidBluetoothService.unregisterService();
+
+ return 0;
+}