mirror of https://github.com/f1xpl/openauto.git
commit
26826aec77
|
@ -32,6 +32,7 @@ find_package(libusb-1.0 REQUIRED)
|
||||||
find_package(Qt5 COMPONENTS Multimedia MultimediaWidgets Bluetooth)
|
find_package(Qt5 COMPONENTS Multimedia MultimediaWidgets Bluetooth)
|
||||||
find_package(Protobuf REQUIRED)
|
find_package(Protobuf REQUIRED)
|
||||||
find_package(OpenSSL REQUIRED)
|
find_package(OpenSSL REQUIRED)
|
||||||
|
find_package(rtaudio REQUIRED)
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
set(WINSOCK2_LIBRARIES "ws2_32")
|
set(WINSOCK2_LIBRARIES "ws2_32")
|
||||||
|
@ -54,6 +55,7 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR}
|
||||||
${LIBUSB_1_INCLUDE_DIRS}
|
${LIBUSB_1_INCLUDE_DIRS}
|
||||||
${PROTOBUF_INCLUDE_DIR}
|
${PROTOBUF_INCLUDE_DIR}
|
||||||
${OPENSSL_INCLUDE_DIR}
|
${OPENSSL_INCLUDE_DIR}
|
||||||
|
${RTAUDIO_INCLUDE_DIRS}
|
||||||
${AASDK_PROTO_INCLUDE_DIRS}
|
${AASDK_PROTO_INCLUDE_DIRS}
|
||||||
${AASDK_INCLUDE_DIRS}
|
${AASDK_INCLUDE_DIRS}
|
||||||
${BCM_HOST_INCLUDE_DIRS}
|
${BCM_HOST_INCLUDE_DIRS}
|
||||||
|
@ -62,10 +64,13 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR}
|
||||||
|
|
||||||
link_directories(${CMAKE_LIBRARY_OUTPUT_DIRECTORY})
|
link_directories(${CMAKE_LIBRARY_OUTPUT_DIRECTORY})
|
||||||
|
|
||||||
set(autoapp_sources_directory ${sources_directory}/autoapp)
|
set(common_include_directory ${include_directory}/f1x/openauto/Common)
|
||||||
file(GLOB_RECURSE source_files ${autoapp_sources_directory}/*.ui ${autoapp_sources_directory}/*.cpp ${include_directory}/*.hpp ${resources_directory}/*.qrc)
|
|
||||||
|
|
||||||
add_executable(autoapp ${source_files})
|
set(autoapp_sources_directory ${sources_directory}/autoapp)
|
||||||
|
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 ${autoapp_source_files})
|
||||||
|
|
||||||
target_link_libraries(autoapp
|
target_link_libraries(autoapp
|
||||||
${Boost_LIBRARIES}
|
${Boost_LIBRARIES}
|
||||||
|
@ -77,5 +82,19 @@ target_link_libraries(autoapp
|
||||||
${BCM_HOST_LIBRARIES}
|
${BCM_HOST_LIBRARIES}
|
||||||
${ILCLIENT_LIBRARIES}
|
${ILCLIENT_LIBRARIES}
|
||||||
${WINSOCK2_LIBRARIES}
|
${WINSOCK2_LIBRARIES}
|
||||||
|
${RTAUDIO_LIBRARIES}
|
||||||
${AASDK_PROTO_LIBRARIES}
|
${AASDK_PROTO_LIBRARIES}
|
||||||
${AASDK_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})
|
||||||
|
|
|
@ -22,6 +22,8 @@ OpenAuto is an AndroidAuto(tm) headunit emulator based on aasdk library and Qt l
|
||||||
- Touchscreen and buttons input
|
- Touchscreen and buttons input
|
||||||
- Bluetooth
|
- Bluetooth
|
||||||
- Automatic launch after device hotplug
|
- 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
|
- User-friendly settings
|
||||||
|
|
||||||
### Supported platforms
|
### Supported platforms
|
||||||
|
@ -42,6 +44,7 @@ Copyrights (c) 2018 f1x.studio (Michal Szwaj)
|
||||||
- [Boost libraries](http://www.boost.org/)
|
- [Boost libraries](http://www.boost.org/)
|
||||||
- [Qt libraries](https://www.qt.io/)
|
- [Qt libraries](https://www.qt.io/)
|
||||||
- [CMake](https://cmake.org/)
|
- [CMake](https://cmake.org/)
|
||||||
|
- [RtAudio](https://www.music.mcgill.ca/~gary/rtaudio/playback.html)
|
||||||
- Broadcom ilclient from RaspberryPI 3 firmware
|
- Broadcom ilclient from RaspberryPI 3 firmware
|
||||||
- OpenMAX IL API
|
- OpenMAX IL API
|
||||||
|
|
||||||
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
|
||||||
|
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)
|
|
@ -20,4 +20,4 @@
|
||||||
|
|
||||||
#include <boost/log/trivial.hpp>
|
#include <boost/log/trivial.hpp>
|
||||||
|
|
||||||
#define OPENAUTO_LOG(severity) BOOST_LOG_TRIVIAL(severity) << "[AaApp] "
|
#define OPENAUTO_LOG(severity) BOOST_LOG_TRIVIAL(severity) << "[OpenAuto] "
|
||||||
|
|
|
@ -19,6 +19,10 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <f1x/aasdk/USB/IUSBHub.hpp>
|
#include <f1x/aasdk/USB/IUSBHub.hpp>
|
||||||
|
#include <f1x/aasdk/USB/IConnectedAccessoriesEnumerator.hpp>
|
||||||
|
#include <f1x/aasdk/USB/USBWrapper.hpp>
|
||||||
|
#include <f1x/aasdk/TCP/ITCPWrapper.hpp>
|
||||||
|
#include <f1x/aasdk/TCP/ITCPEndpoint.hpp>
|
||||||
#include <f1x/openauto/autoapp/Projection/IAndroidAutoEntityEventHandler.hpp>
|
#include <f1x/openauto/autoapp/Projection/IAndroidAutoEntityEventHandler.hpp>
|
||||||
#include <f1x/openauto/autoapp/Projection/IAndroidAutoEntityFactory.hpp>
|
#include <f1x/openauto/autoapp/Projection/IAndroidAutoEntityFactory.hpp>
|
||||||
|
|
||||||
|
@ -28,31 +32,35 @@ namespace openauto
|
||||||
{
|
{
|
||||||
namespace autoapp
|
namespace autoapp
|
||||||
{
|
{
|
||||||
namespace usb
|
|
||||||
{
|
|
||||||
|
|
||||||
class USBApp: public projection::IAndroidAutoEntityEventHandler, public std::enable_shared_from_this<USBApp>
|
class App: public projection::IAndroidAutoEntityEventHandler, public std::enable_shared_from_this<App>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef std::shared_ptr<USBApp> Pointer;
|
typedef std::shared_ptr<App> 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 stop();
|
||||||
void onAndroidAutoQuit() override;
|
void onAndroidAutoQuit() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
using std::enable_shared_from_this<USBApp>::shared_from_this;
|
using std::enable_shared_from_this<App>::shared_from_this;
|
||||||
|
|
||||||
|
void enumerateDevices();
|
||||||
void waitForDevice();
|
void waitForDevice();
|
||||||
void aoapDeviceHandler(aasdk::usb::DeviceHandle deviceHandle);
|
void aoapDeviceHandler(aasdk::usb::DeviceHandle deviceHandle);
|
||||||
void onUSBHubError(const aasdk::error::Error& error);
|
void onUSBHubError(const aasdk::error::Error& error);
|
||||||
|
|
||||||
boost::asio::io_service& ioService_;
|
boost::asio::io_service& ioService_;
|
||||||
|
aasdk::usb::USBWrapper& usbWrapper_;
|
||||||
|
aasdk::tcp::ITCPWrapper& tcpWrapper_;
|
||||||
boost::asio::io_service::strand strand_;
|
boost::asio::io_service::strand strand_;
|
||||||
projection::IAndroidAutoEntityFactory& androidAutoEntityFactory_;
|
projection::IAndroidAutoEntityFactory& androidAutoEntityFactory_;
|
||||||
aasdk::usb::IUSBHub::Pointer usbHub_;
|
aasdk::usb::IUSBHub::Pointer usbHub_;
|
||||||
|
aasdk::usb::IConnectedAccessoriesEnumerator::Pointer connectedAccessoriesEnumerator_;
|
||||||
projection::IAndroidAutoEntity::Pointer androidAutoEntity_;
|
projection::IAndroidAutoEntity::Pointer androidAutoEntity_;
|
||||||
bool isStopped_;
|
bool isStopped_;
|
||||||
};
|
};
|
||||||
|
@ -60,4 +68,3 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace f1x
|
||||||
|
{
|
||||||
|
namespace openauto
|
||||||
|
{
|
||||||
|
namespace autoapp
|
||||||
|
{
|
||||||
|
namespace configuration
|
||||||
|
{
|
||||||
|
|
||||||
|
enum class AudioOutputBackendType
|
||||||
|
{
|
||||||
|
RTAUDIO,
|
||||||
|
QT
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -52,6 +52,8 @@ public:
|
||||||
void setScreenDPI(size_t value) override;
|
void setScreenDPI(size_t value) override;
|
||||||
void setOMXLayerIndex(int32_t value) override;
|
void setOMXLayerIndex(int32_t value) override;
|
||||||
int32_t getOMXLayerIndex() const override;
|
int32_t getOMXLayerIndex() const override;
|
||||||
|
void setVideoMargins(QRect value) override;
|
||||||
|
QRect getVideoMargins() const override;
|
||||||
|
|
||||||
bool getTouchscreenEnabled() const override;
|
bool getTouchscreenEnabled() const override;
|
||||||
void setTouchscreenEnabled(bool value) override;
|
void setTouchscreenEnabled(bool value) override;
|
||||||
|
@ -67,6 +69,8 @@ public:
|
||||||
void setMusicAudioChannelEnabled(bool value) override;
|
void setMusicAudioChannelEnabled(bool value) override;
|
||||||
bool speechAudioChannelEnabled() const override;
|
bool speechAudioChannelEnabled() const override;
|
||||||
void setSpeechAudioChannelEnabled(bool value) override;
|
void setSpeechAudioChannelEnabled(bool value) override;
|
||||||
|
AudioOutputBackendType getAudioOutputBackendType() const override;
|
||||||
|
void setAudioOutputBackendType(AudioOutputBackendType value) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void readButtonCodes(boost::property_tree::ptree& iniConfig);
|
void readButtonCodes(boost::property_tree::ptree& iniConfig);
|
||||||
|
@ -79,12 +83,14 @@ private:
|
||||||
aasdk::proto::enums::VideoResolution::Enum videoResolution_;
|
aasdk::proto::enums::VideoResolution::Enum videoResolution_;
|
||||||
size_t screenDPI_;
|
size_t screenDPI_;
|
||||||
int32_t omxLayerIndex_;
|
int32_t omxLayerIndex_;
|
||||||
|
QRect videoMargins_;
|
||||||
bool enableTouchscreen_;
|
bool enableTouchscreen_;
|
||||||
ButtonCodes buttonCodes_;
|
ButtonCodes buttonCodes_;
|
||||||
BluetoothAdapterType bluetoothAdapterType_;
|
BluetoothAdapterType bluetoothAdapterType_;
|
||||||
std::string bluetoothRemoteAdapterAddress_;
|
std::string bluetoothRemoteAdapterAddress_;
|
||||||
bool musicAudioChannelEnabled_;
|
bool musicAudioChannelEnabled_;
|
||||||
bool speechAudiochannelEnabled_;
|
bool speechAudiochannelEnabled_;
|
||||||
|
AudioOutputBackendType audioOutputBackendType_;
|
||||||
|
|
||||||
static const std::string cConfigFileName;
|
static const std::string cConfigFileName;
|
||||||
|
|
||||||
|
@ -95,9 +101,12 @@ private:
|
||||||
static const std::string cVideoResolutionKey;
|
static const std::string cVideoResolutionKey;
|
||||||
static const std::string cVideoScreenDPIKey;
|
static const std::string cVideoScreenDPIKey;
|
||||||
static const std::string cVideoOMXLayerIndexKey;
|
static const std::string cVideoOMXLayerIndexKey;
|
||||||
|
static const std::string cVideoMarginWidth;
|
||||||
|
static const std::string cVideoMarginHeight;
|
||||||
|
|
||||||
static const std::string cAudioMusicAudioChannelEnabled;
|
static const std::string cAudioMusicAudioChannelEnabled;
|
||||||
static const std::string cAudioSpeechAudioChannelEnabled;
|
static const std::string cAudioSpeechAudioChannelEnabled;
|
||||||
|
static const std::string cAudioOutputBackendType;
|
||||||
|
|
||||||
static const std::string cBluetoothAdapterTypeKey;
|
static const std::string cBluetoothAdapterTypeKey;
|
||||||
static const std::string cBluetoothRemoteAdapterAddressKey;
|
static const std::string cBluetoothRemoteAdapterAddressKey;
|
||||||
|
|
|
@ -19,11 +19,13 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <QRect>
|
||||||
#include <aasdk_proto/VideoFPSEnum.pb.h>
|
#include <aasdk_proto/VideoFPSEnum.pb.h>
|
||||||
#include <aasdk_proto/VideoResolutionEnum.pb.h>
|
#include <aasdk_proto/VideoResolutionEnum.pb.h>
|
||||||
#include <aasdk_proto/ButtonCodeEnum.pb.h>
|
#include <aasdk_proto/ButtonCodeEnum.pb.h>
|
||||||
#include <f1x/openauto/autoapp/Configuration/BluetootAdapterType.hpp>
|
#include <f1x/openauto/autoapp/Configuration/BluetootAdapterType.hpp>
|
||||||
#include <f1x/openauto/autoapp/Configuration/HandednessOfTrafficType.hpp>
|
#include <f1x/openauto/autoapp/Configuration/HandednessOfTrafficType.hpp>
|
||||||
|
#include <f1x/openauto/autoapp/Configuration/AudioOutputBackendType.hpp>
|
||||||
|
|
||||||
namespace f1x
|
namespace f1x
|
||||||
{
|
{
|
||||||
|
@ -59,6 +61,8 @@ public:
|
||||||
virtual void setScreenDPI(size_t value) = 0;
|
virtual void setScreenDPI(size_t value) = 0;
|
||||||
virtual void setOMXLayerIndex(int32_t value) = 0;
|
virtual void setOMXLayerIndex(int32_t value) = 0;
|
||||||
virtual int32_t getOMXLayerIndex() const = 0;
|
virtual int32_t getOMXLayerIndex() const = 0;
|
||||||
|
virtual void setVideoMargins(QRect value) = 0;
|
||||||
|
virtual QRect getVideoMargins() const = 0;
|
||||||
|
|
||||||
virtual bool getTouchscreenEnabled() const = 0;
|
virtual bool getTouchscreenEnabled() const = 0;
|
||||||
virtual void setTouchscreenEnabled(bool value) = 0;
|
virtual void setTouchscreenEnabled(bool value) = 0;
|
||||||
|
@ -74,6 +78,8 @@ public:
|
||||||
virtual void setMusicAudioChannelEnabled(bool value) = 0;
|
virtual void setMusicAudioChannelEnabled(bool value) = 0;
|
||||||
virtual bool speechAudioChannelEnabled() const = 0;
|
virtual bool speechAudioChannelEnabled() const = 0;
|
||||||
virtual void setSpeechAudioChannelEnabled(bool value) = 0;
|
virtual void setSpeechAudioChannelEnabled(bool value) = 0;
|
||||||
|
virtual AudioOutputBackendType getAudioOutputBackendType() const = 0;
|
||||||
|
virtual void setAudioOutputBackendType(AudioOutputBackendType value) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,24 +16,31 @@
|
||||||
* along with openauto. If not, see <http://www.gnu.org/licenses/>.
|
* along with openauto. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <f1x/openauto/autoapp/USB/USBMain.hpp>
|
#pragma once
|
||||||
#include <f1x/openauto/Common/Log.hpp>
|
|
||||||
|
|
||||||
namespace aasdk = f1x::aasdk;
|
#include <deque>
|
||||||
namespace autoapp = f1x::openauto::autoapp;
|
#include <string>
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
namespace f1x
|
||||||
|
{
|
||||||
|
namespace openauto
|
||||||
|
{
|
||||||
|
namespace autoapp
|
||||||
|
{
|
||||||
|
namespace configuration
|
||||||
{
|
{
|
||||||
libusb_context* context;
|
|
||||||
if(libusb_init(&context) != 0)
|
|
||||||
{
|
|
||||||
OPENAUTO_LOG(error) << "[OpenAuto] libusb init failed.";
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
autoapp::usb::USBMain main(context);
|
class IRecentAddressesList
|
||||||
auto result = main.exec(argc, argv);
|
{
|
||||||
|
public:
|
||||||
|
typedef std::deque<std::string> RecentAddresses;
|
||||||
|
|
||||||
|
virtual void read() = 0;
|
||||||
|
virtual void insertAddress(const std::string& address) = 0;
|
||||||
|
virtual RecentAddresses getList() const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
libusb_exit(context);
|
}
|
||||||
return result;
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <deque>
|
||||||
|
#include <f1x/openauto/autoapp/Configuration/IRecentAddressesList.hpp>
|
||||||
|
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,6 +19,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <boost/asio.hpp>
|
#include <boost/asio.hpp>
|
||||||
|
#include <f1x/aasdk/Transport/ITransport.hpp>
|
||||||
#include <f1x/openauto/autoapp/Configuration/IConfiguration.hpp>
|
#include <f1x/openauto/autoapp/Configuration/IConfiguration.hpp>
|
||||||
#include <f1x/openauto/autoapp/Projection/IAndroidAutoEntityFactory.hpp>
|
#include <f1x/openauto/autoapp/Projection/IAndroidAutoEntityFactory.hpp>
|
||||||
#include <f1x/openauto/autoapp/Projection/IServiceFactory.hpp>
|
#include <f1x/openauto/autoapp/Projection/IServiceFactory.hpp>
|
||||||
|
@ -35,15 +36,16 @@ namespace projection
|
||||||
class AndroidAutoEntityFactory: public IAndroidAutoEntityFactory
|
class AndroidAutoEntityFactory: public IAndroidAutoEntityFactory
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AndroidAutoEntityFactory(aasdk::usb::IUSBWrapper& usbWrapper,
|
AndroidAutoEntityFactory(boost::asio::io_service& ioService,
|
||||||
boost::asio::io_service& ioService,
|
|
||||||
configuration::IConfiguration::Pointer configuration,
|
configuration::IConfiguration::Pointer configuration,
|
||||||
IServiceFactory& serviceFactory);
|
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:
|
private:
|
||||||
aasdk::usb::IUSBWrapper& usbWrapper_;
|
IAndroidAutoEntity::Pointer create(aasdk::transport::ITransport::Pointer transport);
|
||||||
|
|
||||||
boost::asio::io_service& ioService_;
|
boost::asio::io_service& ioService_;
|
||||||
configuration::IConfiguration::Pointer configuration_;
|
configuration::IConfiguration::Pointer configuration_;
|
||||||
IServiceFactory& serviceFactory_;
|
IServiceFactory& serviceFactory_;
|
||||||
|
|
|
@ -18,7 +18,8 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <f1x/aasdk/USB/USBWrapper.hpp>
|
#include <f1x/aasdk/TCP/ITCPEndpoint.hpp>
|
||||||
|
#include <f1x/aasdk/USB/IAOAPDevice.hpp>
|
||||||
#include <f1x/openauto/autoapp/Projection/IAndroidAutoEntity.hpp>
|
#include <f1x/openauto/autoapp/Projection/IAndroidAutoEntity.hpp>
|
||||||
|
|
||||||
namespace f1x
|
namespace f1x
|
||||||
|
@ -35,7 +36,8 @@ class IAndroidAutoEntityFactory
|
||||||
public:
|
public:
|
||||||
virtual ~IAndroidAutoEntityFactory() = default;
|
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;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <f1x/aasdk/Messenger/Timestamp.hpp>
|
||||||
#include <f1x/aasdk/Common/Data.hpp>
|
#include <f1x/aasdk/Common/Data.hpp>
|
||||||
|
|
||||||
namespace f1x
|
namespace f1x
|
||||||
|
@ -39,7 +40,7 @@ public:
|
||||||
virtual ~IAudioOutput() = default;
|
virtual ~IAudioOutput() = default;
|
||||||
|
|
||||||
virtual bool open() = 0;
|
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 start() = 0;
|
||||||
virtual void stop() = 0;
|
virtual void stop() = 0;
|
||||||
virtual void suspend() = 0;
|
virtual void suspend() = 0;
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <QRect>
|
||||||
#include <aasdk_proto/VideoFPSEnum.pb.h>
|
#include <aasdk_proto/VideoFPSEnum.pb.h>
|
||||||
#include <aasdk_proto/VideoResolutionEnum.pb.h>
|
#include <aasdk_proto/VideoResolutionEnum.pb.h>
|
||||||
#include <f1x/aasdk/Common/Data.hpp>
|
#include <f1x/aasdk/Common/Data.hpp>
|
||||||
|
@ -47,6 +48,7 @@ public:
|
||||||
virtual aasdk::proto::enums::VideoFPS::Enum getVideoFPS() const = 0;
|
virtual aasdk::proto::enums::VideoFPS::Enum getVideoFPS() const = 0;
|
||||||
virtual aasdk::proto::enums::VideoResolution::Enum getVideoResolution() const = 0;
|
virtual aasdk::proto::enums::VideoResolution::Enum getVideoResolution() const = 0;
|
||||||
virtual size_t getScreenDPI() const = 0;
|
virtual size_t getScreenDPI() const = 0;
|
||||||
|
virtual QRect getVideoMargins() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,11 +32,11 @@ namespace autoapp
|
||||||
namespace projection
|
namespace projection
|
||||||
{
|
{
|
||||||
|
|
||||||
class AudioInput: public QObject, public IAudioInput
|
class QtAudioInput: public QObject, public IAudioInput
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
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 open() override;
|
||||||
bool isActive() const override;
|
bool isActive() const override;
|
|
@ -32,14 +32,14 @@ namespace autoapp
|
||||||
namespace projection
|
namespace projection
|
||||||
{
|
{
|
||||||
|
|
||||||
class AudioOutput: public QObject, public IAudioOutput
|
class QtAudioOutput: public QObject, public IAudioOutput
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AudioOutput(uint32_t channelCount, uint32_t sampleSize, uint32_t sampleRate);
|
QtAudioOutput(uint32_t channelCount, uint32_t sampleSize, uint32_t sampleRate);
|
||||||
bool open() override;
|
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 start() override;
|
||||||
void stop() override;
|
void stop() override;
|
||||||
void suspend() override;
|
void suspend() override;
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <RtAudio.h>
|
||||||
|
#include <f1x/openauto/autoapp/Projection/IAudioOutput.hpp>
|
||||||
|
#include <f1x/openauto/autoapp/Projection/SequentialBuffer.hpp>
|
||||||
|
|
||||||
|
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<RtAudio> dac_;
|
||||||
|
std::mutex mutex_;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -40,6 +40,7 @@ private:
|
||||||
IService::Pointer createVideoService(aasdk::messenger::IMessenger::Pointer messenger);
|
IService::Pointer createVideoService(aasdk::messenger::IMessenger::Pointer messenger);
|
||||||
IService::Pointer createBluetoothService(aasdk::messenger::IMessenger::Pointer messenger);
|
IService::Pointer createBluetoothService(aasdk::messenger::IMessenger::Pointer messenger);
|
||||||
IService::Pointer createInputService(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_;
|
boost::asio::io_service& ioService_;
|
||||||
configuration::IConfiguration::Pointer configuration_;
|
configuration::IConfiguration::Pointer configuration_;
|
||||||
|
|
|
@ -38,6 +38,7 @@ public:
|
||||||
aasdk::proto::enums::VideoFPS::Enum getVideoFPS() const override;
|
aasdk::proto::enums::VideoFPS::Enum getVideoFPS() const override;
|
||||||
aasdk::proto::enums::VideoResolution::Enum getVideoResolution() const override;
|
aasdk::proto::enums::VideoResolution::Enum getVideoResolution() const override;
|
||||||
size_t getScreenDPI() const override;
|
size_t getScreenDPI() const override;
|
||||||
|
QRect getVideoMargins() const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
configuration::IConfiguration::Pointer configuration_;
|
configuration::IConfiguration::Pointer configuration_;
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
#include <QStringListModel>
|
||||||
|
#include <f1x/aasdk/TCP/ITCPEndpoint.hpp>
|
||||||
|
#include <f1x/aasdk/TCP/ITCPWrapper.hpp>
|
||||||
|
#include <f1x/openauto/autoapp/Configuration/IRecentAddressesList.hpp>
|
||||||
|
|
||||||
|
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_;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -46,6 +46,7 @@ signals:
|
||||||
void exit();
|
void exit();
|
||||||
void openSettings();
|
void openSettings();
|
||||||
void toggleCursor();
|
void toggleCursor();
|
||||||
|
void openConnectDialog();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::MainWindow* ui_;
|
Ui::MainWindow* ui_;
|
||||||
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <thread>
|
|
||||||
#include <f1x/aasdk/USB/USBWrapper.hpp>
|
|
||||||
#include <f1x/aasdk/USB/AccessoryModeQueryChain.hpp>
|
|
||||||
#include <f1x/aasdk/USB/AccessoryModeQueryChainFactory.hpp>
|
|
||||||
#include <f1x/aasdk/USB/AccessoryModeQueryFactory.hpp>
|
|
||||||
#include <f1x/openauto/autoapp/USB/USBApp.hpp>
|
|
||||||
#include <f1x/openauto/autoapp/Configuration/IConfiguration.hpp>
|
|
||||||
#include <f1x/openauto/autoapp/Projection/AndroidAutoEntityFactory.hpp>
|
|
||||||
#include <f1x/openauto/autoapp/Projection/ServiceFactory.hpp>
|
|
||||||
|
|
||||||
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<std::thread> 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_;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <memory>
|
||||||
|
#include <QBluetoothServer>
|
||||||
|
#include <f1x/openauto/btservice/IAndroidBluetoothServer.hpp>
|
||||||
|
|
||||||
|
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<QBluetoothServer> rfcommServer_;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QBluetoothServiceInfo>
|
||||||
|
#include <f1x/openauto/btservice/IAndroidBluetoothService.hpp>
|
||||||
|
|
||||||
|
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_;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QBluetoothAddress>
|
||||||
|
|
||||||
|
namespace f1x
|
||||||
|
{
|
||||||
|
namespace openauto
|
||||||
|
{
|
||||||
|
namespace btservice
|
||||||
|
{
|
||||||
|
|
||||||
|
class IAndroidBluetoothServer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~IAndroidBluetoothServer() = default;
|
||||||
|
|
||||||
|
virtual bool start(const QBluetoothAddress& address, uint16_t portNumber) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QBluetoothAddress>
|
||||||
|
|
||||||
|
namespace f1x
|
||||||
|
{
|
||||||
|
namespace openauto
|
||||||
|
{
|
||||||
|
namespace btservice
|
||||||
|
{
|
||||||
|
|
||||||
|
class IAndroidBluetoothService
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~IAndroidBluetoothService() = default;
|
||||||
|
|
||||||
|
virtual bool registerService(const QBluetoothAddress& bluetoothAddress) = 0;
|
||||||
|
virtual bool unregisterService() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <thread>
|
||||||
|
#include <f1x/aasdk/USB/AOAPDevice.hpp>
|
||||||
|
#include <f1x/aasdk/TCP/TCPEndpoint.hpp>
|
||||||
|
#include <f1x/openauto/autoapp/App.hpp>
|
||||||
|
#include <f1x/openauto/Common/Log.hpp>
|
||||||
|
|
||||||
|
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<aasdk::tcp::TCPEndpoint>(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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -37,9 +37,12 @@ const std::string Configuration::cVideoFPSKey = "Video.FPS";
|
||||||
const std::string Configuration::cVideoResolutionKey = "Video.Resolution";
|
const std::string Configuration::cVideoResolutionKey = "Video.Resolution";
|
||||||
const std::string Configuration::cVideoScreenDPIKey = "Video.ScreenDPI";
|
const std::string Configuration::cVideoScreenDPIKey = "Video.ScreenDPI";
|
||||||
const std::string Configuration::cVideoOMXLayerIndexKey = "Video.OMXLayerIndex";
|
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::cAudioMusicAudioChannelEnabled = "Audio.MusicAudioChannelEnabled";
|
||||||
const std::string Configuration::cAudioSpeechAudioChannelEnabled = "Audio.SpeechAudioChannelEnabled";
|
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::cBluetoothAdapterTypeKey = "Bluetooth.AdapterType";
|
||||||
const std::string Configuration::cBluetoothRemoteAdapterAddressKey = "Bluetooth.RemoteAdapterAddress";
|
const std::string Configuration::cBluetoothRemoteAdapterAddressKey = "Bluetooth.RemoteAdapterAddress";
|
||||||
|
@ -87,6 +90,7 @@ void Configuration::load()
|
||||||
screenDPI_ = iniConfig.get<size_t>(cVideoScreenDPIKey, 140);
|
screenDPI_ = iniConfig.get<size_t>(cVideoScreenDPIKey, 140);
|
||||||
|
|
||||||
omxLayerIndex_ = iniConfig.get<int32_t>(cVideoOMXLayerIndexKey, 1);
|
omxLayerIndex_ = iniConfig.get<int32_t>(cVideoOMXLayerIndexKey, 1);
|
||||||
|
videoMargins_ = QRect(0, 0, iniConfig.get<int32_t>(cVideoMarginWidth, 0), iniConfig.get<int32_t>(cVideoMarginHeight, 0));
|
||||||
|
|
||||||
enableTouchscreen_ = iniConfig.get<bool>(cInputEnableTouchscreenKey, true);
|
enableTouchscreen_ = iniConfig.get<bool>(cInputEnableTouchscreenKey, true);
|
||||||
this->readButtonCodes(iniConfig);
|
this->readButtonCodes(iniConfig);
|
||||||
|
@ -98,6 +102,7 @@ void Configuration::load()
|
||||||
|
|
||||||
musicAudioChannelEnabled_ = iniConfig.get<bool>(cAudioMusicAudioChannelEnabled, true);
|
musicAudioChannelEnabled_ = iniConfig.get<bool>(cAudioMusicAudioChannelEnabled, true);
|
||||||
speechAudiochannelEnabled_ = iniConfig.get<bool>(cAudioSpeechAudioChannelEnabled, true);
|
speechAudiochannelEnabled_ = iniConfig.get<bool>(cAudioSpeechAudioChannelEnabled, true);
|
||||||
|
audioOutputBackendType_ = static_cast<AudioOutputBackendType>(iniConfig.get<uint32_t>(cAudioOutputBackendType, static_cast<uint32_t>(AudioOutputBackendType::RTAUDIO)));
|
||||||
}
|
}
|
||||||
catch(const boost::property_tree::ini_parser_error& e)
|
catch(const boost::property_tree::ini_parser_error& e)
|
||||||
{
|
{
|
||||||
|
@ -116,12 +121,14 @@ void Configuration::reset()
|
||||||
videoResolution_ = aasdk::proto::enums::VideoResolution::_480p;
|
videoResolution_ = aasdk::proto::enums::VideoResolution::_480p;
|
||||||
screenDPI_ = 140;
|
screenDPI_ = 140;
|
||||||
omxLayerIndex_ = 1;
|
omxLayerIndex_ = 1;
|
||||||
|
videoMargins_ = QRect(0, 0, 0, 0);
|
||||||
enableTouchscreen_ = true;
|
enableTouchscreen_ = true;
|
||||||
buttonCodes_.clear();
|
buttonCodes_.clear();
|
||||||
bluetoothAdapterType_ = BluetoothAdapterType::NONE;
|
bluetoothAdapterType_ = BluetoothAdapterType::NONE;
|
||||||
bluetoothRemoteAdapterAddress_ = "";
|
bluetoothRemoteAdapterAddress_ = "";
|
||||||
musicAudioChannelEnabled_ = true;
|
musicAudioChannelEnabled_ = true;
|
||||||
speechAudiochannelEnabled_ = true;
|
speechAudiochannelEnabled_ = true;
|
||||||
|
audioOutputBackendType_ = AudioOutputBackendType::RTAUDIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Configuration::save()
|
void Configuration::save()
|
||||||
|
@ -134,6 +141,8 @@ void Configuration::save()
|
||||||
iniConfig.put<uint32_t>(cVideoResolutionKey, static_cast<uint32_t>(videoResolution_));
|
iniConfig.put<uint32_t>(cVideoResolutionKey, static_cast<uint32_t>(videoResolution_));
|
||||||
iniConfig.put<size_t>(cVideoScreenDPIKey, screenDPI_);
|
iniConfig.put<size_t>(cVideoScreenDPIKey, screenDPI_);
|
||||||
iniConfig.put<int32_t>(cVideoOMXLayerIndexKey, omxLayerIndex_);
|
iniConfig.put<int32_t>(cVideoOMXLayerIndexKey, omxLayerIndex_);
|
||||||
|
iniConfig.put<uint32_t>(cVideoMarginWidth, videoMargins_.width());
|
||||||
|
iniConfig.put<uint32_t>(cVideoMarginHeight, videoMargins_.height());
|
||||||
|
|
||||||
iniConfig.put<bool>(cInputEnableTouchscreenKey, enableTouchscreen_);
|
iniConfig.put<bool>(cInputEnableTouchscreenKey, enableTouchscreen_);
|
||||||
this->writeButtonCodes(iniConfig);
|
this->writeButtonCodes(iniConfig);
|
||||||
|
@ -143,6 +152,7 @@ void Configuration::save()
|
||||||
|
|
||||||
iniConfig.put<bool>(cAudioMusicAudioChannelEnabled, musicAudioChannelEnabled_);
|
iniConfig.put<bool>(cAudioMusicAudioChannelEnabled, musicAudioChannelEnabled_);
|
||||||
iniConfig.put<bool>(cAudioSpeechAudioChannelEnabled, speechAudiochannelEnabled_);
|
iniConfig.put<bool>(cAudioSpeechAudioChannelEnabled, speechAudiochannelEnabled_);
|
||||||
|
iniConfig.put<uint32_t>(cAudioOutputBackendType, static_cast<uint32_t>(audioOutputBackendType_));
|
||||||
boost::property_tree::ini_parser::write_ini(cConfigFileName, iniConfig);
|
boost::property_tree::ini_parser::write_ini(cConfigFileName, iniConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -206,6 +216,16 @@ int32_t Configuration::getOMXLayerIndex() const
|
||||||
return omxLayerIndex_;
|
return omxLayerIndex_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Configuration::setVideoMargins(QRect value)
|
||||||
|
{
|
||||||
|
videoMargins_ = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
QRect Configuration::getVideoMargins() const
|
||||||
|
{
|
||||||
|
return videoMargins_;
|
||||||
|
}
|
||||||
|
|
||||||
bool Configuration::getTouchscreenEnabled() const
|
bool Configuration::getTouchscreenEnabled() const
|
||||||
{
|
{
|
||||||
return enableTouchscreen_;
|
return enableTouchscreen_;
|
||||||
|
@ -266,6 +286,16 @@ void Configuration::setSpeechAudioChannelEnabled(bool value)
|
||||||
speechAudiochannelEnabled_ = value;
|
speechAudiochannelEnabled_ = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AudioOutputBackendType Configuration::getAudioOutputBackendType() const
|
||||||
|
{
|
||||||
|
return audioOutputBackendType_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Configuration::setAudioOutputBackendType(AudioOutputBackendType value)
|
||||||
|
{
|
||||||
|
audioOutputBackendType_ = value;
|
||||||
|
}
|
||||||
|
|
||||||
void Configuration::readButtonCodes(boost::property_tree::ptree& iniConfig)
|
void Configuration::readButtonCodes(boost::property_tree::ptree& iniConfig)
|
||||||
{
|
{
|
||||||
this->insertButtonCode(iniConfig, cInputPlayButtonKey, aasdk::proto::enums::ButtonCode::PLAY);
|
this->insertButtonCode(iniConfig, cInputPlayButtonKey, aasdk::proto::enums::ButtonCode::PLAY);
|
||||||
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <boost/property_tree/ini_parser.hpp>
|
||||||
|
#include <f1x/openauto/Common/Log.hpp>
|
||||||
|
#include <f1x/openauto/autoapp/Configuration/RecentAddressesList.hpp>
|
||||||
|
|
||||||
|
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<size_t>(cRecentEntiresCount, 0));
|
||||||
|
|
||||||
|
for(size_t i = 0; i < listSize; ++i)
|
||||||
|
{
|
||||||
|
const auto key = cRecentEntryPrefix + std::to_string(i);
|
||||||
|
const auto address = iniConfig.get<RecentAddresses::value_type>(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<size_t>(cRecentEntiresCount, entiresCount);
|
||||||
|
|
||||||
|
for(size_t i = 0; i < entiresCount; ++i)
|
||||||
|
{
|
||||||
|
const auto key = cRecentEntryPrefix + std::to_string(i);
|
||||||
|
iniConfig.put<RecentAddresses::value_type>(key, list_.at(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::property_tree::ini_parser::write_ini(cConfigFileName, iniConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,6 +19,7 @@
|
||||||
#include <f1x/aasdk/USB/AOAPDevice.hpp>
|
#include <f1x/aasdk/USB/AOAPDevice.hpp>
|
||||||
#include <f1x/aasdk/Transport/SSLWrapper.hpp>
|
#include <f1x/aasdk/Transport/SSLWrapper.hpp>
|
||||||
#include <f1x/aasdk/Transport/USBTransport.hpp>
|
#include <f1x/aasdk/Transport/USBTransport.hpp>
|
||||||
|
#include <f1x/aasdk/Transport/TCPTransport.hpp>
|
||||||
#include <f1x/aasdk/Messenger/Cryptor.hpp>
|
#include <f1x/aasdk/Messenger/Cryptor.hpp>
|
||||||
#include <f1x/openauto/autoapp/Projection/AndroidAutoEntityFactory.hpp>
|
#include <f1x/openauto/autoapp/Projection/AndroidAutoEntityFactory.hpp>
|
||||||
#include <f1x/openauto/autoapp/Projection/AndroidAutoEntity.hpp>
|
#include <f1x/openauto/autoapp/Projection/AndroidAutoEntity.hpp>
|
||||||
|
@ -32,23 +33,30 @@ namespace autoapp
|
||||||
namespace projection
|
namespace projection
|
||||||
{
|
{
|
||||||
|
|
||||||
AndroidAutoEntityFactory::AndroidAutoEntityFactory(aasdk::usb::IUSBWrapper& usbWrapper,
|
AndroidAutoEntityFactory::AndroidAutoEntityFactory(boost::asio::io_service& ioService,
|
||||||
boost::asio::io_service& ioService,
|
|
||||||
configuration::IConfiguration::Pointer configuration,
|
configuration::IConfiguration::Pointer configuration,
|
||||||
IServiceFactory& serviceFactory)
|
IServiceFactory& serviceFactory)
|
||||||
: usbWrapper_(usbWrapper)
|
: ioService_(ioService)
|
||||||
, ioService_(ioService)
|
|
||||||
, configuration_(std::move(configuration))
|
, configuration_(std::move(configuration))
|
||||||
, serviceFactory_(serviceFactory)
|
, 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<aasdk::transport::USBTransport>(ioService_, std::move(aoapDevice)));
|
||||||
auto transport(std::make_shared<aasdk::transport::USBTransport>(ioService_, aoapDevice));
|
return create(std::move(transport));
|
||||||
|
}
|
||||||
|
|
||||||
|
IAndroidAutoEntity::Pointer AndroidAutoEntityFactory::create(aasdk::tcp::ITCPEndpoint::Pointer tcpEndpoint)
|
||||||
|
{
|
||||||
|
auto transport(std::make_shared<aasdk::transport::TCPTransport>(ioService_, std::move(tcpEndpoint)));
|
||||||
|
return create(std::move(transport));
|
||||||
|
}
|
||||||
|
|
||||||
|
IAndroidAutoEntity::Pointer AndroidAutoEntityFactory::create(aasdk::transport::ITransport::Pointer transport)
|
||||||
|
{
|
||||||
auto sslWrapper(std::make_shared<aasdk::transport::SSLWrapper>());
|
auto sslWrapper(std::make_shared<aasdk::transport::SSLWrapper>());
|
||||||
auto cryptor(std::make_shared<aasdk::messenger::Cryptor>(std::move(sslWrapper)));
|
auto cryptor(std::make_shared<aasdk::messenger::Cryptor>(std::move(sslWrapper)));
|
||||||
|
|
||||||
|
|
|
@ -93,6 +93,12 @@ void AudioService::onChannelOpenRequest(const aasdk::proto::messages::ChannelOpe
|
||||||
OPENAUTO_LOG(info) << "[AudioService] open request"
|
OPENAUTO_LOG(info) << "[AudioService] open request"
|
||||||
<< ", channel: " << aasdk::messenger::channelIdToString(channel_->getId())
|
<< ", channel: " << aasdk::messenger::channelIdToString(channel_->getId())
|
||||||
<< ", priority: " << request.priority();
|
<< ", 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;
|
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
|
OPENAUTO_LOG(info) << "[AudioService] open status: " << status
|
||||||
<< ", channel: " << aasdk::messenger::channelIdToString(channel_->getId());
|
<< ", channel: " << aasdk::messenger::channelIdToString(channel_->getId());
|
||||||
|
@ -146,14 +152,9 @@ void AudioService::onAVChannelStopIndication(const aasdk::proto::messages::AVCha
|
||||||
channel_->receive(this->shared_from_this());
|
channel_->receive(this->shared_from_this());
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioService::onAVMediaWithTimestampIndication(aasdk::messenger::Timestamp::ValueType, const aasdk::common::DataConstBuffer& buffer)
|
void AudioService::onAVMediaWithTimestampIndication(aasdk::messenger::Timestamp::ValueType timestamp, const aasdk::common::DataConstBuffer& buffer)
|
||||||
{
|
{
|
||||||
this->onAVMediaIndication(buffer);
|
audioOutput_->write(timestamp, buffer);
|
||||||
}
|
|
||||||
|
|
||||||
void AudioService::onAVMediaIndication(const aasdk::common::DataConstBuffer& buffer)
|
|
||||||
{
|
|
||||||
audioOutput_->write(buffer);
|
|
||||||
aasdk::proto::messages::AVMediaAckIndication indication;
|
aasdk::proto::messages::AVMediaAckIndication indication;
|
||||||
indication.set_session(session_);
|
indication.set_session(session_);
|
||||||
indication.set_value(1);
|
indication.set_value(1);
|
||||||
|
@ -164,6 +165,11 @@ void AudioService::onAVMediaIndication(const aasdk::common::DataConstBuffer& buf
|
||||||
channel_->receive(this->shared_from_this());
|
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)
|
void AudioService::onChannelError(const aasdk::error::Error& e)
|
||||||
{
|
{
|
||||||
OPENAUTO_LOG(error) << "[AudioService] channel error: " << e.what()
|
OPENAUTO_LOG(error) << "[AudioService] channel error: " << e.what()
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <f1x/openauto/autoapp/Projection/AudioInput.hpp>
|
#include <f1x/openauto/autoapp/Projection/QtAudioInput.hpp>
|
||||||
#include <f1x/openauto/Common/Log.hpp>
|
#include <f1x/openauto/Common/Log.hpp>
|
||||||
|
|
||||||
namespace f1x
|
namespace f1x
|
||||||
|
@ -29,7 +29,7 @@ namespace autoapp
|
||||||
namespace projection
|
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)
|
: ioDevice_(nullptr)
|
||||||
{
|
{
|
||||||
qRegisterMetaType<IAudioInput::StartPromise::Pointer>("StartPromise::Pointer");
|
qRegisterMetaType<IAudioInput::StartPromise::Pointer>("StartPromise::Pointer");
|
||||||
|
@ -42,32 +42,32 @@ AudioInput::AudioInput(uint32_t channelCount, uint32_t sampleSize, uint32_t samp
|
||||||
audioFormat_.setSampleType(QAudioFormat::SignedInt);
|
audioFormat_.setSampleType(QAudioFormat::SignedInt);
|
||||||
|
|
||||||
this->moveToThread(QApplication::instance()->thread());
|
this->moveToThread(QApplication::instance()->thread());
|
||||||
connect(this, &AudioInput::startRecording, this, &AudioInput::onStartRecording, Qt::QueuedConnection);
|
connect(this, &QtAudioInput::startRecording, this, &QtAudioInput::onStartRecording, Qt::QueuedConnection);
|
||||||
connect(this, &AudioInput::stopRecording, this, &AudioInput::onStopRecording, Qt::QueuedConnection);
|
connect(this, &QtAudioInput::stopRecording, this, &QtAudioInput::onStopRecording, Qt::QueuedConnection);
|
||||||
QMetaObject::invokeMethod(this, "createAudioInput", Qt::BlockingQueuedConnection);
|
QMetaObject::invokeMethod(this, "createAudioInput", Qt::BlockingQueuedConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioInput::createAudioInput()
|
void QtAudioInput::createAudioInput()
|
||||||
{
|
{
|
||||||
OPENAUTO_LOG(debug) << "[AudioInput] create.";
|
OPENAUTO_LOG(debug) << "[AudioInput] create.";
|
||||||
audioInput_ = (std::make_unique<QAudioInput>(QAudioDeviceInfo::defaultInputDevice(), audioFormat_));
|
audioInput_ = (std::make_unique<QAudioInput>(QAudioDeviceInfo::defaultInputDevice(), audioFormat_));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AudioInput::open()
|
bool QtAudioInput::open()
|
||||||
{
|
{
|
||||||
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
||||||
|
|
||||||
return ioDevice_ == nullptr;
|
return ioDevice_ == nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AudioInput::isActive() const
|
bool QtAudioInput::isActive() const
|
||||||
{
|
{
|
||||||
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
||||||
|
|
||||||
return ioDevice_ != nullptr;
|
return ioDevice_ != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioInput::read(ReadPromise::Pointer promise)
|
void QtAudioInput::read(ReadPromise::Pointer promise)
|
||||||
{
|
{
|
||||||
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
std::lock_guard<decltype(mutex_)> 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));
|
emit startRecording(std::move(promise));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioInput::stop()
|
void QtAudioInput::stop()
|
||||||
{
|
{
|
||||||
emit stopRecording();
|
emit stopRecording();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t AudioInput::getSampleSize() const
|
uint32_t QtAudioInput::getSampleSize() const
|
||||||
{
|
{
|
||||||
return audioFormat_.sampleSize();
|
return audioFormat_.sampleSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t AudioInput::getChannelCount() const
|
uint32_t QtAudioInput::getChannelCount() const
|
||||||
{
|
{
|
||||||
return audioFormat_.channelCount();
|
return audioFormat_.channelCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t AudioInput::getSampleRate() const
|
uint32_t QtAudioInput::getSampleRate() const
|
||||||
{
|
{
|
||||||
return audioFormat_.sampleRate();
|
return audioFormat_.sampleRate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioInput::onStartRecording(StartPromise::Pointer promise)
|
void QtAudioInput::onStartRecording(StartPromise::Pointer promise)
|
||||||
{
|
{
|
||||||
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
||||||
|
|
||||||
|
@ -118,7 +118,7 @@ void AudioInput::onStartRecording(StartPromise::Pointer promise)
|
||||||
|
|
||||||
if(ioDevice_ != nullptr)
|
if(ioDevice_ != nullptr)
|
||||||
{
|
{
|
||||||
connect(ioDevice_, &QIODevice::readyRead, this, &AudioInput::onReadyRead, Qt::QueuedConnection);
|
connect(ioDevice_, &QIODevice::readyRead, this, &QtAudioInput::onReadyRead, Qt::QueuedConnection);
|
||||||
promise->resolve();
|
promise->resolve();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -127,7 +127,7 @@ void AudioInput::onStartRecording(StartPromise::Pointer promise)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioInput::onStopRecording()
|
void QtAudioInput::onStopRecording()
|
||||||
{
|
{
|
||||||
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
||||||
|
|
||||||
|
@ -147,7 +147,7 @@ void AudioInput::onStopRecording()
|
||||||
audioInput_->stop();
|
audioInput_->stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioInput::onReadyRead()
|
void QtAudioInput::onReadyRead()
|
||||||
{
|
{
|
||||||
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <f1x/openauto/autoapp/Projection/AudioOutput.hpp>
|
#include <f1x/openauto/autoapp/Projection/QtAudioOutput.hpp>
|
||||||
#include <f1x/openauto/Common/Log.hpp>
|
#include <f1x/openauto/Common/Log.hpp>
|
||||||
|
|
||||||
namespace f1x
|
namespace f1x
|
||||||
|
@ -29,7 +29,7 @@ namespace autoapp
|
||||||
namespace projection
|
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)
|
: playbackStarted_(false)
|
||||||
{
|
{
|
||||||
audioFormat_.setChannelCount(channelCount);
|
audioFormat_.setChannelCount(channelCount);
|
||||||
|
@ -40,63 +40,60 @@ AudioOutput::AudioOutput(uint32_t channelCount, uint32_t sampleSize, uint32_t sa
|
||||||
audioFormat_.setSampleType(QAudioFormat::SignedInt);
|
audioFormat_.setSampleType(QAudioFormat::SignedInt);
|
||||||
|
|
||||||
this->moveToThread(QApplication::instance()->thread());
|
this->moveToThread(QApplication::instance()->thread());
|
||||||
connect(this, &AudioOutput::startPlayback, this, &AudioOutput::onStartPlayback);
|
connect(this, &QtAudioOutput::startPlayback, this, &QtAudioOutput::onStartPlayback);
|
||||||
connect(this, &AudioOutput::suspendPlayback, this, &AudioOutput::onSuspendPlayback);
|
connect(this, &QtAudioOutput::suspendPlayback, this, &QtAudioOutput::onSuspendPlayback);
|
||||||
connect(this, &AudioOutput::stopPlayback, this, &AudioOutput::onStopPlayback);
|
connect(this, &QtAudioOutput::stopPlayback, this, &QtAudioOutput::onStopPlayback);
|
||||||
|
|
||||||
QMetaObject::invokeMethod(this, "createAudioOutput", Qt::BlockingQueuedConnection);
|
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<QAudioOutput>(QAudioDeviceInfo::defaultOutputDevice(), audioFormat_);
|
audioOutput_ = std::make_unique<QAudioOutput>(QAudioDeviceInfo::defaultOutputDevice(), audioFormat_);
|
||||||
|
|
||||||
// Default volume level (max) produces crackles
|
|
||||||
audioOutput_->setVolume(static_cast<qreal>(0.90));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AudioOutput::open()
|
bool QtAudioOutput::open()
|
||||||
{
|
{
|
||||||
return audioBuffer_.open(QIODevice::ReadWrite);
|
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<const char*>(buffer.cdata), buffer.size);
|
audioBuffer_.write(reinterpret_cast<const char*>(buffer.cdata), buffer.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioOutput::start()
|
void QtAudioOutput::start()
|
||||||
{
|
{
|
||||||
emit startPlayback();
|
emit startPlayback();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioOutput::stop()
|
void QtAudioOutput::stop()
|
||||||
{
|
{
|
||||||
emit stopPlayback();
|
emit stopPlayback();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioOutput::suspend()
|
void QtAudioOutput::suspend()
|
||||||
{
|
{
|
||||||
emit suspendPlayback();
|
emit suspendPlayback();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t AudioOutput::getSampleSize() const
|
uint32_t QtAudioOutput::getSampleSize() const
|
||||||
{
|
{
|
||||||
return audioFormat_.sampleSize();
|
return audioFormat_.sampleSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t AudioOutput::getChannelCount() const
|
uint32_t QtAudioOutput::getChannelCount() const
|
||||||
{
|
{
|
||||||
return audioFormat_.channelCount();
|
return audioFormat_.channelCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t AudioOutput::getSampleRate() const
|
uint32_t QtAudioOutput::getSampleRate() const
|
||||||
{
|
{
|
||||||
return audioFormat_.sampleRate();
|
return audioFormat_.sampleRate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioOutput::onStartPlayback()
|
void QtAudioOutput::onStartPlayback()
|
||||||
{
|
{
|
||||||
if(!playbackStarted_)
|
if(!playbackStarted_)
|
||||||
{
|
{
|
||||||
|
@ -109,12 +106,12 @@ void AudioOutput::onStartPlayback()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioOutput::onSuspendPlayback()
|
void QtAudioOutput::onSuspendPlayback()
|
||||||
{
|
{
|
||||||
audioOutput_->suspend();
|
audioOutput_->suspend();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioOutput::onStopPlayback()
|
void QtAudioOutput::onStopPlayback()
|
||||||
{
|
{
|
||||||
if(playbackStarted_)
|
if(playbackStarted_)
|
||||||
{
|
{
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <f1x/openauto/autoapp/Projection/RtAudioOutput.hpp>
|
||||||
|
#include <f1x/openauto/Common/Log.hpp>
|
||||||
|
|
||||||
|
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<RtAudio::Api> apis;
|
||||||
|
RtAudio::getCompiledApi(apis);
|
||||||
|
dac_ = std::find(apis.begin(), apis.end(), RtAudio::LINUX_PULSE) == apis.end() ? std::make_unique<RtAudio>() : std::make_unique<RtAudio>(RtAudio::LINUX_PULSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RtAudioOutput::open()
|
||||||
|
{
|
||||||
|
std::lock_guard<decltype(mutex_)> 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<void*>(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<const char*>(buffer.cdata), buffer.size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RtAudioOutput::start()
|
||||||
|
{
|
||||||
|
std::lock_guard<decltype(mutex_)> 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<decltype(mutex_)> 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<RtAudioOutput*>(userData);
|
||||||
|
std::lock_guard<decltype(self->mutex_)> lock(self->mutex_);
|
||||||
|
|
||||||
|
const auto bufferSize = nBufferFrames * (self->sampleSize_ / 8) * self->channelCount_;
|
||||||
|
self->audioBuffer_.read(reinterpret_cast<char*>(outputBuffer), bufferSize);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -55,7 +55,8 @@ qint64 SequentialBuffer::readData(char *data, qint64 maxlen)
|
||||||
|
|
||||||
const auto len = std::min<size_t>(maxlen, data_.size());
|
const auto len = std::min<size_t>(maxlen, data_.size());
|
||||||
std::copy(data_.begin(), data_.begin() + len, data);
|
std::copy(data_.begin(), data_.begin() + len, data);
|
||||||
data_.erase(data_.begin(), data_.begin() + len);
|
data_.erase_begin(len);
|
||||||
|
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,8 +32,9 @@
|
||||||
#include <f1x/openauto/autoapp/Projection/InputService.hpp>
|
#include <f1x/openauto/autoapp/Projection/InputService.hpp>
|
||||||
#include <f1x/openauto/autoapp/Projection/QtVideoOutput.hpp>
|
#include <f1x/openauto/autoapp/Projection/QtVideoOutput.hpp>
|
||||||
#include <f1x/openauto/autoapp/Projection/OMXVideoOutput.hpp>
|
#include <f1x/openauto/autoapp/Projection/OMXVideoOutput.hpp>
|
||||||
#include <f1x/openauto/autoapp/Projection/AudioOutput.hpp>
|
#include <f1x/openauto/autoapp/Projection/RtAudioOutput.hpp>
|
||||||
#include <f1x/openauto/autoapp/Projection/AudioInput.hpp>
|
#include <f1x/openauto/autoapp/Projection/QtAudioOutput.hpp>
|
||||||
|
#include <f1x/openauto/autoapp/Projection/QtAudioInput.hpp>
|
||||||
#include <f1x/openauto/autoapp/Projection/InputDevice.hpp>
|
#include <f1x/openauto/autoapp/Projection/InputDevice.hpp>
|
||||||
#include <f1x/openauto/autoapp/Projection/LocalBluetoothDevice.hpp>
|
#include <f1x/openauto/autoapp/Projection/LocalBluetoothDevice.hpp>
|
||||||
#include <f1x/openauto/autoapp/Projection/RemoteBluetoothDevice.hpp>
|
#include <f1x/openauto/autoapp/Projection/RemoteBluetoothDevice.hpp>
|
||||||
|
@ -59,24 +60,9 @@ ServiceList ServiceFactory::create(aasdk::messenger::IMessenger::Pointer messeng
|
||||||
{
|
{
|
||||||
ServiceList serviceList;
|
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<AudioInputService>(ioService_, messenger, std::move(audioInput)));
|
serviceList.emplace_back(std::make_shared<AudioInputService>(ioService_, messenger, std::move(audioInput)));
|
||||||
|
this->createAudioServices(serviceList, messenger);
|
||||||
if(configuration_->musicAudioChannelEnabled())
|
|
||||||
{
|
|
||||||
IAudioOutput::Pointer mediaAudioOutput(new AudioOutput(2, 16, 48000), std::bind(&QObject::deleteLater, std::placeholders::_1));
|
|
||||||
serviceList.emplace_back(std::make_shared<MediaAudioService>(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<SpeechAudioService>(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<SystemAudioService>(ioService_, messenger, std::move(systemAudioOutput)));
|
|
||||||
|
|
||||||
serviceList.emplace_back(std::make_shared<SensorService>(ioService_, messenger));
|
serviceList.emplace_back(std::make_shared<SensorService>(ioService_, messenger));
|
||||||
serviceList.emplace_back(this->createVideoService(messenger));
|
serviceList.emplace_back(this->createVideoService(messenger));
|
||||||
serviceList.emplace_back(this->createBluetoothService(messenger));
|
serviceList.emplace_back(this->createBluetoothService(messenger));
|
||||||
|
@ -141,6 +127,33 @@ IService::Pointer ServiceFactory::createInputService(aasdk::messenger::IMessenge
|
||||||
return std::make_shared<InputService>(ioService_, messenger, std::move(inputDevice));
|
return std::make_shared<InputService>(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<RtAudioOutput>(2, 16, 48000) :
|
||||||
|
IAudioOutput::Pointer(new QtAudioOutput(2, 16, 48000), std::bind(&QObject::deleteLater, std::placeholders::_1));
|
||||||
|
|
||||||
|
serviceList.emplace_back(std::make_shared<MediaAudioService>(ioService_, messenger, std::move(mediaAudioOutput)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(configuration_->speechAudioChannelEnabled())
|
||||||
|
{
|
||||||
|
auto speechAudioOutput = configuration_->getAudioOutputBackendType() == configuration::AudioOutputBackendType::RTAUDIO ?
|
||||||
|
std::make_shared<RtAudioOutput>(1, 16, 16000) :
|
||||||
|
IAudioOutput::Pointer(new QtAudioOutput(1, 16, 16000), std::bind(&QObject::deleteLater, std::placeholders::_1));
|
||||||
|
|
||||||
|
serviceList.emplace_back(std::make_shared<SpeechAudioService>(ioService_, messenger, std::move(speechAudioOutput)));
|
||||||
|
}
|
||||||
|
|
||||||
|
auto systemAudioOutput = configuration_->getAudioOutputBackendType() == configuration::AudioOutputBackendType::RTAUDIO ?
|
||||||
|
std::make_shared<RtAudioOutput>(1, 16, 16000) :
|
||||||
|
IAudioOutput::Pointer(new QtAudioOutput(1, 16, 16000), std::bind(&QObject::deleteLater, std::placeholders::_1));
|
||||||
|
|
||||||
|
serviceList.emplace_back(std::make_shared<SystemAudioService>(ioService_, messenger, std::move(systemAudioOutput)));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,11 @@ size_t VideoOutput::getScreenDPI() const
|
||||||
return configuration_->getScreenDPI();
|
return configuration_->getScreenDPI();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QRect VideoOutput::getVideoMargins() const
|
||||||
|
{
|
||||||
|
return configuration_->getVideoMargins();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -144,8 +144,10 @@ void VideoService::fillFeatures(aasdk::proto::messages::ServiceDiscoveryResponse
|
||||||
auto* videoConfig1 = videoChannel->add_video_configs();
|
auto* videoConfig1 = videoChannel->add_video_configs();
|
||||||
videoConfig1->set_video_resolution(videoOutput_->getVideoResolution());
|
videoConfig1->set_video_resolution(videoOutput_->getVideoResolution());
|
||||||
videoConfig1->set_video_fps(videoOutput_->getVideoFPS());
|
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());
|
videoConfig1->set_dpi(videoOutput_->getScreenDPI());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,125 @@
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <f1x/openauto/autoapp/UI/ConnectDialog.hpp>
|
||||||
|
#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>("aasdk::tcp::ITCPEndpoint::SocketPointer");
|
||||||
|
qRegisterMetaType<std::string>("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<boost::asio::ip::tcp::socket>(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<size_t>(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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -37,6 +37,7 @@ MainWindow::MainWindow(QWidget *parent)
|
||||||
connect(ui_->pushButtonSettings, &QPushButton::clicked, this, &MainWindow::openSettings);
|
connect(ui_->pushButtonSettings, &QPushButton::clicked, this, &MainWindow::openSettings);
|
||||||
connect(ui_->pushButtonExit, &QPushButton::clicked, this, &MainWindow::exit);
|
connect(ui_->pushButtonExit, &QPushButton::clicked, this, &MainWindow::exit);
|
||||||
connect(ui_->pushButtonToggleCursor, &QPushButton::clicked, this, &MainWindow::toggleCursor);
|
connect(ui_->pushButtonToggleCursor, &QPushButton::clicked, this, &MainWindow::toggleCursor);
|
||||||
|
connect(ui_->pushButtonWirelessConnection, &QPushButton::clicked, this, &MainWindow::openConnectDialog);
|
||||||
}
|
}
|
||||||
|
|
||||||
MainWindow::~MainWindow()
|
MainWindow::~MainWindow()
|
||||||
|
|
|
@ -73,6 +73,10 @@ void SettingsWindow::onSave()
|
||||||
|
|
||||||
configuration_->setScreenDPI(static_cast<size_t>(ui_->horizontalSliderScreenDPI->value()));
|
configuration_->setScreenDPI(static_cast<size_t>(ui_->horizontalSliderScreenDPI->value()));
|
||||||
configuration_->setOMXLayerIndex(ui_->spinBoxOmxLayerIndex->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());
|
configuration_->setTouchscreenEnabled(ui_->checkBoxEnableTouchscreen->isChecked());
|
||||||
this->saveButtonCheckBoxes();
|
this->saveButtonCheckBoxes();
|
||||||
|
|
||||||
|
@ -93,6 +97,7 @@ void SettingsWindow::onSave()
|
||||||
|
|
||||||
configuration_->setMusicAudioChannelEnabled(ui_->checkBoxMusicAudioChannel->isChecked());
|
configuration_->setMusicAudioChannelEnabled(ui_->checkBoxMusicAudioChannel->isChecked());
|
||||||
configuration_->setSpeechAudioChannelEnabled(ui_->checkBoxSpeechAudioChannel->isChecked());
|
configuration_->setSpeechAudioChannelEnabled(ui_->checkBoxSpeechAudioChannel->isChecked());
|
||||||
|
configuration_->setAudioOutputBackendType(ui_->radioButtonRtAudio->isChecked() ? configuration::AudioOutputBackendType::RTAUDIO : configuration::AudioOutputBackendType::QT);
|
||||||
|
|
||||||
configuration_->save();
|
configuration_->save();
|
||||||
this->close();
|
this->close();
|
||||||
|
@ -130,6 +135,10 @@ void SettingsWindow::load()
|
||||||
ui_->horizontalSliderScreenDPI->setValue(static_cast<int>(configuration_->getScreenDPI()));
|
ui_->horizontalSliderScreenDPI->setValue(static_cast<int>(configuration_->getScreenDPI()));
|
||||||
ui_->spinBoxOmxLayerIndex->setValue(configuration_->getOMXLayerIndex());
|
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());
|
ui_->checkBoxEnableTouchscreen->setChecked(configuration_->getTouchscreenEnabled());
|
||||||
this->loadButtonCheckBoxes();
|
this->loadButtonCheckBoxes();
|
||||||
|
|
||||||
|
@ -141,6 +150,10 @@ void SettingsWindow::load()
|
||||||
|
|
||||||
ui_->checkBoxMusicAudioChannel->setChecked(configuration_->musicAudioChannelEnabled());
|
ui_->checkBoxMusicAudioChannel->setChecked(configuration_->musicAudioChannelEnabled());
|
||||||
ui_->checkBoxSpeechAudioChannel->setChecked(configuration_->speechAudioChannelEnabled());
|
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()
|
void SettingsWindow::loadButtonCheckBoxes()
|
||||||
|
|
|
@ -0,0 +1,160 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>ConnectDialog</class>
|
||||||
|
<widget class="QDialog" name="ConnectDialog">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>301</width>
|
||||||
|
<height>389</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Connect to device</string>
|
||||||
|
</property>
|
||||||
|
<widget class="QGroupBox" name="groupBoxIPAddress">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>10</x>
|
||||||
|
<y>10</y>
|
||||||
|
<width>281</width>
|
||||||
|
<height>61</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="title">
|
||||||
|
<string>IP Address</string>
|
||||||
|
</property>
|
||||||
|
<widget class="QLineEdit" name="lineEditIPAddress">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>10</x>
|
||||||
|
<y>30</y>
|
||||||
|
<width>261</width>
|
||||||
|
<height>25</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
<widget class="QGroupBox" name="groupBoxRecent">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>10</x>
|
||||||
|
<y>80</y>
|
||||||
|
<width>281</width>
|
||||||
|
<height>181</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="title">
|
||||||
|
<string>Recent</string>
|
||||||
|
</property>
|
||||||
|
<widget class="QListView" name="listViewRecent">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>10</x>
|
||||||
|
<y>30</y>
|
||||||
|
<width>261</width>
|
||||||
|
<height>141</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="editTriggers">
|
||||||
|
<set>QAbstractItemView::NoEditTriggers</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
<widget class="QLabel" name="labelHeadUnitServerInfo">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>60</x>
|
||||||
|
<y>260</y>
|
||||||
|
<width>221</width>
|
||||||
|
<height>81</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string><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></string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QLabel" name="labelCopyrightsInfoIcon">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>20</x>
|
||||||
|
<y>290</y>
|
||||||
|
<width>21</width>
|
||||||
|
<height>21</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string><html><head/><body><p><img src=":/ico_info.png"/></p></body></html></string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QPushButton" name="pushButtonCancel">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>40</x>
|
||||||
|
<y>340</y>
|
||||||
|
<width>121</width>
|
||||||
|
<height>41</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Cancel</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QPushButton" name="pushButtonConnect">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>170</x>
|
||||||
|
<y>340</y>
|
||||||
|
<width>121</width>
|
||||||
|
<height>41</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Connect</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QProgressBar" name="progressBarConnect">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>170</x>
|
||||||
|
<y>340</y>
|
||||||
|
<width>121</width>
|
||||||
|
<height>41</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QLabel" name="labelConnecting">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>188</x>
|
||||||
|
<y>350</y>
|
||||||
|
<width>91</width>
|
||||||
|
<height>20</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Connecting...</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<zorder>groupBoxIPAddress</zorder>
|
||||||
|
<zorder>groupBoxRecent</zorder>
|
||||||
|
<zorder>labelHeadUnitServerInfo</zorder>
|
||||||
|
<zorder>labelCopyrightsInfoIcon</zorder>
|
||||||
|
<zorder>pushButtonCancel</zorder>
|
||||||
|
<zorder>progressBarConnect</zorder>
|
||||||
|
<zorder>labelConnecting</zorder>
|
||||||
|
<zorder>pushButtonConnect</zorder>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
|
@ -48,7 +48,7 @@ color: rgb(238, 238, 236);</string>
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>630</x>
|
<x>630</x>
|
||||||
<y>340</y>
|
<y>370</y>
|
||||||
<width>161</width>
|
<width>161</width>
|
||||||
<height>41</height>
|
<height>41</height>
|
||||||
</rect>
|
</rect>
|
||||||
|
@ -67,7 +67,7 @@ color: rgb(238, 238, 236);</string>
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>630</x>
|
<x>630</x>
|
||||||
<y>390</y>
|
<y>420</y>
|
||||||
<width>161</width>
|
<width>161</width>
|
||||||
<height>41</height>
|
<height>41</height>
|
||||||
</rect>
|
</rect>
|
||||||
|
@ -79,7 +79,7 @@ color: rgb(238, 238, 236);</string>
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QLabel" name="label_2">
|
<widget class="QLabel" name="labelPluginDeviceText">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>340</x>
|
<x>340</x>
|
||||||
|
@ -92,11 +92,11 @@ color: rgb(238, 238, 236);</string>
|
||||||
<string><html><head/><body><p><span style=" font-style:italic; color:#eeeeec;">Plug in your device to start AndroidAuto (tm).</span></p></body></html></string>
|
<string><html><head/><body><p><span style=" font-style:italic; color:#eeeeec;">Plug in your device to start AndroidAuto (tm).</span></p></body></html></string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QLabel" name="label_3">
|
<widget class="QLabel" name="labelProjectHomePage">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>10</x>
|
<x>10</x>
|
||||||
<y>410</y>
|
<y>440</y>
|
||||||
<width>271</width>
|
<width>271</width>
|
||||||
<height>21</height>
|
<height>21</height>
|
||||||
</rect>
|
</rect>
|
||||||
|
@ -167,20 +167,20 @@ color: rgb(238, 238, 236);</string>
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>220</x>
|
<x>220</x>
|
||||||
<y>376</y>
|
<y>400</y>
|
||||||
<width>21</width>
|
<width>21</width>
|
||||||
<height>21</height>
|
<height>31</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string><html><head/><body><p><img src=":/ico_info.png"/></p></body></html></string>
|
<string><html><head/><body><p><img src=":/ico_info.png"/></p></body></html></string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QLabel" name="label_4">
|
<widget class="QLabel" name="labelTrademark">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>250</x>
|
<x>250</x>
|
||||||
<y>370</y>
|
<y>400</y>
|
||||||
<width>361</width>
|
<width>361</width>
|
||||||
<height>31</height>
|
<height>31</height>
|
||||||
</rect>
|
</rect>
|
||||||
|
@ -193,7 +193,7 @@ color: rgb(238, 238, 236);</string>
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>630</x>
|
<x>630</x>
|
||||||
<y>290</y>
|
<y>270</y>
|
||||||
<width>161</width>
|
<width>161</width>
|
||||||
<height>41</height>
|
<height>41</height>
|
||||||
</rect>
|
</rect>
|
||||||
|
@ -208,21 +208,30 @@ color: rgb(238, 238, 236);</string>
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</widget>
|
<widget class="QPushButton" name="pushButtonWirelessConnection">
|
||||||
<widget class="QMenuBar" name="menubar">
|
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>630</x>
|
||||||
<y>0</y>
|
<y>320</y>
|
||||||
<width>800</width>
|
<width>161</width>
|
||||||
<height>22</height>
|
<height>41</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Wireless connection</string>
|
||||||
|
</property>
|
||||||
|
<property name="autoDefault">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="default">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QStatusBar" name="statusbar"/>
|
|
||||||
</widget>
|
</widget>
|
||||||
<tabstops>
|
<tabstops>
|
||||||
<tabstop>pushButtonToggleCursor</tabstop>
|
<tabstop>pushButtonToggleCursor</tabstop>
|
||||||
|
<tabstop>pushButtonWirelessConnection</tabstop>
|
||||||
<tabstop>pushButtonSettings</tabstop>
|
<tabstop>pushButtonSettings</tabstop>
|
||||||
<tabstop>pushButtonExit</tabstop>
|
<tabstop>pushButtonExit</tabstop>
|
||||||
</tabstops>
|
</tabstops>
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Form</string>
|
<string>Settings</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="styleSheet">
|
<property name="styleSheet">
|
||||||
<string notr="true">background-color: rgb(46, 52, 54);
|
<string notr="true">background-color: rgb(46, 52, 54);
|
||||||
|
@ -260,48 +260,6 @@ color: rgb(238, 238, 236);</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QSlider" name="horizontalSliderScreenDPI">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>20</x>
|
|
||||||
<y>390</y>
|
|
||||||
<width>531</width>
|
|
||||||
<height>31</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="maximum">
|
|
||||||
<number>400</number>
|
|
||||||
</property>
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
<widget class="QLabel" name="labelScreenDPI">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>20</x>
|
|
||||||
<y>360</y>
|
|
||||||
<width>91</width>
|
|
||||||
<height>17</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Screen DPI</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
<widget class="QLabel" name="labelScreenDPIValue">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>570</x>
|
|
||||||
<y>380</y>
|
|
||||||
<width>41</width>
|
|
||||||
<height>51</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>400</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
<widget class="QGroupBox" name="groupBoxOmxLayerIndex">
|
<widget class="QGroupBox" name="groupBoxOmxLayerIndex">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
|
@ -312,7 +270,7 @@ color: rgb(238, 238, 236);</string>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>OMX Layer index</string>
|
<string>Display</string>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QLabel" name="labelOmxLayerIndex">
|
<widget class="QLabel" name="labelOmxLayerIndex">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
|
@ -363,6 +321,100 @@ color: rgb(238, 238, 236);</string>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
|
<widget class="QLabel" name="labelVideoMarginWidth">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>200</x>
|
||||||
|
<y>40</y>
|
||||||
|
<width>101</width>
|
||||||
|
<height>21</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Margin width:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QSpinBox" name="spinBoxVideoMarginWidth">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>310</x>
|
||||||
|
<y>30</y>
|
||||||
|
<width>71</width>
|
||||||
|
<height>41</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>99999</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QLabel" name="labelVideoMarginHeight">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>410</x>
|
||||||
|
<y>40</y>
|
||||||
|
<width>111</width>
|
||||||
|
<height>21</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Margin height:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QSpinBox" name="spinBoxVideoMarginHeight">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>520</x>
|
||||||
|
<y>30</y>
|
||||||
|
<width>71</width>
|
||||||
|
<height>41</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>99999</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
<widget class="QGroupBox" name="groupBoxScreenDPI">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>360</y>
|
||||||
|
<width>621</width>
|
||||||
|
<height>81</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="title">
|
||||||
|
<string>Screen DPI</string>
|
||||||
|
</property>
|
||||||
|
<widget class="QLabel" name="labelScreenDPIValue">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>570</x>
|
||||||
|
<y>40</y>
|
||||||
|
<width>41</width>
|
||||||
|
<height>31</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>400</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QSlider" name="horizontalSliderScreenDPI">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>20</x>
|
||||||
|
<y>40</y>
|
||||||
|
<width>531</width>
|
||||||
|
<height>31</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>400</number>
|
||||||
|
</property>
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QWidget" name="tabAudio">
|
<widget class="QWidget" name="tabAudio">
|
||||||
|
@ -434,6 +486,45 @@ color: rgb(238, 238, 236);</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
|
<widget class="QGroupBox" name="groupBoxAudioOutputBackend">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>130</y>
|
||||||
|
<width>621</width>
|
||||||
|
<height>61</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="title">
|
||||||
|
<string>Output backend</string>
|
||||||
|
</property>
|
||||||
|
<widget class="QRadioButton" name="radioButtonRtAudio">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>10</x>
|
||||||
|
<y>30</y>
|
||||||
|
<width>112</width>
|
||||||
|
<height>23</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>RT audio</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QRadioButton" name="radioButtonQtAudio">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>140</x>
|
||||||
|
<y>30</y>
|
||||||
|
<width>112</width>
|
||||||
|
<height>23</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Qt</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QWidget" name="tabInput">
|
<widget class="QWidget" name="tabInput">
|
||||||
<attribute name="title">
|
<attribute name="title">
|
||||||
|
@ -912,9 +1003,13 @@ color: rgb(238, 238, 236);</string>
|
||||||
<tabstop>radioButton720p</tabstop>
|
<tabstop>radioButton720p</tabstop>
|
||||||
<tabstop>radioButton1080p</tabstop>
|
<tabstop>radioButton1080p</tabstop>
|
||||||
<tabstop>spinBoxOmxLayerIndex</tabstop>
|
<tabstop>spinBoxOmxLayerIndex</tabstop>
|
||||||
|
<tabstop>spinBoxVideoMarginWidth</tabstop>
|
||||||
|
<tabstop>spinBoxVideoMarginHeight</tabstop>
|
||||||
<tabstop>horizontalSliderScreenDPI</tabstop>
|
<tabstop>horizontalSliderScreenDPI</tabstop>
|
||||||
<tabstop>checkBoxMusicAudioChannel</tabstop>
|
<tabstop>checkBoxMusicAudioChannel</tabstop>
|
||||||
<tabstop>checkBoxSpeechAudioChannel</tabstop>
|
<tabstop>checkBoxSpeechAudioChannel</tabstop>
|
||||||
|
<tabstop>radioButtonRtAudio</tabstop>
|
||||||
|
<tabstop>radioButtonQtAudio</tabstop>
|
||||||
<tabstop>checkBoxEnableTouchscreen</tabstop>
|
<tabstop>checkBoxEnableTouchscreen</tabstop>
|
||||||
<tabstop>listWidgetButtons</tabstop>
|
<tabstop>listWidgetButtons</tabstop>
|
||||||
<tabstop>checkBoxPlayButton</tabstop>
|
<tabstop>checkBoxPlayButton</tabstop>
|
||||||
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <thread>
|
|
||||||
#include <f1x/openauto/autoapp/USB/USBApp.hpp>
|
|
||||||
#include <f1x/openauto/Common/Log.hpp>
|
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <QApplication>
|
|
||||||
#include <QMainWindow>
|
|
||||||
#include <f1x/aasdk/USB/USBHub.hpp>
|
|
||||||
#include <f1x/openauto/autoapp/Configuration/Configuration.hpp>
|
|
||||||
#include <f1x/openauto/autoapp/UI/MainWindow.hpp>
|
|
||||||
#include <f1x/openauto/autoapp/UI/SettingsWindow.hpp>
|
|
||||||
#include <f1x/openauto/autoapp/USB/USBMain.hpp>
|
|
||||||
|
|
||||||
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<configuration::Configuration>())
|
|
||||||
, serviceFactory_(ioService_, configuration_)
|
|
||||||
, androidAutoEntityFactory_(usbWrapper_, ioService_, configuration_, serviceFactory_)
|
|
||||||
{
|
|
||||||
aasdk::usb::IUSBHub::Pointer usbHub(std::make_shared<aasdk::usb::USBHub>(usbWrapper_, ioService_, queryChainFactory_));
|
|
||||||
usbApp_ = std::make_shared<autoapp::usb::USBApp>(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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <thread>
|
||||||
|
#include <QApplication>
|
||||||
|
#include <f1x/aasdk/USB/USBHub.hpp>
|
||||||
|
#include <f1x/aasdk/USB/ConnectedAccessoriesEnumerator.hpp>
|
||||||
|
#include <f1x/aasdk/USB/AccessoryModeQueryChain.hpp>
|
||||||
|
#include <f1x/aasdk/USB/AccessoryModeQueryChainFactory.hpp>
|
||||||
|
#include <f1x/aasdk/USB/AccessoryModeQueryFactory.hpp>
|
||||||
|
#include <f1x/aasdk/TCP/TCPWrapper.hpp>
|
||||||
|
#include <f1x/openauto/autoapp/App.hpp>
|
||||||
|
#include <f1x/openauto/autoapp/Configuration/IConfiguration.hpp>
|
||||||
|
#include <f1x/openauto/autoapp/Configuration/RecentAddressesList.hpp>
|
||||||
|
#include <f1x/openauto/autoapp/Projection/AndroidAutoEntityFactory.hpp>
|
||||||
|
#include <f1x/openauto/autoapp/Projection/ServiceFactory.hpp>
|
||||||
|
#include <f1x/openauto/autoapp/Configuration/Configuration.hpp>
|
||||||
|
#include <f1x/openauto/autoapp/UI/MainWindow.hpp>
|
||||||
|
#include <f1x/openauto/autoapp/UI/SettingsWindow.hpp>
|
||||||
|
#include <f1x/openauto/autoapp/UI/ConnectDialog.hpp>
|
||||||
|
#include <f1x/openauto/Common/Log.hpp>
|
||||||
|
|
||||||
|
namespace aasdk = f1x::aasdk;
|
||||||
|
namespace autoapp = f1x::openauto::autoapp;
|
||||||
|
using ThreadPool = std::vector<std::thread>;
|
||||||
|
|
||||||
|
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<std::thread> 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::configuration::Configuration>();
|
||||||
|
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<aasdk::usb::USBHub>(usbWrapper, ioService, queryChainFactory));
|
||||||
|
auto connectedAccessoriesEnumerator(std::make_shared<aasdk::usb::ConnectedAccessoriesEnumerator>(usbWrapper, ioService, queryChainFactory));
|
||||||
|
auto app = std::make_shared<autoapp::App>(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;
|
||||||
|
}
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <f1x/openauto/Common/Log.hpp>
|
||||||
|
#include <f1x/openauto/btservice/AndroidBluetoothServer.hpp>
|
||||||
|
|
||||||
|
namespace f1x
|
||||||
|
{
|
||||||
|
namespace openauto
|
||||||
|
{
|
||||||
|
namespace btservice
|
||||||
|
{
|
||||||
|
|
||||||
|
AndroidBluetoothServer::AndroidBluetoothServer()
|
||||||
|
: rfcommServer_(std::make_unique<QBluetoothServer>(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.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <f1x/openauto/btservice/AndroidBluetoothService.hpp>
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
#include <f1x/openauto/Common/Log.hpp>
|
||||||
|
#include <f1x/openauto/btservice/AndroidBluetoothService.hpp>
|
||||||
|
#include <f1x/openauto/btservice/AndroidBluetoothServer.hpp>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
Loading…
Reference in New Issue