Initial commit

pull/10/head
michal.szwaj 2018-02-11 20:39:49 +01:00
commit 02db0e0eda
82 changed files with 7384 additions and 0 deletions

4
.gitignore vendored 100644
View File

@ -0,0 +1,4 @@
# Add any directories, files, or patterns you don't want to be tracked by version control
lib/
bin/
CMakeLists.txt.user

73
CMakeLists.txt 100644
View File

@ -0,0 +1,73 @@
cmake_minimum_required(VERSION 3.5.1)
project(openauto CXX)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTORCC ON)
set(base_directory ${CMAKE_CURRENT_SOURCE_DIR})
set(resources_directory ${base_directory}/assets)
set(sources_directory ${base_directory}/src)
set(include_directory ${base_directory}/include)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${base_directory}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${base_directory}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${base_directory}/bin)
set(EXECUTABLE_OUTPUT_PATH ${base_directory}/bin)
set(Boost_USE_STATIC_LIBS OFF)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake_modules/")
SET(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS_INIT} -Wall -pedantic -fPIC")
set(CMAKE_CXX_FLAGS_DEBUG "-g -O0")
set(CMAKE_CXX_FLAGS_RELEASE "-g -O3")
add_definitions(-DBOOST_ALL_DYN_LINK)
find_package(Boost REQUIRED COMPONENTS system log OPTIONAL_COMPONENTS unit_test_framework)
find_package(libusb-1.0 REQUIRED)
find_package(Qt5 COMPONENTS Multimedia MultimediaWidgets Bluetooth)
find_package(Protobuf REQUIRED)
if(RPI3_BUILD)
add_definitions(-DUSE_OMX -DOMX_SKIP64BIT)
set(BCM_HOST_LIBRARIES "/opt/vc/lib/libbcm_host.so")
set(BCM_HOST_INCLUDE_DIRS "/opt/vc/include")
set(ILCLIENT_INCLUDE_DIRS "/opt/vc/src/hello_pi/libs/ilclient")
set(ILCLIENT_LIBRARIES "/opt/vc/src/hello_pi/libs/ilclient/libilclient.a;/opt/vc/lib/libvcos.so;/opt/vc/lib/libvcilcs.a;/opt/vc/lib/libvchiq_arm.so")
endif(RPI3_BUILD)
include_directories(${CMAKE_CURRENT_BINARY_DIR}
${Qt5Multimedia_INCLUDE_DIRS}
${Qt5MultimediaWidgets_INCLUDE_DIRS}
${Qt5Widgets_INCLUDE_DIRS}
${Qt5Bluetooth_INCLUDE_DIRS}
${Boost_INCLUDE_DIRS}
${LIBUSB_1_INCLUDE_DIRS}
${PROTOBUF_INCLUDE_DIR}
${AASDK_PROTO_INCLUDE_DIRS}
${AASDK_INCLUDE_DIRS}
${BCM_HOST_INCLUDE_DIRS}
${ILCLIENT_INCLUDE_DIRS}
${include_directory})
link_directories(${CMAKE_LIBRARY_OUTPUT_DIRECTORY})
set(autoapp_sources_directory ${sources_directory}/autoapp)
file(GLOB_RECURSE source_files ${autoapp_sources_directory}/*.ui ${autoapp_sources_directory}/*.cpp ${include_directory}/*.hpp ${resources_directory}/*.qrc)
add_executable(autoapp ${source_files})
target_link_libraries(autoapp
${Boost_LIBRARIES}
${Qt5Multimedia_LIBRARIES}
${Qt5MultimediaWidgets_LIBRARIES}
${Qt5Bluetooth_LIBRARIES}
${LIBUSB_1_LIBRARIES}
${PROTOBUF_LIBRARIES}
${BCM_HOST_LIBRARIES}
${ILCLIENT_LIBRARIES}
${AASDK_PROTO_LIBRARIES}
${AASDK_LIBRARIES})

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

BIN
assets/ico_info.png 100755

Binary file not shown.

After

Width:  |  Height:  |  Size: 438 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 751 B

View File

@ -0,0 +1,8 @@
<RCC>
<qresource prefix="/">
<file>ico_androidauto.png</file>
<file>ico_warning.png</file>
<file>ico_setting.png</file>
<file>ico_info.png</file>
</qresource>
</RCC>

View File

@ -0,0 +1,98 @@
# - Try to find libusb-1.0
# Once done this will define
#
# LIBUSB_1_FOUND - system has libusb
# LIBUSB_1_INCLUDE_DIRS - the libusb include directory
# LIBUSB_1_LIBRARIES - Link these to use libusb
# LIBUSB_1_DEFINITIONS - Compiler switches required for using libusb
#
# Adapted from cmake-modules Google Code project
#
# Copyright (c) 2006 Andreas Schneider <mail@cynapses.org>
#
# (Changes for libusb) Copyright (c) 2008 Kyle Machulis <kyle@nonpolynomial.com>
#
# Redistribution and use is allowed according to the terms of the New BSD license.
#
# CMake-Modules Project New BSD License
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# * Neither the name of the CMake-Modules Project nor the names of its
# contributors may be used to endorse or promote products derived from this
# software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
if (LIBUSB_1_LIBRARIES AND LIBUSB_1_INCLUDE_DIRS)
# in cache already
set(LIBUSB_FOUND TRUE)
else (LIBUSB_1_LIBRARIES AND LIBUSB_1_INCLUDE_DIRS)
find_path(LIBUSB_1_INCLUDE_DIR
NAMES
libusb.h
PATHS
/usr/include
/usr/local/include
/opt/local/include
/sw/include
PATH_SUFFIXES
libusb-1.0
)
find_library(LIBUSB_1_LIBRARY
NAMES
usb-1.0 usb
PATHS
/usr/lib
/usr/local/lib
/opt/local/lib
/sw/lib
)
set(LIBUSB_1_INCLUDE_DIRS
${LIBUSB_1_INCLUDE_DIR}
)
set(LIBUSB_1_LIBRARIES
${LIBUSB_1_LIBRARY}
)
if (LIBUSB_1_INCLUDE_DIRS AND LIBUSB_1_LIBRARIES)
set(LIBUSB_1_FOUND TRUE)
endif (LIBUSB_1_INCLUDE_DIRS AND LIBUSB_1_LIBRARIES)
if (LIBUSB_1_FOUND)
if (NOT libusb_1_FIND_QUIETLY)
message(STATUS "Found libusb-1.0:")
message(STATUS " - Includes: ${LIBUSB_1_INCLUDE_DIRS}")
message(STATUS " - Libraries: ${LIBUSB_1_LIBRARIES}")
endif (NOT libusb_1_FIND_QUIETLY)
else (LIBUSB_1_FOUND)
if (libusb_1_FIND_REQUIRED)
message(FATAL_ERROR "Could not find libusb")
endif (libusb_1_FIND_REQUIRED)
endif (LIBUSB_1_FOUND)
# show the LIBUSB_1_INCLUDE_DIRS and LIBUSB_1_LIBRARIES variables only in the advanced view
mark_as_advanced(LIBUSB_1_INCLUDE_DIRS LIBUSB_1_LIBRARIES)
endif (LIBUSB_1_LIBRARIES AND LIBUSB_1_INCLUDE_DIRS)

View File

@ -0,0 +1,23 @@
/*
* 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 <boost/log/trivial.hpp>
#define OPENAUTO_LOG(severity) BOOST_LOG_TRIVIAL(severity) << "[AaApp] "

View File

@ -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
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace configuration
{
enum class BluetoothAdapterType
{
NONE,
LOCAL,
REMOTE
};
}
}
}
}

View File

@ -0,0 +1,113 @@
/*
* 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 <boost/property_tree/ini_parser.hpp>
#include <f1x/openauto/autoapp/Configuration/IConfiguration.hpp>
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace configuration
{
class Configuration: public IConfiguration
{
public:
Configuration();
void load() override;
void reset() override;
void save() override;
void setHandednessOfTrafficType(HandednessOfTrafficType value) override;
HandednessOfTrafficType getHandednessOfTrafficType() const override;
void showClock(bool value) override;
bool showClock() const override;
aasdk::proto::enums::VideoFPS::Enum getVideoFPS() const override;
void setVideoFPS(aasdk::proto::enums::VideoFPS::Enum value) override;
aasdk::proto::enums::VideoResolution::Enum getVideoResolution() const override;
void setVideoResolution(aasdk::proto::enums::VideoResolution::Enum value) override;
size_t getScreenDPI() const override;
void setScreenDPI(size_t value) override;
bool getTouchscreenEnabled() const override;
void setTouchscreenEnabled(bool value) override;
ButtonCodes getButtonCodes() const override;
void setButtonCodes(const ButtonCodes& value) override;
BluetoothAdapterType getBluetoothAdapterType() const override;
void setBluetoothAdapterType(BluetoothAdapterType value) override;
std::string getBluetoothRemoteAdapterAddress() const override;
void setBluetoothRemoteAdapterAddress(const std::string& value) override;
private:
void readButtonCodes(boost::property_tree::ptree& iniConfig);
void insertButtonCode(boost::property_tree::ptree& iniConfig, const std::string& buttonCodeKey, aasdk::proto::enums::ButtonCode::Enum buttonCode);
void writeButtonCodes(boost::property_tree::ptree& iniConfig);
HandednessOfTrafficType handednessOfTrafficType_;
bool showClock_;
aasdk::proto::enums::VideoFPS::Enum videoFPS_;
aasdk::proto::enums::VideoResolution::Enum videoResolution_;
size_t screenDPI_;
bool enableTouchscreen_;
ButtonCodes buttonCodes_;
BluetoothAdapterType bluetoothAdapterType_;
std::string bluetoothRemoteAdapterAddress_;
static const std::string cConfigFileName;
static const std::string cGeneralShowClockKey;
static const std::string cGeneralHandednessOfTrafficTypeKey;
static const std::string cVideoFPSKey;
static const std::string cVideoResolutionKey;
static const std::string cVideoScreenDPIKey;
static const std::string cBluetoothAdapterTypeKey;
static const std::string cBluetoothRemoteAdapterAddressKey;
static const std::string cInputEnableTouchscreenKey;
static const std::string cInputPlayButtonKey;
static const std::string cInputPauseButtonKey;
static const std::string cInputTogglePlayButtonKey;
static const std::string cInputNextTrackButtonKey;
static const std::string cInputPreviousTrackButtonKey;
static const std::string cInputHomeButtonKey;
static const std::string cInputPhoneButtonKey;
static const std::string cInputCallEndButtonKey;
static const std::string cInputVoiceCommandButtonKey;
static const std::string cInputLeftButtonKey;
static const std::string cInputRightButtonKey;
static const std::string cInputUpButtonKey;
static const std::string cInputDownButtonKey;
static const std::string cInputScrollWheelButtonKey;
static const std::string cInputBackButtonKey;
static const std::string cInputEnterButtonKey;
};
}
}
}
}

View File

@ -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 HandednessOfTrafficType
{
LEFT_HAND_DRIVE,
RIGHT_HAND_DRIVE
};
}
}
}
}

View File

@ -0,0 +1,75 @@
/*
* 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 <string>
#include <aasdk_proto/VideoFPSEnum.pb.h>
#include <aasdk_proto/VideoResolutionEnum.pb.h>
#include <aasdk_proto/ButtonCodeEnum.pb.h>
#include <f1x/openauto/autoapp/Configuration/BluetootAdapterType.hpp>
#include <f1x/openauto/autoapp/Configuration/HandednessOfTrafficType.hpp>
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace configuration
{
class IConfiguration
{
public:
typedef std::shared_ptr<IConfiguration> Pointer;
typedef std::vector<aasdk::proto::enums::ButtonCode::Enum> ButtonCodes;
virtual ~IConfiguration() = default;
virtual void load() = 0;
virtual void reset() = 0;
virtual void save() = 0;
virtual void setHandednessOfTrafficType(HandednessOfTrafficType value) = 0;
virtual HandednessOfTrafficType getHandednessOfTrafficType() const = 0;
virtual void showClock(bool value) = 0;
virtual bool showClock() const = 0;
virtual aasdk::proto::enums::VideoFPS::Enum getVideoFPS() const = 0;
virtual void setVideoFPS(aasdk::proto::enums::VideoFPS::Enum value) = 0;
virtual aasdk::proto::enums::VideoResolution::Enum getVideoResolution() const = 0;
virtual void setVideoResolution(aasdk::proto::enums::VideoResolution::Enum value) = 0;
virtual size_t getScreenDPI() const = 0;
virtual void setScreenDPI(size_t value) = 0;
virtual bool getTouchscreenEnabled() const = 0;
virtual void setTouchscreenEnabled(bool value) = 0;
virtual ButtonCodes getButtonCodes() const = 0;
virtual void setButtonCodes(const ButtonCodes& value) = 0;
virtual BluetoothAdapterType getBluetoothAdapterType() const = 0;
virtual void setBluetoothAdapterType(BluetoothAdapterType value) = 0;
virtual std::string getBluetoothRemoteAdapterAddress() const = 0;
virtual void setBluetoothRemoteAdapterAddress(const std::string& value) = 0;
};
}
}
}
}

View File

@ -0,0 +1,78 @@
/*
* 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 <boost/asio.hpp>
#include <f1x/aasdk/Transport/ITransport.hpp>
#include <f1x/aasdk/Channel/Control/ControlServiceChannel.hpp>
#include <f1x/aasdk/Channel/Control/IControlServiceChannelEventHandler.hpp>
#include <f1x/aasdk/Channel/AV/VideoServiceChannel.hpp>
#include <f1x/openauto/autoapp/Configuration/IConfiguration.hpp>
#include <f1x/openauto/autoapp/Projection/IAndroidAutoEntity.hpp>
#include <f1x/openauto/autoapp/Projection/IServiceFactory.hpp>
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace projection
{
class AndroidAutoEntity: public IAndroidAutoEntity, public aasdk::channel::control::IControlServiceChannelEventHandler, public std::enable_shared_from_this<AndroidAutoEntity>
{
public:
AndroidAutoEntity(boost::asio::io_service& ioService,
aasdk::messenger::ICryptor::Pointer cryptor,
aasdk::transport::ITransport::Pointer transport,
configuration::IConfiguration::Pointer configuration,
IServiceFactory& serviceFactory);
~AndroidAutoEntity() override;
void start(IAndroidAutoEntityEventHandler& eventHandler) override;
void stop() override;
void onVersionResponse(uint16_t majorCode, uint16_t minorCode, aasdk::proto::enums::VersionResponseStatus::Enum status) override;
void onHandshake(const aasdk::common::DataConstBuffer& payload) override;
void onServiceDiscoveryRequest(const aasdk::proto::messages::ServiceDiscoveryRequest& request) override;
void onAudioFocusRequest(const aasdk::proto::messages::AudioFocusRequest& request) override;
void onShutdownRequest(const aasdk::proto::messages::ShutdownRequest& request) override;
void onShutdownResponse(const aasdk::proto::messages::ShutdownResponse& response) override;
void onNavigationFocusRequest(const aasdk::proto::messages::NavigationFocusRequest& request) override;
void onChannelError(const aasdk::error::Error& e) override;
private:
using std::enable_shared_from_this<AndroidAutoEntity>::shared_from_this;
void handleStop();
boost::asio::io_service::strand strand_;
aasdk::messenger::ICryptor::Pointer cryptor_;
aasdk::transport::ITransport::Pointer transport_;
configuration::IConfiguration::Pointer configuration_;
IServiceFactory& serviceFactory_;
aasdk::messenger::IMessenger::Pointer messenger_;
aasdk::channel::control::ControlServiceChannel::Pointer controlServiceChannel_;
ServiceList serviceList_;
IAndroidAutoEntityEventHandler* eventHandler_;
};
}
}
}
}

View File

@ -0,0 +1,55 @@
/*
* 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 <boost/asio.hpp>
#include <f1x/openauto/autoapp/Configuration/IConfiguration.hpp>
#include <f1x/openauto/autoapp/Projection/IAndroidAutoEntityFactory.hpp>
#include <f1x/openauto/autoapp/Projection/IServiceFactory.hpp>
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace projection
{
class AndroidAutoEntityFactory: public IAndroidAutoEntityFactory
{
public:
AndroidAutoEntityFactory(aasdk::usb::IUSBWrapper& usbWrapper,
boost::asio::io_service& ioService,
configuration::IConfiguration::Pointer configuration,
IServiceFactory& serviceFactory);
IAndroidAutoEntity::Pointer create(aasdk::usb::DeviceHandle deviceHandle) override;
private:
aasdk::usb::IUSBWrapper& usbWrapper_;
boost::asio::io_service& ioService_;
configuration::IConfiguration::Pointer configuration_;
IServiceFactory& serviceFactory_;
};
}
}
}
}

View File

@ -0,0 +1,73 @@
/*
* 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 <mutex>
#include <QAudioInput>
#include <QAudioFormat>
#include <f1x/openauto/autoapp/Projection/IAudioInput.hpp>
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace projection
{
class AudioInput: public QObject, public IAudioInput
{
Q_OBJECT
public:
AudioInput(uint32_t channelCount, uint32_t sampleSize, uint32_t sampleRate);
bool open() override;
bool isActive() const override;
void read(ReadPromise::Pointer promise) override;
void start(StartPromise::Pointer promise) override;
void stop() override;
uint32_t getSampleSize() const override;
uint32_t getChannelCount() const override;
uint32_t getSampleRate() const override;
signals:
void startRecording(StartPromise::Pointer promise);
void stopRecording();
private slots:
void createAudioInput();
void onStartRecording(StartPromise::Pointer promise);
void onStopRecording();
void onReadyRead();
private:
QAudioFormat audioFormat_;
QIODevice* ioDevice_;
std::unique_ptr<QAudioInput> audioInput_;
ReadPromise::Pointer readPromise_;
mutable std::mutex mutex_;
static constexpr size_t cSampleSize = 2056;
};
}
}
}
}

View File

@ -0,0 +1,65 @@
/*
* 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 <f1x/aasdk/Channel/AV/AVInputServiceChannel.hpp>
#include <f1x/openauto/autoapp/Projection/IService.hpp>
#include <f1x/openauto/autoapp/Projection/IAudioInput.hpp>
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace projection
{
class AudioInputService: public aasdk::channel::av::IAVInputServiceChannelEventHandler, public IService, public std::enable_shared_from_this<AudioInputService>
{
public:
typedef std::shared_ptr<AudioInputService> Pointer;
AudioInputService(boost::asio::io_service& ioService, aasdk::messenger::IMessenger::Pointer messenger, IAudioInput::Pointer audioInput);
void start() override;
void stop() override;
void fillFeatures(aasdk::proto::messages::ServiceDiscoveryResponse& response) override;
void onChannelOpenRequest(const aasdk::proto::messages::ChannelOpenRequest& request) override;
void onAVChannelSetupRequest(const aasdk::proto::messages::AVChannelSetupRequest& request) override;
void onAVInputOpenRequest(const aasdk::proto::messages::AVInputOpenRequest& request) override;
void onAVMediaAckIndication(const aasdk::proto::messages::AVMediaAckIndication& indication) override;
void onChannelError(const aasdk::error::Error& e) override;
private:
using std::enable_shared_from_this<AudioInputService>::shared_from_this;
void onAudioInputOpenSucceed();
void onAudioInputDataReady(aasdk::common::Data data);
void readAudioInput();
boost::asio::io_service::strand strand_;
aasdk::channel::av::AVInputServiceChannel::Pointer channel_;
IAudioInput::Pointer audioInput_;
int32_t session_;
};
}
}
}
}

View File

@ -0,0 +1,67 @@
/*
* 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 <QAudioOutput>
#include <QAudioFormat>
#include <f1x/openauto/autoapp/Projection/IAudioOutput.hpp>
#include <f1x/openauto/autoapp/Projection/SequentialBuffer.hpp>
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace projection
{
class AudioOutput: public QObject, public IAudioOutput
{
Q_OBJECT
public:
AudioOutput(uint32_t channelCount, uint32_t sampleSize, uint32_t sampleRate);
bool open() override;
void write(const aasdk::common::DataConstBuffer& buffer) override;
void start() override;
void stop() override;
uint32_t getSampleSize() const override;
uint32_t getChannelCount() const override;
uint32_t getSampleRate() const override;
signals:
void startPlayback();
void stopPlayback();
protected slots:
void createAudioOutput();
void onStartPlayback();
void onStopPlayback();
private:
QAudioFormat audioFormat_;
SequentialBuffer audioBuffer_;
std::unique_ptr<QAudioOutput> audioOutput_;
};
}
}
}
}

View File

@ -0,0 +1,65 @@
/*
* 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 <f1x/aasdk/Channel/AV/IAudioServiceChannel.hpp>
#include <f1x/aasdk/Channel/AV/IAudioServiceChannelEventHandler.hpp>
#include <f1x/openauto/autoapp/Projection/IAudioOutput.hpp>
#include <f1x/openauto/autoapp/Projection/IService.hpp>
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace projection
{
class AudioService: public aasdk::channel::av::IAudioServiceChannelEventHandler, public IService, public std::enable_shared_from_this<AudioService>
{
public:
typedef std::shared_ptr<AudioService> Pointer;
AudioService(boost::asio::io_service& ioService, aasdk::channel::av::IAudioServiceChannel::Pointer channel, IAudioOutput::Pointer audioOutput);
void start() override;
void stop() override;
void fillFeatures(aasdk::proto::messages::ServiceDiscoveryResponse& response) override;
void onChannelOpenRequest(const aasdk::proto::messages::ChannelOpenRequest& request) override;
void onAVChannelSetupRequest(const aasdk::proto::messages::AVChannelSetupRequest& request) override;
void onAVChannelStartIndication(const aasdk::proto::messages::AVChannelStartIndication& indication) override;
void onAVChannelStopIndication(const aasdk::proto::messages::AVChannelStopIndication& indication) override;
void onAVMediaWithTimestampIndication(aasdk::messenger::Timestamp::ValueType timestamp, const aasdk::common::DataConstBuffer& buffer) override;
void onAVMediaIndication(const aasdk::common::DataConstBuffer& buffer) override;
void onChannelError(const aasdk::error::Error& e) override;
protected:
using std::enable_shared_from_this<AudioService>::shared_from_this;
boost::asio::io_service::strand strand_;
aasdk::channel::av::IAudioServiceChannel::Pointer channel_;
IAudioOutput::Pointer audioOutput_;
int32_t session_;
};
}
}
}
}

View File

@ -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/>.
*/
#pragma once
#include <f1x/aasdk/Channel/Bluetooth/BluetoothServiceChannel.hpp>
#include <f1x/openauto/autoapp/Projection/IBluetoothDevice.hpp>
#include <f1x/openauto/autoapp/Projection/IService.hpp>
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace projection
{
class BluetoothService: public aasdk::channel::bluetooth::IBluetoothServiceChannelEventHandler, public IService, public std::enable_shared_from_this<BluetoothService>
{
public:
BluetoothService(boost::asio::io_service& ioService, aasdk::messenger::IMessenger::Pointer messenger, IBluetoothDevice::Pointer bluetoothDevice);
void start() override;
void stop() override;
void fillFeatures(aasdk::proto::messages::ServiceDiscoveryResponse& response) override;
void onChannelOpenRequest(const aasdk::proto::messages::ChannelOpenRequest& request) override;
void onBluetoothPairingRequest(const aasdk::proto::messages::BluetoothPairingRequest& request) override;
void onChannelError(const aasdk::error::Error& e) override;
private:
using std::enable_shared_from_this<BluetoothService>::shared_from_this;
boost::asio::io_service::strand strand_;
aasdk::channel::bluetooth::BluetoothServiceChannel::Pointer channel_;
IBluetoothDevice::Pointer bluetoothDevice_;
};
}
}
}
}

View File

@ -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 <f1x/openauto/autoapp/Projection/IBluetoothDevice.hpp>
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace projection
{
class DummyBluetoothDevice: public IBluetoothDevice
{
public:
void stop() override;
bool isPaired(const std::string& address) const override;
void pair(const std::string& address, PairingPromise::Pointer promise) override;
std::string getLocalAddress() const override;
bool isAvailable() const override;
};
}
}
}
}

View File

@ -0,0 +1,47 @@
/*
* 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 <memory>
#include <f1x/openauto/autoapp/Projection/IAndroidAutoEntityEventHandler.hpp>
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace projection
{
class IAndroidAutoEntity
{
public:
typedef std::shared_ptr<IAndroidAutoEntity> Pointer;
virtual ~IAndroidAutoEntity() = default;
virtual void start(IAndroidAutoEntityEventHandler& eventHandler) = 0;
virtual void stop() = 0;
};
}
}
}
}

View File

@ -0,0 +1,42 @@
/*
* 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 <f1x/aasdk/Error/Error.hpp>
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace projection
{
class IAndroidAutoEntityEventHandler
{
public:
virtual ~IAndroidAutoEntityEventHandler() = default;
virtual void onAndroidAutoQuit() = 0;
};
}
}
}
}

View File

@ -0,0 +1,44 @@
/*
* 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 <f1x/aasdk/USB/USBWrapper.hpp>
#include <f1x/openauto/autoapp/Projection/IAndroidAutoEntity.hpp>
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace projection
{
class IAndroidAutoEntityFactory
{
public:
virtual ~IAndroidAutoEntityFactory() = default;
virtual IAndroidAutoEntity::Pointer create(aasdk::usb::DeviceHandle deviceHandle) = 0;
};
}
}
}
}

View File

@ -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/>.
*/
#pragma once
#include <memory>
#include <f1x/aasdk/IO/Promise.hpp>
#include <f1x/aasdk/Common/Data.hpp>
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace projection
{
class IAudioInput
{
public:
typedef aasdk::io::Promise<void, void> StartPromise;
typedef aasdk::io::Promise<aasdk::common::Data, void> ReadPromise;
typedef std::shared_ptr<IAudioInput> Pointer;
virtual ~IAudioInput() = default;
virtual bool open() = 0;
virtual bool isActive() const = 0;
virtual void read(ReadPromise::Pointer promise) = 0;
virtual void start(StartPromise::Pointer promise) = 0;
virtual void stop() = 0;
virtual uint32_t getSampleSize() const = 0;
virtual uint32_t getChannelCount() const = 0;
virtual uint32_t getSampleRate() const = 0;
};
}
}
}
}

View File

@ -0,0 +1,53 @@
/*
* 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 <memory>
#include <f1x/aasdk/Common/Data.hpp>
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace projection
{
class IAudioOutput
{
public:
typedef std::shared_ptr<IAudioOutput> Pointer;
IAudioOutput() = default;
virtual ~IAudioOutput() = default;
virtual bool open() = 0;
virtual void write(const aasdk::common::DataConstBuffer& buffer) = 0;
virtual void start() = 0;
virtual void stop() = 0;
virtual uint32_t getSampleSize() const = 0;
virtual uint32_t getChannelCount() const = 0;
virtual uint32_t getSampleRate() const = 0;
};
}
}
}
}

View File

@ -0,0 +1,48 @@
/*
* 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/aasdk/IO/Promise.hpp>
#pragma once
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace projection
{
class IBluetoothDevice
{
public:
typedef aasdk::io::Promise<void, void> PairingPromise;
typedef std::shared_ptr<IBluetoothDevice> Pointer;
virtual void stop() = 0;
virtual bool isPaired(const std::string& address) const = 0;
virtual void pair(const std::string& address, PairingPromise::Pointer promise) = 0;
virtual std::string getLocalAddress() const = 0;
virtual bool isAvailable() const = 0;
};
}
}
}
}

View File

@ -0,0 +1,53 @@
/*
* 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 <QRect>
#include <f1x/aasdk/IO/Promise.hpp>
#include <f1x/openauto/autoapp/Projection/InputEvent.hpp>
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace projection
{
class IInputDeviceEventHandler;
class IInputDevice
{
public:
typedef std::shared_ptr<IInputDevice> Pointer;
typedef std::vector<aasdk::proto::enums::ButtonCode::Enum> ButtonCodes;
virtual ~IInputDevice() = default;
virtual void start(IInputDeviceEventHandler& eventHandler) = 0;
virtual void stop() = 0;
virtual ButtonCodes getSupportedButtonCodes() const = 0;
virtual bool hasTouchscreen() const = 0;
virtual QRect getTouchscreenGeometry() const = 0;
};
}
}
}
}

View File

@ -0,0 +1,44 @@
/*
* 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 <f1x/openauto/autoapp/Projection/InputEvent.hpp>
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace projection
{
class IInputDeviceEventHandler
{
public:
virtual ~IInputDeviceEventHandler() = default;
virtual void onButtonEvent(const ButtonEvent& event) = 0;
virtual void onTouchEvent(const TouchEvent& event) = 0;
};
}
}
}
}

View File

@ -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 <vector>
#include <memory>
#include <aasdk_proto/ServiceDiscoveryResponseMessage.pb.h>
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace projection
{
class IService
{
public:
typedef std::shared_ptr<IService> Pointer;
virtual ~IService() = default;
virtual void start() = 0;
virtual void stop() = 0;
virtual void fillFeatures(aasdk::proto::messages::ServiceDiscoveryResponse& response) = 0;
};
typedef std::vector<IService::Pointer> ServiceList;
}
}
}
}

View File

@ -0,0 +1,44 @@
/*
* 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 <f1x/aasdk/Messenger/IMessenger.hpp>
#include <f1x/openauto/autoapp/Projection/IService.hpp>
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace projection
{
class IServiceFactory
{
public:
virtual ~IServiceFactory() = default;
virtual ServiceList create(aasdk::messenger::IMessenger::Pointer messenger) = 0;
};
}
}
}
}

View File

@ -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/>.
*/
#pragma once
#include <memory>
#include <aasdk_proto/VideoFPSEnum.pb.h>
#include <aasdk_proto/VideoResolutionEnum.pb.h>
#include <f1x/aasdk/Common/Data.hpp>
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace projection
{
class IVideoOutput
{
public:
typedef std::shared_ptr<IVideoOutput> Pointer;
IVideoOutput() = default;
virtual ~IVideoOutput() = default;
virtual bool open() = 0;
virtual bool init() = 0;
virtual void write(uint64_t timestamp, const aasdk::common::DataConstBuffer& buffer) = 0;
virtual void stop() = 0;
virtual bool isActive() const = 0;
virtual aasdk::proto::enums::VideoFPS::Enum getVideoFPS() const = 0;
virtual aasdk::proto::enums::VideoResolution::Enum getVideoResolution() const = 0;
virtual size_t getScreenDPI() const = 0;
};
}
}
}
}

View File

@ -0,0 +1,66 @@
/*
* 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 <QObject>
#include <QKeyEvent>
#include <f1x/openauto/autoapp/Projection/IInputDevice.hpp>
#include <f1x/openauto/autoapp/Configuration/IConfiguration.hpp>
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace projection
{
class InputDevice: public QObject, public IInputDevice, boost::noncopyable
{
Q_OBJECT
public:
InputDevice(QObject& parent, configuration::IConfiguration::Pointer configuration, const QRect& touchscreenGeometry, const QRect& videoGeometry);
void start(IInputDeviceEventHandler& eventHandler) override;
void stop() override;
ButtonCodes getSupportedButtonCodes() const override;
bool eventFilter(QObject* obj, QEvent* event) override;
bool hasTouchscreen() const override;
QRect getTouchscreenGeometry() const override;
private:
void setVideoGeometry();
bool handleKeyEvent(QEvent* event, QKeyEvent* key);
void dispatchKeyEvent(ButtonEvent event);
bool handleTouchEvent(QEvent* event);
QObject& parent_;
configuration::IConfiguration::Pointer configuration_;
QRect touchscreenGeometry_;
QRect displayGeometry_;
IInputDeviceEventHandler* eventHandler_;
std::mutex mutex_;
};
}
}
}
}

View File

@ -0,0 +1,66 @@
/*
* 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 <aasdk_proto/ButtonCodeEnum.pb.h>
#include <aasdk_proto/TouchActionEnum.pb.h>
#include <f1x/aasdk/IO/Promise.hpp>
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace projection
{
enum class ButtonEventType
{
NONE,
PRESS,
RELEASE
};
enum class WheelDirection
{
NONE,
LEFT,
RIGHT
};
struct ButtonEvent
{
ButtonEventType type;
WheelDirection wheelDirection;
aasdk::proto::enums::ButtonCode::Enum code;
};
struct TouchEvent
{
aasdk::proto::enums::TouchAction::Enum type;
uint32_t x;
uint32_t y;
uint32_t pointerId;
};
}
}
}
}

View File

@ -0,0 +1,65 @@
/*
* 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 <aasdk_proto/ButtonCodeEnum.pb.h>
#include <f1x/aasdk/Channel/Input/InputServiceChannel.hpp>
#include <f1x/openauto/autoapp/Projection/IService.hpp>
#include <f1x/openauto/autoapp/Projection/IInputDevice.hpp>
#include <f1x/openauto/autoapp/Projection/IInputDeviceEventHandler.hpp>
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace projection
{
class InputService:
public aasdk::channel::input::IInputServiceChannelEventHandler,
public IService,
public IInputDeviceEventHandler,
public std::enable_shared_from_this<InputService>
{
public:
InputService(boost::asio::io_service& ioService, aasdk::messenger::IMessenger::Pointer messenger, IInputDevice::Pointer inputDevice);
void start() override;
void stop() override;
void fillFeatures(aasdk::proto::messages::ServiceDiscoveryResponse& response) override;
void onChannelOpenRequest(const aasdk::proto::messages::ChannelOpenRequest& request) override;
void onBindingRequest(const aasdk::proto::messages::BindingRequest& request) override;
void onChannelError(const aasdk::error::Error& e) override;
void onButtonEvent(const ButtonEvent& event) override;
void onTouchEvent(const TouchEvent& event) override;
private:
using std::enable_shared_from_this<InputService>::shared_from_this;
boost::asio::io_service::strand strand_;
aasdk::channel::input::InputServiceChannel::Pointer channel_;
IInputDevice::Pointer inputDevice_;
};
}
}
}
}

View File

@ -0,0 +1,68 @@
/*
* 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 <QBluetoothLocalDevice>
#include <f1x/openauto/autoapp/Projection/IBluetoothDevice.hpp>
#pragma once
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace projection
{
class LocalBluetoothDevice: public QObject, public IBluetoothDevice
{
Q_OBJECT
public:
LocalBluetoothDevice();
void stop() override;
bool isPaired(const std::string& address) const override;
void pair(const std::string& address, PairingPromise::Pointer promise) override;
std::string getLocalAddress() const override;
bool isAvailable() const override;
signals:
void startPairing(const QString& address, PairingPromise::Pointer promise);
private slots:
void createBluetoothLocalDevice();
void onStartPairing(const QString& address, PairingPromise::Pointer promise);
void onPairingDisplayConfirmation(const QBluetoothAddress &address, QString pin);
void onPairingDisplayPinCode(const QBluetoothAddress &address, QString pin);
void onPairingFinished(const QBluetoothAddress &address, QBluetoothLocalDevice::Pairing pairing);
void onError(QBluetoothLocalDevice::Error error);
void onHostModeStateChanged(QBluetoothLocalDevice::HostMode state);
private:
mutable std::mutex mutex_;
std::unique_ptr<QBluetoothLocalDevice> localDevice_;
PairingPromise::Pointer pairingPromise_;
QBluetoothAddress pairingAddress_;
};
}
}
}
}

View File

@ -0,0 +1,42 @@
/*
* 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 <f1x/aasdk/Messenger/IMessenger.hpp>
#include <f1x/openauto/autoapp/Projection/AudioService.hpp>
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace projection
{
class MediaAudioService: public AudioService
{
public:
MediaAudioService(boost::asio::io_service& ioService, aasdk::messenger::IMessenger::Pointer messenger, IAudioOutput::Pointer audioOutput);
};
}
}
}
}

View File

@ -0,0 +1,72 @@
/*
* 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/>.
*/
#ifdef USE_OMX
#pragma once
extern "C"
{
#include <ilclient.h>
}
#include <mutex>
#include <condition_variable>
#include <thread>
#include <boost/circular_buffer.hpp>
#include <f1x/openauto/autoapp/Projection/VideoOutput.hpp>
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace projection
{
class OMXVideoOutput: public VideoOutput
{
public:
OMXVideoOutput(configuration::IConfiguration::Pointer configuration);
bool open() override;
bool init() override;
void write(uint64_t timestamp, const aasdk::common::DataConstBuffer& buffer) override;
void stop() override;
bool isActive() const override;
private:
bool createComponents();
bool initClock();
bool setupTunnels();
bool enablePortBuffers();
mutable std::mutex mutex_;
bool isActive_;
bool portSettingsChanged_;
ILCLIENT_T* client_;
COMPONENT_T* components_[5];
TUNNEL_T tunnels_[4];
};
}
}
}
}
#endif

View File

@ -0,0 +1,67 @@
/*
* 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 <QMediaPlayer>
#include <QVideoWidget>
#include <boost/noncopyable.hpp>
#include <f1x/openauto/autoapp/Projection/VideoOutput.hpp>
#include <f1x/openauto/autoapp/Projection/SequentialBuffer.hpp>
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace projection
{
class QtVideoOutput: public QObject, public VideoOutput, boost::noncopyable
{
Q_OBJECT
public:
QtVideoOutput(configuration::IConfiguration::Pointer configuration);
bool open() override;
bool init() override;
void write(uint64_t timestamp, const aasdk::common::DataConstBuffer& buffer) override;
void stop() override;
bool isActive() const override;
signals:
void startPlayback();
void stopPlayback();
protected slots:
void createVideoOutput();
void onStartPlayback();
void onStopPlayback();
private:
SequentialBuffer videoBuffer_;
std::unique_ptr<QVideoWidget> videoWidget_;
std::unique_ptr<QMediaPlayer> mediaPlayer_;
mutable std::mutex mutex_;
};
}
}
}
}

View File

@ -0,0 +1,50 @@
/*
* 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 <f1x/openauto/autoapp/Projection/IBluetoothDevice.hpp>
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace projection
{
class RemoteBluetoothDevice: public IBluetoothDevice
{
public:
RemoteBluetoothDevice(const std::string& address);
void stop() override;
bool isPaired(const std::string& address) const override;
void pair(const std::string& address, PairingPromise::Pointer promise) override;
std::string getLocalAddress() const override;
bool isAvailable() const override;
private:
std::string address_;
};
}
}
}
}

View File

@ -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/>.
*/
#pragma once
#include <f1x/aasdk/Channel/Sensor/SensorServiceChannel.hpp>
#include <f1x/openauto/autoapp/Projection/IService.hpp>
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace projection
{
class SensorService: public aasdk::channel::sensor::ISensorServiceChannelEventHandler, public IService, public std::enable_shared_from_this<SensorService>
{
public:
SensorService(boost::asio::io_service& ioService, aasdk::messenger::IMessenger::Pointer messenger);
void start() override;
void stop() override;
void fillFeatures(aasdk::proto::messages::ServiceDiscoveryResponse& response) override;
void onChannelOpenRequest(const aasdk::proto::messages::ChannelOpenRequest& request) override;
void onSensorStartRequest(const aasdk::proto::messages::SensorStartRequestMessage& request) override;
void onChannelError(const aasdk::error::Error& e) override;
private:
using std::enable_shared_from_this<SensorService>::shared_from_this;
void sendDrivingStatusUnrestricted();
boost::asio::io_service::strand strand_;
aasdk::channel::sensor::SensorServiceChannel::Pointer channel_;
};
}
}
}
}

View File

@ -0,0 +1,60 @@
/*
* 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 <QIODevice>
#include <mutex>
#include <boost/circular_buffer.hpp>
#include <f1x/aasdk/Common/Data.hpp>
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace projection
{
class SequentialBuffer: public QIODevice
{
public:
SequentialBuffer();
bool isSequential() const override;
qint64 size() const override;
qint64 pos() const override;
bool seek(qint64 pos) override;
bool atEnd() const override;
bool reset() override;
bool canReadLine() const override;
qint64 bytesAvailable() const override;
protected:
qint64 readData(char *data, qint64 maxlen) override;
qint64 writeData(const char *data, qint64 len) override;
private:
boost::circular_buffer<aasdk::common::Data::value_type> data_;
mutable std::mutex mutex_;
};
}
}
}
}

View File

@ -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 <f1x/openauto/autoapp/Projection/IServiceFactory.hpp>
#include <f1x/openauto/autoapp/Configuration/IConfiguration.hpp>
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace projection
{
class ServiceFactory: public IServiceFactory
{
public:
ServiceFactory(boost::asio::io_service& ioService, configuration::IConfiguration::Pointer configuration);
ServiceList create(aasdk::messenger::IMessenger::Pointer messenger) override;
private:
IService::Pointer createVideoService(aasdk::messenger::IMessenger::Pointer messenger);
IService::Pointer createBluetoothService(aasdk::messenger::IMessenger::Pointer messenger);
IService::Pointer createInputService(aasdk::messenger::IMessenger::Pointer messenger);
boost::asio::io_service& ioService_;
configuration::IConfiguration::Pointer configuration_;
};
}
}
}
}

View File

@ -0,0 +1,37 @@
/*
* 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 <f1x/aasdk/IO/Promise.hpp>
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace projection
{
typedef aasdk::io::Promise<void> ServiceFinishPromise;
}
}
}
}

View File

@ -0,0 +1,42 @@
/*
* 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 <f1x/aasdk/Messenger/IMessenger.hpp>
#include <f1x/openauto/autoapp/Projection/AudioService.hpp>
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace projection
{
class SpeechAudioService: public AudioService
{
public:
SpeechAudioService(boost::asio::io_service& ioService, aasdk::messenger::IMessenger::Pointer messenger, IAudioOutput::Pointer audioOutput);
};
}
}
}
}

View File

@ -0,0 +1,42 @@
/*
* 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 <f1x/aasdk/Messenger/IMessenger.hpp>
#include <f1x/openauto/autoapp/Projection/AudioService.hpp>
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace projection
{
class SystemAudioService: public AudioService
{
public:
SystemAudioService(boost::asio::io_service& ioService, aasdk::messenger::IMessenger::Pointer messenger, IAudioOutput::Pointer audioOutput);
};
}
}
}
}

View File

@ -0,0 +1,49 @@
/*
* 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 <f1x/openauto/autoapp/Configuration/IConfiguration.hpp>
#include <f1x/openauto/autoapp/Projection/IVideoOutput.hpp>
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace projection
{
class VideoOutput: public IVideoOutput
{
public:
VideoOutput(configuration::IConfiguration::Pointer configuration);
aasdk::proto::enums::VideoFPS::Enum getVideoFPS() const override;
aasdk::proto::enums::VideoResolution::Enum getVideoResolution() const override;
size_t getScreenDPI() const override;
protected:
configuration::IConfiguration::Pointer configuration_;
};
}
}
}
}

View File

@ -0,0 +1,68 @@
/*
* 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 <memory>
#include <f1x/aasdk/Channel/AV/VideoServiceChannel.hpp>
#include <f1x/aasdk/Channel/AV/IVideoServiceChannelEventHandler.hpp>
#include <f1x/openauto/autoapp/Projection/ServiceFinishPromise.hpp>
#include <f1x/openauto/autoapp/Projection/IVideoOutput.hpp>
#include <f1x/openauto/autoapp/Projection/IService.hpp>
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace projection
{
class VideoService: public aasdk::channel::av::IVideoServiceChannelEventHandler, public IService, public std::enable_shared_from_this<VideoService>
{
public:
typedef std::shared_ptr<VideoService> Pointer;
VideoService(boost::asio::io_service& ioService, aasdk::messenger::IMessenger::Pointer messenger, IVideoOutput::Pointer videoOutput);
void start() override;
void stop() override;
void fillFeatures(aasdk::proto::messages::ServiceDiscoveryResponse& response) override;
void onChannelOpenRequest(const aasdk::proto::messages::ChannelOpenRequest& request) override;
void onAVChannelSetupRequest(const aasdk::proto::messages::AVChannelSetupRequest& request) override;
void onAVChannelStartIndication(const aasdk::proto::messages::AVChannelStartIndication& indication) override;
void onAVMediaWithTimestampIndication(aasdk::messenger::Timestamp::ValueType timestamp, const aasdk::common::DataConstBuffer& buffer) override;
void onAVMediaIndication(const aasdk::common::DataConstBuffer& buffer) override;
void onVideoFocusRequest(const aasdk::proto::messages::VideoFocusRequest& request) override;
void onChannelError(const aasdk::error::Error& e) override;
private:
using std::enable_shared_from_this<VideoService>::shared_from_this;
void sendVideoFocusIndication();
boost::asio::io_service::strand strand_;
aasdk::channel::av::VideoServiceChannel::Pointer channel_;
IVideoOutput::Pointer videoOutput_;
int32_t session_;
};
}
}
}
}

View File

@ -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/>.
*/
#pragma once
#include <memory>
#include <QMainWindow>
namespace Ui
{
class MainWindow;
}
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace ui
{
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow() override;
signals:
void exit();
void openSettings();
private:
Ui::MainWindow* ui_;
};
}
}
}
}

View File

@ -0,0 +1,69 @@
/*
* 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 <memory>
#include <QWidget>
#include <f1x/openauto/autoapp/Configuration/IConfiguration.hpp>
class QCheckBox;
namespace Ui
{
class SettingsWindow;
}
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace ui
{
class SettingsWindow : public QWidget
{
Q_OBJECT
public:
explicit SettingsWindow(configuration::IConfiguration::Pointer configuration, QWidget *parent = nullptr);
~SettingsWindow() override;
private slots:
void onSave();
void onResetToDefaults();
void onUpdateScreenDPI(int value);
void onShowBindings();
private:
void showEvent(QShowEvent* event);
void load();
void loadButtonCheckBoxes();
void saveButtonCheckBoxes();
void saveButtonCheckBox(const QCheckBox* checkBox, configuration::IConfiguration::ButtonCodes& buttonCodes, aasdk::proto::enums::ButtonCode::Enum buttonCode);
void setButtonCheckBoxes(bool value);
Ui::SettingsWindow* ui_;
configuration::IConfiguration::Pointer configuration_;
};
}
}
}
}

View File

@ -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 <f1x/aasdk/USB/IUSBHub.hpp>
#include <f1x/openauto/autoapp/Projection/IAndroidAutoEntityEventHandler.hpp>
#include <f1x/openauto/autoapp/Projection/IAndroidAutoEntityFactory.hpp>
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace usb
{
class USBApp: public projection::IAndroidAutoEntityEventHandler, public std::enable_shared_from_this<USBApp>
{
public:
typedef std::shared_ptr<USBApp> Pointer;
USBApp(boost::asio::io_service& ioService, projection::IAndroidAutoEntityFactory& androidAutoEntityFactory, aasdk::usb::IUSBHub::Pointer usbHub);
void start();
void stop();
void onAndroidAutoQuit() override;
private:
using std::enable_shared_from_this<USBApp>::shared_from_this;
void waitForDevice();
void aoapDeviceHandler(aasdk::usb::DeviceHandle deviceHandle);
void onUSBHubError(const aasdk::error::Error& error);
boost::asio::io_service& ioService_;
boost::asio::io_service::strand strand_;
projection::IAndroidAutoEntityFactory& androidAutoEntityFactory_;
aasdk::usb::IUSBHub::Pointer usbHub_;
projection::IAndroidAutoEntity::Pointer androidAutoEntity_;
bool isStopped_;
};
}
}
}
}

View File

@ -0,0 +1,68 @@
/*
* 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_;
};
}
}
}
}

View File

@ -0,0 +1,273 @@
/*
* 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/Configuration/Configuration.hpp>
#include <f1x/openauto/Common/Log.hpp>
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace configuration
{
const std::string Configuration::cConfigFileName = "configuration.ini";
const std::string Configuration::cGeneralShowClockKey = "General.ShowClock";
const std::string Configuration::cGeneralHandednessOfTrafficTypeKey = "General.HandednessOfTrafficType";
const std::string Configuration::cVideoFPSKey = "Video.FPS";
const std::string Configuration::cVideoResolutionKey = "Video.Resolution";
const std::string Configuration::cVideoScreenDPIKey = "Video.ScreenDPI";
const std::string Configuration::cBluetoothAdapterTypeKey = "Bluetooth.AdapterType";
const std::string Configuration::cBluetoothRemoteAdapterAddressKey = "Bluetooth.RemoteAdapterAddress";
const std::string Configuration::cInputEnableTouchscreenKey = "Input.EnableTouchscreen";
const std::string Configuration::cInputPlayButtonKey = "Input.PlayButton";
const std::string Configuration::cInputPauseButtonKey = "Input.PauseButton";
const std::string Configuration::cInputTogglePlayButtonKey = "Input.TogglePlayButton";
const std::string Configuration::cInputNextTrackButtonKey = "Input.NextTrackButton";
const std::string Configuration::cInputPreviousTrackButtonKey = "Input.PreviousTrackButton";
const std::string Configuration::cInputHomeButtonKey = "Input.HomeButton";
const std::string Configuration::cInputPhoneButtonKey = "Input.PhoneButton";
const std::string Configuration::cInputCallEndButtonKey = "Input.CallEndButton";
const std::string Configuration::cInputVoiceCommandButtonKey = "Input.VoiceCommandButton";
const std::string Configuration::cInputLeftButtonKey = "Input.LeftButton";
const std::string Configuration::cInputRightButtonKey = "Input.RightButton";
const std::string Configuration::cInputUpButtonKey = "Input.UpButton";
const std::string Configuration::cInputDownButtonKey = "Input.DownButton";
const std::string Configuration::cInputScrollWheelButtonKey = "Input.ScrollWheelButton";
const std::string Configuration::cInputBackButtonKey = "Input.BackButton";
const std::string Configuration::cInputEnterButtonKey = "Input.EnterButton";
Configuration::Configuration()
{
this->load();
}
void Configuration::load()
{
boost::property_tree::ptree iniConfig;
try
{
boost::property_tree::ini_parser::read_ini(cConfigFileName, iniConfig);
handednessOfTrafficType_ = static_cast<HandednessOfTrafficType>(iniConfig.get<uint32_t>(cGeneralHandednessOfTrafficTypeKey,
static_cast<uint32_t>(HandednessOfTrafficType::LEFT_HAND_DRIVE)));
showClock_ = iniConfig.get<bool>(cGeneralShowClockKey, true);
videoFPS_ = static_cast<aasdk::proto::enums::VideoFPS::Enum>(iniConfig.get<uint32_t>(cVideoFPSKey,
aasdk::proto::enums::VideoFPS::_60));
videoResolution_ = static_cast<aasdk::proto::enums::VideoResolution::Enum>(iniConfig.get<uint32_t>(cVideoResolutionKey,
aasdk::proto::enums::VideoResolution::_480p));
screenDPI_ = iniConfig.get<size_t>(cVideoScreenDPIKey, 140);
enableTouchscreen_ = iniConfig.get<bool>(cInputEnableTouchscreenKey, true);
this->readButtonCodes(iniConfig);
bluetoothAdapterType_ = static_cast<BluetoothAdapterType>(iniConfig.get<uint32_t>(cBluetoothAdapterTypeKey,
static_cast<uint32_t>(BluetoothAdapterType::NONE)));
bluetoothRemoteAdapterAddress_ = iniConfig.get<std::string>(cBluetoothRemoteAdapterAddressKey, "");
}
catch(const boost::property_tree::ini_parser_error& e)
{
OPENAUTO_LOG(warning) << "[Configuration] failed to read configuration file: " << cConfigFileName
<< ", error: " << e.what();
this->reset();
}
}
void Configuration::reset()
{
handednessOfTrafficType_ = HandednessOfTrafficType::LEFT_HAND_DRIVE;
showClock_ = true;
videoFPS_ = aasdk::proto::enums::VideoFPS::_60;
videoResolution_ = aasdk::proto::enums::VideoResolution::_480p;
screenDPI_ = 140;
enableTouchscreen_ = true;
buttonCodes_.clear();
bluetoothAdapterType_ = BluetoothAdapterType::NONE;
bluetoothRemoteAdapterAddress_ = "";
}
void Configuration::save()
{
boost::property_tree::ptree iniConfig;
iniConfig.put<uint32_t>(cGeneralHandednessOfTrafficTypeKey, static_cast<uint32_t>(handednessOfTrafficType_));
iniConfig.put<bool>(cGeneralShowClockKey, showClock_);
iniConfig.put<uint32_t>(cVideoFPSKey, static_cast<uint32_t>(videoFPS_));
iniConfig.put<uint32_t>(cVideoResolutionKey, static_cast<uint32_t>(videoResolution_));
iniConfig.put<size_t>(cVideoScreenDPIKey, screenDPI_);
iniConfig.put<bool>(cInputEnableTouchscreenKey, enableTouchscreen_);
this->writeButtonCodes(iniConfig);
iniConfig.put<uint32_t>(cBluetoothAdapterTypeKey, static_cast<uint32_t>(bluetoothAdapterType_));
iniConfig.put<std::string>(cBluetoothRemoteAdapterAddressKey, bluetoothRemoteAdapterAddress_);
boost::property_tree::ini_parser::write_ini(cConfigFileName, iniConfig);
}
void Configuration::setHandednessOfTrafficType(HandednessOfTrafficType value)
{
handednessOfTrafficType_ = value;
}
HandednessOfTrafficType Configuration::getHandednessOfTrafficType() const
{
return handednessOfTrafficType_;
}
void Configuration::showClock(bool value)
{
showClock_ = value;
}
bool Configuration::showClock() const
{
return showClock_;
}
aasdk::proto::enums::VideoFPS::Enum Configuration::getVideoFPS() const
{
return videoFPS_;
}
void Configuration::setVideoFPS(aasdk::proto::enums::VideoFPS::Enum value)
{
videoFPS_ = value;
}
aasdk::proto::enums::VideoResolution::Enum Configuration::getVideoResolution() const
{
return videoResolution_;
}
void Configuration::setVideoResolution(aasdk::proto::enums::VideoResolution::Enum value)
{
videoResolution_ = value;
}
size_t Configuration::getScreenDPI() const
{
return screenDPI_;
}
void Configuration::setScreenDPI(size_t value)
{
screenDPI_ = value;
}
bool Configuration::getTouchscreenEnabled() const
{
return enableTouchscreen_;
}
void Configuration::setTouchscreenEnabled(bool value)
{
enableTouchscreen_ = value;
}
Configuration::ButtonCodes Configuration::getButtonCodes() const
{
return buttonCodes_;
}
void Configuration::setButtonCodes(const ButtonCodes& value)
{
buttonCodes_ = value;
}
BluetoothAdapterType Configuration::getBluetoothAdapterType() const
{
return bluetoothAdapterType_;
}
void Configuration::setBluetoothAdapterType(BluetoothAdapterType value)
{
bluetoothAdapterType_ = value;
}
std::string Configuration::getBluetoothRemoteAdapterAddress() const
{
return bluetoothRemoteAdapterAddress_;
}
void Configuration::setBluetoothRemoteAdapterAddress(const std::string& value)
{
bluetoothRemoteAdapterAddress_ = value;
}
void Configuration::readButtonCodes(boost::property_tree::ptree& iniConfig)
{
this->insertButtonCode(iniConfig, cInputPlayButtonKey, aasdk::proto::enums::ButtonCode::PLAY);
this->insertButtonCode(iniConfig, cInputPauseButtonKey, aasdk::proto::enums::ButtonCode::PAUSE);
this->insertButtonCode(iniConfig, cInputTogglePlayButtonKey, aasdk::proto::enums::ButtonCode::TOGGLE_PLAY);
this->insertButtonCode(iniConfig, cInputNextTrackButtonKey, aasdk::proto::enums::ButtonCode::NEXT);
this->insertButtonCode(iniConfig, cInputPreviousTrackButtonKey, aasdk::proto::enums::ButtonCode::PREV);
this->insertButtonCode(iniConfig, cInputHomeButtonKey, aasdk::proto::enums::ButtonCode::HOME);
this->insertButtonCode(iniConfig, cInputPhoneButtonKey, aasdk::proto::enums::ButtonCode::PHONE);
this->insertButtonCode(iniConfig, cInputCallEndButtonKey, aasdk::proto::enums::ButtonCode::CALL_END);
this->insertButtonCode(iniConfig, cInputVoiceCommandButtonKey, aasdk::proto::enums::ButtonCode::MICROPHONE_1);
this->insertButtonCode(iniConfig, cInputLeftButtonKey, aasdk::proto::enums::ButtonCode::LEFT);
this->insertButtonCode(iniConfig, cInputRightButtonKey, aasdk::proto::enums::ButtonCode::RIGHT);
this->insertButtonCode(iniConfig, cInputUpButtonKey, aasdk::proto::enums::ButtonCode::UP);
this->insertButtonCode(iniConfig, cInputDownButtonKey, aasdk::proto::enums::ButtonCode::DOWN);
this->insertButtonCode(iniConfig, cInputScrollWheelButtonKey, aasdk::proto::enums::ButtonCode::SCROLL_WHEEL);
this->insertButtonCode(iniConfig, cInputBackButtonKey, aasdk::proto::enums::ButtonCode::BACK);
this->insertButtonCode(iniConfig, cInputEnterButtonKey, aasdk::proto::enums::ButtonCode::ENTER);
}
void Configuration::insertButtonCode(boost::property_tree::ptree& iniConfig, const std::string& buttonCodeKey, aasdk::proto::enums::ButtonCode::Enum buttonCode)
{
if(iniConfig.get<bool>(buttonCodeKey, false))
{
buttonCodes_.push_back(buttonCode);
}
}
void Configuration::writeButtonCodes(boost::property_tree::ptree& iniConfig)
{
iniConfig.put<bool>(cInputPlayButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aasdk::proto::enums::ButtonCode::PLAY) != buttonCodes_.end());
iniConfig.put<bool>(cInputPauseButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aasdk::proto::enums::ButtonCode::PAUSE) != buttonCodes_.end());
iniConfig.put<bool>(cInputTogglePlayButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aasdk::proto::enums::ButtonCode::TOGGLE_PLAY) != buttonCodes_.end());
iniConfig.put<bool>(cInputNextTrackButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aasdk::proto::enums::ButtonCode::NEXT) != buttonCodes_.end());
iniConfig.put<bool>(cInputPreviousTrackButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aasdk::proto::enums::ButtonCode::PREV) != buttonCodes_.end());
iniConfig.put<bool>(cInputHomeButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aasdk::proto::enums::ButtonCode::HOME) != buttonCodes_.end());
iniConfig.put<bool>(cInputPhoneButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aasdk::proto::enums::ButtonCode::PHONE) != buttonCodes_.end());
iniConfig.put<bool>(cInputCallEndButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aasdk::proto::enums::ButtonCode::CALL_END) != buttonCodes_.end());
iniConfig.put<bool>(cInputVoiceCommandButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aasdk::proto::enums::ButtonCode::MICROPHONE_1) != buttonCodes_.end());
iniConfig.put<bool>(cInputLeftButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aasdk::proto::enums::ButtonCode::LEFT) != buttonCodes_.end());
iniConfig.put<bool>(cInputRightButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aasdk::proto::enums::ButtonCode::RIGHT) != buttonCodes_.end());
iniConfig.put<bool>(cInputUpButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aasdk::proto::enums::ButtonCode::UP) != buttonCodes_.end());
iniConfig.put<bool>(cInputDownButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aasdk::proto::enums::ButtonCode::DOWN) != buttonCodes_.end());
iniConfig.put<bool>(cInputScrollWheelButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aasdk::proto::enums::ButtonCode::SCROLL_WHEEL) != buttonCodes_.end());
iniConfig.put<bool>(cInputBackButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aasdk::proto::enums::ButtonCode::BACK) != buttonCodes_.end());
iniConfig.put<bool>(cInputEnterButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aasdk::proto::enums::ButtonCode::ENTER) != buttonCodes_.end());
}
}
}
}
}

View File

@ -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/>.
*/
#include <f1x/openauto/autoapp/USB/USBMain.hpp>
#include <f1x/openauto/Common/Log.hpp>
namespace aasdk = f1x::aasdk;
namespace autoapp = f1x::openauto::autoapp;
int main(int argc, char* argv[])
{
libusb_context* context;
if(libusb_init(&context) != 0)
{
OPENAUTO_LOG(error) << "[OpenAuto] libusb init failed.";
return 1;
}
autoapp::usb::USBMain main(context);
auto result = main.exec(argc, argv);
libusb_exit(context);
return result;
}

View File

@ -0,0 +1,249 @@
/*
* 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/aasdk/Messenger/MessageInStream.hpp>
#include <f1x/aasdk/Messenger/MessageOutStream.hpp>
#include <f1x/aasdk/Messenger/Messenger.hpp>
#include <f1x/openauto/autoapp/Projection/AndroidAutoEntity.hpp>
#include <f1x/openauto/Common/Log.hpp>
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace projection
{
AndroidAutoEntity::AndroidAutoEntity(boost::asio::io_service& ioService,
aasdk::messenger::ICryptor::Pointer cryptor,
aasdk::transport::ITransport::Pointer transport,
configuration::IConfiguration::Pointer configuration,
IServiceFactory& serviceFactory)
: strand_(ioService)
, cryptor_(std::move(cryptor))
, transport_(std::move(transport))
, configuration_(std::move(configuration))
, serviceFactory_(serviceFactory)
, messenger_(std::make_shared<aasdk::messenger::Messenger>(ioService,
std::make_shared<aasdk::messenger::MessageInStream>(ioService, transport_, cryptor_),
std::make_shared<aasdk::messenger::MessageOutStream>(ioService, transport_, cryptor_)))
, controlServiceChannel_(std::make_shared<aasdk::channel::control::ControlServiceChannel>(strand_, messenger_))
, eventHandler_(nullptr)
{
}
AndroidAutoEntity::~AndroidAutoEntity()
{
OPENAUTO_LOG(debug) << "[AndroidAutoEntity] destroy.";
}
void AndroidAutoEntity::start(IAndroidAutoEntityEventHandler& eventHandler)
{
strand_.dispatch([this, self = this->shared_from_this(), eventHandler = &eventHandler]() {
OPENAUTO_LOG(info) << "[AndroidAutoEntity] start.";
eventHandler_ = eventHandler;
cryptor_->init();
serviceList_ = serviceFactory_.create(messenger_);
std::for_each(serviceList_.begin(), serviceList_.end(), std::bind(&IService::start, std::placeholders::_1));
controlServiceChannel_->receive(this->shared_from_this());
auto versionRequestPromise = aasdk::channel::SendPromise::defer(strand_);
versionRequestPromise->then([]() {}, std::bind(&AndroidAutoEntity::onChannelError, this->shared_from_this(), std::placeholders::_1));
controlServiceChannel_->sendVersionRequest(std::move(versionRequestPromise));
});
}
void AndroidAutoEntity::stop()
{
strand_.dispatch([this, self = this->shared_from_this()]() {
OPENAUTO_LOG(info) << "[AndroidAutoEntity] stop.";
this->handleStop();
});
}
void AndroidAutoEntity::onVersionResponse(uint16_t majorCode, uint16_t minorCode, aasdk::proto::enums::VersionResponseStatus::Enum status)
{
OPENAUTO_LOG(info) << "[AndroidAutoEntity] version response, version: " << majorCode
<< "." << minorCode
<< ", status: " << status;
if(status == aasdk::proto::enums::VersionResponseStatus::MISMATCH)
{
OPENAUTO_LOG(error) << "[AndroidAutoEntity] version mismatch.";
eventHandler_->onAndroidAutoQuit();
}
else
{
OPENAUTO_LOG(info) << "[AndroidAutoEntity] Begin handshake.";
try
{
cryptor_->doHandshake();
auto handshakePromise = aasdk::channel::SendPromise::defer(strand_);
handshakePromise->then([]() {}, std::bind(&AndroidAutoEntity::onChannelError, this->shared_from_this(), std::placeholders::_1));
controlServiceChannel_->sendHandshake(cryptor_->readHandshakeBuffer(), std::move(handshakePromise));
controlServiceChannel_->receive(this->shared_from_this());
}
catch(const aasdk::error::Error& e)
{
this->onChannelError(e);
}
}
}
void AndroidAutoEntity::onHandshake(const aasdk::common::DataConstBuffer& payload)
{
OPENAUTO_LOG(info) << "[AndroidAutoEntity] Handshake, size: " << payload.size;
try
{
cryptor_->writeHandshakeBuffer(payload);
if(!cryptor_->doHandshake())
{
OPENAUTO_LOG(info) << "[AndroidAutoEntity] continue handshake.";
auto handshakePromise = aasdk::channel::SendPromise::defer(strand_);
handshakePromise->then([]() {}, std::bind(&AndroidAutoEntity::onChannelError, this->shared_from_this(), std::placeholders::_1));
controlServiceChannel_->sendHandshake(cryptor_->readHandshakeBuffer(), std::move(handshakePromise));
}
else
{
OPENAUTO_LOG(info) << "[AndroidAutoEntity] Auth completed.";
aasdk::proto::messages::AuthCompleteIndication authCompleteIndication;
authCompleteIndication.set_status(aasdk::proto::enums::Status::OK);
auto authCompletePromise = aasdk::channel::SendPromise::defer(strand_);
authCompletePromise->then([]() {}, std::bind(&AndroidAutoEntity::onChannelError, this->shared_from_this(), std::placeholders::_1));
controlServiceChannel_->sendAuthComplete(authCompleteIndication, std::move(authCompletePromise));
}
controlServiceChannel_->receive(this->shared_from_this());
}
catch(const aasdk::error::Error& e)
{
this->onChannelError(e);
}
}
void AndroidAutoEntity::onServiceDiscoveryRequest(const aasdk::proto::messages::ServiceDiscoveryRequest& request)
{
OPENAUTO_LOG(info) << "[AndroidAutoEntity] Discovery request, device name: " << request.device_name()
<< ", brand: " << request.device_brand();
aasdk::proto::messages::ServiceDiscoveryResponse serviceDiscoveryResponse;
serviceDiscoveryResponse.mutable_channels()->Reserve(256);
serviceDiscoveryResponse.set_head_unit_name("OpenAuto");
serviceDiscoveryResponse.set_car_model("Universal");
serviceDiscoveryResponse.set_car_year("2018");
serviceDiscoveryResponse.set_car_serial("20180301");
serviceDiscoveryResponse.set_left_hand_drive_vehicle(configuration_->getHandednessOfTrafficType() == configuration::HandednessOfTrafficType::LEFT_HAND_DRIVE);
serviceDiscoveryResponse.set_headunit_manufacturer("f1x");
serviceDiscoveryResponse.set_headunit_model("OpenAuto Autoapp");
serviceDiscoveryResponse.set_sw_build("1");
serviceDiscoveryResponse.set_sw_version("1.0");
serviceDiscoveryResponse.set_can_play_native_media_during_vr(false);
serviceDiscoveryResponse.set_hide_clock(!configuration_->showClock());
std::for_each(serviceList_.begin(), serviceList_.end(), std::bind(&IService::fillFeatures, std::placeholders::_1, std::ref(serviceDiscoveryResponse)));
auto promise = aasdk::channel::SendPromise::defer(strand_);
promise->then([]() {}, std::bind(&AndroidAutoEntity::onChannelError, this->shared_from_this(), std::placeholders::_1));
controlServiceChannel_->sendServiceDiscoveryResponse(serviceDiscoveryResponse, std::move(promise));
controlServiceChannel_->receive(this->shared_from_this());
}
void AndroidAutoEntity::onAudioFocusRequest(const aasdk::proto::messages::AudioFocusRequest& request)
{
OPENAUTO_LOG(info) << "[AndroidAutoEntity] requested audio focus, type: " << request.audio_focus_type();
aasdk::proto::enums::AudioFocusState::Enum audioFocusState =
request.audio_focus_type() == aasdk::proto::enums::AudioFocusType::RELEASE ? aasdk::proto::enums::AudioFocusState::LOSS
: aasdk::proto::enums::AudioFocusState::GAIN;
OPENAUTO_LOG(info) << "[AndroidAutoEntity] audio focus state: " << audioFocusState;
aasdk::proto::messages::AudioFocusResponse response;
response.set_audio_focus_state(audioFocusState);
auto promise = aasdk::channel::SendPromise::defer(strand_);
promise->then([]() {}, std::bind(&AndroidAutoEntity::onChannelError, this->shared_from_this(), std::placeholders::_1));
controlServiceChannel_->sendAudioFocusResponse(response, std::move(promise));
controlServiceChannel_->receive(this->shared_from_this());
}
void AndroidAutoEntity::onShutdownRequest(const aasdk::proto::messages::ShutdownRequest& request)
{
OPENAUTO_LOG(info) << "[AndroidAutoEntity] Shutdown request, reason: " << request.reason();
aasdk::proto::messages::ShutdownResponse response;
auto promise = aasdk::channel::SendPromise::defer(strand_);
promise->then([this, self = this->shared_from_this()]() {
eventHandler_->onAndroidAutoQuit();
},
std::bind(&AndroidAutoEntity::onChannelError, this->shared_from_this(), std::placeholders::_1));
controlServiceChannel_->sendShutdownResponse(response, std::move(promise));
controlServiceChannel_->receive(this->shared_from_this());
}
void AndroidAutoEntity::onShutdownResponse(const aasdk::proto::messages::ShutdownResponse&)
{
OPENAUTO_LOG(info) << "[AndroidAutoEntity] Shutdown response ";
eventHandler_->onAndroidAutoQuit();
}
void AndroidAutoEntity::onNavigationFocusRequest(const aasdk::proto::messages::NavigationFocusRequest& request)
{
OPENAUTO_LOG(info) << "[AndroidAutoEntity] navigation focus request, type: " << request.type();
aasdk::proto::messages::NavigationFocusResponse response;
response.set_type(2);
auto promise = aasdk::channel::SendPromise::defer(strand_);
promise->then([]() {}, std::bind(&AndroidAutoEntity::onChannelError, this->shared_from_this(), std::placeholders::_1));
controlServiceChannel_->sendNavigationFocusResponse(response, std::move(promise));
controlServiceChannel_->receive(this->shared_from_this());
}
void AndroidAutoEntity::onChannelError(const aasdk::error::Error& e)
{
OPENAUTO_LOG(error) << "[AndroidAutoEntity] channel error: " << e.what();
eventHandler_->onAndroidAutoQuit();
}
void AndroidAutoEntity::handleStop()
{
std::for_each(serviceList_.begin(), serviceList_.end(), std::bind(&IService::stop, std::placeholders::_1));
messenger_->stop();
cryptor_->deinit();
transport_->stop();
eventHandler_ = nullptr;
}
}
}
}
}

View File

@ -0,0 +1,61 @@
/*
* 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/aasdk/USB/AOAPDevice.hpp>
#include <f1x/aasdk/Transport/SSLWrapper.hpp>
#include <f1x/aasdk/Transport/USBTransport.hpp>
#include <f1x/aasdk/Messenger/Cryptor.hpp>
#include <f1x/openauto/autoapp/Projection/AndroidAutoEntityFactory.hpp>
#include <f1x/openauto/autoapp/Projection/AndroidAutoEntity.hpp>
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace projection
{
AndroidAutoEntityFactory::AndroidAutoEntityFactory(aasdk::usb::IUSBWrapper& usbWrapper,
boost::asio::io_service& ioService,
configuration::IConfiguration::Pointer configuration,
IServiceFactory& serviceFactory)
: usbWrapper_(usbWrapper)
, ioService_(ioService)
, configuration_(std::move(configuration))
, serviceFactory_(serviceFactory)
{
}
IAndroidAutoEntity::Pointer AndroidAutoEntityFactory::create(aasdk::usb::DeviceHandle deviceHandle)
{
auto aoapDevice(aasdk::usb::AOAPDevice::create(usbWrapper_, ioService_, deviceHandle));
auto transport(std::make_shared<aasdk::transport::USBTransport>(ioService_, aoapDevice));
auto sslWrapper(std::make_shared<aasdk::transport::SSLWrapper>());
auto cryptor(std::make_shared<aasdk::messenger::Cryptor>(std::move(sslWrapper)));
return std::make_shared<AndroidAutoEntity>(ioService_, std::move(cryptor), std::move(transport), configuration_, serviceFactory_);
}
}
}
}
}

View File

@ -0,0 +1,172 @@
/*
* 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/autoapp/Projection/AudioInput.hpp>
#include <f1x/openauto/Common/Log.hpp>
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace projection
{
AudioInput::AudioInput(uint32_t channelCount, uint32_t sampleSize, uint32_t sampleRate)
: ioDevice_(nullptr)
{
qRegisterMetaType<IAudioInput::StartPromise::Pointer>("StartPromise::Pointer");
audioFormat_.setChannelCount(channelCount);
audioFormat_.setSampleRate(sampleRate);
audioFormat_.setSampleSize(sampleSize);
audioFormat_.setCodec("audio/pcm");
audioFormat_.setByteOrder(QAudioFormat::LittleEndian);
audioFormat_.setSampleType(QAudioFormat::SignedInt);
this->moveToThread(QApplication::instance()->thread());
connect(this, &AudioInput::startRecording, this, &AudioInput::onStartRecording, Qt::QueuedConnection);
connect(this, &AudioInput::stopRecording, this, &AudioInput::onStopRecording, Qt::QueuedConnection);
QMetaObject::invokeMethod(this, "createAudioInput", Qt::BlockingQueuedConnection);
}
void AudioInput::createAudioInput()
{
OPENAUTO_LOG(debug) << "[AudioInput] create.";
audioInput_ = (std::make_unique<QAudioInput>(QAudioDeviceInfo::defaultInputDevice(), audioFormat_));
}
bool AudioInput::open()
{
std::lock_guard<decltype(mutex_)> lock(mutex_);
return ioDevice_ == nullptr;
}
bool AudioInput::isActive() const
{
std::lock_guard<decltype(mutex_)> lock(mutex_);
return ioDevice_ != nullptr;
}
void AudioInput::read(ReadPromise::Pointer promise)
{
std::lock_guard<decltype(mutex_)> lock(mutex_);
if(ioDevice_ == nullptr)
{
promise->reject();
}
else if(readPromise_ != nullptr)
{
promise->reject();
}
else
{
readPromise_ = std::move(promise);
}
}
void AudioInput::start(StartPromise::Pointer promise)
{
emit startRecording(std::move(promise));
}
void AudioInput::stop()
{
emit stopRecording();
}
uint32_t AudioInput::getSampleSize() const
{
std::lock_guard<decltype(mutex_)> lock(mutex_);
return audioFormat_.sampleSize();
}
uint32_t AudioInput::getChannelCount() const
{
std::lock_guard<decltype(mutex_)> lock(mutex_);
return audioFormat_.channelCount();
}
uint32_t AudioInput::getSampleRate() const
{
std::lock_guard<decltype(mutex_)> lock(mutex_);
return audioFormat_.sampleRate();
}
void AudioInput::onStartRecording(StartPromise::Pointer promise)
{
ioDevice_ = audioInput_->start();
if(ioDevice_ != nullptr)
{
connect(ioDevice_, &QIODevice::readyRead, this, &AudioInput::onReadyRead, Qt::QueuedConnection);
promise->resolve();
}
else
{
promise->reject();
}
}
void AudioInput::onStopRecording()
{
if(readPromise_ != nullptr)
{
readPromise_->reject();
readPromise_.reset();
}
ioDevice_->reset();
ioDevice_->disconnect();
audioInput_->stop();
ioDevice_ = nullptr;
}
void AudioInput::onReadyRead()
{
if(readPromise_ == nullptr)
{
return;
}
aasdk::common::Data data(cSampleSize, 0);
aasdk::common::DataBuffer buffer(data);
auto readSize = ioDevice_->read(reinterpret_cast<char*>(buffer.data), buffer.size);
if(readSize != -1)
{
data.resize(readSize);
readPromise_->resolve(std::move(data));
readPromise_.reset();
}
else
{
readPromise_->reject();
readPromise_.reset();
}
}
}
}
}
}

View File

@ -0,0 +1,208 @@
/*
* 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 <time.h>
#include <f1x/openauto/Common/Log.hpp>
#include <f1x/openauto/autoapp/Projection/AudioInputService.hpp>
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace projection
{
AudioInputService::AudioInputService(boost::asio::io_service& ioService, aasdk::messenger::IMessenger::Pointer messenger, IAudioInput::Pointer audioInput)
: strand_(ioService)
, channel_(std::make_shared<aasdk::channel::av::AVInputServiceChannel>(strand_, std::move(messenger)))
, audioInput_(std::move(audioInput))
, session_(0)
{
}
void AudioInputService::start()
{
strand_.dispatch([this, self = this->shared_from_this()]() {
OPENAUTO_LOG(info) << "[AudioInputService] start.";
channel_->receive(this->shared_from_this());
});
}
void AudioInputService::stop()
{
strand_.dispatch([this, self = this->shared_from_this()]() {
OPENAUTO_LOG(info) << "[AudioInputService] stop.";
if(audioInput_->isActive())
{
audioInput_->stop();
}
});
}
void AudioInputService::fillFeatures(aasdk::proto::messages::ServiceDiscoveryResponse& response)
{
OPENAUTO_LOG(info) << "[AudioInputService] fill features.";
auto* channelDescriptor = response.add_channels();
channelDescriptor->set_channel_id(static_cast<uint32_t>(channel_->getId()));
auto* avInputChannel = channelDescriptor->mutable_av_input_channel();
avInputChannel->set_stream_type(aasdk::proto::enums::AVStreamType::AUDIO);
auto audioConfig = avInputChannel->mutable_audio_config();
audioConfig->set_sample_rate(audioInput_->getSampleRate());
audioConfig->set_bit_depth(audioInput_->getSampleSize());
audioConfig->set_channel_count(audioInput_->getChannelCount());
}
void AudioInputService::onChannelOpenRequest(const aasdk::proto::messages::ChannelOpenRequest& request)
{
OPENAUTO_LOG(info) << "[AudioInputService] open request, priority: " << request.priority();
const aasdk::proto::enums::Status::Enum status = audioInput_->open() ? aasdk::proto::enums::Status::OK : aasdk::proto::enums::Status::FAIL;
OPENAUTO_LOG(info) << "[AudioInputService] open status: " << status;
aasdk::proto::messages::ChannelOpenResponse response;
response.set_status(status);
auto promise = aasdk::channel::SendPromise::defer(strand_);
promise->then([]() {}, std::bind(&AudioInputService::onChannelError, this->shared_from_this(), std::placeholders::_1));
channel_->sendChannelOpenResponse(response, std::move(promise));
channel_->receive(this->shared_from_this());
}
void AudioInputService::onAVChannelSetupRequest(const aasdk::proto::messages::AVChannelSetupRequest& request)
{
OPENAUTO_LOG(info) << "[AudioInputService] setup request, config index: " << request.config_index();
const aasdk::proto::enums::AVChannelSetupStatus::Enum status = aasdk::proto::enums::AVChannelSetupStatus::OK;
OPENAUTO_LOG(info) << "[AudioInputService] setup status: " << status;
aasdk::proto::messages::AVChannelSetupResponse response;
response.set_media_status(status);
response.set_max_unacked(1);
response.add_configs(0);
auto promise = aasdk::channel::SendPromise::defer(strand_);
promise->then([]() {}, std::bind(&AudioInputService::onChannelError, this->shared_from_this(), std::placeholders::_1));
channel_->sendAVChannelSetupResponse(response, std::move(promise));
channel_->receive(this->shared_from_this());
}
void AudioInputService::onAVInputOpenRequest(const aasdk::proto::messages::AVInputOpenRequest& request)
{
OPENAUTO_LOG(info) << "[AudioInputService] input open request, open: " << request.open()
<< ", anc: " << request.anc()
<< ", ec: " << request.ec()
<< ", max unacked: " << request.max_unacked();
if(request.open())
{
auto startPromise = IAudioInput::StartPromise::defer(strand_);
startPromise->then(std::bind(&AudioInputService::onAudioInputOpenSucceed, this->shared_from_this()),
[this, self = this->shared_from_this()]() {
OPENAUTO_LOG(error) << "[AudioInputService] audio input open failed.";
aasdk::proto::messages::AVInputOpenResponse response;
response.set_session(session_);
response.set_value(1);
auto sendPromise = aasdk::channel::SendPromise::defer(strand_);
sendPromise->then([]() {}, std::bind(&AudioInputService::onChannelError, this->shared_from_this(), std::placeholders::_1));
channel_->sendAVInputOpenResponse(response, std::move(sendPromise));
});
audioInput_->start(std::move(startPromise));
}
else
{
audioInput_->stop();
aasdk::proto::messages::AVInputOpenResponse response;
response.set_session(session_);
response.set_value(0);
auto sendPromise = aasdk::channel::SendPromise::defer(strand_);
sendPromise->then([]() {}, std::bind(&AudioInputService::onChannelError, this->shared_from_this(), std::placeholders::_1));
channel_->sendAVInputOpenResponse(response, std::move(sendPromise));
}
channel_->receive(this->shared_from_this());
}
void AudioInputService::onAVMediaAckIndication(const aasdk::proto::messages::AVMediaAckIndication&)
{
channel_->receive(this->shared_from_this());
}
void AudioInputService::onChannelError(const aasdk::error::Error& e)
{
OPENAUTO_LOG(error) << "[AudioInputService] channel error: " << e.what();
}
void AudioInputService::onAudioInputOpenSucceed()
{
OPENAUTO_LOG(info) << "[AudioInputService] audio input open succeed.";
aasdk::proto::messages::AVInputOpenResponse response;
response.set_session(session_);
response.set_value(0);
auto sendPromise = aasdk::channel::SendPromise::defer(strand_);
sendPromise->then([]() {}, std::bind(&AudioInputService::onChannelError, this->shared_from_this(), std::placeholders::_1));
channel_->sendAVInputOpenResponse(response, std::move(sendPromise));
this->readAudioInput();
}
void AudioInputService::onAudioInputDataReady(aasdk::common::Data data)
{
auto sendPromise = aasdk::channel::SendPromise::defer(strand_);
sendPromise->then(std::bind(&AudioInputService::readAudioInput, this->shared_from_this()),
std::bind(&AudioInputService::onChannelError, this->shared_from_this(), std::placeholders::_1));
timespec tp;
clock_gettime(CLOCK_REALTIME, &tp);
auto timestamp = tp.tv_sec * 1000000 + tp.tv_nsec / 1000;
channel_->sendAVMediaWithTimestampIndication(timestamp, std::move(data), std::move(sendPromise));
}
void AudioInputService::readAudioInput()
{
if(audioInput_->isActive())
{
auto readPromise = IAudioInput::ReadPromise::defer(strand_);
readPromise->then(std::bind(&AudioInputService::onAudioInputDataReady, this->shared_from_this(), std::placeholders::_1),
[this, self = this->shared_from_this()]() {
OPENAUTO_LOG(info) << "[AudioInputService] audio input read rejected.";
});
audioInput_->read(std::move(readPromise));
}
}
}
}
}
}

View File

@ -0,0 +1,102 @@
/*
* 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/autoapp/Projection/AudioOutput.hpp>
#include <f1x/openauto/Common/Log.hpp>
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace projection
{
AudioOutput::AudioOutput(uint32_t channelCount, uint32_t sampleSize, uint32_t sampleRate)
{
audioFormat_.setChannelCount(channelCount);
audioFormat_.setSampleRate(sampleRate);
audioFormat_.setSampleSize(sampleSize);
audioFormat_.setCodec("audio/pcm");
audioFormat_.setByteOrder(QAudioFormat::LittleEndian);
audioFormat_.setSampleType(QAudioFormat::SignedInt);
this->moveToThread(QApplication::instance()->thread());
connect(this, &AudioOutput::startPlayback, this, &AudioOutput::onStartPlayback);
connect(this, &AudioOutput::stopPlayback, this, &AudioOutput::onStopPlayback);
QMetaObject::invokeMethod(this, "createAudioOutput", Qt::BlockingQueuedConnection);
}
void AudioOutput::createAudioOutput()
{
OPENAUTO_LOG(debug) << "[AudioOutput] create.";
audioOutput_ = std::make_unique<QAudioOutput>(QAudioDeviceInfo::defaultOutputDevice(), audioFormat_);
}
bool AudioOutput::open()
{
return audioBuffer_.open(QIODevice::ReadWrite);
}
void AudioOutput::write(const aasdk::common::DataConstBuffer& buffer)
{
audioBuffer_.write(reinterpret_cast<const char*>(buffer.cdata), buffer.size);
}
void AudioOutput::start()
{
emit startPlayback();
}
void AudioOutput::stop()
{
emit stopPlayback();
}
uint32_t AudioOutput::getSampleSize() const
{
return audioFormat_.sampleSize();
}
uint32_t AudioOutput::getChannelCount() const
{
return audioFormat_.channelCount();
}
uint32_t AudioOutput::getSampleRate() const
{
return audioFormat_.sampleRate();
}
void AudioOutput::onStartPlayback()
{
audioOutput_->start(&audioBuffer_);
}
void AudioOutput::onStopPlayback()
{
audioOutput_->suspend();
}
}
}
}
}

View File

@ -0,0 +1,176 @@
/*
* 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/autoapp/Projection/AudioService.hpp>
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace projection
{
AudioService::AudioService(boost::asio::io_service& ioService, aasdk::channel::av::IAudioServiceChannel::Pointer channel, IAudioOutput::Pointer audioOutput)
: strand_(ioService)
, channel_(std::move(channel))
, audioOutput_(std::move(audioOutput))
, session_(-1)
{
}
void AudioService::start()
{
strand_.dispatch([this, self = this->shared_from_this()]() {
OPENAUTO_LOG(info) << "[AudioService] start, channel: " << aasdk::messenger::channelIdToString(channel_->getId());
channel_->receive(this->shared_from_this());
});
}
void AudioService::stop()
{
strand_.dispatch([this, self = this->shared_from_this()]() {
OPENAUTO_LOG(info) << "[AudioService] stop, channel: " << aasdk::messenger::channelIdToString(channel_->getId());
audioOutput_->stop();
});
}
void AudioService::fillFeatures(aasdk::proto::messages::ServiceDiscoveryResponse& response)
{
OPENAUTO_LOG(info) << "[AudioService] fill features, channel: " << aasdk::messenger::channelIdToString(channel_->getId());
auto* channelDescriptor = response.add_channels();
channelDescriptor->set_channel_id(static_cast<uint32_t>(channel_->getId()));
auto* audioChannel = channelDescriptor->mutable_av_channel();
audioChannel->set_stream_type(aasdk::proto::enums::AVStreamType::AUDIO);
switch(channel_->getId())
{
case aasdk::messenger::ChannelId::SYSTEM_AUDIO:
audioChannel->set_audio_type(aasdk::proto::enums::AudioType::SYSTEM);
break;
case aasdk::messenger::ChannelId::MEDIA_AUDIO:
audioChannel->set_audio_type(aasdk::proto::enums::AudioType::MEDIA);
break;
case aasdk::messenger::ChannelId::SPEECH_AUDIO:
audioChannel->set_audio_type(aasdk::proto::enums::AudioType::SPEECH);
break;
default:
break;
}
audioChannel->set_available_while_in_call(true);
auto* audioConfig = audioChannel->add_audio_configs();
audioConfig->set_sample_rate(audioOutput_->getSampleRate());
audioConfig->set_bit_depth(audioOutput_->getSampleSize());
audioConfig->set_channel_count(audioOutput_->getChannelCount());
}
void AudioService::onChannelOpenRequest(const aasdk::proto::messages::ChannelOpenRequest& request)
{
OPENAUTO_LOG(info) << "[AudioService] open request"
<< ", channel: " << aasdk::messenger::channelIdToString(channel_->getId())
<< ", priority: " << request.priority();
const aasdk::proto::enums::Status::Enum status = audioOutput_->open() ? aasdk::proto::enums::Status::OK : aasdk::proto::enums::Status::FAIL;
OPENAUTO_LOG(info) << "[AudioService] open status: " << status
<< ", channel: " << aasdk::messenger::channelIdToString(channel_->getId());
aasdk::proto::messages::ChannelOpenResponse response;
response.set_status(status);
auto promise = aasdk::channel::SendPromise::defer(strand_);
promise->then([]() {}, std::bind(&AudioService::onChannelError, this->shared_from_this(), std::placeholders::_1));
channel_->sendChannelOpenResponse(response, std::move(promise));
channel_->receive(this->shared_from_this());
}
void AudioService::onAVChannelSetupRequest(const aasdk::proto::messages::AVChannelSetupRequest& request)
{
OPENAUTO_LOG(info) << "[AudioService] setup request"
<< ", channel: " << aasdk::messenger::channelIdToString(channel_->getId())
<< ", config index: " << request.config_index();
const aasdk::proto::enums::AVChannelSetupStatus::Enum status = aasdk::proto::enums::AVChannelSetupStatus::OK;
OPENAUTO_LOG(info) << "[AudioService] setup status: " << status
<< ", channel: " << aasdk::messenger::channelIdToString(channel_->getId());
aasdk::proto::messages::AVChannelSetupResponse response;
response.set_media_status(status);
response.set_max_unacked(1);
response.add_configs(0);
auto promise = aasdk::channel::SendPromise::defer(strand_);
promise->then([]() {}, std::bind(&AudioService::onChannelError, this->shared_from_this(), std::placeholders::_1));
channel_->sendAVChannelSetupResponse(response, std::move(promise));
channel_->receive(this->shared_from_this());
}
void AudioService::onAVChannelStartIndication(const aasdk::proto::messages::AVChannelStartIndication& indication)
{
OPENAUTO_LOG(info) << "[AudioService] start indication"
<< ", channel: " << aasdk::messenger::channelIdToString(channel_->getId())
<< ", session: " << indication.session();
session_ = indication.session();
audioOutput_->start();
channel_->receive(this->shared_from_this());
}
void AudioService::onAVChannelStopIndication(const aasdk::proto::messages::AVChannelStopIndication& indication)
{
OPENAUTO_LOG(info) << "[AudioService] stop indication"
<< ", channel: " << aasdk::messenger::channelIdToString(channel_->getId())
<< ", session: " << session_;
session_ = -1;
audioOutput_->stop();
channel_->receive(this->shared_from_this());
}
void AudioService::onAVMediaWithTimestampIndication(aasdk::messenger::Timestamp::ValueType, const aasdk::common::DataConstBuffer& buffer)
{
this->onAVMediaIndication(buffer);
}
void AudioService::onAVMediaIndication(const aasdk::common::DataConstBuffer& buffer)
{
audioOutput_->write(buffer);
aasdk::proto::messages::AVMediaAckIndication indication;
indication.set_session(session_);
indication.set_value(1);
auto promise = aasdk::channel::SendPromise::defer(strand_);
promise->then([]() {}, std::bind(&AudioService::onChannelError, this->shared_from_this(), std::placeholders::_1));
channel_->sendAVMediaAckIndication(indication, std::move(promise));
channel_->receive(this->shared_from_this());
}
void AudioService::onChannelError(const aasdk::error::Error& e)
{
OPENAUTO_LOG(error) << "[AudioService] channel error: " << e.what()
<< ", channel: " << aasdk::messenger::channelIdToString(channel_->getId());
}
}
}
}
}

View File

@ -0,0 +1,111 @@
/*
* 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/autoapp/Projection/BluetoothService.hpp>
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace projection
{
BluetoothService::BluetoothService(boost::asio::io_service& ioService, aasdk::messenger::IMessenger::Pointer messenger, IBluetoothDevice::Pointer bluetoothDevice)
: strand_(ioService)
, channel_(std::make_shared<aasdk::channel::bluetooth::BluetoothServiceChannel>(strand_, std::move(messenger)))
, bluetoothDevice_(std::move(bluetoothDevice))
{
}
void BluetoothService::start()
{
strand_.dispatch([this, self = this->shared_from_this()]() {
OPENAUTO_LOG(info) << "[BluetoothService] start.";
channel_->receive(this->shared_from_this());
});
}
void BluetoothService::stop()
{
strand_.dispatch([this, self = this->shared_from_this()]() {
OPENAUTO_LOG(info) << "[BluetoothService] stop.";
bluetoothDevice_->stop();
});
}
void BluetoothService::fillFeatures(aasdk::proto::messages::ServiceDiscoveryResponse& response)
{
OPENAUTO_LOG(info) << "[BluetoothService] fill features";
if(bluetoothDevice_->isAvailable())
{
OPENAUTO_LOG(info) << "[BluetoothService] sending local adapter adress: " << bluetoothDevice_->getLocalAddress();
auto* channelDescriptor = response.add_channels();
channelDescriptor->set_channel_id(static_cast<uint32_t>(channel_->getId()));
auto bluetoothChannel = channelDescriptor->mutable_bluetooth_channel();
bluetoothChannel->set_adapter_address(bluetoothDevice_->getLocalAddress());
}
}
void BluetoothService::onChannelOpenRequest(const aasdk::proto::messages::ChannelOpenRequest& request)
{
OPENAUTO_LOG(info) << "[BluetoothService] open request, priority: " << request.priority();
const aasdk::proto::enums::Status::Enum status = aasdk::proto::enums::Status::OK;
OPENAUTO_LOG(info) << "[BluetoothService] open status: " << status;
aasdk::proto::messages::ChannelOpenResponse response;
response.set_status(status);
auto promise = aasdk::channel::SendPromise::defer(strand_);
promise->then([]() {}, std::bind(&BluetoothService::onChannelError, this->shared_from_this(), std::placeholders::_1));
channel_->sendChannelOpenResponse(response, std::move(promise));
channel_->receive(this->shared_from_this());
}
void BluetoothService::onBluetoothPairingRequest(const aasdk::proto::messages::BluetoothPairingRequest& request)
{
OPENAUTO_LOG(info) << "[BluetoothService] pairing request, address: " << request.phone_address();
aasdk::proto::messages::BluetoothPairingResponse response;
const auto isPaired = bluetoothDevice_->isPaired(request.phone_address());
response.set_already_paired(isPaired);
response.set_status(isPaired ? aasdk::proto::enums::BluetoothPairingStatus::OK : aasdk::proto::enums::BluetoothPairingStatus::FAIL);
auto promise = aasdk::channel::SendPromise::defer(strand_);
promise->then([]() {}, std::bind(&BluetoothService::onChannelError, this->shared_from_this(), std::placeholders::_1));
channel_->sendBluetoothPairingResponse(response, std::move(promise));
channel_->receive(this->shared_from_this());
}
void BluetoothService::onChannelError(const aasdk::error::Error& e)
{
OPENAUTO_LOG(error) << "[BluetoothService] channel error: " << e.what();
}
}
}
}
}

View File

@ -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 <f1x/openauto/autoapp/Projection/DummyBluetoothDevice.hpp>
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace projection
{
void DummyBluetoothDevice::stop()
{
}
bool DummyBluetoothDevice::isPaired(const std::string&) const
{
return false;
}
void DummyBluetoothDevice::pair(const std::string&, PairingPromise::Pointer promise)
{
promise->reject();
}
std::string DummyBluetoothDevice::getLocalAddress() const
{
return "";
}
bool DummyBluetoothDevice::isAvailable() const
{
return false;
}
}
}
}
}

View File

@ -0,0 +1,233 @@
/*
* 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/autoapp/Projection/IInputDeviceEventHandler.hpp>
#include <f1x/openauto/autoapp/Projection/InputDevice.hpp>
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace projection
{
InputDevice::InputDevice(QObject& parent, configuration::IConfiguration::Pointer configuration, const QRect& touchscreenGeometry, const QRect& displayGeometry)
: parent_(parent)
, configuration_(std::move(configuration))
, touchscreenGeometry_(touchscreenGeometry)
, displayGeometry_(displayGeometry)
, eventHandler_(nullptr)
{
this->moveToThread(parent.thread());
}
void InputDevice::start(IInputDeviceEventHandler& eventHandler)
{
std::lock_guard<decltype(mutex_)> lock(mutex_);
OPENAUTO_LOG(info) << "[InputDevice] start.";
eventHandler_ = &eventHandler;
parent_.installEventFilter(this);
}
void InputDevice::stop()
{
std::lock_guard<decltype(mutex_)> lock(mutex_);
OPENAUTO_LOG(info) << "[InputDevice] stop.";
parent_.removeEventFilter(this);
eventHandler_ = nullptr;
}
bool InputDevice::eventFilter(QObject* obj, QEvent* event)
{
std::lock_guard<decltype(mutex_)> lock(mutex_);
if(eventHandler_ != nullptr)
{
if(event->type() == QEvent::KeyPress || event->type() == QEvent::KeyRelease)
{
QKeyEvent* key = static_cast<QKeyEvent*>(event);
if(!key->isAutoRepeat())
{
return this->handleKeyEvent(event, key);
}
}
else if(event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonRelease || event->type() == QEvent::MouseMove)
{
return this->handleTouchEvent(event);
}
}
return QObject::eventFilter(obj, event);
}
bool InputDevice::handleKeyEvent(QEvent* event, QKeyEvent* key)
{
auto eventType = event->type() == QEvent::KeyPress ? ButtonEventType::PRESS : ButtonEventType::RELEASE;
aasdk::proto::enums::ButtonCode::Enum buttonCode;
WheelDirection wheelDirection = WheelDirection::NONE;
switch(key->key())
{
case Qt::Key_Return:
case Qt::Key_Enter:
buttonCode = aasdk::proto::enums::ButtonCode::ENTER;
break;
case Qt::Key_Left:
buttonCode = aasdk::proto::enums::ButtonCode::LEFT;
break;
case Qt::Key_Right:
buttonCode = aasdk::proto::enums::ButtonCode::RIGHT;
break;
case Qt::Key_Up:
buttonCode = aasdk::proto::enums::ButtonCode::UP;
break;
case Qt::Key_Down:
buttonCode = aasdk::proto::enums::ButtonCode::DOWN;
break;
case Qt::Key_Escape:
buttonCode = aasdk::proto::enums::ButtonCode::BACK;
break;
case Qt::Key_H:
buttonCode = aasdk::proto::enums::ButtonCode::HOME;
break;
case Qt::Key_P:
buttonCode = aasdk::proto::enums::ButtonCode::PHONE;
break;
case Qt::Key_O:
buttonCode = aasdk::proto::enums::ButtonCode::CALL_END;
break;
case Qt::Key_X:
buttonCode = aasdk::proto::enums::ButtonCode::PLAY;
break;
case Qt::Key_C:
buttonCode = aasdk::proto::enums::ButtonCode::PAUSE;
break;
case Qt::Key_V:
buttonCode = aasdk::proto::enums::ButtonCode::PREV;
break;
case Qt::Key_B:
buttonCode = aasdk::proto::enums::ButtonCode::TOGGLE_PLAY;
break;
case Qt::Key_N:
buttonCode = aasdk::proto::enums::ButtonCode::NEXT;
break;
case Qt::Key_M:
buttonCode = aasdk::proto::enums::ButtonCode::MICROPHONE_1;
break;
case Qt::Key_1:
wheelDirection = WheelDirection::LEFT;
eventType = ButtonEventType::NONE;
buttonCode = aasdk::proto::enums::ButtonCode::SCROLL_WHEEL;
break;
case Qt::Key_2:
wheelDirection = WheelDirection::RIGHT;
eventType = ButtonEventType::NONE;
buttonCode = aasdk::proto::enums::ButtonCode::SCROLL_WHEEL;
break;
default:
return false;
}
const auto& buttonCodes = this->getSupportedButtonCodes();
if(std::find(buttonCodes.begin(), buttonCodes.end(), buttonCode) != buttonCodes.end())
{
if(buttonCode != aasdk::proto::enums::ButtonCode::SCROLL_WHEEL || event->type() == QEvent::KeyRelease)
{
eventHandler_->onButtonEvent({eventType, wheelDirection, buttonCode});
}
}
return true;
}
bool InputDevice::handleTouchEvent(QEvent* event)
{
if(!configuration_->getTouchscreenEnabled())
{
return false;
}
aasdk::proto::enums::TouchAction::Enum type;
switch(event->type())
{
case QEvent::MouseButtonPress:
type = aasdk::proto::enums::TouchAction::PRESS;
break;
case QEvent::MouseButtonRelease:
type = aasdk::proto::enums::TouchAction::RELEASE;
break;
case QEvent::MouseMove:
type = aasdk::proto::enums::TouchAction::DRAG;
break;
default:
return false;
};
QMouseEvent* mouse = static_cast<QMouseEvent*>(event);
if(event->type() == QEvent::MouseButtonRelease || mouse->buttons().testFlag(Qt::LeftButton))
{
const uint32_t x = (static_cast<float>(mouse->pos().x()) / touchscreenGeometry_.width()) * displayGeometry_.width();
const uint32_t y = (static_cast<float>(mouse->pos().y()) / touchscreenGeometry_.height()) * displayGeometry_.height();
eventHandler_->onTouchEvent({type, x, y, 0});
}
return true;
}
bool InputDevice::hasTouchscreen() const
{
return configuration_->getTouchscreenEnabled();
}
QRect InputDevice::getTouchscreenGeometry() const
{
return touchscreenGeometry_;
}
IInputDevice::ButtonCodes InputDevice::getSupportedButtonCodes() const
{
return configuration_->getButtonCodes();
}
}
}
}
}

View File

@ -0,0 +1,195 @@
/*
* 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 <aasdk_proto/InputEventIndicationMessage.pb.h>
#include <f1x/openauto/Common/Log.hpp>
#include <f1x/openauto/autoapp/Projection/InputService.hpp>
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace projection
{
InputService::InputService(boost::asio::io_service& ioService, aasdk::messenger::IMessenger::Pointer messenger, IInputDevice::Pointer inputDevice)
: strand_(ioService)
, channel_(std::make_shared<aasdk::channel::input::InputServiceChannel>(strand_, std::move(messenger)))
, inputDevice_(std::move(inputDevice))
{
}
void InputService::start()
{
strand_.dispatch([this, self = this->shared_from_this()]() {
OPENAUTO_LOG(info) << "[InputService] start.";
channel_->receive(this->shared_from_this());
});
}
void InputService::stop()
{
strand_.dispatch([this, self = this->shared_from_this()]() {
OPENAUTO_LOG(info) << "[InputService] stop.";
inputDevice_->stop();
});
}
void InputService::fillFeatures(aasdk::proto::messages::ServiceDiscoveryResponse& response)
{
OPENAUTO_LOG(info) << "[InputService] fill features.";
auto* channelDescriptor = response.add_channels();
channelDescriptor->set_channel_id(static_cast<uint32_t>(channel_->getId()));
auto* inputChannel = channelDescriptor->mutable_input_channel();
const auto& supportedButtonCodes = inputDevice_->getSupportedButtonCodes();
for(const auto& buttonCode : supportedButtonCodes)
{
inputChannel->add_supported_keycodes(buttonCode);
}
if(inputDevice_->hasTouchscreen())
{
const auto& touchscreenSurface = inputDevice_->getTouchscreenGeometry();
auto touchscreenConfig = inputChannel->mutable_touch_screen_config();
touchscreenConfig->set_width(touchscreenSurface.width());
touchscreenConfig->set_height(touchscreenSurface.height());
}
}
void InputService::onChannelOpenRequest(const aasdk::proto::messages::ChannelOpenRequest& request)
{
OPENAUTO_LOG(info) << "[InputService] open request, priority: " << request.priority();
const aasdk::proto::enums::Status::Enum status = aasdk::proto::enums::Status::OK;
OPENAUTO_LOG(info) << "[InputService] open status: " << status;
aasdk::proto::messages::ChannelOpenResponse response;
response.set_status(status);
auto promise = aasdk::channel::SendPromise::defer(strand_);
promise->then([]() {}, std::bind(&InputService::onChannelError, this->shared_from_this(), std::placeholders::_1));
channel_->sendChannelOpenResponse(response, std::move(promise));
channel_->receive(this->shared_from_this());
}
void InputService::onBindingRequest(const aasdk::proto::messages::BindingRequest& request)
{
OPENAUTO_LOG(info) << "[InputService] binding request, scan codes count: " << request.scan_codes_size();
aasdk::proto::enums::Status::Enum status = aasdk::proto::enums::Status::OK;
const auto& supportedButtonCodes = inputDevice_->getSupportedButtonCodes();
for(int i = 0; i < request.scan_codes_size(); ++i)
{
if(std::find(supportedButtonCodes.begin(), supportedButtonCodes.end(), request.scan_codes(i)) == supportedButtonCodes.end())
{
OPENAUTO_LOG(error) << "[InputService] binding request, scan code: " << request.scan_codes(i)
<< " is not supported.";
status = aasdk::proto::enums::Status::FAIL;
break;
}
}
aasdk::proto::messages::BindingResponse response;
response.set_status(status);
if(status == aasdk::proto::enums::Status::OK)
{
inputDevice_->start(*this);
}
OPENAUTO_LOG(info) << "[InputService] binding request, status: " << status;
auto promise = aasdk::channel::SendPromise::defer(strand_);
promise->then([]() {}, std::bind(&InputService::onChannelError, this->shared_from_this(), std::placeholders::_1));
channel_->sendBindingResponse(response, std::move(promise));
channel_->receive(this->shared_from_this());
}
void InputService::onChannelError(const aasdk::error::Error& e)
{
OPENAUTO_LOG(error) << "[SensorService] channel error: " << e.what();
}
void InputService::onButtonEvent(const ButtonEvent& event)
{
timespec tp;
clock_gettime(CLOCK_REALTIME, &tp);
auto timestamp = tp.tv_sec * 1000000 + tp.tv_nsec / 1000;
strand_.dispatch([this, self = this->shared_from_this(), event = std::move(event), timestamp]() {
aasdk::proto::messages::InputEventIndication inputEventIndication;
inputEventIndication.set_timestamp(timestamp);
if(event.code == aasdk::proto::enums::ButtonCode::SCROLL_WHEEL)
{
auto relativeEvent = inputEventIndication.mutable_relative_input_event()->add_relative_input_events();
relativeEvent->set_delta(event.wheelDirection == WheelDirection::LEFT ? -1 : 1);
relativeEvent->set_scan_code(event.code);
}
else
{
auto buttonEvent = inputEventIndication.mutable_button_event()->add_button_events();
buttonEvent->set_meta(0);
buttonEvent->set_is_pressed(event.type == ButtonEventType::PRESS);
buttonEvent->set_long_press(false);
buttonEvent->set_scan_code(event.code);
}
auto promise = aasdk::channel::SendPromise::defer(strand_);
promise->then([]() {}, std::bind(&InputService::onChannelError, this->shared_from_this(), std::placeholders::_1));
channel_->sendInputEventIndication(inputEventIndication, std::move(promise));
});
}
void InputService::onTouchEvent(const TouchEvent& event)
{
timespec tp;
clock_gettime(CLOCK_REALTIME, &tp);
auto timestamp = tp.tv_sec * 1000000 + tp.tv_nsec / 1000;
strand_.dispatch([this, self = this->shared_from_this(), event = std::move(event), timestamp]() {
aasdk::proto::messages::InputEventIndication inputEventIndication;
inputEventIndication.set_timestamp(timestamp);
auto touchEvent = inputEventIndication.mutable_touch_event();
touchEvent->set_touch_action(event.type);
auto touchLocation = touchEvent->add_touch_location();
touchLocation->set_x(event.x);
touchLocation->set_y(event.y);
touchLocation->set_pointer_id(0);
auto promise = aasdk::channel::SendPromise::defer(strand_);
promise->then([]() {}, std::bind(&InputService::onChannelError, this->shared_from_this(), std::placeholders::_1));
channel_->sendInputEventIndication(inputEventIndication, std::move(promise));
});
}
}
}
}
}

View File

@ -0,0 +1,184 @@
/*
* 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/autoapp/Projection/LocalBluetoothDevice.hpp>
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace projection
{
LocalBluetoothDevice::LocalBluetoothDevice()
{
qRegisterMetaType<IBluetoothDevice::PairingPromise::Pointer>("PairingPromise::Pointer");
this->moveToThread(QApplication::instance()->thread());
connect(this, &LocalBluetoothDevice::startPairing, this, &LocalBluetoothDevice::onStartPairing, Qt::QueuedConnection);
QMetaObject::invokeMethod(this, "createBluetoothLocalDevice", Qt::BlockingQueuedConnection);
}
void LocalBluetoothDevice::createBluetoothLocalDevice()
{
OPENAUTO_LOG(debug) << "[LocalBluetoothDevice] create.";
localDevice_ = std::make_unique<QBluetoothLocalDevice>(QBluetoothAddress());
connect(localDevice_.get(), &QBluetoothLocalDevice::pairingDisplayConfirmation, this, &LocalBluetoothDevice::onPairingDisplayConfirmation);
connect(localDevice_.get(), &QBluetoothLocalDevice::pairingDisplayPinCode, this, &LocalBluetoothDevice::onPairingDisplayPinCode);
connect(localDevice_.get(), &QBluetoothLocalDevice::pairingFinished, this, &LocalBluetoothDevice::onPairingFinished);
connect(localDevice_.get(), &QBluetoothLocalDevice::error, this, &LocalBluetoothDevice::onError);
connect(localDevice_.get(), &QBluetoothLocalDevice::hostModeStateChanged, this, &LocalBluetoothDevice::onHostModeStateChanged);
localDevice_->setHostMode(QBluetoothLocalDevice::HostDiscoverable);
}
void LocalBluetoothDevice::stop()
{
std::lock_guard<decltype(mutex_)> lock(mutex_);
if(pairingPromise_ != nullptr)
{
pairingPromise_->reject();
pairingPromise_.reset();
pairingAddress_ = QBluetoothAddress();
}
}
bool LocalBluetoothDevice::isPaired(const std::string& address) const
{
std::lock_guard<decltype(mutex_)> lock(mutex_);
return localDevice_->pairingStatus(QBluetoothAddress(QString::fromStdString(address))) != QBluetoothLocalDevice::Unpaired;
}
void LocalBluetoothDevice::pair(const std::string& address, PairingPromise::Pointer promise)
{
emit startPairing(QString::fromStdString(address), std::move(promise));
}
std::string LocalBluetoothDevice::getLocalAddress() const
{
std::lock_guard<decltype(mutex_)> lock(mutex_);
return localDevice_->isValid() ? localDevice_->address().toString().toStdString() : "";
}
bool LocalBluetoothDevice::isAvailable() const
{
std::lock_guard<decltype(mutex_)> lock(mutex_);
return localDevice_->isValid();
}
void LocalBluetoothDevice::onStartPairing(const QString& address, PairingPromise::Pointer promise)
{
OPENAUTO_LOG(debug) << "[LocalBluetoothDevice] onStartPairing, address: " << address.toStdString();
std::lock_guard<decltype(mutex_)> lock(mutex_);
if(!localDevice_->isValid())
{
promise->reject();
}
else
{
if(pairingPromise_ != nullptr)
{
pairingPromise_->reject();
}
pairingAddress_ = QBluetoothAddress(address);
pairingPromise_ = std::move(promise);
localDevice_->requestPairing(pairingAddress_, QBluetoothLocalDevice::AuthorizedPaired);
}
}
void LocalBluetoothDevice::onPairingDisplayConfirmation(const QBluetoothAddress &address, QString pin)
{
OPENAUTO_LOG(debug) << "[LocalBluetoothDevice] onPairingDisplayConfirmation, address: " << address.toString().toStdString()
<< ", pin: " << pin.toStdString();
std::lock_guard<decltype(mutex_)> lock(mutex_);
localDevice_->pairingConfirmation(address == pairingAddress_);
}
void LocalBluetoothDevice::onPairingDisplayPinCode(const QBluetoothAddress &address, QString pin)
{
OPENAUTO_LOG(debug) << "[LocalBluetoothDevice] onPairingDisplayPinCode, address: " << address.toString().toStdString()
<< ", pin: " << pin.toStdString();
std::lock_guard<decltype(mutex_)> lock(mutex_);
localDevice_->pairingConfirmation(address == pairingAddress_);
}
void LocalBluetoothDevice::onPairingFinished(const QBluetoothAddress &address, QBluetoothLocalDevice::Pairing pairing)
{
OPENAUTO_LOG(debug) << "[LocalBluetoothDevice] onPairingDisplayPinCode, address: " << address.toString().toStdString()
<< ", pin: " << pairing;
std::lock_guard<decltype(mutex_)> lock(mutex_);
if(address == pairingAddress_)
{
if(pairing != QBluetoothLocalDevice::Unpaired)
{
pairingPromise_->resolve();
}
else
{
pairingPromise_->reject();
}
pairingPromise_.reset();
pairingAddress_ = QBluetoothAddress();
}
}
void LocalBluetoothDevice::onError(QBluetoothLocalDevice::Error error)
{
OPENAUTO_LOG(debug) << "[LocalBluetoothDevice] onError, error: " << error;
std::lock_guard<decltype(mutex_)> lock(mutex_);
if(pairingPromise_ != nullptr)
{
pairingPromise_->reject();
pairingPromise_.reset();
pairingAddress_ = QBluetoothAddress();
}
}
void LocalBluetoothDevice::onHostModeStateChanged(QBluetoothLocalDevice::HostMode state)
{
std::lock_guard<decltype(mutex_)> lock(mutex_);
if(state == QBluetoothLocalDevice::HostPoweredOff && pairingPromise_ != nullptr)
{
pairingPromise_->reject();
pairingPromise_.reset();
pairingAddress_ = QBluetoothAddress();
}
}
}
}
}
}

View File

@ -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/>.
*/
#include <f1x/aasdk/Channel/AV/MediaAudioServiceChannel.hpp>
#include <f1x/openauto/autoapp/Projection/MediaAudioService.hpp>
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace projection
{
MediaAudioService::MediaAudioService(boost::asio::io_service& ioService, aasdk::messenger::IMessenger::Pointer messenger, IAudioOutput::Pointer audioOutput)
: AudioService(ioService, std::make_shared<aasdk::channel::av::MediaAudioServiceChannel>(strand_, std::move(messenger)), std::move(audioOutput))
{
}
}
}
}
}

View File

@ -0,0 +1,271 @@
/*
* 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/>.
*/
#ifdef USE_OMX
extern "C"
{
#include <bcm_host.h>
}
#include <f1x/aasdk/Common/Data.hpp>
#include <f1x/openauto/autoapp/Projection/OMXVideoOutput.hpp>
#include <f1x/openauto/Common/Log.hpp>
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace projection
{
namespace VideoComponent
{
static constexpr uint32_t DECODER = 0;
static constexpr uint32_t RENDERER = 1;
static constexpr uint32_t CLOCK = 2;
static constexpr uint32_t SCHEDULER = 3;
}
OMXVideoOutput::OMXVideoOutput(configuration::IConfiguration::Pointer configuration)
: VideoOutput(std::move(configuration))
, isActive_(false)
, portSettingsChanged_(false)
, client_(nullptr)
{
memset(components_, 0, sizeof(components_));
memset(tunnels_, 0, sizeof(tunnels_));
}
bool OMXVideoOutput::open()
{
std::lock_guard<decltype(mutex_)> lock(mutex_);
OPENAUTO_LOG(info) << "[OMXVideoOutput] open.";
bcm_host_init();
if(OMX_Init() != OMX_ErrorNone)
{
OPENAUTO_LOG(error) << "[OMXVideoOutput] omx init failed.";
return false;
}
client_ = ilclient_init();
if(client_ == nullptr)
{
OPENAUTO_LOG(error) << "[OMXVideoOutput] ilclient init failed.";
return false;
}
if(!this->createComponents())
{
return false;
}
if(!this->setupTunnels())
{
OPENAUTO_LOG(error) << "[OMXVideoOutput] setup tunnels failed.";
return false;
}
ilclient_change_component_state(components_[VideoComponent::CLOCK], OMX_StateExecuting);
ilclient_change_component_state(components_[VideoComponent::DECODER], OMX_StateIdle);
if(!this->enablePortBuffers())
{
OPENAUTO_LOG(error) << "[OMXVideoOutput] enable port buffers failed.";
return false;
}
isActive_ = true;
return true;
}
bool OMXVideoOutput::init()
{
std::lock_guard<decltype(mutex_)> lock(mutex_);
OPENAUTO_LOG(info) << "[OMXVideoOutput] init, state: " << isActive_;
ilclient_change_component_state(components_[VideoComponent::DECODER], OMX_StateExecuting);
return true;
}
void OMXVideoOutput::write(uint64_t timestamp, const aasdk::common::DataConstBuffer& buffer)
{
std::lock_guard<decltype(mutex_)> lock(mutex_);
size_t writeSize = 0;
while(isActive_ && writeSize < buffer.size)
{
OMX_BUFFERHEADERTYPE* buf = ilclient_get_input_buffer(components_[VideoComponent::DECODER], 130, 1);
if(buf == nullptr)
{
break;
}
else
{
aasdk::common::DataConstBuffer currentBuffer(buffer.cdata, buffer.size, writeSize);
buf->nFilledLen = std::min<size_t>(buf->nAllocLen, currentBuffer.size);
memcpy(buf->pBuffer, &currentBuffer.cdata[0], buf->nFilledLen);
buf->nTimeStamp = omx_ticks_from_s64(timestamp / 1000000);
buf->nOffset = 0;
writeSize += buf->nFilledLen;
if(timestamp == 0)
{
buf->nFlags = OMX_BUFFERFLAG_STARTTIME;
}
if(!portSettingsChanged_ && ilclient_remove_event(components_[VideoComponent::DECODER], OMX_EventPortSettingsChanged, 131, 0, 0, 1) == 0)
{
portSettingsChanged_ = true;
if(ilclient_setup_tunnel(&tunnels_[0], 0, 0) != 0)
{
break;
}
ilclient_change_component_state(components_[VideoComponent::SCHEDULER], OMX_StateExecuting);
if(ilclient_setup_tunnel(&tunnels_[1], 0, 1000) != 0)
{
break;
}
ilclient_change_component_state(components_[VideoComponent::RENDERER], OMX_StateExecuting);
}
if(OMX_EmptyThisBuffer(ILC_GET_HANDLE(components_[VideoComponent::DECODER]), buf) != OMX_ErrorNone)
{
break;
}
}
}
}
void OMXVideoOutput::stop()
{
OPENAUTO_LOG(info) << "[OMXVideoOutput] stop.";
std::lock_guard<decltype(mutex_)> lock(mutex_);
if(isActive_)
{
isActive_ = false;
ilclient_disable_tunnel(&tunnels_[0]);
ilclient_disable_tunnel(&tunnels_[1]);
ilclient_disable_tunnel(&tunnels_[2]);
ilclient_disable_port_buffers(components_[VideoComponent::DECODER], 130, NULL, NULL, NULL);
ilclient_teardown_tunnels(tunnels_);
ilclient_state_transition(components_, OMX_StateIdle);
ilclient_state_transition(components_, OMX_StateLoaded);
ilclient_cleanup_components(components_);
OMX_Deinit();
ilclient_destroy(client_);
}
}
bool OMXVideoOutput::isActive() const
{
std::lock_guard<decltype(mutex_)> lock(mutex_);
return isActive_;
}
bool OMXVideoOutput::createComponents()
{
if(ilclient_create_component(client_, &components_[VideoComponent::DECODER], "video_decode", static_cast<ILCLIENT_CREATE_FLAGS_T>(ILCLIENT_DISABLE_ALL_PORTS | ILCLIENT_ENABLE_INPUT_BUFFERS)) != 0)
{
OPENAUTO_LOG(error) << "[OMXVideoOutput] video decode component creation failed.";
return false;
}
if(ilclient_create_component(client_, &components_[VideoComponent::RENDERER], "video_render", ILCLIENT_DISABLE_ALL_PORTS) != 0)
{
OPENAUTO_LOG(error) << "[OMXVideoOutput] video renderer component creation failed.";
return false;
}
if(ilclient_create_component(client_, &components_[VideoComponent::CLOCK], "clock", ILCLIENT_DISABLE_ALL_PORTS) != 0)
{
OPENAUTO_LOG(error) << "[OMXVideoOutput] clock component creation failed.";
return false;
}
if(!this->initClock())
{
OPENAUTO_LOG(error) << "[OMXVideoOutput] clock init failed.";
return false;
}
if(ilclient_create_component(client_, &components_[VideoComponent::SCHEDULER], "video_scheduler", ILCLIENT_DISABLE_ALL_PORTS) != 0)
{
OPENAUTO_LOG(error) << "[OMXVideoOutput] video scheduler component creation failed.";
return false;
}
return true;
}
bool OMXVideoOutput::initClock()
{
OMX_TIME_CONFIG_CLOCKSTATETYPE cstate;
memset(&cstate, 0, sizeof(cstate));
cstate.nSize = sizeof(cstate);
cstate.nVersion.nVersion = OMX_VERSION;
cstate.eState = OMX_TIME_ClockStateWaitingForStartTime;
cstate.nWaitMask = 1;
return OMX_SetParameter(ILC_GET_HANDLE(components_[VideoComponent::CLOCK]), OMX_IndexConfigTimeClockState, &cstate) == OMX_ErrorNone;
}
bool OMXVideoOutput::setupTunnels()
{
set_tunnel(&tunnels_[0], components_[VideoComponent::DECODER], 131, components_[VideoComponent::SCHEDULER], 10);
set_tunnel(&tunnels_[1], components_[VideoComponent::SCHEDULER], 11, components_[VideoComponent::RENDERER], 90);
set_tunnel(&tunnels_[2], components_[VideoComponent::CLOCK], 80, components_[VideoComponent::SCHEDULER], 12);
return ilclient_setup_tunnel(&tunnels_[2], 0, 0) == 0;
}
bool OMXVideoOutput::enablePortBuffers()
{
OMX_VIDEO_PARAM_PORTFORMATTYPE format;
memset(&format, 0, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE));
format.nSize = sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE);
format.nVersion.nVersion = OMX_VERSION;
format.nPortIndex = 130;
format.eCompressionFormat = OMX_VIDEO_CodingAVC;
return OMX_SetParameter(ILC_GET_HANDLE(components_[VideoComponent::DECODER]), OMX_IndexParamVideoPortFormat, &format) == OMX_ErrorNone &&
ilclient_enable_port_buffers(components_[VideoComponent::DECODER], 130, NULL, NULL, NULL) == 0;
}
}
}
}
}
#endif

View File

@ -0,0 +1,99 @@
/*
* 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/autoapp/Projection/QtVideoOutput.hpp>
#include <f1x/openauto/Common/Log.hpp>
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace projection
{
QtVideoOutput::QtVideoOutput(configuration::IConfiguration::Pointer configuration)
: VideoOutput(std::move(configuration))
{
this->moveToThread(QApplication::instance()->thread());
connect(this, &QtVideoOutput::startPlayback, this, &QtVideoOutput::onStartPlayback, Qt::QueuedConnection);
connect(this, &QtVideoOutput::stopPlayback, this, &QtVideoOutput::onStopPlayback, Qt::QueuedConnection);
QMetaObject::invokeMethod(this, "createVideoOutput", Qt::BlockingQueuedConnection);
}
void QtVideoOutput::createVideoOutput()
{
OPENAUTO_LOG(debug) << "[QtVideoOutput] create.";
videoWidget_ = std::make_unique<QVideoWidget>();
mediaPlayer_ = std::make_unique<QMediaPlayer>(nullptr, QMediaPlayer::StreamPlayback);
}
bool QtVideoOutput::open()
{
std::lock_guard<decltype(mutex_)> lock(mutex_);
return videoBuffer_.open(QIODevice::ReadWrite);
}
bool QtVideoOutput::init()
{
emit startPlayback();
return true;
}
bool QtVideoOutput::isActive() const
{
std::lock_guard<decltype(mutex_)> lock(mutex_);
return videoWidget_ != nullptr && videoWidget_->isVisible();
}
void QtVideoOutput::stop()
{
emit stopPlayback();
}
void QtVideoOutput::write(uint64_t, const aasdk::common::DataConstBuffer& buffer)
{
std::lock_guard<decltype(mutex_)> lock(mutex_);
videoBuffer_.write(reinterpret_cast<const char*>(buffer.cdata), buffer.size);
}
void QtVideoOutput::onStartPlayback()
{
videoWidget_->setFocus();
videoWidget_->setFullScreen(true);
videoWidget_->show();
mediaPlayer_->setVideoOutput(videoWidget_.get());
mediaPlayer_->setMedia(QMediaContent(), &videoBuffer_);
mediaPlayer_->play();
}
void QtVideoOutput::onStopPlayback()
{
videoWidget_->hide();
mediaPlayer_->stop();
}
}
}
}
}

View File

@ -0,0 +1,64 @@
/*
* 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/RemoteBluetoothDevice.hpp>
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace projection
{
RemoteBluetoothDevice::RemoteBluetoothDevice(const std::string& address)
: address_(address)
{
}
void RemoteBluetoothDevice::stop()
{
}
bool RemoteBluetoothDevice::isPaired(const std::string&) const
{
return true;
}
void RemoteBluetoothDevice::pair(const std::string&, PairingPromise::Pointer promise)
{
promise->resolve();
}
std::string RemoteBluetoothDevice::getLocalAddress() const
{
return address_;
}
bool RemoteBluetoothDevice::isAvailable() const
{
return true;
}
}
}
}
}

View File

@ -0,0 +1,124 @@
/*
* 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 <aasdk_proto/DrivingStatusEnum.pb.h>
#include <f1x/openauto/Common/Log.hpp>
#include <f1x/openauto/autoapp/Projection/SensorService.hpp>
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace projection
{
SensorService::SensorService(boost::asio::io_service& ioService, aasdk::messenger::IMessenger::Pointer messenger)
: strand_(ioService)
, channel_(std::make_shared<aasdk::channel::sensor::SensorServiceChannel>(strand_, std::move(messenger)))
{
}
void SensorService::start()
{
strand_.dispatch([this, self = this->shared_from_this()]() {
OPENAUTO_LOG(info) << "[SensorService] start.";
channel_->receive(this->shared_from_this());
});
}
void SensorService::stop()
{
strand_.dispatch([this, self = this->shared_from_this()]() {
OPENAUTO_LOG(info) << "[SensorService] stop.";
});
}
void SensorService::fillFeatures(aasdk::proto::messages::ServiceDiscoveryResponse& response)
{
OPENAUTO_LOG(info) << "[SensorService] fill features.";
auto* channelDescriptor = response.add_channels();
channelDescriptor->set_channel_id(static_cast<uint32_t>(channel_->getId()));
auto* sensorChannel = channelDescriptor->mutable_sensor_channel();
sensorChannel->add_sensors()->set_type(aasdk::proto::enums::SensorType::DRIVING_STATUS);
//sensorChannel->add_sensors()->set_type(aasdk::proto::enums::SensorType::LOCATION);
//sensorChannel->add_sensors()->set_type(aasdk::proto::enums::SensorType::NIGHT_DATA);
}
void SensorService::onChannelOpenRequest(const aasdk::proto::messages::ChannelOpenRequest& request)
{
OPENAUTO_LOG(info) << "[SensorService] open request, priority: " << request.priority();
const aasdk::proto::enums::Status::Enum status = aasdk::proto::enums::Status::OK;
OPENAUTO_LOG(info) << "[SensorService] open status: " << status;
aasdk::proto::messages::ChannelOpenResponse response;
response.set_status(status);
auto promise = aasdk::channel::SendPromise::defer(strand_);
promise->then([]() {}, std::bind(&SensorService::onChannelError, this->shared_from_this(), std::placeholders::_1));
channel_->sendChannelOpenResponse(response, std::move(promise));
channel_->receive(this->shared_from_this());
}
void SensorService::onSensorStartRequest(const aasdk::proto::messages::SensorStartRequestMessage& request)
{
OPENAUTO_LOG(info) << "[SensorService] sensor start request, type: " << request.sensor_type();
aasdk::proto::messages::SensorStartResponseMessage response;
response.set_status(aasdk::proto::enums::Status::OK);
auto promise = aasdk::channel::SendPromise::defer(strand_);
if(request.sensor_type() == aasdk::proto::enums::SensorType::DRIVING_STATUS)
{
promise->then(std::bind(&SensorService::sendDrivingStatusUnrestricted, this->shared_from_this()),
std::bind(&SensorService::onChannelError, this->shared_from_this(), std::placeholders::_1));
}
else
{
promise->then([]() {}, std::bind(&SensorService::onChannelError, this->shared_from_this(), std::placeholders::_1));
}
channel_->sendSensorStartResponse(response, std::move(promise));
channel_->receive(this->shared_from_this());
}
void SensorService::sendDrivingStatusUnrestricted()
{
aasdk::proto::messages::SensorEventIndication indication;
indication.add_driving_status()->set_status(aasdk::proto::enums::DrivingStatus::UNRESTRICTED);
auto promise = aasdk::channel::SendPromise::defer(strand_);
promise->then([]() {}, std::bind(&SensorService::onChannelError, this->shared_from_this(), std::placeholders::_1));
channel_->sendSensorEventIndication(indication, std::move(promise));
}
void SensorService::onChannelError(const aasdk::error::Error& e)
{
OPENAUTO_LOG(error) << "[SensorService] channel error: " << e.what();
}
}
}
}
}

View File

@ -0,0 +1,106 @@
/*
* This file is part of openauto project.
* Copyright (C) 2018 f1x.studio (Michal Szwaj)
*
* openauto is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
* openauto is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with openauto. If not, see <http://www.gnu.org/licenses/>.
*/
#include <f1x/openauto/autoapp/Projection/SequentialBuffer.hpp>
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace projection
{
SequentialBuffer::SequentialBuffer()
: data_(aasdk::common::cStaticDataSize)
{
}
bool SequentialBuffer::isSequential() const
{
return true;
}
qint64 SequentialBuffer::readData(char *data, qint64 maxlen)
{
std::lock_guard<decltype(mutex_)> lock(mutex_);
if(data_.empty())
{
return 0;
}
const auto len = std::min<size_t>(maxlen, data_.size());
std::copy(data_.begin(), data_.begin() + len, data);
data_.erase(data_.begin(), data_.begin() + len);
return len;
}
qint64 SequentialBuffer::writeData(const char *data, qint64 len)
{
std::lock_guard<decltype(mutex_)> lock(mutex_);
data_.insert(data_.end(), data, data + len);
emit readyRead();
return len;
}
qint64 SequentialBuffer::size() const
{
return this->bytesAvailable();
}
qint64 SequentialBuffer::pos() const
{
return 0;
}
bool SequentialBuffer::seek(qint64)
{
return false;
}
bool SequentialBuffer::atEnd() const
{
return false;
}
bool SequentialBuffer::reset()
{
data_.clear();
return true;
}
qint64 SequentialBuffer::bytesAvailable() const
{
std::lock_guard<decltype(mutex_)> lock(mutex_);
return QIODevice::bytesAvailable() + std::max<qint64>(1, data_.size());
}
bool SequentialBuffer::canReadLine() const
{
return true;
}
}
}
}
}

View File

@ -0,0 +1,141 @@
/*
* 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 <QScreen>
#include <f1x/aasdk/Channel/AV/MediaAudioServiceChannel.hpp>
#include <f1x/aasdk/Channel/AV/SystemAudioServiceChannel.hpp>
#include <f1x/aasdk/Channel/AV/SpeechAudioServiceChannel.hpp>
#include <f1x/openauto/autoapp/Projection/ServiceFactory.hpp>
#include <f1x/openauto/autoapp/Projection/VideoService.hpp>
#include <f1x/openauto/autoapp/Projection/MediaAudioService.hpp>
#include <f1x/openauto/autoapp/Projection/SpeechAudioService.hpp>
#include <f1x/openauto/autoapp/Projection/SystemAudioService.hpp>
#include <f1x/openauto/autoapp/Projection/AudioInputService.hpp>
#include <f1x/openauto/autoapp/Projection/SensorService.hpp>
#include <f1x/openauto/autoapp/Projection/BluetoothService.hpp>
#include <f1x/openauto/autoapp/Projection/InputService.hpp>
#include <f1x/openauto/autoapp/Projection/QtVideoOutput.hpp>
#include <f1x/openauto/autoapp/Projection/OMXVideoOutput.hpp>
#include <f1x/openauto/autoapp/Projection/AudioOutput.hpp>
#include <f1x/openauto/autoapp/Projection/AudioInput.hpp>
#include <f1x/openauto/autoapp/Projection/InputDevice.hpp>
#include <f1x/openauto/autoapp/Projection/LocalBluetoothDevice.hpp>
#include <f1x/openauto/autoapp/Projection/RemoteBluetoothDevice.hpp>
#include <f1x/openauto/autoapp/Projection/DummyBluetoothDevice.hpp>
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace projection
{
ServiceFactory::ServiceFactory(boost::asio::io_service& ioService, configuration::IConfiguration::Pointer configuration)
: ioService_(ioService)
, configuration_(std::move(configuration))
{
}
ServiceList ServiceFactory::create(aasdk::messenger::IMessenger::Pointer messenger)
{
ServiceList serviceList;
IAudioInput::Pointer audioInput(new AudioInput(1, 16, 16000), std::bind(&QObject::deleteLater, std::placeholders::_1));
serviceList.emplace_back(std::make_shared<AudioInputService>(ioService_, messenger, std::move(audioInput)));
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)));
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(this->createVideoService(messenger));
serviceList.emplace_back(this->createBluetoothService(messenger));
serviceList.emplace_back(this->createInputService(messenger));
return serviceList;
}
IService::Pointer ServiceFactory::createVideoService(aasdk::messenger::IMessenger::Pointer messenger)
{
#ifdef USE_OMX
IVideoOutput::Pointer videoOutput(std::make_shared<OMXVideoOutput>(configuration_));
#else
IVideoOutput::Pointer videoOutput(new QtVideoOutput(configuration_), std::bind(&QObject::deleteLater, std::placeholders::_1));
#endif
return std::make_shared<VideoService>(ioService_, messenger, std::move(videoOutput));
}
IService::Pointer ServiceFactory::createBluetoothService(aasdk::messenger::IMessenger::Pointer messenger)
{
IBluetoothDevice::Pointer bluetoothDevice;
switch(configuration_->getBluetoothAdapterType())
{
case configuration::BluetoothAdapterType::LOCAL:
bluetoothDevice = IBluetoothDevice::Pointer(new LocalBluetoothDevice(), std::bind(&QObject::deleteLater, std::placeholders::_1));
break;
case configuration::BluetoothAdapterType::REMOTE:
bluetoothDevice = std::make_shared<RemoteBluetoothDevice>(configuration_->getBluetoothRemoteAdapterAddress());
break;
default:
bluetoothDevice = std::make_shared<DummyBluetoothDevice>();
break;
}
return std::make_shared<BluetoothService>(ioService_, messenger, std::move(bluetoothDevice));
}
IService::Pointer ServiceFactory::createInputService(aasdk::messenger::IMessenger::Pointer messenger)
{
QRect videoGeometry;
switch(configuration_->getVideoResolution())
{
case aasdk::proto::enums::VideoResolution::_720p:
videoGeometry = QRect(0, 0, 1280, 720);
break;
case aasdk::proto::enums::VideoResolution::_1080p:
videoGeometry = QRect(0, 0, 1920, 1080);
break;
default:
videoGeometry = QRect(0, 0, 800, 480);
break;
}
QScreen* screen = QGuiApplication::primaryScreen();
QRect screenGeometry = screen == nullptr ? QRect(0, 0, 1, 1) : screen->geometry();
IInputDevice::Pointer inputDevice(std::make_shared<InputDevice>(*QApplication::instance(), configuration_, std::move(screenGeometry), std::move(videoGeometry)));
return std::make_shared<InputService>(ioService_, messenger, std::move(inputDevice));
}
}
}
}
}

View File

@ -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/>.
*/
#include <f1x/aasdk/Channel/AV/SpeechAudioServiceChannel.hpp>
#include <f1x/openauto/autoapp/Projection/SpeechAudioService.hpp>
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace projection
{
SpeechAudioService::SpeechAudioService(boost::asio::io_service& ioService, aasdk::messenger::IMessenger::Pointer messenger, IAudioOutput::Pointer audioOutput)
: AudioService(ioService, std::make_shared<aasdk::channel::av::SpeechAudioServiceChannel>(strand_, std::move(messenger)), std::move(audioOutput))
{
}
}
}
}
}

View File

@ -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/>.
*/
#include <f1x/aasdk/Channel/AV/SystemAudioServiceChannel.hpp>
#include <f1x/openauto/autoapp/Projection/SystemAudioService.hpp>
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace projection
{
SystemAudioService::SystemAudioService(boost::asio::io_service& ioService, aasdk::messenger::IMessenger::Pointer messenger, IAudioOutput::Pointer audioOutput)
: AudioService(ioService, std::make_shared<aasdk::channel::av::SystemAudioServiceChannel>(strand_, std::move(messenger)), std::move(audioOutput))
{
}
}
}
}
}

View File

@ -0,0 +1,54 @@
/*
* 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/VideoOutput.hpp>
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace projection
{
VideoOutput::VideoOutput(configuration::IConfiguration::Pointer configuration)
: configuration_(std::move(configuration))
{
}
aasdk::proto::enums::VideoFPS::Enum VideoOutput::getVideoFPS() const
{
return configuration_->getVideoFPS();
}
aasdk::proto::enums::VideoResolution::Enum VideoOutput::getVideoResolution() const
{
return configuration_->getVideoResolution();
}
size_t VideoOutput::getScreenDPI() const
{
return configuration_->getScreenDPI();
}
}
}
}
}

View File

@ -0,0 +1,178 @@
/*
* 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/autoapp/Projection/VideoService.hpp>
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace projection
{
VideoService::VideoService(boost::asio::io_service& ioService, aasdk::messenger::IMessenger::Pointer messenger, IVideoOutput::Pointer videoOutput)
: strand_(ioService)
, channel_(std::make_shared<aasdk::channel::av::VideoServiceChannel>(strand_, std::move(messenger)))
, videoOutput_(std::move(videoOutput))
, session_(-1)
{
}
void VideoService::start()
{
strand_.dispatch([this, self = this->shared_from_this()]() {
OPENAUTO_LOG(info) << "[VideoService] start.";
channel_->receive(this->shared_from_this());
});
}
void VideoService::stop()
{
strand_.dispatch([this, self = this->shared_from_this()]() {
OPENAUTO_LOG(info) << "[VideoService] stop.";
videoOutput_->stop();
});
}
void VideoService::onChannelOpenRequest(const aasdk::proto::messages::ChannelOpenRequest& request)
{
OPENAUTO_LOG(info) << "[VideoService] open request, priority: " << request.priority();
const aasdk::proto::enums::Status::Enum status = videoOutput_->open() ? aasdk::proto::enums::Status::OK : aasdk::proto::enums::Status::FAIL;
OPENAUTO_LOG(info) << "[VideoService] open status: " << status;
aasdk::proto::messages::ChannelOpenResponse response;
response.set_status(status);
auto promise = aasdk::channel::SendPromise::defer(strand_);
promise->then([]() {}, std::bind(&VideoService::onChannelError, this->shared_from_this(), std::placeholders::_1));
channel_->sendChannelOpenResponse(response, std::move(promise));
channel_->receive(this->shared_from_this());
}
void VideoService::onAVChannelSetupRequest(const aasdk::proto::messages::AVChannelSetupRequest& request)
{
OPENAUTO_LOG(info) << "[VideoService] setup request, config index: " << request.config_index();
const aasdk::proto::enums::AVChannelSetupStatus::Enum status = videoOutput_->init() ? aasdk::proto::enums::AVChannelSetupStatus::OK : aasdk::proto::enums::AVChannelSetupStatus::FAIL;
OPENAUTO_LOG(info) << "[VideoService] setup status: " << status;
aasdk::proto::messages::AVChannelSetupResponse response;
response.set_media_status(status);
response.set_max_unacked(1);
response.add_configs(0);
auto promise = aasdk::channel::SendPromise::defer(strand_);
promise->then(std::bind(&VideoService::sendVideoFocusIndication, this->shared_from_this()),
std::bind(&VideoService::onChannelError, this->shared_from_this(), std::placeholders::_1));
channel_->sendAVChannelSetupResponse(response, std::move(promise));
channel_->receive(this->shared_from_this());
}
void VideoService::onAVChannelStartIndication(const aasdk::proto::messages::AVChannelStartIndication& indication)
{
OPENAUTO_LOG(info) << "[VideoService] start indication, session: " << indication.session();
session_ = indication.session();
channel_->receive(this->shared_from_this());
}
void VideoService::onAVMediaWithTimestampIndication(aasdk::messenger::Timestamp::ValueType timestamp, const aasdk::common::DataConstBuffer& buffer)
{
videoOutput_->write(timestamp, buffer);
aasdk::proto::messages::AVMediaAckIndication indication;
indication.set_session(session_);
indication.set_value(1);
auto promise = aasdk::channel::SendPromise::defer(strand_);
promise->then([]() {}, std::bind(&VideoService::onChannelError, this->shared_from_this(), std::placeholders::_1));
channel_->sendAVMediaAckIndication(indication, std::move(promise));
channel_->receive(this->shared_from_this());
}
void VideoService::onAVMediaIndication(const aasdk::common::DataConstBuffer& buffer)
{
videoOutput_->write(0, buffer);
aasdk::proto::messages::AVMediaAckIndication indication;
indication.set_session(session_);
indication.set_value(1);
auto promise = aasdk::channel::SendPromise::defer(strand_);
promise->then([]() {}, std::bind(&VideoService::onChannelError, this->shared_from_this(), std::placeholders::_1));
channel_->sendAVMediaAckIndication(indication, std::move(promise));
channel_->receive(this->shared_from_this());
}
void VideoService::onChannelError(const aasdk::error::Error& e)
{
OPENAUTO_LOG(error) << "[VideoService] channel error: " << e.what();
}
void VideoService::fillFeatures(aasdk::proto::messages::ServiceDiscoveryResponse& response)
{
OPENAUTO_LOG(info) << "[VideoService] fill features.";
auto* channelDescriptor = response.add_channels();
channelDescriptor->set_channel_id(static_cast<uint32_t>(channel_->getId()));
auto* videoChannel = channelDescriptor->mutable_av_channel();
videoChannel->set_stream_type(aasdk::proto::enums::AVStreamType::VIDEO);
videoChannel->set_available_while_in_call(true);
auto* videoConfig1 = videoChannel->add_video_configs();
videoConfig1->set_video_resolution(videoOutput_->getVideoResolution());
videoConfig1->set_video_fps(videoOutput_->getVideoFPS());
videoConfig1->set_margin_height(0);
videoConfig1->set_margin_width(0);
videoConfig1->set_dpi(videoOutput_->getScreenDPI());
}
void VideoService::onVideoFocusRequest(const aasdk::proto::messages::VideoFocusRequest& request)
{
OPENAUTO_LOG(info) << "[VideoService] video focus request, display index: " << request.disp_index()
<< ", focus mode: " << request.focus_mode()
<< ", focus reason: " << request.focus_reason();
this->sendVideoFocusIndication();
channel_->receive(this->shared_from_this());
}
void VideoService::sendVideoFocusIndication()
{
OPENAUTO_LOG(info) << "[VideoService] video focus indication.";
aasdk::proto::messages::VideoFocusIndication videoFocusIndication;
videoFocusIndication.set_focus_mode(aasdk::proto::enums::VideoFocusMode::FOCUSED);
videoFocusIndication.set_unrequested(false);
auto promise = aasdk::channel::SendPromise::defer(strand_);
promise->then([]() {}, std::bind(&VideoService::onChannelError, this->shared_from_this(), std::placeholders::_1));
channel_->sendVideoFocusIndication(videoFocusIndication, std::move(promise));
}
}
}
}
}

View File

@ -0,0 +1,48 @@
/*
* 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/UI/MainWindow.hpp>
#include "ui_mainwindow.h"
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace ui
{
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui_(new Ui::MainWindow)
{
ui_->setupUi(this);
connect(ui_->pushButtonSettings, &QPushButton::clicked, this, &MainWindow::openSettings);
connect(ui_->pushButtonExit, &QPushButton::clicked, this, &MainWindow::exit);
}
MainWindow::~MainWindow()
{
delete ui_;
}
}
}
}
}

View File

@ -0,0 +1,242 @@
/*
* 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 <QMessageBox>
#include <f1x/openauto/autoapp/UI/SettingsWindow.hpp>
#include "ui_settingswindow.h"
namespace f1x
{
namespace openauto
{
namespace autoapp
{
namespace ui
{
SettingsWindow::SettingsWindow(configuration::IConfiguration::Pointer configuration, QWidget *parent)
: QWidget(parent)
, ui_(new Ui::SettingsWindow)
, configuration_(std::move(configuration))
{
ui_->setupUi(this);
connect(ui_->pushButtonCancel, &QPushButton::clicked, this, &SettingsWindow::close);
connect(ui_->pushButtonSave, &QPushButton::clicked, this, &SettingsWindow::onSave);
connect(ui_->horizontalSliderScreenDPI, &QSlider::valueChanged, this, &SettingsWindow::onUpdateScreenDPI);
connect(ui_->radioButtonUseExternalBluetoothAdapter, &QRadioButton::clicked, [&](bool checked) { ui_->lineEditExternalBluetoothAdapterAddress->setEnabled(checked); });
connect(ui_->radioButtonDisableBluetooth, &QRadioButton::clicked, [&]() { ui_->lineEditExternalBluetoothAdapterAddress->setEnabled(false); });
connect(ui_->radioButtonUseLocalBluetoothAdapter, &QRadioButton::clicked, [&]() { ui_->lineEditExternalBluetoothAdapterAddress->setEnabled(false); });
connect(ui_->pushButtonClearSelection, &QPushButton::clicked, std::bind(&SettingsWindow::setButtonCheckBoxes, this, false));
connect(ui_->pushButtonSelectAll, &QPushButton::clicked, std::bind(&SettingsWindow::setButtonCheckBoxes, this, true));
connect(ui_->pushButtonResetToDefaults, &QPushButton::clicked, this, &SettingsWindow::onResetToDefaults);
connect(ui_->pushButtonShowBindings, &QPushButton::clicked, this, &SettingsWindow::onShowBindings);
}
SettingsWindow::~SettingsWindow()
{
delete ui_;
}
void SettingsWindow::onSave()
{
configuration_->setHandednessOfTrafficType(ui_->radioButtonLeftHandDrive->isChecked() ? configuration::HandednessOfTrafficType::LEFT_HAND_DRIVE : configuration::HandednessOfTrafficType::RIGHT_HAND_DRIVE);
configuration_->showClock(ui_->checkBoxShowClock->isChecked());
configuration_->setVideoFPS(ui_->radioButton30FPS->isChecked() ? aasdk::proto::enums::VideoFPS::_30 : aasdk::proto::enums::VideoFPS::_60);
if(ui_->radioButton480p->isChecked())
{
configuration_->setVideoResolution(aasdk::proto::enums::VideoResolution::_480p);
}
else if(ui_->radioButton720p->isChecked())
{
configuration_->setVideoResolution(aasdk::proto::enums::VideoResolution::_720p);
}
else if(ui_->radioButton1080p->isChecked())
{
configuration_->setVideoResolution(aasdk::proto::enums::VideoResolution::_1080p);
}
configuration_->setScreenDPI(static_cast<size_t>(ui_->horizontalSliderScreenDPI->value()));
configuration_->setTouchscreenEnabled(ui_->checkBoxEnableTouchscreen->isChecked());
this->saveButtonCheckBoxes();
if(ui_->radioButtonDisableBluetooth->isChecked())
{
configuration_->setBluetoothAdapterType(configuration::BluetoothAdapterType::NONE);
}
else if(ui_->radioButtonUseLocalBluetoothAdapter->isChecked())
{
configuration_->setBluetoothAdapterType(configuration::BluetoothAdapterType::LOCAL);
}
else if(ui_->radioButtonUseExternalBluetoothAdapter->isChecked())
{
configuration_->setBluetoothAdapterType(configuration::BluetoothAdapterType::REMOTE);
}
configuration_->setBluetoothRemoteAdapterAddress(ui_->lineEditExternalBluetoothAdapterAddress->text().toStdString());
configuration_->save();
this->close();
}
void SettingsWindow::onResetToDefaults()
{
QMessageBox confirmationMessage(QMessageBox::Question, "Confirmation", "Are you sure you want to reset settings?", QMessageBox::Yes | QMessageBox::Cancel);
confirmationMessage.setWindowFlags(Qt::WindowStaysOnTopHint);
if(confirmationMessage.exec() == QMessageBox::Yes)
{
configuration_->reset();
this->load();
}
}
void SettingsWindow::showEvent(QShowEvent* event)
{
QWidget::showEvent(event);
this->load();
}
void SettingsWindow::load()
{
ui_->radioButtonLeftHandDrive->setChecked(configuration_->getHandednessOfTrafficType() == configuration::HandednessOfTrafficType::LEFT_HAND_DRIVE);
ui_->radioButtonRightHandDrive->setChecked(configuration_->getHandednessOfTrafficType() == configuration::HandednessOfTrafficType::RIGHT_HAND_DRIVE);
ui_->checkBoxShowClock->setChecked(configuration_->showClock());
ui_->radioButton30FPS->setChecked(configuration_->getVideoFPS() == aasdk::proto::enums::VideoFPS::_30);
ui_->radioButton60FPS->setChecked(configuration_->getVideoFPS() == aasdk::proto::enums::VideoFPS::_60);
ui_->radioButton480p->setChecked(configuration_->getVideoResolution() == aasdk::proto::enums::VideoResolution::_480p);
ui_->radioButton720p->setChecked(configuration_->getVideoResolution() == aasdk::proto::enums::VideoResolution::_720p);
ui_->radioButton1080p->setChecked(configuration_->getVideoResolution() == aasdk::proto::enums::VideoResolution::_1080p);
ui_->horizontalSliderScreenDPI->setValue(static_cast<int>(configuration_->getScreenDPI()));
ui_->checkBoxEnableTouchscreen->setChecked(configuration_->getTouchscreenEnabled());
this->loadButtonCheckBoxes();
ui_->radioButtonDisableBluetooth->setChecked(configuration_->getBluetoothAdapterType() == configuration::BluetoothAdapterType::NONE);
ui_->radioButtonUseLocalBluetoothAdapter->setChecked(configuration_->getBluetoothAdapterType() == configuration::BluetoothAdapterType::LOCAL);
ui_->radioButtonUseExternalBluetoothAdapter->setChecked(configuration_->getBluetoothAdapterType() == configuration::BluetoothAdapterType::REMOTE);
ui_->lineEditExternalBluetoothAdapterAddress->setEnabled(configuration_->getBluetoothAdapterType() == configuration::BluetoothAdapterType::REMOTE);
ui_->lineEditExternalBluetoothAdapterAddress->setText(QString::fromStdString(configuration_->getBluetoothRemoteAdapterAddress()));
}
void SettingsWindow::loadButtonCheckBoxes()
{
const auto& buttonCodes = configuration_->getButtonCodes();
ui_->checkBoxPlayButton->setChecked(std::find(buttonCodes.begin(), buttonCodes.end(), aasdk::proto::enums::ButtonCode::PLAY) != buttonCodes.end());
ui_->checkBoxPauseButton->setChecked(std::find(buttonCodes.begin(), buttonCodes.end(), aasdk::proto::enums::ButtonCode::PAUSE) != buttonCodes.end());
ui_->checkBoxTogglePlayButton->setChecked(std::find(buttonCodes.begin(), buttonCodes.end(), aasdk::proto::enums::ButtonCode::TOGGLE_PLAY) != buttonCodes.end());
ui_->checkBoxNextTrackButton->setChecked(std::find(buttonCodes.begin(), buttonCodes.end(), aasdk::proto::enums::ButtonCode::NEXT) != buttonCodes.end());
ui_->checkBoxPreviousTrackButton->setChecked(std::find(buttonCodes.begin(), buttonCodes.end(), aasdk::proto::enums::ButtonCode::PREV) != buttonCodes.end());
ui_->checkBoxHomeButton->setChecked(std::find(buttonCodes.begin(), buttonCodes.end(), aasdk::proto::enums::ButtonCode::HOME) != buttonCodes.end());
ui_->checkBoxPhoneButton->setChecked(std::find(buttonCodes.begin(), buttonCodes.end(), aasdk::proto::enums::ButtonCode::PHONE) != buttonCodes.end());
ui_->checkBoxCallEndButton->setChecked(std::find(buttonCodes.begin(), buttonCodes.end(), aasdk::proto::enums::ButtonCode::CALL_END) != buttonCodes.end());
ui_->checkBoxVoiceCommandButton->setChecked(std::find(buttonCodes.begin(), buttonCodes.end(), aasdk::proto::enums::ButtonCode::MICROPHONE_1) != buttonCodes.end());
ui_->checkBoxLeftButton->setChecked(std::find(buttonCodes.begin(), buttonCodes.end(), aasdk::proto::enums::ButtonCode::LEFT) != buttonCodes.end());
ui_->checkBoxRightButton->setChecked(std::find(buttonCodes.begin(), buttonCodes.end(), aasdk::proto::enums::ButtonCode::RIGHT) != buttonCodes.end());
ui_->checkBoxUpButton->setChecked(std::find(buttonCodes.begin(), buttonCodes.end(), aasdk::proto::enums::ButtonCode::UP) != buttonCodes.end());
ui_->checkBoxDownButton->setChecked(std::find(buttonCodes.begin(), buttonCodes.end(), aasdk::proto::enums::ButtonCode::DOWN) != buttonCodes.end());
ui_->checkBoxScrollWheelButton->setChecked(std::find(buttonCodes.begin(), buttonCodes.end(), aasdk::proto::enums::ButtonCode::SCROLL_WHEEL) != buttonCodes.end());
ui_->checkBoxBackButton->setChecked(std::find(buttonCodes.begin(), buttonCodes.end(), aasdk::proto::enums::ButtonCode::BACK) != buttonCodes.end());
ui_->checkBoxEnterButton->setChecked(std::find(buttonCodes.begin(), buttonCodes.end(), aasdk::proto::enums::ButtonCode::ENTER) != buttonCodes.end());
}
void SettingsWindow::setButtonCheckBoxes(bool value)
{
ui_->checkBoxPlayButton->setChecked(value);
ui_->checkBoxPauseButton->setChecked(value);
ui_->checkBoxTogglePlayButton->setChecked(value);
ui_->checkBoxNextTrackButton->setChecked(value);
ui_->checkBoxPreviousTrackButton->setChecked(value);
ui_->checkBoxHomeButton->setChecked(value);
ui_->checkBoxPhoneButton->setChecked(value);
ui_->checkBoxCallEndButton->setChecked(value);
ui_->checkBoxVoiceCommandButton->setChecked(value);
ui_->checkBoxLeftButton->setChecked(value);
ui_->checkBoxRightButton->setChecked(value);
ui_->checkBoxUpButton->setChecked(value);
ui_->checkBoxDownButton->setChecked(value);
ui_->checkBoxScrollWheelButton->setChecked(value);
ui_->checkBoxBackButton->setChecked(value);
ui_->checkBoxEnterButton->setChecked(value);
}
void SettingsWindow::saveButtonCheckBoxes()
{
configuration::IConfiguration::ButtonCodes buttonCodes;
this->saveButtonCheckBox(ui_->checkBoxPlayButton, buttonCodes, aasdk::proto::enums::ButtonCode::PLAY);
this->saveButtonCheckBox(ui_->checkBoxPauseButton, buttonCodes, aasdk::proto::enums::ButtonCode::PAUSE);
this->saveButtonCheckBox(ui_->checkBoxTogglePlayButton, buttonCodes, aasdk::proto::enums::ButtonCode::TOGGLE_PLAY);
this->saveButtonCheckBox(ui_->checkBoxNextTrackButton, buttonCodes, aasdk::proto::enums::ButtonCode::NEXT);
this->saveButtonCheckBox(ui_->checkBoxPreviousTrackButton, buttonCodes, aasdk::proto::enums::ButtonCode::PREV);
this->saveButtonCheckBox(ui_->checkBoxHomeButton, buttonCodes, aasdk::proto::enums::ButtonCode::HOME);
this->saveButtonCheckBox(ui_->checkBoxPhoneButton, buttonCodes, aasdk::proto::enums::ButtonCode::PHONE);
this->saveButtonCheckBox(ui_->checkBoxCallEndButton, buttonCodes, aasdk::proto::enums::ButtonCode::CALL_END);
this->saveButtonCheckBox(ui_->checkBoxVoiceCommandButton, buttonCodes, aasdk::proto::enums::ButtonCode::MICROPHONE_1);
this->saveButtonCheckBox(ui_->checkBoxLeftButton, buttonCodes, aasdk::proto::enums::ButtonCode::LEFT);
this->saveButtonCheckBox(ui_->checkBoxRightButton, buttonCodes, aasdk::proto::enums::ButtonCode::RIGHT);
this->saveButtonCheckBox(ui_->checkBoxUpButton, buttonCodes, aasdk::proto::enums::ButtonCode::UP);
this->saveButtonCheckBox(ui_->checkBoxDownButton, buttonCodes, aasdk::proto::enums::ButtonCode::DOWN);
this->saveButtonCheckBox(ui_->checkBoxScrollWheelButton, buttonCodes, aasdk::proto::enums::ButtonCode::SCROLL_WHEEL);
this->saveButtonCheckBox(ui_->checkBoxBackButton, buttonCodes, aasdk::proto::enums::ButtonCode::BACK);
this->saveButtonCheckBox(ui_->checkBoxEnterButton, buttonCodes, aasdk::proto::enums::ButtonCode::ENTER);
configuration_->setButtonCodes(buttonCodes);
}
void SettingsWindow::saveButtonCheckBox(const QCheckBox* checkBox, configuration::IConfiguration::ButtonCodes& buttonCodes, aasdk::proto::enums::ButtonCode::Enum buttonCode)
{
if(checkBox->isChecked())
{
buttonCodes.push_back(buttonCode);
}
}
void SettingsWindow::onUpdateScreenDPI(int value)
{
ui_->labelScreenDPIValue->setText(QString::number(value));
}
void SettingsWindow::onShowBindings()
{
const QString message = QString("Enter -> [Enter] \n")
+ QString("Left -> [Left] \n")
+ QString("Right -> [Right] \n")
+ QString("Up -> [Up] \n")
+ QString("Down -> [Down] \n")
+ QString("Back -> [Esc] \n")
+ QString("Home -> [H] \n")
+ QString("Phone -> [P] \n")
+ QString("Call end -> [O] \n")
+ QString("Play -> [X] \n")
+ QString("Pause -> [C] \n")
+ QString("Previous track -> [V] \n")
+ QString("Next track -> [N] \n")
+ QString("Toggle play -> [B] \n")
+ QString("Voice command -> [M] \n")
+ QString("Wheel left -> [1] \n")
+ QString("Wheel right -> [2]");
QMessageBox confirmationMessage(QMessageBox::Information, "Information", message, QMessageBox::Ok);
confirmationMessage.setWindowFlags(Qt::WindowStaysOnTopHint);
confirmationMessage.exec();
}
}
}
}
}

View File

@ -0,0 +1,207 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>480</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<property name="styleSheet">
<string notr="true">background-color: rgb(46, 52, 54);
color: rgb(238, 238, 236);</string>
</property>
<widget class="QWidget" name="centralwidget">
<widget class="QLabel" name="labelWaitingForDevice">
<property name="geometry">
<rect>
<x>290</x>
<y>30</y>
<width>281</width>
<height>41</height>
</rect>
</property>
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:22pt; font-weight:600; font-style:italic; color:#3465a4;&quot;&gt;Waiting for device...&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>180</x>
<y>20</y>
<width>101</width>
<height>101</height>
</rect>
</property>
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;img src=&quot;:/ico_androidauto.png&quot;/&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
<widget class="QPushButton" name="pushButtonSettings">
<property name="geometry">
<rect>
<x>630</x>
<y>340</y>
<width>161</width>
<height>41</height>
</rect>
</property>
<property name="text">
<string>Settings</string>
</property>
<property name="autoDefault">
<bool>true</bool>
</property>
<property name="default">
<bool>false</bool>
</property>
</widget>
<widget class="QPushButton" name="pushButtonExit">
<property name="geometry">
<rect>
<x>630</x>
<y>390</y>
<width>161</width>
<height>41</height>
</rect>
</property>
<property name="text">
<string>Exit</string>
</property>
<property name="autoDefault">
<bool>true</bool>
</property>
</widget>
<widget class="QLabel" name="label_2">
<property name="geometry">
<rect>
<x>340</x>
<y>70</y>
<width>301</width>
<height>31</height>
</rect>
</property>
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-style:italic; color:#eeeeec;&quot;&gt;Plug in your device to start AndroidAuto (tm).&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
<widget class="QLabel" name="label_3">
<property name="geometry">
<rect>
<x>10</x>
<y>410</y>
<width>271</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/f1xpl/openauto&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#007af4;&quot;&gt;https://github.com/f1xpl/openauto&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
<widget class="QLabel" name="labelDistractionWarningIcon">
<property name="geometry">
<rect>
<x>30</x>
<y>170</y>
<width>31</width>
<height>41</height>
</rect>
</property>
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;img src=&quot;:/ico_warning.png&quot;/&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
<widget class="QLabel" name="labelDistractionWarning">
<property name="geometry">
<rect>
<x>80</x>
<y>130</y>
<width>531</width>
<height>101</height>
</rect>
</property>
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;&lt;span style=&quot; color:#ef2929;&quot;&gt;WARNING!&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; color:#ef2929;&quot;&gt;Distraction may cause accidents. Do not attempt to operate while driving. Always concentrate on driving and obey Traffic Regulations. You assume total responsibility and risk for using this software.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
<widget class="QLabel" name="labelCertificationWarning">
<property name="geometry">
<rect>
<x>80</x>
<y>240</y>
<width>531</width>
<height>121</height>
</rect>
</property>
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; color:#ef2929;&quot;&gt;This software is not certified by Google Inc. It is created for R&amp;amp;D purposes and may not work as expected by the original authors. Do not use while driving.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; color:#ef2929;&quot;&gt;You use this software at your own risk.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
<widget class="QLabel" name="labelCertificationWarningIcon">
<property name="geometry">
<rect>
<x>30</x>
<y>270</y>
<width>31</width>
<height>41</height>
</rect>
</property>
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;img src=&quot;:/ico_warning.png&quot;/&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
<widget class="QLabel" name="labelCopyrightsInfoIcon">
<property name="geometry">
<rect>
<x>220</x>
<y>376</y>
<width>21</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;img src=&quot;:/ico_info.png&quot;/&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
<widget class="QLabel" name="label_4">
<property name="geometry">
<rect>
<x>250</x>
<y>370</y>
<width>361</width>
<height>31</height>
</rect>
</property>
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-style:italic;&quot;&gt;AndroidAuto is registered trademark of Google Inc.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>22</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1,768 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SettingsWindow</class>
<widget class="QWidget" name="SettingsWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>480</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>800</width>
<height>480</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>800</width>
<height>480</height>
</size>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<property name="styleSheet">
<string notr="true">background-color: rgb(46, 52, 54);
color: rgb(238, 238, 236);</string>
</property>
<widget class="QPushButton" name="pushButtonSave">
<property name="geometry">
<rect>
<x>630</x>
<y>430</y>
<width>161</width>
<height>41</height>
</rect>
</property>
<property name="text">
<string>Save</string>
</property>
<property name="autoDefault">
<bool>true</bool>
</property>
</widget>
<widget class="QPushButton" name="pushButtonCancel">
<property name="geometry">
<rect>
<x>630</x>
<y>330</y>
<width>161</width>
<height>41</height>
</rect>
</property>
<property name="text">
<string>Cancel</string>
</property>
<property name="autoDefault">
<bool>true</bool>
</property>
<property name="default">
<bool>false</bool>
</property>
</widget>
<widget class="QTabWidget" name="tabWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>621</width>
<height>481</height>
</rect>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="tabGeneral">
<attribute name="title">
<string>General</string>
</attribute>
<widget class="QGroupBox" name="groupBoxHandenessOfTraffic">
<property name="geometry">
<rect>
<x>0</x>
<y>10</y>
<width>621</width>
<height>91</height>
</rect>
</property>
<property name="title">
<string>Handedness of traffic</string>
</property>
<widget class="QRadioButton" name="radioButtonLeftHandDrive">
<property name="geometry">
<rect>
<x>10</x>
<y>30</y>
<width>141</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>Left-hand drive</string>
</property>
</widget>
<widget class="QRadioButton" name="radioButtonRightHandDrive">
<property name="geometry">
<rect>
<x>10</x>
<y>60</y>
<width>151</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>Right-hand drive</string>
</property>
</widget>
</widget>
<widget class="QCheckBox" name="checkBoxShowClock">
<property name="geometry">
<rect>
<x>10</x>
<y>110</y>
<width>111</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>Show clock</string>
</property>
</widget>
</widget>
<widget class="QWidget" name="tabVideo">
<attribute name="title">
<string>Video</string>
</attribute>
<widget class="QGroupBox" name="groupBoxResolution">
<property name="geometry">
<rect>
<x>0</x>
<y>130</y>
<width>621</width>
<height>211</height>
</rect>
</property>
<property name="title">
<string>Resolution</string>
</property>
<widget class="QRadioButton" name="radioButton480p">
<property name="geometry">
<rect>
<x>10</x>
<y>30</y>
<width>112</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>480p</string>
</property>
</widget>
<widget class="QRadioButton" name="radioButton720p">
<property name="geometry">
<rect>
<x>10</x>
<y>70</y>
<width>112</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>720p</string>
</property>
</widget>
<widget class="QRadioButton" name="radioButton1080p">
<property name="geometry">
<rect>
<x>10</x>
<y>110</y>
<width>112</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>1080p</string>
</property>
</widget>
<widget class="QLabel" name="labelResolutionWarning">
<property name="geometry">
<rect>
<x>50</x>
<y>150</y>
<width>551</width>
<height>51</height>
</rect>
</property>
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;justify&quot;&gt;&lt;span style=&quot; font-style:italic;&quot;&gt;720p and 1080p must be activated in hidden Developer settings of Android Auto application.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
<widget class="QLabel" name="labelResolutionWarningIcon">
<property name="geometry">
<rect>
<x>10</x>
<y>150</y>
<width>41</width>
<height>51</height>
</rect>
</property>
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;justify&quot;&gt;&lt;img src=&quot;:/ico_warning.png&quot;/&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</widget>
<widget class="QGroupBox" name="groupBoxFrameRate">
<property name="geometry">
<rect>
<x>0</x>
<y>10</y>
<width>621</width>
<height>101</height>
</rect>
</property>
<property name="title">
<string>Frame rate</string>
</property>
<widget class="QRadioButton" name="radioButton60FPS">
<property name="geometry">
<rect>
<x>10</x>
<y>70</y>
<width>112</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>60 FPS</string>
</property>
</widget>
<widget class="QRadioButton" name="radioButton30FPS">
<property name="geometry">
<rect>
<x>10</x>
<y>30</y>
<width>112</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>30 FPS</string>
</property>
</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>999</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>999</string>
</property>
</widget>
</widget>
<widget class="QWidget" name="tabInput">
<attribute name="title">
<string>Input</string>
</attribute>
<widget class="QCheckBox" name="checkBoxEnableTouchscreen">
<property name="geometry">
<rect>
<x>0</x>
<y>10</y>
<width>161</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>Enable touchscreen</string>
</property>
</widget>
<widget class="QListWidget" name="listWidgetButtons">
<property name="geometry">
<rect>
<x>0</x>
<y>70</y>
<width>621</width>
<height>381</height>
</rect>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::MultiSelection</enum>
</property>
</widget>
<widget class="QLabel" name="labelButtons">
<property name="geometry">
<rect>
<x>10</x>
<y>50</y>
<width>67</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>Buttons</string>
</property>
</widget>
<widget class="QCheckBox" name="checkBoxPlayButton">
<property name="geometry">
<rect>
<x>20</x>
<y>80</y>
<width>92</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>Play</string>
</property>
</widget>
<widget class="QCheckBox" name="checkBoxPauseButton">
<property name="geometry">
<rect>
<x>20</x>
<y>120</y>
<width>92</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>Pause</string>
</property>
</widget>
<widget class="QCheckBox" name="checkBoxTogglePlayButton">
<property name="geometry">
<rect>
<x>20</x>
<y>160</y>
<width>111</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>Toggle play</string>
</property>
</widget>
<widget class="QCheckBox" name="checkBoxNextTrackButton">
<property name="geometry">
<rect>
<x>20</x>
<y>200</y>
<width>92</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>Next track</string>
</property>
</widget>
<widget class="QCheckBox" name="checkBoxPreviousTrackButton">
<property name="geometry">
<rect>
<x>20</x>
<y>240</y>
<width>121</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>Previous track</string>
</property>
</widget>
<widget class="QCheckBox" name="checkBoxHomeButton">
<property name="geometry">
<rect>
<x>20</x>
<y>280</y>
<width>92</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>Home</string>
</property>
</widget>
<widget class="QCheckBox" name="checkBoxBackButton">
<property name="geometry">
<rect>
<x>200</x>
<y>320</y>
<width>92</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>Back</string>
</property>
</widget>
<widget class="QCheckBox" name="checkBoxEnterButton">
<property name="geometry">
<rect>
<x>200</x>
<y>360</y>
<width>92</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>Enter</string>
</property>
</widget>
<widget class="QCheckBox" name="checkBoxPhoneButton">
<property name="geometry">
<rect>
<x>20</x>
<y>320</y>
<width>92</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>Phone</string>
</property>
</widget>
<widget class="QCheckBox" name="checkBoxCallEndButton">
<property name="geometry">
<rect>
<x>20</x>
<y>360</y>
<width>92</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>Call end</string>
</property>
</widget>
<widget class="QCheckBox" name="checkBoxVoiceCommandButton">
<property name="geometry">
<rect>
<x>200</x>
<y>80</y>
<width>141</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>Voice command</string>
</property>
</widget>
<widget class="QCheckBox" name="checkBoxLeftButton">
<property name="geometry">
<rect>
<x>200</x>
<y>120</y>
<width>92</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>Left</string>
</property>
</widget>
<widget class="QCheckBox" name="checkBoxRightButton">
<property name="geometry">
<rect>
<x>200</x>
<y>160</y>
<width>92</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>Right</string>
</property>
</widget>
<widget class="QCheckBox" name="checkBoxUpButton">
<property name="geometry">
<rect>
<x>200</x>
<y>200</y>
<width>92</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>Up</string>
</property>
</widget>
<widget class="QCheckBox" name="checkBoxDownButton">
<property name="geometry">
<rect>
<x>200</x>
<y>240</y>
<width>92</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>Down</string>
</property>
</widget>
<widget class="QCheckBox" name="checkBoxScrollWheelButton">
<property name="geometry">
<rect>
<x>200</x>
<y>280</y>
<width>111</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>Scroll wheel</string>
</property>
</widget>
<widget class="QPushButton" name="pushButtonSelectAll">
<property name="geometry">
<rect>
<x>490</x>
<y>80</y>
<width>121</width>
<height>41</height>
</rect>
</property>
<property name="text">
<string>Select all</string>
</property>
<property name="autoDefault">
<bool>true</bool>
</property>
</widget>
<widget class="QPushButton" name="pushButtonClearSelection">
<property name="geometry">
<rect>
<x>490</x>
<y>140</y>
<width>121</width>
<height>41</height>
</rect>
</property>
<property name="text">
<string>Clear selection</string>
</property>
<property name="autoDefault">
<bool>true</bool>
</property>
</widget>
<widget class="QPushButton" name="pushButtonShowBindings">
<property name="geometry">
<rect>
<x>490</x>
<y>200</y>
<width>121</width>
<height>41</height>
</rect>
</property>
<property name="text">
<string>Show bindings</string>
</property>
<property name="autoDefault">
<bool>true</bool>
</property>
</widget>
</widget>
<widget class="QWidget" name="tabBluetooth">
<attribute name="title">
<string>Bluetooth</string>
</attribute>
<widget class="QGroupBox" name="groupBoxBluetoothAdapter">
<property name="geometry">
<rect>
<x>0</x>
<y>10</y>
<width>621</width>
<height>441</height>
</rect>
</property>
<property name="title">
<string>Bluetooth adapter</string>
</property>
<widget class="QRadioButton" name="radioButtonDisableBluetooth">
<property name="geometry">
<rect>
<x>20</x>
<y>30</y>
<width>171</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>Disable bluetooth</string>
</property>
</widget>
<widget class="QRadioButton" name="radioButtonUseExternalBluetoothAdapter">
<property name="geometry">
<rect>
<x>20</x>
<y>90</y>
<width>171</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>Use external adapter</string>
</property>
</widget>
<widget class="QLineEdit" name="lineEditExternalBluetoothAdapterAddress">
<property name="geometry">
<rect>
<x>130</x>
<y>120</y>
<width>231</width>
<height>31</height>
</rect>
</property>
</widget>
<widget class="QLabel" name="labelBluetoothAdapterAddress">
<property name="geometry">
<rect>
<x>60</x>
<y>120</y>
<width>67</width>
<height>31</height>
</rect>
</property>
<property name="text">
<string>Address:</string>
</property>
</widget>
<widget class="QLabel" name="labelBluetoothAddressFormatInfo">
<property name="geometry">
<rect>
<x>180</x>
<y>160</y>
<width>271</width>
<height>31</height>
</rect>
</property>
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:10pt; font-style:italic; color:#babdb6;&quot;&gt;Provide address in format AA:BB:CC:DD:EE:FF.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
<widget class="QLabel" name="labelBluetoothAddressFormatInfoIcon">
<property name="geometry">
<rect>
<x>150</x>
<y>160</y>
<width>21</width>
<height>31</height>
</rect>
</property>
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;img src=&quot;:/ico_info.png&quot;/&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
<widget class="QRadioButton" name="radioButtonUseLocalBluetoothAdapter">
<property name="geometry">
<rect>
<x>20</x>
<y>60</y>
<width>151</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>Use local adapter</string>
</property>
</widget>
<widget class="QLabel" name="labelPairWarningIcon">
<property name="geometry">
<rect>
<x>10</x>
<y>206</y>
<width>31</width>
<height>41</height>
</rect>
</property>
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;img src=&quot;:/ico_warning.png&quot;/&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
<widget class="QLabel" name="labelPairWarning">
<property name="geometry">
<rect>
<x>50</x>
<y>210</y>
<width>501</width>
<height>31</height>
</rect>
</property>
<property name="text">
<string>In order to use bluetooth features please remember to pair your device.</string>
</property>
</widget>
</widget>
</widget>
</widget>
<widget class="QLabel" name="labelSettingsIcon">
<property name="geometry">
<rect>
<x>650</x>
<y>80</y>
<width>131</width>
<height>151</height>
</rect>
</property>
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;img src=&quot;:/ico_setting.png&quot;/&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
<widget class="QPushButton" name="pushButtonResetToDefaults">
<property name="geometry">
<rect>
<x>630</x>
<y>380</y>
<width>161</width>
<height>41</height>
</rect>
</property>
<property name="text">
<string>Reset to defaults</string>
</property>
<property name="autoDefault">
<bool>true</bool>
</property>
</widget>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1,124 @@
/*
* 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
{
//std::this_thread::sleep_for(std::chrono::seconds(10));
androidAutoEntity_ = androidAutoEntityFactory_.create(std::move(deviceHandle));
androidAutoEntity_->start(*this);
}
catch(const aasdk::error::Error& error)
{
OPENAUTO_LOG(error) << "[USBApp] AndroidAutoEntity create error: " << error.what();
}
}
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();
}
}
}
}
}
}

View File

@ -0,0 +1,105 @@
/*
* 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);
qApplication.setOverrideCursor(Qt::BlankCursor);
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);
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);
}
void USBMain::startIOServiceWorkers()
{
auto ioServiceWorker = [this]() {
while(!ioService_.stopped())
{
ioService_.run();
}
};
threadPool_.emplace_back(ioServiceWorker);
threadPool_.emplace_back(ioServiceWorker);
threadPool_.emplace_back(ioServiceWorker);
}
}
}
}
}