From be8c0ab9cde8d2c47b9aabe62567a8a735b1f1b8 Mon Sep 17 00:00:00 2001 From: Simon Dean Date: Wed, 13 Nov 2024 12:25:09 +0000 Subject: [PATCH] Compiles and Builds, but problems with Video, WiFi Projection and Bluetooth. --- cmake_modules/Findaap_protobuf.cmake | 8 +- cmake_modules/Findlibusb-1.0.cmake | 8 +- include/f1x/openauto/Common/Log.hpp | 3 +- .../autoapp/Configuration/Configuration.hpp | 26 +- .../autoapp/Configuration/IConfiguration.hpp | 16 +- .../autoapp/Projection/IInputDevice.hpp | 2 +- .../autoapp/Projection/IVideoOutput.hpp | 8 +- .../autoapp/Projection/InputEvent.hpp | 8 +- .../Projection/LocalBluetoothDevice.hpp | 1 - .../autoapp/Projection/VideoOutput.hpp | 4 +- .../autoapp/Service/AndroidAutoEntity.hpp | 17 +- .../Service/Bluetooth/BluetoothService.hpp | 6 +- .../GenericNotificationService.hpp | 4 +- .../f1x/openauto/autoapp/Service/IService.hpp | 4 +- .../InputSource/InputSourceService.hpp | 8 +- .../MediaBrowser/MediaBrowserService.hpp | 4 +- .../MediaPlaybackStatusService.hpp | 4 +- .../MediaSink/AudioMediaSinkService.hpp | 10 +- .../MediaSink/VideoMediaSinkService.hpp | 12 +- .../MediaSource/MediaSourceService.hpp | 8 +- .../NavigationStatusService.hpp | 10 +- .../PhoneStatus/PhoneStatusService.hpp | 4 +- .../autoapp/Service/Radio/RadioService.hpp | 4 +- .../autoapp/Service/Sensor/SensorService.hpp | 6 +- .../f1x/openauto/autoapp/Service/Service.hpp | 2 +- .../VendorExtensionService.hpp | 4 +- .../WifiProjection/WifiProjectionService.hpp | 4 +- .../openauto/autoapp/UI/SettingsWindow.hpp | 2 +- .../btservice/AndroidBluetoothServer.hpp | 3 + src/autoapp/Configuration/Configuration.cpp | 114 +++---- src/autoapp/Projection/InputDevice.cpp | 48 +-- .../Projection/LocalBluetoothDevice.cpp | 52 +-- src/autoapp/Projection/QtVideoOutput.cpp | 1 + src/autoapp/Projection/VideoOutput.cpp | 54 ++- src/autoapp/Service/AndroidAutoEntity.cpp | 99 ++++-- .../Service/Bluetooth/BluetoothService.cpp | 27 +- .../GenericNotificationService.cpp | 6 +- .../InputSource/InputSourceService.cpp | 18 +- .../MediaBrowser/MediaBrowserService.cpp | 6 +- .../MediaPlaybackStatusService.cpp | 6 +- .../MediaSink/AudioMediaSinkService.cpp | 37 ++- .../MediaSink/VideoMediaSinkService.cpp | 44 ++- .../MediaSource/MediaSourceService.cpp | 19 +- .../NavigationStatusService.cpp | 12 +- .../PhoneStatus/PhoneStatusService.cpp | 6 +- src/autoapp/Service/Radio/RadioService.cpp | 6 +- src/autoapp/Service/Sensor/SensorService.cpp | 47 +-- src/autoapp/Service/ServiceFactory.cpp | 8 +- .../VendorExtensionService.cpp | 6 +- .../WifiProjection/WifiProjectionStatus.cpp | 6 +- src/autoapp/UI/SettingsWindow.cpp | 90 ++--- src/autoapp/UI/assets/journey.jpg | Bin 0 -> 95089 bytes src/autoapp/UI/journey.cpp | 14 - src/autoapp/UI/journey.h | 22 -- src/autoapp/UI/journey.ui | 31 -- src/btservice/AndroidBluetoothServer.cpp | 308 +++++++++--------- src/btservice/AndroidBluetoothService.cpp | 30 +- src/btservice/btservice.cpp | 56 ++-- 58 files changed, 649 insertions(+), 724 deletions(-) create mode 100644 src/autoapp/UI/assets/journey.jpg delete mode 100644 src/autoapp/UI/journey.cpp delete mode 100644 src/autoapp/UI/journey.h delete mode 100644 src/autoapp/UI/journey.ui diff --git a/cmake_modules/Findaap_protobuf.cmake b/cmake_modules/Findaap_protobuf.cmake index 56a29b1..7e2eda8 100644 --- a/cmake_modules/Findaap_protobuf.cmake +++ b/cmake_modules/Findaap_protobuf.cmake @@ -1,11 +1,11 @@ if (AAP_PROTOBUF_LIB_DIRS AND AAP_PROTOBUF_INCLUDE_DIRS) # in cache already - message(STATUS "aap_protobuf cached") + message(STATUS "aap_protobuf is cached") set(AAP_PROTOBUF_FOUND TRUE) else (AAP_PROTOBUF_LIB_DIRS AND AAP_PROTOBUF_INCLUDE_DIRS) find_path(AAP_PROTOBUF_INCLUDE_DIR NAMES - channel/ChannelCloseNotification.pb.h + channel/control/GalConstants.pb.h PATHS /usr/include /usr/local/include @@ -37,7 +37,7 @@ else (AAP_PROTOBUF_LIB_DIRS AND AAP_PROTOBUF_INCLUDE_DIRS) endif (AAP_PROTOBUF_INCLUDE_DIRS AND AAP_PROTOBUF_LIB_DIRS) if (AAP_PROTOBUF_FOUND) - message(STATUS "Found aap_protobuf:") + message(STATUS "SUCCESS. Found: aap_protobuf:") message(STATUS " - Includes: ${AAP_PROTOBUF_INCLUDE_DIRS}") message(STATUS " - Libraries: ${AAP_PROTOBUF_LIB_DIRS}") add_library(aap_protobuf INTERFACE) @@ -46,7 +46,7 @@ else (AAP_PROTOBUF_LIB_DIRS AND AAP_PROTOBUF_INCLUDE_DIRS) else (AAP_PROTOBUF_FOUND) message(STATUS " - Includes: ${AAP_PROTOBUF_INCLUDE_DIRS}") message(STATUS " - Libraries: ${AAP_PROTOBUF_LIB_DIRS}") - message(FATAL_ERROR "Could not find aap_protobuf") + message(FATAL_ERROR "Could not locate aap_protobuf") endif (AAP_PROTOBUF_FOUND) # show the AAP_PROTOBUF_INCLUDE_DIRS and AAP_PROTOBUF_LIB_DIRS variables only in the advanced view diff --git a/cmake_modules/Findlibusb-1.0.cmake b/cmake_modules/Findlibusb-1.0.cmake index 80f52dc..311cbc1 100644 --- a/cmake_modules/Findlibusb-1.0.cmake +++ b/cmake_modules/Findlibusb-1.0.cmake @@ -49,7 +49,7 @@ if (LIBUSB_1_LIBRARIES AND LIBUSB_1_INCLUDE_DIRS) else (LIBUSB_1_LIBRARIES AND LIBUSB_1_INCLUDE_DIRS) find_path(LIBUSB_1_INCLUDE_DIR NAMES - libusb.h + libusb.h PATHS /usr/include /usr/local/include @@ -90,12 +90,12 @@ else (LIBUSB_1_LIBRARIES AND LIBUSB_1_INCLUDE_DIRS) target_link_libraries(libusb INTERFACE ${LIBUSB_1_LIBRARY}) endif (NOT libusb_1_FIND_QUIETLY) else (LIBUSB_1_FOUND) - if (libusb_1_FIND_REQUIRED) + if (libusb-1.0_FIND_REQUIRED) message(FATAL_ERROR "Could not find libusb") - endif (libusb_1_FIND_REQUIRED) + endif (libusb-1.0_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) \ No newline at end of file +endif (LIBUSB_1_LIBRARIES AND LIBUSB_1_INCLUDE_DIRS) diff --git a/include/f1x/openauto/Common/Log.hpp b/include/f1x/openauto/Common/Log.hpp index 4215961..91fd0df 100644 --- a/include/f1x/openauto/Common/Log.hpp +++ b/include/f1x/openauto/Common/Log.hpp @@ -20,4 +20,5 @@ #include -#define OPENAUTO_LOG(severity) BOOST_LOG_TRIVIAL(severity) << "[OpenAuto] " +#define OPENAUTO_LOG_CONTEXT "" //"(" << typeid(*this).name() << "::" << __func__ << ")" +#define OPENAUTO_LOG(severity) BOOST_LOG_TRIVIAL(severity) << "[OpenAuto] " << OPENAUTO_LOG_CONTEXT diff --git a/include/f1x/openauto/autoapp/Configuration/Configuration.hpp b/include/f1x/openauto/autoapp/Configuration/Configuration.hpp index e077135..e7d760f 100644 --- a/include/f1x/openauto/autoapp/Configuration/Configuration.hpp +++ b/include/f1x/openauto/autoapp/Configuration/Configuration.hpp @@ -89,10 +89,10 @@ public: QString readFileContent(QString fileName) const override; QString getParamFromFile(QString fileName, QString searchString) const override; - aap_protobuf::service::media::shared::message::VideoFrameRateType getVideoFPS() const override; - void setVideoFPS(aap_protobuf::service::media::shared::message::VideoFrameRateType value) override; - aap_protobuf::service::media::shared::message::VideoCodecResolutionType getVideoResolution() const override; - void setVideoResolution(aap_protobuf::service::media::shared::message::VideoCodecResolutionType value) override; + aap_protobuf::service::media::sink::message::VideoFrameRateType getVideoFPS() const override; + void setVideoFPS(aap_protobuf::service::media::sink::message::VideoFrameRateType value) override; + aap_protobuf::service::media::sink::message::VideoCodecResolutionType getVideoResolution() const override; + void setVideoResolution(aap_protobuf::service::media::sink::message::VideoCodecResolutionType value) override; size_t getScreenDPI() const override; void setScreenDPI(size_t value) override; void setOMXLayerIndex(int32_t value) override; @@ -125,7 +125,7 @@ public: void setAudioOutputBackendType(AudioOutputBackendType value) override; private: void readButtonCodes(boost::property_tree::ptree& iniConfig); - void insertButtonCode(boost::property_tree::ptree& iniConfig, const std::string& buttonCodeKey, aap_protobuf::service::media::sink::KeyCode buttonCode); + void insertButtonCode(boost::property_tree::ptree& iniConfig, const std::string& buttonCodeKey, aap_protobuf::service::media::sink::message::KeyCode buttonCode); void writeButtonCodes(boost::property_tree::ptree& iniConfig); HandednessOfTrafficType handednessOfTrafficType_; @@ -148,8 +148,8 @@ private: bool showAutoPlay_; bool instantPlay_; - aap_protobuf::service::media::shared::message::VideoFrameRateType videoFPS_; - aap_protobuf::service::media::shared::message::VideoCodecResolutionType videoResolution_; + aap_protobuf::service::media::sink::message::VideoFrameRateType videoFPS_; + aap_protobuf::service::media::sink::message::VideoCodecResolutionType videoResolution_; size_t screenDPI_; int32_t omxLayerIndex_; QRect videoMargins_; @@ -196,14 +196,10 @@ private: static const std::string cVideoMarginWidth; static const std::string cVideoMarginHeight; - struct Audio { - struct Channel { - static const std::string cMediaEnabled; - static const std::string cGuidanceEnabled; - static const std::string cSystemEnabled; - static const std::string cTelephonyEnabled; - }; - }; + static const std::string cAudioChannelMediaEnabled; + static const std::string cAudioChannelGuidanceEnabled; + static const std::string cAudioChannelSystemEnabled; + static const std::string cAudioChannelTelephonyEnabled; static const std::string cAudioOutputBackendType; diff --git a/include/f1x/openauto/autoapp/Configuration/IConfiguration.hpp b/include/f1x/openauto/autoapp/Configuration/IConfiguration.hpp index a34678a..091eecb 100644 --- a/include/f1x/openauto/autoapp/Configuration/IConfiguration.hpp +++ b/include/f1x/openauto/autoapp/Configuration/IConfiguration.hpp @@ -20,9 +20,9 @@ #include #include -#include -#include -#include +#include +#include +#include #include #include #include @@ -40,7 +40,7 @@ class IConfiguration { public: typedef std::shared_ptr Pointer; - typedef std::vector ButtonCodes; + typedef std::vector ButtonCodes; virtual ~IConfiguration() = default; @@ -92,10 +92,10 @@ public: virtual QString readFileContent(QString fileName) const = 0; virtual QString getParamFromFile(QString fileName, QString searchString) const = 0; - virtual aap_protobuf::service::media::shared::message::VideoFrameRateType getVideoFPS() const = 0; - virtual void setVideoFPS(aap_protobuf::service::media::shared::message::VideoFrameRateType value) = 0; - virtual aap_protobuf::service::media::shared::message::VideoCodecResolutionType getVideoResolution() const = 0; - virtual void setVideoResolution(aap_protobuf::service::media::shared::message::VideoCodecResolutionType value) = 0; + virtual aap_protobuf::service::media::sink::message::VideoFrameRateType getVideoFPS() const = 0; + virtual void setVideoFPS(aap_protobuf::service::media::sink::message::VideoFrameRateType value) = 0; + virtual aap_protobuf::service::media::sink::message::VideoCodecResolutionType getVideoResolution() const = 0; + virtual void setVideoResolution(aap_protobuf::service::media::sink::message::VideoCodecResolutionType value) = 0; virtual size_t getScreenDPI() const = 0; virtual void setScreenDPI(size_t value) = 0; virtual void setOMXLayerIndex(int32_t value) = 0; diff --git a/include/f1x/openauto/autoapp/Projection/IInputDevice.hpp b/include/f1x/openauto/autoapp/Projection/IInputDevice.hpp index dc97b2c..2e6aee3 100644 --- a/include/f1x/openauto/autoapp/Projection/IInputDevice.hpp +++ b/include/f1x/openauto/autoapp/Projection/IInputDevice.hpp @@ -37,7 +37,7 @@ class IInputDevice { public: typedef std::shared_ptr Pointer; - typedef std::vector ButtonCodes; + typedef std::vector ButtonCodes; virtual ~IInputDevice() = default; virtual void start(IInputDeviceEventHandler& eventHandler) = 0; diff --git a/include/f1x/openauto/autoapp/Projection/IVideoOutput.hpp b/include/f1x/openauto/autoapp/Projection/IVideoOutput.hpp index 668c329..ab93288 100644 --- a/include/f1x/openauto/autoapp/Projection/IVideoOutput.hpp +++ b/include/f1x/openauto/autoapp/Projection/IVideoOutput.hpp @@ -22,8 +22,8 @@ #include #include #include -#include -#include +#include +#include namespace f1x { @@ -47,8 +47,8 @@ public: virtual void write(aasdk::messenger::Timestamp::ValueType timestamp, const aasdk::common::DataConstBuffer& buffer) = 0; virtual void stop() = 0; - virtual aap_protobuf::service::media::shared::message::VideoFrameRateType getVideoFPS() const = 0; - virtual aap_protobuf::service::media::shared::message::VideoCodecResolutionType getVideoResolution() const = 0; + virtual aap_protobuf::service::media::sink::message::VideoFrameRateType getVideoFPS() const = 0; + virtual aap_protobuf::service::media::sink::message::VideoCodecResolutionType getVideoResolution() const = 0; virtual size_t getScreenDPI() const = 0; virtual QRect getVideoMargins() const = 0; diff --git a/include/f1x/openauto/autoapp/Projection/InputEvent.hpp b/include/f1x/openauto/autoapp/Projection/InputEvent.hpp index a5c39d0..c0cda35 100644 --- a/include/f1x/openauto/autoapp/Projection/InputEvent.hpp +++ b/include/f1x/openauto/autoapp/Projection/InputEvent.hpp @@ -18,8 +18,8 @@ #pragma once -#include -#include +#include +#include #include namespace f1x @@ -49,12 +49,12 @@ struct ButtonEvent { ButtonEventType type; WheelDirection wheelDirection; - aap_protobuf::service::media::sink::KeyCode code; + aap_protobuf::service::media::sink::message::KeyCode code; }; struct TouchEvent { - aap_protobuf::service::input::message::PointerAction type; + aap_protobuf::service::inputsource::message::PointerAction type; uint32_t x; uint32_t y; uint32_t pointerId; diff --git a/include/f1x/openauto/autoapp/Projection/LocalBluetoothDevice.hpp b/include/f1x/openauto/autoapp/Projection/LocalBluetoothDevice.hpp index c8677cb..68bc416 100644 --- a/include/f1x/openauto/autoapp/Projection/LocalBluetoothDevice.hpp +++ b/include/f1x/openauto/autoapp/Projection/LocalBluetoothDevice.hpp @@ -65,7 +65,6 @@ private: QBluetoothServiceInfo serviceInfo_; std::unique_ptr rfcommServer_; - void onClientConnected(); }; } diff --git a/include/f1x/openauto/autoapp/Projection/VideoOutput.hpp b/include/f1x/openauto/autoapp/Projection/VideoOutput.hpp index 098fae3..3b6965c 100644 --- a/include/f1x/openauto/autoapp/Projection/VideoOutput.hpp +++ b/include/f1x/openauto/autoapp/Projection/VideoOutput.hpp @@ -35,8 +35,8 @@ class VideoOutput: public IVideoOutput public: VideoOutput(configuration::IConfiguration::Pointer configuration); - aap_protobuf::service::media::shared::message::VideoFrameRateType getVideoFPS() const override; - aap_protobuf::service::media::shared::message::VideoCodecResolutionType getVideoResolution() const override; + aap_protobuf::service::media::sink::message::VideoFrameRateType getVideoFPS() const override; + aap_protobuf::service::media::sink::message::VideoCodecResolutionType getVideoResolution() const override; size_t getScreenDPI() const override; QRect getVideoMargins() const override; diff --git a/include/f1x/openauto/autoapp/Service/AndroidAutoEntity.hpp b/include/f1x/openauto/autoapp/Service/AndroidAutoEntity.hpp index 19acce9..b44d839 100644 --- a/include/f1x/openauto/autoapp/Service/AndroidAutoEntity.hpp +++ b/include/f1x/openauto/autoapp/Service/AndroidAutoEntity.hpp @@ -56,14 +56,15 @@ public: // TODO: on channel open request... on channel close... on navigation focus, on voice session notification, on user switch, on call availability, on service disc update, on battery status, on car connected devices void onVersionResponse(uint16_t majorCode, uint16_t minorCode, aap_protobuf::shared::MessageStatus status) override; void onHandshake(const aasdk::common::DataConstBuffer& payload) override; - void onServiceDiscoveryRequest(const aap_protobuf::channel::control::servicediscovery::event::ServiceDiscoveryRequest& request) override; - void onAudioFocusRequest(const aap_protobuf::channel::control::focus::audio::event::AudioFocusRequest& request) override; - void onByeByeRequest(const aap_protobuf::channel::control::byebye::event::ByeByeRequest& request) override; - void onByeByeResponse(const aap_protobuf::channel::control::byebye::notification::ByeByeResponse& response) override; - void onNavigationFocusRequest(const aap_protobuf::channel::control::focus::navigation::event::NavFocusRequestNotification& request) override; - void onVoiceSessionRequest(const aap_protobuf::channel::control::voice::VoiceSessionNotification &request) override; - void onPingResponse(const aap_protobuf::channel::control::ping::PingResponse& response) override; - void onPingRequest(const aap_protobuf::channel::control::ping::PingRequest& request) override; + void onServiceDiscoveryRequest(const aap_protobuf::service::control::message::ServiceDiscoveryRequest& request) override; + void onAudioFocusRequest(const aap_protobuf::service::control::message::AudioFocusRequest& request) override; + void onByeByeRequest(const aap_protobuf::service::control::message::ByeByeRequest& request) override; + void onByeByeResponse(const aap_protobuf::service::control::message::ByeByeResponse& response) override; + void onNavigationFocusRequest(const aap_protobuf::service::control::message::NavFocusRequestNotification& request) override; + void onVoiceSessionRequest(const aap_protobuf::service::control::message::VoiceSessionNotification &request) override; + void onBatteryStatusNotification(const aap_protobuf::service::control::message::BatteryStatusNotification ¬ification) override; + void onPingResponse(const aap_protobuf::service::control::message::PingResponse& response) override; + void onPingRequest(const aap_protobuf::service::control::message::PingRequest& request) override; void onChannelError(const aasdk::error::Error& e) override; private: diff --git a/include/f1x/openauto/autoapp/Service/Bluetooth/BluetoothService.hpp b/include/f1x/openauto/autoapp/Service/Bluetooth/BluetoothService.hpp index b6bd3fa..cda49bb 100644 --- a/include/f1x/openauto/autoapp/Service/Bluetooth/BluetoothService.hpp +++ b/include/f1x/openauto/autoapp/Service/Bluetooth/BluetoothService.hpp @@ -41,12 +41,12 @@ namespace f1x { void stop() override; void pause() override; void resume() override; - void fillFeatures(aap_protobuf::channel::control::servicediscovery::notification::ServiceDiscoveryResponse &response) override; + void fillFeatures(aap_protobuf::service::control::message::ServiceDiscoveryResponse &response) override; - void onChannelOpenRequest(const aap_protobuf::channel::ChannelOpenRequest &request) override; + void onChannelOpenRequest(const aap_protobuf::service::control::message::ChannelOpenRequest &request) override; void onBluetoothPairingRequest( - const aap_protobuf::channel::bluetooth::event::BluetoothPairingRequest &request) override; + const aap_protobuf::service::bluetooth::message::BluetoothPairingRequest &request) override; void onChannelError(const aasdk::error::Error &e) override; diff --git a/include/f1x/openauto/autoapp/Service/GenericNotification/GenericNotificationService.hpp b/include/f1x/openauto/autoapp/Service/GenericNotification/GenericNotificationService.hpp index b4a9da5..1162e23 100644 --- a/include/f1x/openauto/autoapp/Service/GenericNotification/GenericNotificationService.hpp +++ b/include/f1x/openauto/autoapp/Service/GenericNotification/GenericNotificationService.hpp @@ -40,9 +40,9 @@ namespace f1x { void stop() override; void pause() override; void resume() override; - void fillFeatures(aap_protobuf::channel::control::servicediscovery::notification::ServiceDiscoveryResponse &response) override; + void fillFeatures(aap_protobuf::service::control::message::ServiceDiscoveryResponse &response) override; - void onChannelOpenRequest(const aap_protobuf::channel::ChannelOpenRequest &request) override; + void onChannelOpenRequest(const aap_protobuf::service::control::message::ChannelOpenRequest &request) override; void onChannelError(const aasdk::error::Error &e) override; diff --git a/include/f1x/openauto/autoapp/Service/IService.hpp b/include/f1x/openauto/autoapp/Service/IService.hpp index 5a8a91a..9731894 100644 --- a/include/f1x/openauto/autoapp/Service/IService.hpp +++ b/include/f1x/openauto/autoapp/Service/IService.hpp @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include namespace f1x @@ -44,7 +44,7 @@ public: virtual void stop() = 0; virtual void pause() = 0; virtual void resume() = 0; - virtual void fillFeatures(aap_protobuf::channel::control::servicediscovery::notification::ServiceDiscoveryResponse& response) = 0; + virtual void fillFeatures(aap_protobuf::service::control::message::ServiceDiscoveryResponse& response) = 0; }; typedef std::vector ServiceList; diff --git a/include/f1x/openauto/autoapp/Service/InputSource/InputSourceService.hpp b/include/f1x/openauto/autoapp/Service/InputSource/InputSourceService.hpp index a612c26..4309ce1 100644 --- a/include/f1x/openauto/autoapp/Service/InputSource/InputSourceService.hpp +++ b/include/f1x/openauto/autoapp/Service/InputSource/InputSourceService.hpp @@ -18,7 +18,7 @@ #pragma once -#include +#include #include #include #include @@ -43,12 +43,12 @@ namespace f1x { void stop() override; void pause() override; void resume() override; - void fillFeatures(aap_protobuf::channel::control::servicediscovery::notification::ServiceDiscoveryResponse &response) override; + void fillFeatures(aap_protobuf::service::control::message::ServiceDiscoveryResponse &response) override; - void onChannelOpenRequest(const aap_protobuf::channel::ChannelOpenRequest &request) override; + void onChannelOpenRequest(const aap_protobuf::service::control::message::ChannelOpenRequest &request) override; - void onKeyBindingRequest(const aap_protobuf::channel::input::event::KeyBindingRequest &request) override; + void onKeyBindingRequest(const aap_protobuf::service::media::sink::message::KeyBindingRequest &request) override; void onChannelError(const aasdk::error::Error &e) override; diff --git a/include/f1x/openauto/autoapp/Service/MediaBrowser/MediaBrowserService.hpp b/include/f1x/openauto/autoapp/Service/MediaBrowser/MediaBrowserService.hpp index e2455b9..b013a97 100644 --- a/include/f1x/openauto/autoapp/Service/MediaBrowser/MediaBrowserService.hpp +++ b/include/f1x/openauto/autoapp/Service/MediaBrowser/MediaBrowserService.hpp @@ -40,9 +40,9 @@ namespace f1x { void stop() override; void pause() override; void resume() override; - void fillFeatures(aap_protobuf::channel::control::servicediscovery::notification::ServiceDiscoveryResponse &response) override; + void fillFeatures(aap_protobuf::service::control::message::ServiceDiscoveryResponse &response) override; - void onChannelOpenRequest(const aap_protobuf::channel::ChannelOpenRequest &request) override; + void onChannelOpenRequest(const aap_protobuf::service::control::message::ChannelOpenRequest &request) override; void onChannelError(const aasdk::error::Error &e) override; diff --git a/include/f1x/openauto/autoapp/Service/MediaPlaybackStatus/MediaPlaybackStatusService.hpp b/include/f1x/openauto/autoapp/Service/MediaPlaybackStatus/MediaPlaybackStatusService.hpp index c4d543b..923a9fb 100644 --- a/include/f1x/openauto/autoapp/Service/MediaPlaybackStatus/MediaPlaybackStatusService.hpp +++ b/include/f1x/openauto/autoapp/Service/MediaPlaybackStatus/MediaPlaybackStatusService.hpp @@ -40,9 +40,9 @@ namespace f1x { void stop() override; void pause() override; void resume() override; - void fillFeatures(aap_protobuf::channel::control::servicediscovery::notification::ServiceDiscoveryResponse &response) override; + void fillFeatures(aap_protobuf::service::control::message::ServiceDiscoveryResponse &response) override; - void onChannelOpenRequest(const aap_protobuf::channel::ChannelOpenRequest &request) override; + void onChannelOpenRequest(const aap_protobuf::service::control::message::ChannelOpenRequest &request) override; void onChannelError(const aasdk::error::Error &e) override; diff --git a/include/f1x/openauto/autoapp/Service/MediaSink/AudioMediaSinkService.hpp b/include/f1x/openauto/autoapp/Service/MediaSink/AudioMediaSinkService.hpp index b46f1ea..aa8ae9c 100644 --- a/include/f1x/openauto/autoapp/Service/MediaSink/AudioMediaSinkService.hpp +++ b/include/f1x/openauto/autoapp/Service/MediaSink/AudioMediaSinkService.hpp @@ -44,18 +44,18 @@ namespace f1x { void stop() override; void pause() override; void resume() override; - void fillFeatures(aap_protobuf::channel::control::servicediscovery::notification::ServiceDiscoveryResponse &response) override; + void fillFeatures(aap_protobuf::service::control::message::ServiceDiscoveryResponse &response) override; - void onChannelOpenRequest(const aap_protobuf::channel::ChannelOpenRequest &request) override; + void onChannelOpenRequest(const aap_protobuf::service::control::message::ChannelOpenRequest &request) override; void onMediaChannelSetupRequest( - const aap_protobuf::channel::media::event::Setup &request) override; + const aap_protobuf::service::media::shared::message::Setup &request) override; void onMediaChannelStartIndication( - const aap_protobuf::channel::media::event::Start &indication) override; + const aap_protobuf::service::media::shared::message::Start &indication) override; void onMediaChannelStopIndication( - const aap_protobuf::channel::media::event::Stop &indication) override; + const aap_protobuf::service::media::shared::message::Stop &indication) override; void onMediaWithTimestampIndication(aasdk::messenger::Timestamp::ValueType timestamp, const aasdk::common::DataConstBuffer &buffer) override; diff --git a/include/f1x/openauto/autoapp/Service/MediaSink/VideoMediaSinkService.hpp b/include/f1x/openauto/autoapp/Service/MediaSink/VideoMediaSinkService.hpp index 11a05e0..13ebb34 100644 --- a/include/f1x/openauto/autoapp/Service/MediaSink/VideoMediaSinkService.hpp +++ b/include/f1x/openauto/autoapp/Service/MediaSink/VideoMediaSinkService.hpp @@ -46,18 +46,18 @@ namespace f1x { void stop() override; void pause() override; void resume() override; - void fillFeatures(aap_protobuf::channel::control::servicediscovery::notification::ServiceDiscoveryResponse &response) override; + void fillFeatures(aap_protobuf::service::control::message::ServiceDiscoveryResponse &response) override; - void onChannelOpenRequest(const aap_protobuf::channel::ChannelOpenRequest &request) override; + void onChannelOpenRequest(const aap_protobuf::service::control::message::ChannelOpenRequest &request) override; void onMediaChannelSetupRequest( - const aap_protobuf::channel::media::event::Setup &request) override; + const aap_protobuf::service::media::shared::message::Setup &request) override; void onMediaChannelStartIndication( - const aap_protobuf::channel::media::event::Start &indication) override; + const aap_protobuf::service::media::shared::message::Start &indication) override; void onMediaChannelStopIndication( - const aap_protobuf::channel::media::event::Stop &indication) override; + const aap_protobuf::service::media::shared::message::Stop &indication) override; void onMediaWithTimestampIndication(aasdk::messenger::Timestamp::ValueType timestamp, const aasdk::common::DataConstBuffer &buffer) override; @@ -66,7 +66,7 @@ namespace f1x { void onChannelError(const aasdk::error::Error &e) override; - void onVideoFocusRequest(const aap_protobuf::channel::control::focus::video::event::VideoFocusRequestNotification &request) override; + void onVideoFocusRequest(const aap_protobuf::service::media::video::message::VideoFocusRequestNotification &request) override; void sendVideoFocusIndication(); protected: using std::enable_shared_from_this::shared_from_this; diff --git a/include/f1x/openauto/autoapp/Service/MediaSource/MediaSourceService.hpp b/include/f1x/openauto/autoapp/Service/MediaSource/MediaSourceService.hpp index 9f2600f..917c068 100644 --- a/include/f1x/openauto/autoapp/Service/MediaSource/MediaSourceService.hpp +++ b/include/f1x/openauto/autoapp/Service/MediaSource/MediaSourceService.hpp @@ -55,18 +55,18 @@ namespace service void resume() override; void fillFeatures( - aap_protobuf::channel::control::servicediscovery::notification::ServiceDiscoveryResponse &response) override; + aap_protobuf::service::control::message::ServiceDiscoveryResponse &response) override; - void onChannelOpenRequest(const aap_protobuf::channel::ChannelOpenRequest &request) override; + void onChannelOpenRequest(const aap_protobuf::service::control::message::ChannelOpenRequest &request) override; void onMediaChannelSetupRequest( - const aap_protobuf::channel::media::event::Setup &request) override; + const aap_protobuf::service::media::shared::message::Setup &request) override; void onMediaSourceOpenRequest( const aap_protobuf::service::media::source::message::MicrophoneRequest &request) override; void onMediaChannelAckIndication( - const aap_protobuf::service::media::source::message::MediaSourceMediaAckIndication &indication) override; + const aap_protobuf::service::media::source::message::Ack &indication) override; void onChannelError(const aasdk::error::Error &e) override; diff --git a/include/f1x/openauto/autoapp/Service/NavigationStatus/NavigationStatusService.hpp b/include/f1x/openauto/autoapp/Service/NavigationStatus/NavigationStatusService.hpp index 2019675..8f37b5a 100644 --- a/include/f1x/openauto/autoapp/Service/NavigationStatus/NavigationStatusService.hpp +++ b/include/f1x/openauto/autoapp/Service/NavigationStatus/NavigationStatusService.hpp @@ -40,15 +40,15 @@ namespace f1x { void stop() override; void pause() override; void resume() override; - void fillFeatures(aap_protobuf::channel::control::servicediscovery::notification::ServiceDiscoveryResponse &response) override; + void fillFeatures(aap_protobuf::service::control::message::ServiceDiscoveryResponse &response) override; - void onChannelOpenRequest(const aap_protobuf::channel::ChannelOpenRequest &request) override; + void onChannelOpenRequest(const aap_protobuf::service::control::message::ChannelOpenRequest &request) override; void onChannelError(const aasdk::error::Error &e) override; - void NavigationStatusService::onStatusUpdate(const aap_protobuf::channel::navigation::event::NavigationStatus &navStatus) override; - void NavigationStatusService::onTurnEvent(const aap_protobuf::channel::navigation::event::NavigationNextTurnEvent &turnEvent) override; - void NavigationStatusService::onDistanceEvent(const aap_protobuf::service::navigation::message::NavigationNextTurnDistanceEvent &distanceEvent) override; + void onStatusUpdate(const aap_protobuf::service::navigationstatus::message::NavigationStatus &navStatus) override; + void onTurnEvent(const aap_protobuf::service::navigationstatus::message::NavigationNextTurnEvent &turnEvent) override; + void onDistanceEvent(const aap_protobuf::service::navigationstatus::message::NavigationNextTurnDistanceEvent &distanceEvent) override; private: using std::enable_shared_from_this::shared_from_this; diff --git a/include/f1x/openauto/autoapp/Service/PhoneStatus/PhoneStatusService.hpp b/include/f1x/openauto/autoapp/Service/PhoneStatus/PhoneStatusService.hpp index a5b5f2e..289b4ee 100644 --- a/include/f1x/openauto/autoapp/Service/PhoneStatus/PhoneStatusService.hpp +++ b/include/f1x/openauto/autoapp/Service/PhoneStatus/PhoneStatusService.hpp @@ -40,9 +40,9 @@ namespace f1x { void stop() override; void pause() override; void resume() override; - void fillFeatures(aap_protobuf::channel::control::servicediscovery::notification::ServiceDiscoveryResponse &response) override; + void fillFeatures(aap_protobuf::service::control::message::ServiceDiscoveryResponse &response) override; - void onChannelOpenRequest(const aap_protobuf::channel::ChannelOpenRequest &request) override; + void onChannelOpenRequest(const aap_protobuf::service::control::message::ChannelOpenRequest &request) override; void onChannelError(const aasdk::error::Error &e) override; diff --git a/include/f1x/openauto/autoapp/Service/Radio/RadioService.hpp b/include/f1x/openauto/autoapp/Service/Radio/RadioService.hpp index 305b591..ba698d9 100644 --- a/include/f1x/openauto/autoapp/Service/Radio/RadioService.hpp +++ b/include/f1x/openauto/autoapp/Service/Radio/RadioService.hpp @@ -40,9 +40,9 @@ namespace f1x { void stop() override; void pause() override; void resume() override; - void fillFeatures(aap_protobuf::channel::control::servicediscovery::notification::ServiceDiscoveryResponse &response) override; + void fillFeatures(aap_protobuf::service::control::message::ServiceDiscoveryResponse &response) override; - void onChannelOpenRequest(const aap_protobuf::channel::ChannelOpenRequest &request) override; + void onChannelOpenRequest(const aap_protobuf::service::control::message::ChannelOpenRequest &request) override; void onChannelError(const aasdk::error::Error &e) override; diff --git a/include/f1x/openauto/autoapp/Service/Sensor/SensorService.hpp b/include/f1x/openauto/autoapp/Service/Sensor/SensorService.hpp index de2b10a..3e2f855 100644 --- a/include/f1x/openauto/autoapp/Service/Sensor/SensorService.hpp +++ b/include/f1x/openauto/autoapp/Service/Sensor/SensorService.hpp @@ -45,12 +45,12 @@ namespace f1x { void stop() override; void pause() override; void resume() override; - void fillFeatures(aap_protobuf::channel::control::servicediscovery::notification::ServiceDiscoveryResponse &response) override; + void fillFeatures(aap_protobuf::service::control::message::ServiceDiscoveryResponse &response) override; - void onChannelOpenRequest(const aap_protobuf::channel::ChannelOpenRequest &request) override; + void onChannelOpenRequest(const aap_protobuf::service::control::message::ChannelOpenRequest &request) override; void onSensorStartRequest( - const aap_protobuf::channel::sensor::event::SensorRequest &request) override; + const aap_protobuf::service::sensorsource::message::SensorRequest &request) override; void onChannelError(const aasdk::error::Error &e) override; diff --git a/include/f1x/openauto/autoapp/Service/Service.hpp b/include/f1x/openauto/autoapp/Service/Service.hpp index e406e48..7157f2b 100644 --- a/include/f1x/openauto/autoapp/Service/Service.hpp +++ b/include/f1x/openauto/autoapp/Service/Service.hpp @@ -40,7 +40,7 @@ namespace f1x { void resume() override; - void fillFeatures(aap_protobuf::channel::control::servicediscovery::notification::ServiceDiscoveryResponse &response) override; + void fillFeatures(aap_protobuf::service::control::message::ServiceDiscoveryResponse &response) override; private: diff --git a/include/f1x/openauto/autoapp/Service/VendorExtension/VendorExtensionService.hpp b/include/f1x/openauto/autoapp/Service/VendorExtension/VendorExtensionService.hpp index dea205b..88db0eb 100644 --- a/include/f1x/openauto/autoapp/Service/VendorExtension/VendorExtensionService.hpp +++ b/include/f1x/openauto/autoapp/Service/VendorExtension/VendorExtensionService.hpp @@ -40,9 +40,9 @@ namespace f1x { void stop() override; void pause() override; void resume() override; - void fillFeatures(aap_protobuf::channel::control::servicediscovery::notification::ServiceDiscoveryResponse &response) override; + void fillFeatures(aap_protobuf::service::control::message::ServiceDiscoveryResponse &response) override; - void onChannelOpenRequest(const aap_protobuf::channel::ChannelOpenRequest &request) override; + void onChannelOpenRequest(const aap_protobuf::service::control::message::ChannelOpenRequest &request) override; void onChannelError(const aasdk::error::Error &e) override; diff --git a/include/f1x/openauto/autoapp/Service/WifiProjection/WifiProjectionService.hpp b/include/f1x/openauto/autoapp/Service/WifiProjection/WifiProjectionService.hpp index 242448a..322732e 100644 --- a/include/f1x/openauto/autoapp/Service/WifiProjection/WifiProjectionService.hpp +++ b/include/f1x/openauto/autoapp/Service/WifiProjection/WifiProjectionService.hpp @@ -40,9 +40,9 @@ namespace f1x { void stop() override; void pause() override; void resume() override; - void fillFeatures(aap_protobuf::channel::control::servicediscovery::notification::ServiceDiscoveryResponse &response) override; + void fillFeatures(aap_protobuf::service::control::message::ServiceDiscoveryResponse &response) override; - void onChannelOpenRequest(const aap_protobuf::channel::ChannelOpenRequest &request) override; + void onChannelOpenRequest(const aap_protobuf::service::control::message::ChannelOpenRequest &request) override; void onChannelError(const aasdk::error::Error &e) override; diff --git a/include/f1x/openauto/autoapp/UI/SettingsWindow.hpp b/include/f1x/openauto/autoapp/UI/SettingsWindow.hpp index b91be8f..03d7dbc 100644 --- a/include/f1x/openauto/autoapp/UI/SettingsWindow.hpp +++ b/include/f1x/openauto/autoapp/UI/SettingsWindow.hpp @@ -102,7 +102,7 @@ private: void load(); void loadButtonCheckBoxes(); void saveButtonCheckBoxes(); - void saveButtonCheckBox(const QCheckBox* checkBox, configuration::IConfiguration::ButtonCodes& buttonCodes, aap_protobuf::service::media::sink::KeyCode buttonCode); + void saveButtonCheckBox(const QCheckBox* checkBox, configuration::IConfiguration::ButtonCodes& buttonCodes, aap_protobuf::service::media::sink::message::KeyCode buttonCode); void setButtonCheckBoxes(bool value); Ui::SettingsWindow* ui_; diff --git a/include/f1x/openauto/btservice/AndroidBluetoothServer.hpp b/include/f1x/openauto/btservice/AndroidBluetoothServer.hpp index 4eb540b..2ecfd5b 100644 --- a/include/f1x/openauto/btservice/AndroidBluetoothServer.hpp +++ b/include/f1x/openauto/btservice/AndroidBluetoothServer.hpp @@ -24,6 +24,9 @@ #include #include #include +#include +#include +#include namespace f1x { diff --git a/src/autoapp/Configuration/Configuration.cpp b/src/autoapp/Configuration/Configuration.cpp index 63e7908..a62a845 100644 --- a/src/autoapp/Configuration/Configuration.cpp +++ b/src/autoapp/Configuration/Configuration.cpp @@ -60,10 +60,10 @@ const std::string Configuration::cVideoOMXLayerIndexKey = "Video.OMXLayerIndex"; const std::string Configuration::cVideoMarginWidth = "Video.MarginWidth"; const std::string Configuration::cVideoMarginHeight = "Video.MarginHeight"; -const std::string Configuration::Audio::Channel::cMediaEnabled = "Audio.Channel.MediaEnabled"; -const std::string Configuration::Audio::Channel::cGuidanceEnabled = "Audio.Channel.GuidanceEnabled"; -const std::string Configuration::Audio::Channel::cSystemEnabled = "Audio.Channel.SystemEnabled"; -const std::string Configuration::Audio::Channel::cTelephonyEnabled = "Audio.Channel.TelephonyEnabled"; +const std::string Configuration::cAudioChannelMediaEnabled = "AudioChannel.MediaEnabled"; +const std::string Configuration::cAudioChannelGuidanceEnabled = "AudioChannel.GuidanceEnabled"; +const std::string Configuration::cAudioChannelSystemEnabled = "AudioChannel.SystemEnabled"; +const std::string Configuration::cAudioChannelTelephonyEnabled = "AudioChannel.TelephonyEnabled"; const std::string Configuration::cAudioOutputBackendType = "Audio.OutputBackendType"; @@ -123,11 +123,11 @@ void Configuration::load() showAutoPlay_ = iniConfig.get(cGeneralShowAutoPlayKey, false); instantPlay_ = iniConfig.get(cGeneralInstantPlayKey, false); - videoFPS_ = static_cast(iniConfig.get(cVideoFPSKey, - aap_protobuf::service::media::shared::message::VideoFrameRateType::VIDEO_FPS_30)); + videoFPS_ = static_cast(iniConfig.get(cVideoFPSKey, + aap_protobuf::service::media::sink::message::VideoFrameRateType::VIDEO_FPS_30)); - videoResolution_ = static_cast(iniConfig.get(cVideoResolutionKey, - aap_protobuf::service::media::shared::message::VideoCodecResolutionType::VIDEO_800x480)); + videoResolution_ = static_cast(iniConfig.get(cVideoResolutionKey, + aap_protobuf::service::media::sink::message::VideoCodecResolutionType::VIDEO_800x480)); screenDPI_ = iniConfig.get(cVideoScreenDPIKey, 140); omxLayerIndex_ = iniConfig.get(cVideoOMXLayerIndexKey, 1); @@ -142,10 +142,10 @@ void Configuration::load() bluetoothRemoteAdapterAddress_ = iniConfig.get(cBluetoothRemoteAdapterAddressKey, ""); - _audioChannelEnabledMedia = iniConfig.get(Audio::Channel::cMediaEnabled, true); - _audioChannelEnabledGuidance = iniConfig.get(Audio::Channel::cGuidanceEnabled, true); - _audioChannelEnabledSystem = iniConfig.get(Audio::Channel::cSystemEnabled, true); - _audioChannelEnabledTelephony = iniConfig.get(Audio::Channel::cTelephonyEnabled, true); + _audioChannelEnabledMedia = iniConfig.get(cAudioChannelMediaEnabled, true); + _audioChannelEnabledGuidance = iniConfig.get(cAudioChannelGuidanceEnabled, true); + _audioChannelEnabledSystem = iniConfig.get(cAudioChannelSystemEnabled, true); + _audioChannelEnabledTelephony = iniConfig.get(cAudioChannelTelephonyEnabled, true); audioOutputBackendType_ = static_cast(iniConfig.get(cAudioOutputBackendType, static_cast(AudioOutputBackendType::RTAUDIO))); } @@ -178,8 +178,8 @@ void Configuration::reset() mp3AutoPlay_ = false; showAutoPlay_ = false; instantPlay_ = false; - videoFPS_ = aap_protobuf::service::media::shared::message::VideoFrameRateType::VIDEO_FPS_30; - videoResolution_ = aap_protobuf::service::media::shared::message::VideoCodecResolutionType::VIDEO_800x480; + videoFPS_ = aap_protobuf::service::media::sink::message::VideoFrameRateType::VIDEO_FPS_30; + videoResolution_ = aap_protobuf::service::media::sink::message::VideoCodecResolutionType::VIDEO_800x480; screenDPI_ = 140; omxLayerIndex_ = 1; videoMargins_ = QRect(0, 0, 0, 0); @@ -234,10 +234,10 @@ void Configuration::save() iniConfig.put(cBluetoothAdapterTypeKey, static_cast(bluetoothAdapterType_)); iniConfig.put(cBluetoothRemoteAdapterAddressKey, bluetoothRemoteAdapterAddress_); - iniConfig.put(Audio::Channel::cMediaEnabled, _audioChannelEnabledMedia); - iniConfig.put(Audio::Channel::cGuidanceEnabled, _audioChannelEnabledGuidance); - iniConfig.put(Audio::Channel::cSystemEnabled, _audioChannelEnabledSystem); - iniConfig.put(Audio::Channel::cTelephonyEnabled, _audioChannelEnabledTelephony); + iniConfig.put(cAudioChannelMediaEnabled, _audioChannelEnabledMedia); + iniConfig.put(cAudioChannelGuidanceEnabled, _audioChannelEnabledGuidance); + iniConfig.put(cAudioChannelSystemEnabled, _audioChannelEnabledSystem); + iniConfig.put(cAudioChannelTelephonyEnabled, _audioChannelEnabledTelephony); iniConfig.put(cAudioOutputBackendType, static_cast(audioOutputBackendType_)); boost::property_tree::ini_parser::write_ini(cConfigFileName, iniConfig); @@ -442,22 +442,22 @@ bool Configuration::instantPlay() const return instantPlay_; } -aap_protobuf::service::media::shared::message::VideoFrameRateType Configuration::getVideoFPS() const +aap_protobuf::service::media::sink::message::VideoFrameRateType Configuration::getVideoFPS() const { return videoFPS_; } -void Configuration::setVideoFPS(aap_protobuf::service::media::shared::message::VideoFrameRateType value) +void Configuration::setVideoFPS(aap_protobuf::service::media::sink::message::VideoFrameRateType value) { videoFPS_ = value; } -aap_protobuf::service::media::shared::message::VideoCodecResolutionType Configuration::getVideoResolution() const +aap_protobuf::service::media::sink::message::VideoCodecResolutionType Configuration::getVideoResolution() const { return videoResolution_; } -void Configuration::setVideoResolution(aap_protobuf::service::media::shared::message::VideoCodecResolutionType value) +void Configuration::setVideoResolution(aap_protobuf::service::media::sink::message::VideoCodecResolutionType value) { videoResolution_ = value; } @@ -717,26 +717,26 @@ QString Configuration::readFileContent(QString fileName) const void Configuration::readButtonCodes(boost::property_tree::ptree& iniConfig) { - this->insertButtonCode(iniConfig, cInputPlayButtonKey, aap_protobuf::service::media::sink::KeyCode::KEYCODE_MEDIA_PLAY); - this->insertButtonCode(iniConfig, cInputPauseButtonKey, aap_protobuf::service::media::sink::KeyCode::KEYCODE_MEDIA_PAUSE); - this->insertButtonCode(iniConfig, cInputTogglePlayButtonKey, aap_protobuf::service::media::sink::KeyCode::KEYCODE_MEDIA_PLAY_PAUSE); - this->insertButtonCode(iniConfig, cInputNextTrackButtonKey, aap_protobuf::service::media::sink::KeyCode::KEYCODE_MEDIA_NEXT); - this->insertButtonCode(iniConfig, cInputPreviousTrackButtonKey, aap_protobuf::service::media::sink::KeyCode::KEYCODE_MEDIA_PREVIOUS); - this->insertButtonCode(iniConfig, cInputHomeButtonKey, aap_protobuf::service::media::sink::KeyCode::KEYCODE_HOME); - this->insertButtonCode(iniConfig, cInputPhoneButtonKey, aap_protobuf::service::media::sink::KeyCode::KEYCODE_CALL); - this->insertButtonCode(iniConfig, cInputCallEndButtonKey, aap_protobuf::service::media::sink::KeyCode::KEYCODE_ENDCALL); - this->insertButtonCode(iniConfig, cInputVoiceCommandButtonKey, aap_protobuf::service::media::sink::KeyCode::KEYCODE_SEARCH); - this->insertButtonCode(iniConfig, cInputLeftButtonKey, aap_protobuf::service::media::sink::KeyCode::KEYCODE_DPAD_LEFT); - this->insertButtonCode(iniConfig, cInputRightButtonKey, aap_protobuf::service::media::sink::KeyCode::KEYCODE_DPAD_RIGHT); - this->insertButtonCode(iniConfig, cInputUpButtonKey, aap_protobuf::service::media::sink::KeyCode::KEYCODE_DPAD_UP); - this->insertButtonCode(iniConfig, cInputDownButtonKey, aap_protobuf::service::media::sink::KeyCode::KEYCODE_DPAD_DOWN); - this->insertButtonCode(iniConfig, cInputScrollWheelButtonKey, aap_protobuf::service::media::sink::KeyCode::KEYCODE_ROTARY_CONTROLLER); - this->insertButtonCode(iniConfig, cInputBackButtonKey, aap_protobuf::service::media::sink::KeyCode::KEYCODE_BACK); - this->insertButtonCode(iniConfig, cInputEnterButtonKey, aap_protobuf::service::media::sink::KeyCode::KEYCODE_DPAD_CENTER); - this->insertButtonCode(iniConfig, cInputNavButtonKey, aap_protobuf::service::media::sink::KeyCode::KEYCODE_NAVIGATION); + this->insertButtonCode(iniConfig, cInputPlayButtonKey, aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_MEDIA_PLAY); + this->insertButtonCode(iniConfig, cInputPauseButtonKey, aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_MEDIA_PAUSE); + this->insertButtonCode(iniConfig, cInputTogglePlayButtonKey, aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_MEDIA_PLAY_PAUSE); + this->insertButtonCode(iniConfig, cInputNextTrackButtonKey, aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_MEDIA_NEXT); + this->insertButtonCode(iniConfig, cInputPreviousTrackButtonKey, aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_MEDIA_PREVIOUS); + this->insertButtonCode(iniConfig, cInputHomeButtonKey, aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_HOME); + this->insertButtonCode(iniConfig, cInputPhoneButtonKey, aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_CALL); + this->insertButtonCode(iniConfig, cInputCallEndButtonKey, aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_ENDCALL); + this->insertButtonCode(iniConfig, cInputVoiceCommandButtonKey, aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_SEARCH); + this->insertButtonCode(iniConfig, cInputLeftButtonKey, aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_DPAD_LEFT); + this->insertButtonCode(iniConfig, cInputRightButtonKey, aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_DPAD_RIGHT); + this->insertButtonCode(iniConfig, cInputUpButtonKey, aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_DPAD_UP); + this->insertButtonCode(iniConfig, cInputDownButtonKey, aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_DPAD_DOWN); + this->insertButtonCode(iniConfig, cInputScrollWheelButtonKey, aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_ROTARY_CONTROLLER); + this->insertButtonCode(iniConfig, cInputBackButtonKey, aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_BACK); + this->insertButtonCode(iniConfig, cInputEnterButtonKey, aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_DPAD_CENTER); + this->insertButtonCode(iniConfig, cInputNavButtonKey, aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_NAVIGATION); } -void Configuration::insertButtonCode(boost::property_tree::ptree& iniConfig, const std::string& buttonCodeKey, aap_protobuf::service::media::sink::KeyCode buttonCode) +void Configuration::insertButtonCode(boost::property_tree::ptree& iniConfig, const std::string& buttonCodeKey, aap_protobuf::service::media::sink::message::KeyCode buttonCode) { if(iniConfig.get(buttonCodeKey, false)) { @@ -746,23 +746,23 @@ void Configuration::insertButtonCode(boost::property_tree::ptree& iniConfig, con void Configuration::writeButtonCodes(boost::property_tree::ptree& iniConfig) { - iniConfig.put(cInputPlayButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aap_protobuf::service::media::sink::KeyCode::KEYCODE_MEDIA_PLAY) != buttonCodes_.end()); - iniConfig.put(cInputPauseButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aap_protobuf::service::media::sink::KeyCode::KEYCODE_MEDIA_PAUSE) != buttonCodes_.end()); - iniConfig.put(cInputTogglePlayButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aap_protobuf::service::media::sink::KeyCode::KEYCODE_MEDIA_PLAY_PAUSE) != buttonCodes_.end()); - iniConfig.put(cInputNextTrackButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aap_protobuf::service::media::sink::KeyCode::KEYCODE_MEDIA_NEXT) != buttonCodes_.end()); - iniConfig.put(cInputPreviousTrackButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aap_protobuf::service::media::sink::KeyCode::KEYCODE_MEDIA_PREVIOUS) != buttonCodes_.end()); - iniConfig.put(cInputHomeButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aap_protobuf::service::media::sink::KeyCode::KEYCODE_HOME) != buttonCodes_.end()); - iniConfig.put(cInputPhoneButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aap_protobuf::service::media::sink::KeyCode::KEYCODE_CALL) != buttonCodes_.end()); - iniConfig.put(cInputCallEndButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aap_protobuf::service::media::sink::KeyCode::KEYCODE_ENDCALL) != buttonCodes_.end()); - iniConfig.put(cInputVoiceCommandButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aap_protobuf::service::media::sink::KeyCode::KEYCODE_SEARCH) != buttonCodes_.end()); - iniConfig.put(cInputLeftButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aap_protobuf::service::media::sink::KeyCode::KEYCODE_DPAD_LEFT) != buttonCodes_.end()); - iniConfig.put(cInputRightButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aap_protobuf::service::media::sink::KeyCode::KEYCODE_DPAD_RIGHT) != buttonCodes_.end()); - iniConfig.put(cInputUpButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aap_protobuf::service::media::sink::KeyCode::KEYCODE_DPAD_UP) != buttonCodes_.end()); - iniConfig.put(cInputDownButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aap_protobuf::service::media::sink::KeyCode::KEYCODE_DPAD_DOWN) != buttonCodes_.end()); - iniConfig.put(cInputScrollWheelButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aap_protobuf::service::media::sink::KeyCode::KEYCODE_ROTARY_CONTROLLER) != buttonCodes_.end()); - iniConfig.put(cInputBackButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aap_protobuf::service::media::sink::KeyCode::KEYCODE_BACK) != buttonCodes_.end()); - iniConfig.put(cInputEnterButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aap_protobuf::service::media::sink::KeyCode::KEYCODE_DPAD_CENTER) != buttonCodes_.end()); - iniConfig.put(cInputNavButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aap_protobuf::service::media::sink::KeyCode::KEYCODE_NAVIGATION) != buttonCodes_.end()); + iniConfig.put(cInputPlayButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_MEDIA_PLAY) != buttonCodes_.end()); + iniConfig.put(cInputPauseButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_MEDIA_PAUSE) != buttonCodes_.end()); + iniConfig.put(cInputTogglePlayButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_MEDIA_PLAY_PAUSE) != buttonCodes_.end()); + iniConfig.put(cInputNextTrackButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_MEDIA_NEXT) != buttonCodes_.end()); + iniConfig.put(cInputPreviousTrackButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_MEDIA_PREVIOUS) != buttonCodes_.end()); + iniConfig.put(cInputHomeButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_HOME) != buttonCodes_.end()); + iniConfig.put(cInputPhoneButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_CALL) != buttonCodes_.end()); + iniConfig.put(cInputCallEndButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_ENDCALL) != buttonCodes_.end()); + iniConfig.put(cInputVoiceCommandButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_SEARCH) != buttonCodes_.end()); + iniConfig.put(cInputLeftButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_DPAD_LEFT) != buttonCodes_.end()); + iniConfig.put(cInputRightButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_DPAD_RIGHT) != buttonCodes_.end()); + iniConfig.put(cInputUpButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_DPAD_UP) != buttonCodes_.end()); + iniConfig.put(cInputDownButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_DPAD_DOWN) != buttonCodes_.end()); + iniConfig.put(cInputScrollWheelButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_ROTARY_CONTROLLER) != buttonCodes_.end()); + iniConfig.put(cInputBackButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_BACK) != buttonCodes_.end()); + iniConfig.put(cInputEnterButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_DPAD_CENTER) != buttonCodes_.end()); + iniConfig.put(cInputNavButtonKey, std::find(buttonCodes_.begin(), buttonCodes_.end(), aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_NAVIGATION) != buttonCodes_.end()); } } diff --git a/src/autoapp/Projection/InputDevice.cpp b/src/autoapp/Projection/InputDevice.cpp index cb39975..3f7ac95 100644 --- a/src/autoapp/Projection/InputDevice.cpp +++ b/src/autoapp/Projection/InputDevice.cpp @@ -83,91 +83,91 @@ bool InputDevice::eventFilter(QObject* obj, QEvent* event) bool InputDevice::handleKeyEvent(QEvent* event, QKeyEvent* key) { auto eventType = event->type() == QEvent::KeyPress ? ButtonEventType::PRESS : ButtonEventType::RELEASE; - aap_protobuf::service::media::sink::KeyCode buttonCode; + aap_protobuf::service::media::sink::message::KeyCode buttonCode; WheelDirection wheelDirection = WheelDirection::NONE; switch(key->key()) { case Qt::Key_Return: case Qt::Key_Enter: - buttonCode = aap_protobuf::service::media::sink::KeyCode::KEYCODE_DPAD_CENTER; + buttonCode = aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_DPAD_CENTER; break; case Qt::Key_Left: - buttonCode = aap_protobuf::service::media::sink::KeyCode::KEYCODE_DPAD_LEFT; + buttonCode = aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_DPAD_LEFT; break; case Qt::Key_Right: - buttonCode = aap_protobuf::service::media::sink::KeyCode::KEYCODE_DPAD_RIGHT; + buttonCode = aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_DPAD_RIGHT; break; case Qt::Key_Up: - buttonCode = aap_protobuf::service::media::sink::KeyCode::KEYCODE_DPAD_UP; + buttonCode = aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_DPAD_UP; break; case Qt::Key_Down: - buttonCode = aap_protobuf::service::media::sink::KeyCode::KEYCODE_DPAD_DOWN; + buttonCode = aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_DPAD_DOWN; break; case Qt::Key_Escape: - buttonCode = aap_protobuf::service::media::sink::KeyCode::KEYCODE_BACK; + buttonCode = aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_BACK; break; case Qt::Key_H: - buttonCode = aap_protobuf::service::media::sink::KeyCode::KEYCODE_HOME; + buttonCode = aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_HOME; break; case Qt::Key_P: - buttonCode = aap_protobuf::service::media::sink::KeyCode::KEYCODE_CALL; + buttonCode = aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_CALL; break; case Qt::Key_O: - buttonCode = aap_protobuf::service::media::sink::KeyCode::KEYCODE_ENDCALL; + buttonCode = aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_ENDCALL; break; case Qt::Key_MediaPlay: case Qt::Key_X: - buttonCode = aap_protobuf::service::media::sink::KeyCode::KEYCODE_MEDIA_PLAY; + buttonCode = aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_MEDIA_PLAY; break; case Qt::Key_MediaPause: case Qt::Key_C: - buttonCode = aap_protobuf::service::media::sink::KeyCode::KEYCODE_MEDIA_PAUSE; + buttonCode = aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_MEDIA_PAUSE; break; case Qt::Key_MediaPrevious: case Qt::Key_V: - buttonCode = aap_protobuf::service::media::sink::KeyCode::KEYCODE_MEDIA_PREVIOUS; + buttonCode = aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_MEDIA_PREVIOUS; break; case Qt::Key_MediaTogglePlayPause: case Qt::Key_B: - buttonCode = aap_protobuf::service::media::sink::KeyCode::KEYCODE_MEDIA_PLAY_PAUSE; + buttonCode = aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_MEDIA_PLAY_PAUSE; break; case Qt::Key_MediaNext: case Qt::Key_N: - buttonCode = aap_protobuf::service::media::sink::KeyCode::KEYCODE_MEDIA_NEXT; + buttonCode = aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_MEDIA_NEXT; break; case Qt::Key_M: - buttonCode = aap_protobuf::service::media::sink::KeyCode::KEYCODE_SEARCH; + buttonCode = aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_SEARCH; break; case Qt::Key_1: wheelDirection = WheelDirection::LEFT; eventType = ButtonEventType::NONE; - buttonCode = aap_protobuf::service::media::sink::KeyCode::KEYCODE_ROTARY_CONTROLLER; + buttonCode = aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_ROTARY_CONTROLLER; break; case Qt::Key_2: wheelDirection = WheelDirection::RIGHT; eventType = ButtonEventType::NONE; - buttonCode = aap_protobuf::service::media::sink::KeyCode::KEYCODE_ROTARY_CONTROLLER; + buttonCode = aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_ROTARY_CONTROLLER; break; case Qt::Key_F: - buttonCode = aap_protobuf::service::media::sink::KeyCode::KEYCODE_NAVIGATION; + buttonCode = aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_NAVIGATION; break; default: @@ -177,7 +177,7 @@ bool InputDevice::handleKeyEvent(QEvent* event, QKeyEvent* key) const auto& buttonCodes = this->getSupportedButtonCodes(); if(std::find(buttonCodes.begin(), buttonCodes.end(), buttonCode) != buttonCodes.end()) { - if(buttonCode != aap_protobuf::service::media::sink::KeyCode::KEYCODE_ROTARY_CONTROLLER || event->type() == QEvent::KeyRelease) + if(buttonCode != aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_ROTARY_CONTROLLER || event->type() == QEvent::KeyRelease) { eventHandler_->onButtonEvent({eventType, wheelDirection, buttonCode}); } @@ -193,18 +193,18 @@ bool InputDevice::handleTouchEvent(QEvent* event) return true; } - aap_protobuf::service::input::message::PointerAction type; + aap_protobuf::service::inputsource::message::PointerAction type; switch(event->type()) { case QEvent::MouseButtonPress: - type = aap_protobuf::service::input::message::PointerAction::ACTION_DOWN; + type = aap_protobuf::service::inputsource::message::PointerAction::ACTION_DOWN; break; case QEvent::MouseButtonRelease: - type = aap_protobuf::service::input::message::PointerAction::ACTION_UP; + type = aap_protobuf::service::inputsource::message::PointerAction::ACTION_UP; break; case QEvent::MouseMove: - type = aap_protobuf::service::input::message::PointerAction::ACTION_MOVED; + type = aap_protobuf::service::inputsource::message::PointerAction::ACTION_MOVED; break; default: return true; diff --git a/src/autoapp/Projection/LocalBluetoothDevice.cpp b/src/autoapp/Projection/LocalBluetoothDevice.cpp index 4086eff..58eb52d 100644 --- a/src/autoapp/Projection/LocalBluetoothDevice.cpp +++ b/src/autoapp/Projection/LocalBluetoothDevice.cpp @@ -54,44 +54,7 @@ void LocalBluetoothDevice::createBluetoothLocalDevice() localDevice_->powerOn(); localDevice_->setHostMode(QBluetoothLocalDevice::HostDiscoverable); -// -// rfcommServer_ = std::make_unique(QBluetoothServiceInfo::RfcommProtocol, this); -// connect(rfcommServer_.get(), &QBluetoothServer::newConnection, this, &LocalBluetoothDevice::onClientConnected, Qt::QueuedConnection); -// if (rfcommServer_->listen(localDevice_->address())) { -// OPENAUTO_LOG(debug) << "Listening for rfcomm connections on port " << rfcommServer_->serverPort(); -// } -// else { -// OPENAUTO_LOG(debug) << "Could not start rfcomm"; -// } -// -// //"4de17a00-52cb-11e6-bdf4-0800200c9a66"; -// //"669a0c20-0008-f4bd-e611-cb52007ae14d"; -// const QBluetoothUuid serviceUuid(QLatin1String("4de17a00-52cb-11e6-bdf4-0800200c9a66")); -// -// QBluetoothServiceInfo::Sequence classId; -// classId << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::SerialPort)); -// serviceInfo_.setAttribute(QBluetoothServiceInfo::BluetoothProfileDescriptorList, classId); -// classId.prepend(QVariant::fromValue(serviceUuid)); -// serviceInfo_.setAttribute(QBluetoothServiceInfo::ServiceClassIds, classId); -// serviceInfo_.setAttribute(QBluetoothServiceInfo::ServiceName, "OpenAuto Bluetooth Service"); -// serviceInfo_.setAttribute(QBluetoothServiceInfo::ServiceDescription, "AndroidAuto WiFi projection automatic setup"); -// serviceInfo_.setAttribute(QBluetoothServiceInfo::ServiceProvider, "f1xstudio.com"); -// serviceInfo_.setServiceUuid(serviceUuid); -// -// QBluetoothServiceInfo::Sequence publicBrowse; -// publicBrowse << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::PublicBrowseGroup)); -// serviceInfo_.setAttribute(QBluetoothServiceInfo::BrowseGroupList, publicBrowse); -// -// QBluetoothServiceInfo::Sequence protocolDescriptorList; -// QBluetoothServiceInfo::Sequence protocol; -// protocol << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::L2cap)); -// protocolDescriptorList.append(QVariant::fromValue(protocol)); -// protocol.clear(); -// protocol << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::Rfcomm)) -// << QVariant::fromValue(quint8(rfcommServer_->serverPort())); -// protocolDescriptorList.append(QVariant::fromValue(protocol)); -// serviceInfo_.setAttribute(QBluetoothServiceInfo::ProtocolDescriptorList, protocolDescriptorList); -// serviceInfo_.registerService(localDevice_->address()); + } void LocalBluetoothDevice::stop() @@ -220,19 +183,6 @@ void LocalBluetoothDevice::onHostModeStateChanged(QBluetoothLocalDevice::HostMod } } -void LocalBluetoothDevice::onClientConnected() { - auto socket = rfcommServer_->nextPendingConnection(); - - if(socket != nullptr) - { - OPENAUTO_LOG(info) << "[BluetoothServer] rfcomm client connected, peer name: " << socket->peerName().toStdString(); - } - else - { - OPENAUTO_LOG(error) << "[BluetoothServer] received null socket during client connection."; - } -} - } } } diff --git a/src/autoapp/Projection/QtVideoOutput.cpp b/src/autoapp/Projection/QtVideoOutput.cpp index e1b15fd..42da94a 100644 --- a/src/autoapp/Projection/QtVideoOutput.cpp +++ b/src/autoapp/Projection/QtVideoOutput.cpp @@ -78,6 +78,7 @@ void QtVideoOutput::onStartPlayback() mediaPlayer_->setVideoOutput(videoWidget_.get()); mediaPlayer_->setMedia(QMediaContent(), &videoBuffer_); mediaPlayer_->play(); + OPENAUTO_LOG(debug) << "Player error state -> " << mediaPlayer_->errorString().toStdString(); } diff --git a/src/autoapp/Projection/VideoOutput.cpp b/src/autoapp/Projection/VideoOutput.cpp index 75edbd3..26d7beb 100644 --- a/src/autoapp/Projection/VideoOutput.cpp +++ b/src/autoapp/Projection/VideoOutput.cpp @@ -16,44 +16,36 @@ * along with openauto. If not, see . */ +#include #include -namespace f1x -{ -namespace openauto -{ -namespace autoapp -{ -namespace projection -{ +namespace f1x { + namespace openauto { + namespace autoapp { + namespace projection { -VideoOutput::VideoOutput(configuration::IConfiguration::Pointer configuration) - : configuration_(std::move(configuration)) -{ + VideoOutput::VideoOutput(configuration::IConfiguration::Pointer configuration) + : configuration_(std::move(configuration)) { -} + } -aap_protobuf::service::media::shared::message::VideoFrameRateType VideoOutput::getVideoFPS() const -{ - return configuration_->getVideoFPS(); -} + aap_protobuf::service::media::sink::message::VideoFrameRateType VideoOutput::getVideoFPS() const { + return configuration_->getVideoFPS(); + } -aap_protobuf::service::media::shared::message::VideoCodecResolutionType VideoOutput::getVideoResolution() const -{ - return configuration_->getVideoResolution(); -} + aap_protobuf::service::media::sink::message::VideoCodecResolutionType VideoOutput::getVideoResolution() const { + return configuration_->getVideoResolution(); + } -size_t VideoOutput::getScreenDPI() const -{ - return configuration_->getScreenDPI(); -} + size_t VideoOutput::getScreenDPI() const { + return configuration_->getScreenDPI(); + } -QRect VideoOutput::getVideoMargins() const -{ - return configuration_->getVideoMargins(); -} + QRect VideoOutput::getVideoMargins() const { + return configuration_->getVideoMargins(); + } -} -} -} + } + } + } } diff --git a/src/autoapp/Service/AndroidAutoEntity.cpp b/src/autoapp/Service/AndroidAutoEntity.cpp index ee486f3..c69d8ef 100644 --- a/src/autoapp/Service/AndroidAutoEntity.cpp +++ b/src/autoapp/Service/AndroidAutoEntity.cpp @@ -16,12 +16,12 @@ * along with openauto. If not, see . */ -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include #include #include #include @@ -36,7 +36,7 @@ * * AAP needs Bluetooth HFP for Telephone * - * HU > MD Bluetooth Announcement (HU MAC Address, Supported Pairing Methods) *********** + * HU > MD Bluetooth Announcement (HU MAC Address, Supported Pairing Methods) Done as Service Discovery * HU < MD Bluetooth Pairing Request *********** * HU > MD Bluetoth Pairing Response*********** * @@ -205,7 +205,7 @@ namespace f1x { } else { OPENAUTO_LOG(info) << "[AndroidAutoEntity] Handshake completed."; - aap_protobuf::channel::control::auth::AuthResponse authCompleteIndication; + aap_protobuf::service::control::message::AuthResponse authCompleteIndication; authCompleteIndication.set_status(aap_protobuf::shared::MessageStatus::STATUS_SUCCESS); auto authCompletePromise = aasdk::channel::SendPromise::defer(strand_); @@ -223,24 +223,38 @@ namespace f1x { } void AndroidAutoEntity::onServiceDiscoveryRequest( - const aap_protobuf::channel::control::servicediscovery::event::ServiceDiscoveryRequest &request) { + const aap_protobuf::service::control::message::ServiceDiscoveryRequest &request) { OPENAUTO_LOG(info) << "[AndroidAutoEntity] onServiceDiscoveryRequest()"; OPENAUTO_LOG(info) << "[AndroidAutoEntity] Type: " << request.label_text() << ", Model: " << request.device_name(); - aap_protobuf::channel::control::servicediscovery::notification::ServiceDiscoveryResponse serviceDiscoveryResponse; + aap_protobuf::service::control::message::ServiceDiscoveryResponse serviceDiscoveryResponse; serviceDiscoveryResponse.mutable_channels()->Reserve(256); + serviceDiscoveryResponse.set_driver_position(aap_protobuf::service::control::message::DriverPosition::DRIVER_POSITION_RIGHT); + serviceDiscoveryResponse.set_can_play_native_media_during_vr(false); + serviceDiscoveryResponse.set_display_name("CubeOne Journey"); + serviceDiscoveryResponse.set_probe_for_support(false); + + auto *connectionConfiguration = serviceDiscoveryResponse.mutable_connection_configuration(); + + auto *pingConfiguration = connectionConfiguration->mutable_ping_configuration(); + pingConfiguration->set_tracked_ping_count(5); + pingConfiguration->set_timeout_ms(3000); + pingConfiguration->set_interval_ms(1000); + pingConfiguration->set_high_latency_threshold_ms(200); + + auto *headUnitInfo = serviceDiscoveryResponse.mutable_headunit_info(); serviceDiscoveryResponse.set_display_name("JourneyOS"); headUnitInfo->set_make("CubeOne"); headUnitInfo->set_model("Journey"); headUnitInfo->set_year("2024"); - headUnitInfo->set_vehicle_id("2009"); + headUnitInfo->set_vehicle_id("2024110822150988"); headUnitInfo->set_head_unit_make("CubeOne"); headUnitInfo->set_head_unit_model("Journey"); - headUnitInfo->set_head_unit_software_build("2024.10.15"); - headUnitInfo->set_head_unit_software_version("1"); + headUnitInfo->set_head_unit_software_build("1"); + headUnitInfo->set_head_unit_software_version("1.0"); std::for_each(serviceList_.begin(), serviceList_.end(), std::bind(&IService::fillFeatures, std::placeholders::_1, std::ref(serviceDiscoveryResponse))); @@ -253,22 +267,36 @@ namespace f1x { } void AndroidAutoEntity::onAudioFocusRequest( - const aap_protobuf::channel::control::focus::audio::event::AudioFocusRequest &request) { + const aap_protobuf::service::control::message::AudioFocusRequest &request) { OPENAUTO_LOG(info) << "[AndroidAutoEntity] onAudioFocusRequest()"; OPENAUTO_LOG(info) << "[AndroidAutoEntity] AudioFocusRequestType received: " << AudioFocusRequestType_Name(request.audio_focus_type()); - aap_protobuf::channel::control::focus::audio::notification::AudioFocusStateType audioFocusStateType = + /* + * When the MD starts playing music for example, it sends a gain request. The HU replies: + * STATE_GAIN - no restrictions + * STATE_GAIN_MEDIA_ONLY when using a guidance channel + * STATE_LOSS when vehicle is playing high priority sound after stopping native media (ie USB, RADIO) + * + * When HU starts playing music, we should send a STATE LOSS to stop MD music and guidance. + */ + + // If release, we should stop all playback + // MD wants to play a sound, get a notifiation regarding GAIN + // HU grants focus - to enable MD to send audio over both MEDIA and GUIDANCE channels. + // MD can then play guidance over the MEDIA or GUIDANCE streams + // HU should send STATE_LOSS to stop MD playing (ie if user starts radio player) + aap_protobuf::service::control::message::AudioFocusStateType audioFocusStateType = request.audio_focus_type() == - aap_protobuf::channel::control::focus::audio::event::AudioFocusRequestType::AUDIO_FOCUS_RELEASE - ? aap_protobuf::channel::control::focus::audio::notification::AudioFocusStateType::AUDIO_FOCUS_STATE_LOSS - : aap_protobuf::channel::control::focus::audio::notification::AudioFocusStateType::AUDIO_FOCUS_STATE_GAIN; + aap_protobuf::service::control::message::AudioFocusRequestType::AUDIO_FOCUS_RELEASE + ? aap_protobuf::service::control::message::AudioFocusStateType::AUDIO_FOCUS_STATE_LOSS + : aap_protobuf::service::control::message::AudioFocusStateType::AUDIO_FOCUS_STATE_GAIN; OPENAUTO_LOG(info) << "[AndroidAutoEntity] AudioFocusStateType determined: " << AudioFocusStateType_Name(audioFocusStateType); - aap_protobuf::channel::control::focus::audio::notification::AudioFocusNotification response; - response.set_audio_focus_state(audioFocusStateType); + aap_protobuf::service::control::message::AudioFocusNotification response; + response.set_focus_state(audioFocusStateType); auto promise = aasdk::channel::SendPromise::defer(strand_); promise->then([]() { OPENAUTO_LOG(info) "[AndroidAutoEntity] Resolved Promise"; }, @@ -278,11 +306,11 @@ namespace f1x { } void AndroidAutoEntity::onByeByeRequest( - const aap_protobuf::channel::control::byebye::event::ByeByeRequest &request) { + const aap_protobuf::service::control::message::ByeByeRequest &request) { OPENAUTO_LOG(info) << "[AndroidAutoEntity] onByeByeRequest()"; OPENAUTO_LOG(info) << "[AndroidAutoEntity] Reason received: " << request.reason(); - aap_protobuf::channel::control::byebye::notification::ByeByeResponse response; + aap_protobuf::service::control::message::ByeByeResponse response; auto promise = aasdk::channel::SendPromise::defer(strand_); promise->then(std::bind(&AndroidAutoEntity::triggerQuit, this->shared_from_this()), std::bind(&AndroidAutoEntity::onChannelError, this->shared_from_this(), std::placeholders::_1)); @@ -291,19 +319,25 @@ namespace f1x { } void AndroidAutoEntity::onByeByeResponse( - const aap_protobuf::channel::control::byebye::notification::ByeByeResponse &response) { + const aap_protobuf::service::control::message::ByeByeResponse &response) { OPENAUTO_LOG(info) << "[AndroidAutoEntity] onByeByeResponse()"; this->triggerQuit(); } void AndroidAutoEntity::onNavigationFocusRequest( - const aap_protobuf::channel::control::focus::navigation::event::NavFocusRequestNotification &request) { + const aap_protobuf::service::control::message::NavFocusRequestNotification &request) { OPENAUTO_LOG(info) << "[AndroidAutoEntity] onByeByeResponse()"; OPENAUTO_LOG(info) << "[AndroidAutoEntity] NavFocusRequestNotification type received: " << NavFocusType_Name(request.focus_type()); - aap_protobuf::channel::control::focus::navigation::notification::NavFocusNotification response; + /* + * If the MD sends NAV_FOCUS_PROJECTED in the request, we should stop any local navigation on the HU and grant NAV_FOCUS_NATIVE in the response. + * If the HU starts its own Nav, we should send NAV_FOCUS_NATIVE. + * + * For now, this is fine to be hardcoded as OpenAuto does not provide any local navigation, only that provided through Android Auto. + */ + aap_protobuf::service::control::message::NavFocusNotification response; response.set_focus_type( - aap_protobuf::channel::control::focus::navigation::shared::NavFocusType::NAV_FOCUS_PROJECTED); + aap_protobuf::service::control::message::NavFocusType::NAV_FOCUS_PROJECTED); auto promise = aasdk::channel::SendPromise::defer(strand_); promise->then([]() {}, @@ -312,18 +346,23 @@ namespace f1x { controlServiceChannel_->receive(this->shared_from_this()); } - void AndroidAutoEntity::onBatteryStatusNotification(const aap_protobuf::channel::control::BatteryStatusNotification ¬ification) { + void AndroidAutoEntity::onBatteryStatusNotification(const aap_protobuf::service::control::message::BatteryStatusNotification ¬ification) { OPENAUTO_LOG(info) << "[AndroidAutoEntity] onBatteryStatusNotification()"; controlServiceChannel_->receive(this->shared_from_this()); } + void AndroidAutoEntity::onPingRequest(const aap_protobuf::service::control::message::PingRequest& request) { + OPENAUTO_LOG(info) << "[AndroidAutoEntity] onPingRequest()"; + controlServiceChannel_->receive(this->shared_from_this()); + } + void AndroidAutoEntity::onVoiceSessionRequest( - const aap_protobuf::channel::control::voice::VoiceSessionNotification &request) { + const aap_protobuf::service::control::message::VoiceSessionNotification &request) { OPENAUTO_LOG(info) << "[AndroidAutoEntity] onVoiceSessionRequest()"; controlServiceChannel_->receive(this->shared_from_this()); } - void AndroidAutoEntity::onPingResponse(const aap_protobuf::channel::control::ping::PingResponse &response) { + void AndroidAutoEntity::onPingResponse(const aap_protobuf::service::control::message::PingResponse &response) { OPENAUTO_LOG(info) << "[AndroidAutoEntity] onPingResponse()"; OPENAUTO_LOG(info) << "[AndroidAutoEntity] Timestamp: " << response.timestamp(); pinger_->pong(); @@ -366,7 +405,7 @@ namespace f1x { promise->then([]() {}, std::bind(&AndroidAutoEntity::onChannelError, this->shared_from_this(), std::placeholders::_1)); - aap_protobuf::channel::control::ping::PingRequest request; + aap_protobuf::service::control::message::PingRequest request; auto timestamp = std::chrono::duration_cast( std::chrono::high_resolution_clock::now().time_since_epoch()); request.set_timestamp(timestamp.count()); diff --git a/src/autoapp/Service/Bluetooth/BluetoothService.cpp b/src/autoapp/Service/Bluetooth/BluetoothService.cpp index c4e07ec..bcb0292 100644 --- a/src/autoapp/Service/Bluetooth/BluetoothService.cpp +++ b/src/autoapp/Service/Bluetooth/BluetoothService.cpp @@ -61,7 +61,7 @@ namespace f1x { } void BluetoothService::fillFeatures( - aap_protobuf::channel::control::servicediscovery::notification::ServiceDiscoveryResponse &response) { + aap_protobuf::service::control::message::ServiceDiscoveryResponse &response) { OPENAUTO_LOG(info) << "[BluetoothService] fillFeatures()"; if (bluetoothDevice_->isAvailable()) { @@ -69,18 +69,24 @@ namespace f1x { auto *service = response.add_channels(); service->set_id(static_cast(channel_->getId())); + auto bluetooth = service->mutable_bluetooth_service(); + // If the HU wants the MD to skip the Bluetooth Pairing and Connection process, the HU can declaire it's address as SKIP_THIS_BLUETOOTH bluetooth->set_car_address(bluetoothDevice_->getLocalAddress()); - bluetooth->add_supported_pairing_methods(aap_protobuf::channel::bluetooth::event::BluetoothPairingMethod::BLUETOOTH_PAIRING_PIN); - bluetooth->add_supported_pairing_methods(aap_protobuf::channel::bluetooth::event::BluetoothPairingMethod::BLUETOOTH_PAIRING_NUMERIC_COMPARISON); + + // AAP supports bth PIN and Numeric Comparison as pairing methods. + bluetooth->add_supported_pairing_methods(aap_protobuf::service::bluetooth::message::BluetoothPairingMethod::BLUETOOTH_PAIRING_PIN); + bluetooth->add_supported_pairing_methods(aap_protobuf::service::bluetooth::message::BluetoothPairingMethod::BLUETOOTH_PAIRING_NUMERIC_COMPARISON); + } else { + OPENAUTO_LOG(info) << "[BluetoothService] Bluetooth Not Available "; } } - void BluetoothService::onChannelOpenRequest(const aap_protobuf::channel::ChannelOpenRequest &request) { + void BluetoothService::onChannelOpenRequest(const aap_protobuf::service::control::message::ChannelOpenRequest &request) { OPENAUTO_LOG(info) << "[BluetoothService] onChannelOpenRequest()"; OPENAUTO_LOG(info) << "[BluetoothService] Channel Id: " << request.service_id() << ", Priority: " << request.priority(); - aap_protobuf::channel::ChannelOpenResponse response; + aap_protobuf::service::control::message::ChannelOpenResponse response; const aap_protobuf::shared::MessageStatus status = aap_protobuf::shared::MessageStatus::STATUS_SUCCESS; response.set_status(status); @@ -93,7 +99,7 @@ namespace f1x { } void BluetoothService::onBluetoothPairingRequest( - const aap_protobuf::channel::bluetooth::event::BluetoothPairingRequest &request) { + const aap_protobuf::service::bluetooth::message::BluetoothPairingRequest &request) { OPENAUTO_LOG(info) << "[BluetoothService] onBluetoothPairingRequest()"; OPENAUTO_LOG(info) << "[BluetoothService] Phone Address: " << request.phone_address(); @@ -106,8 +112,15 @@ namespace f1x { OPENAUTO_LOG(info) << "[BluetoothService] Phone is Not Paired"; } - response.set_already_paired(isPaired); + // TODO: Response Status + /* + * The HU must always sent a STATUS_SUCCESS response, + * or STATUS_BLUETOOTH_PAIRING_DELAYED if: + * there's a delay in allowing bluetooth + * the HU is already engaged in a bluetooth call + */ response.set_status(aap_protobuf::shared::MessageStatus::STATUS_SUCCESS); + response.set_already_paired(isPaired); auto promise = aasdk::channel::SendPromise::defer(strand_); promise->then([]() {}, std::bind(&BluetoothService::onChannelError, this->shared_from_this(), diff --git a/src/autoapp/Service/GenericNotification/GenericNotificationService.cpp b/src/autoapp/Service/GenericNotification/GenericNotificationService.cpp index ec17cbd..1488d3c 100644 --- a/src/autoapp/Service/GenericNotification/GenericNotificationService.cpp +++ b/src/autoapp/Service/GenericNotification/GenericNotificationService.cpp @@ -60,7 +60,7 @@ namespace f1x { } void GenericNotificationService::fillFeatures( - aap_protobuf::channel::control::servicediscovery::notification::ServiceDiscoveryResponse &response) { + aap_protobuf::service::control::message::ServiceDiscoveryResponse &response) { OPENAUTO_LOG(info) << "[GenericNotificationService] fillFeatures()"; auto *service = response.add_channels(); @@ -69,11 +69,11 @@ namespace f1x { auto *genericNotification = service->mutable_wifi_projection_service(); } - void GenericNotificationService::onChannelOpenRequest(const aap_protobuf::channel::ChannelOpenRequest &request) { + void GenericNotificationService::onChannelOpenRequest(const aap_protobuf::service::control::message::ChannelOpenRequest &request) { OPENAUTO_LOG(info) << "[GenericNotificationService] onChannelOpenRequest()"; OPENAUTO_LOG(info) << "[GenericNotificationService] Channel Id: " << request.service_id() << ", Priority: " << request.priority(); - aap_protobuf::channel::ChannelOpenResponse response; + aap_protobuf::service::control::message::ChannelOpenResponse response; const aap_protobuf::shared::MessageStatus status = aap_protobuf::shared::MessageStatus::STATUS_SUCCESS; response.set_status(status); diff --git a/src/autoapp/Service/InputSource/InputSourceService.cpp b/src/autoapp/Service/InputSource/InputSourceService.cpp index 2ca8f64..f4ca384 100644 --- a/src/autoapp/Service/InputSource/InputSourceService.cpp +++ b/src/autoapp/Service/InputSource/InputSourceService.cpp @@ -16,7 +16,7 @@ * along with openauto. If not, see . */ -#include +#include #include #include @@ -61,7 +61,7 @@ namespace f1x { } void InputSourceService::fillFeatures( - aap_protobuf::channel::control::servicediscovery::notification::ServiceDiscoveryResponse &response) { + aap_protobuf::service::control::message::ServiceDiscoveryResponse &response) { OPENAUTO_LOG(info) << "[InputSourceService] fillFeatures()"; auto *service = response.add_channels(); @@ -72,7 +72,7 @@ namespace f1x { const auto &supportedButtonCodes = inputDevice_->getSupportedButtonCodes(); for (const auto &buttonCode: supportedButtonCodes) { - inputChannel->add_supported_keycodes(buttonCode); + inputChannel->add_keycodes_supported(buttonCode); } if (inputDevice_->hasTouchscreen()) { @@ -84,12 +84,12 @@ namespace f1x { } } - void InputSourceService::onChannelOpenRequest(const aap_protobuf::channel::ChannelOpenRequest &request) { + void InputSourceService::onChannelOpenRequest(const aap_protobuf::service::control::message::ChannelOpenRequest &request) { OPENAUTO_LOG(info) << "[InputSourceService] onChannelOpenRequest()"; OPENAUTO_LOG(info) << "[InputSourceService] Channel Id: " << request.service_id() << ", Priority: " << request.priority(); - aap_protobuf::channel::ChannelOpenResponse response; + aap_protobuf::service::control::message::ChannelOpenResponse response; const aap_protobuf::shared::MessageStatus status = aap_protobuf::shared::MessageStatus::STATUS_SUCCESS; response.set_status(status); @@ -100,7 +100,7 @@ namespace f1x { channel_->receive(this->shared_from_this()); } - void InputSourceService::onKeyBindingRequest(const aap_protobuf::channel::input::event::KeyBindingRequest &request) { + void InputSourceService::onKeyBindingRequest(const aap_protobuf::service::media::sink::message::KeyBindingRequest &request) { OPENAUTO_LOG(info) << "[InputSourceService] onKeyBindingRequest()"; OPENAUTO_LOG(info) << "[InputSourceService] KeyCodes Count: " << request.keycodes_size(); @@ -143,10 +143,10 @@ namespace f1x { strand_.dispatch( [this, self = this->shared_from_this(), event = std::move(event), timestamp = std::move(timestamp)]() { - aap_protobuf::service::input::message::InputReport inputReport; + aap_protobuf::service::inputsource::message::InputReport inputReport; inputReport.set_timestamp(timestamp.count()); - if (event.code == aap_protobuf::service::media::sink::KeyCode::KEYCODE_ROTARY_CONTROLLER) { + if (event.code == aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_ROTARY_CONTROLLER) { auto relativeEvent = inputReport.mutable_relative_event()->add_data(); relativeEvent->set_delta(event.wheelDirection == projection::WheelDirection::LEFT ? -1 : 1); relativeEvent->set_keycode(event.code); @@ -172,7 +172,7 @@ namespace f1x { strand_.dispatch( [this, self = this->shared_from_this(), event = std::move(event), timestamp = std::move(timestamp)]() { - aap_protobuf::service::input::message::InputReport inputReport; + aap_protobuf::service::inputsource::message::InputReport inputReport; inputReport.set_timestamp(timestamp.count()); auto touchEvent = inputReport.mutable_touch_event(); diff --git a/src/autoapp/Service/MediaBrowser/MediaBrowserService.cpp b/src/autoapp/Service/MediaBrowser/MediaBrowserService.cpp index ff7f362..ecf04c8 100644 --- a/src/autoapp/Service/MediaBrowser/MediaBrowserService.cpp +++ b/src/autoapp/Service/MediaBrowser/MediaBrowserService.cpp @@ -60,7 +60,7 @@ namespace f1x { } void MediaBrowserService::fillFeatures( - aap_protobuf::channel::control::servicediscovery::notification::ServiceDiscoveryResponse &response) { + aap_protobuf::service::control::message::ServiceDiscoveryResponse &response) { OPENAUTO_LOG(info) << "[MediaBrowserService] fillFeatures()"; auto *service = response.add_channels(); @@ -69,11 +69,11 @@ namespace f1x { auto *mediaBrowser = service->mutable_media_browser_service(); } - void MediaBrowserService::onChannelOpenRequest(const aap_protobuf::channel::ChannelOpenRequest &request) { + void MediaBrowserService::onChannelOpenRequest(const aap_protobuf::service::control::message::ChannelOpenRequest &request) { OPENAUTO_LOG(info) << "[MediaBrowserService] onChannelOpenRequest()"; OPENAUTO_LOG(info) << "[MediaBrowserService] Channel Id: " << request.service_id() << ", Priority: " << request.priority(); - aap_protobuf::channel::ChannelOpenResponse response; + aap_protobuf::service::control::message::ChannelOpenResponse response; const aap_protobuf::shared::MessageStatus status = aap_protobuf::shared::MessageStatus::STATUS_SUCCESS; response.set_status(status); diff --git a/src/autoapp/Service/MediaPlaybackStatus/MediaPlaybackStatusService.cpp b/src/autoapp/Service/MediaPlaybackStatus/MediaPlaybackStatusService.cpp index c736181..4262a89 100644 --- a/src/autoapp/Service/MediaPlaybackStatus/MediaPlaybackStatusService.cpp +++ b/src/autoapp/Service/MediaPlaybackStatus/MediaPlaybackStatusService.cpp @@ -60,7 +60,7 @@ namespace f1x { } void MediaPlaybackStatusService::fillFeatures( - aap_protobuf::channel::control::servicediscovery::notification::ServiceDiscoveryResponse &response) { + aap_protobuf::service::control::message::ServiceDiscoveryResponse &response) { OPENAUTO_LOG(info) << "[MediaPlaybackStatusService] fillFeatures()"; auto *service = response.add_channels(); @@ -69,11 +69,11 @@ namespace f1x { auto *mediaPlaybackStatus = service->mutable_media_playback_service(); } - void MediaPlaybackStatusService::onChannelOpenRequest(const aap_protobuf::channel::ChannelOpenRequest &request) { + void MediaPlaybackStatusService::onChannelOpenRequest(const aap_protobuf::service::control::message::ChannelOpenRequest &request) { OPENAUTO_LOG(info) << "[MediaPlaybackStatusService] onChannelOpenRequest()"; OPENAUTO_LOG(info) << "[MediaPlaybackStatusService] Channel Id: " << request.service_id() << ", Priority: " << request.priority(); - aap_protobuf::channel::ChannelOpenResponse response; + aap_protobuf::service::control::message::ChannelOpenResponse response; const aap_protobuf::shared::MessageStatus status = aap_protobuf::shared::MessageStatus::STATUS_SUCCESS; response.set_status(status); diff --git a/src/autoapp/Service/MediaSink/AudioMediaSinkService.cpp b/src/autoapp/Service/MediaSink/AudioMediaSinkService.cpp index ccc3d09..755f7e9 100644 --- a/src/autoapp/Service/MediaSink/AudioMediaSinkService.cpp +++ b/src/autoapp/Service/MediaSink/AudioMediaSinkService.cpp @@ -69,7 +69,7 @@ namespace f1x { */ void AudioMediaSinkService::fillFeatures( - aap_protobuf::channel::control::servicediscovery::notification::ServiceDiscoveryResponse &response) { + aap_protobuf::service::control::message::ServiceDiscoveryResponse &response) { OPENAUTO_LOG(info) << "[AudioMediaSinkService] fillFeatures()"; OPENAUTO_LOG(info) << "[AudioMediaSinkService] Channel: " << aasdk::messenger::channelIdToString(channel_->getId()); @@ -78,31 +78,31 @@ namespace f1x { auto audioChannel = service->mutable_media_sink_service(); - audioChannel->set_stream_type( + audioChannel->set_available_type( aap_protobuf::service::media::shared::message::MediaCodecType::MEDIA_CODEC_AUDIO_PCM); switch (channel_->getId()) { case aasdk::messenger::ChannelId::MEDIA_SINK_SYSTEM_AUDIO: OPENAUTO_LOG(info) << "[AudioMediaSinkService] System Audio."; audioChannel->set_audio_type( - aap_protobuf::service::media::sink::AudioStreamType::AUDIO_STREAM_SYSTEM_AUDIO); + aap_protobuf::service::media::sink::message::AudioStreamType::AUDIO_STREAM_SYSTEM_AUDIO); break; case aasdk::messenger::ChannelId::MEDIA_SINK_MEDIA_AUDIO: OPENAUTO_LOG(info) << "[AudioMediaSinkService] Music Audio."; - audioChannel->set_audio_type(aap_protobuf::service::media::sink::AudioStreamType::AUDIO_STREAM_MEDIA); + audioChannel->set_audio_type(aap_protobuf::service::media::sink::message::AudioStreamType::AUDIO_STREAM_MEDIA); break; case aasdk::messenger::ChannelId::MEDIA_SINK_GUIDANCE_AUDIO: OPENAUTO_LOG(info) << "[AudioMediaSinkService] Guidance Audio."; audioChannel->set_audio_type( - aap_protobuf::service::media::sink::AudioStreamType::AUDIO_STREAM_GUIDANCE); + aap_protobuf::service::media::sink::message::AudioStreamType::AUDIO_STREAM_GUIDANCE); break; case aasdk::messenger::ChannelId::MEDIA_SINK_TELEPHONY_AUDIO: OPENAUTO_LOG(info) << "[AudioMediaSinkService] Telephony Audio."; audioChannel->set_audio_type( - aap_protobuf::service::media::sink::AudioStreamType::AUDIO_STREAM_TELEPHONY); + aap_protobuf::service::media::sink::message::AudioStreamType::AUDIO_STREAM_TELEPHONY); break; default: OPENAUTO_LOG(info) << "[AudioMediaSinkService] Unknown Audio."; @@ -115,13 +115,18 @@ namespace f1x { audioConfig->set_sampling_rate(audioOutput_->getSampleRate()); audioConfig->set_number_of_bits(audioOutput_->getSampleSize()); audioConfig->set_number_of_channels(audioOutput_->getChannelCount()); + + OPENAUTO_LOG(info) << "[AudioMediaSinkService] getSampleRate " << audioOutput_->getSampleRate(); + OPENAUTO_LOG(info) << "[AudioMediaSinkService] getSampleSize " << audioOutput_->getSampleSize(); + OPENAUTO_LOG(info) << "[AudioMediaSinkService] getChannelCount " << audioOutput_->getChannelCount(); + //OPENAUTO_LOG(info) << "[AudioMediaSinkService] SampleRate " << audioConfig->sampling_rate() << " / " << audioConfig->number_of_bits() << " / " << audioConfig->number_of_channels(); } /* * Base Channel Handling */ - void AudioMediaSinkService::onChannelOpenRequest(const aap_protobuf::channel::ChannelOpenRequest &request) { + void AudioMediaSinkService::onChannelOpenRequest(const aap_protobuf::service::control::message::ChannelOpenRequest &request) { OPENAUTO_LOG(info) << "[AudioMediaSinkService] onChannelOpenRequest()"; OPENAUTO_LOG(info) << "[AudioMediaSinkService] Channel Id: " << request.service_id() << ", Priority: " << request.priority(); @@ -129,11 +134,11 @@ namespace f1x { const aap_protobuf::shared::MessageStatus status = audioOutput_->open() ? aap_protobuf::shared::MessageStatus::STATUS_SUCCESS - : aap_protobuf::shared::MessageStatus::STATUS_INTERNAL_ERROR; + : aap_protobuf::shared::MessageStatus::STATUS_INVALID_CHANNEL; OPENAUTO_LOG(info) << "[AudioMediaSinkService] Status determined: " << aap_protobuf::shared::MessageStatus_Name(status); - aap_protobuf::channel::ChannelOpenResponse response; + aap_protobuf::service::control::message::ChannelOpenResponse response; response.set_status(status); auto promise = aasdk::channel::SendPromise::defer(strand_); @@ -152,13 +157,13 @@ namespace f1x { * Media Channel Handling */ - void AudioMediaSinkService::onMediaChannelSetupRequest(const aap_protobuf::channel::media::event::Setup &request) { + void AudioMediaSinkService::onMediaChannelSetupRequest(const aap_protobuf::service::media::shared::message::Setup &request) { OPENAUTO_LOG(info) << "[AudioMediaSinkService] onMediaChannelSetupRequest()"; OPENAUTO_LOG(info) << "[AudioMediaSinkService] Channel Id: " << aasdk::messenger::channelIdToString(channel_->getId()) << ", Codec: " << MediaCodecType_Name(request.type()); - aap_protobuf::service::media::sink::message::MediaSinkChannelSetupResponse response; - auto status = aap_protobuf::service::media::sink::MediaSinkChannelSetupStatus::STATUS_READY; - response.set_media_status(status); + aap_protobuf::service::media::shared::message::Config response; + auto status = aap_protobuf::service::media::shared::message::Config::STATUS_READY; + response.set_status(status); response.set_max_unacked(1); response.add_configuration_indices(0); @@ -171,7 +176,7 @@ namespace f1x { } - void AudioMediaSinkService::onMediaChannelStartIndication(const aap_protobuf::channel::media::event::Start &indication) { + void AudioMediaSinkService::onMediaChannelStartIndication(const aap_protobuf::service::media::shared::message::Start &indication) { OPENAUTO_LOG(info) << "[AudioMediaSinkService] onMediaChannelStartIndication()"; OPENAUTO_LOG(info) << "[AudioMediaSinkService] Channel Id: " << aasdk::messenger::channelIdToString(channel_->getId()) << ", session: " << indication.session_id(); session_ = indication.session_id(); @@ -179,7 +184,7 @@ namespace f1x { channel_->receive(this->shared_from_this()); } - void AudioMediaSinkService::onMediaChannelStopIndication(const aap_protobuf::channel::media::event::Stop &indication) { + void AudioMediaSinkService::onMediaChannelStopIndication(const aap_protobuf::service::media::shared::message::Stop &indication) { OPENAUTO_LOG(info) << "[AudioMediaSinkService] onMediaChannelStopIndication()"; OPENAUTO_LOG(info) << "[AudioMediaSinkService] Channel Id: " << aasdk::messenger::channelIdToString(channel_->getId()) << ", session: " << session_; @@ -197,7 +202,7 @@ namespace f1x { audioOutput_->write(timestamp, buffer); // TODO: Move MediaSourceMediaAckIndication to Ack and move to Shared. - aap_protobuf::service::media::source::message::MediaSourceMediaAckIndication indication; + aap_protobuf::service::media::source::message::Ack indication; indication.set_session_id(session_); indication.set_ack(1); diff --git a/src/autoapp/Service/MediaSink/VideoMediaSinkService.cpp b/src/autoapp/Service/MediaSink/VideoMediaSinkService.cpp index 3c985e1..076f331 100644 --- a/src/autoapp/Service/MediaSink/VideoMediaSinkService.cpp +++ b/src/autoapp/Service/MediaSink/VideoMediaSinkService.cpp @@ -45,6 +45,7 @@ namespace f1x { OPENAUTO_LOG(info) << "[VideoMediaSinkService] stop()"; OPENAUTO_LOG(info) << "[VideoMediaSinkService] Channel " << aasdk::messenger::channelIdToString(channel_->getId()); + videoOutput_->stop(); }); } @@ -66,7 +67,7 @@ namespace f1x { } void VideoMediaSinkService::fillFeatures( - aap_protobuf::channel::control::servicediscovery::notification::ServiceDiscoveryResponse &response) { + aap_protobuf::service::control::message::ServiceDiscoveryResponse &response) { OPENAUTO_LOG(info) << "[VideoMediaSinkService] fillFeatures()"; OPENAUTO_LOG(info) << "[VideoMediaSinkService] Channel " << aasdk::messenger::channelIdToString(channel_->getId()); @@ -75,10 +76,12 @@ namespace f1x { service->set_id(static_cast(channel_->getId())); auto *videoChannel = service->mutable_media_sink_service(); - videoChannel->set_stream_type( + + videoChannel->set_available_type( aap_protobuf::service::media::shared::message::MediaCodecType::MEDIA_CODEC_VIDEO_H264_BP); videoChannel->set_available_while_in_call(true); + auto *videoConfig1 = videoChannel->add_video_configs(); videoConfig1->set_codec_resolution(videoOutput_->getVideoResolution()); videoConfig1->set_frame_rate(videoOutput_->getVideoFPS()); @@ -88,10 +91,15 @@ namespace f1x { videoConfig1->set_width_margin(videoMargins.width()); videoConfig1->set_density(videoOutput_->getScreenDPI()); + OPENAUTO_LOG(info) << "[VideoMediaSinkService] getVideoResolution " << VideoCodecResolutionType_Name(videoOutput_->getVideoResolution()); + OPENAUTO_LOG(info) << "[VideoMediaSinkService] getVideoFPS " << VideoFrameRateType_Name(videoOutput_->getVideoFPS()); + OPENAUTO_LOG(info) << "[VideoMediaSinkService] width " << videoMargins.width(); + OPENAUTO_LOG(info) << "[VideoMediaSinkService] height " << videoMargins.height(); + OPENAUTO_LOG(info) << "[VideoMediaSinkService] getScreenDPI " << videoOutput_->getScreenDPI(); } void - VideoMediaSinkService::onMediaChannelSetupRequest(const aap_protobuf::channel::media::event::Setup &request) { + VideoMediaSinkService::onMediaChannelSetupRequest(const aap_protobuf::service::media::shared::message::Setup &request) { OPENAUTO_LOG(info) << "[VideoMediaSinkService] onMediaChannelSetupRequest()"; OPENAUTO_LOG(info) << "[VideoMediaSinkService] Channel Id: " << aasdk::messenger::channelIdToString(channel_->getId()) << ", Codec: " @@ -99,13 +107,13 @@ namespace f1x { auto status = videoOutput_->init() - ? aap_protobuf::service::media::sink::MediaSinkChannelSetupStatus::STATUS_READY - : aap_protobuf::service::media::sink::MediaSinkChannelSetupStatus::STATUS_WAIT; + ? aap_protobuf::service::media::shared::message::Config::STATUS_READY + : aap_protobuf::service::media::shared::message::Config::STATUS_WAIT; - OPENAUTO_LOG(info) << "[VideoMediaSinkService] setup status: " << status; + OPENAUTO_LOG(info) << "[VideoMediaSinkService] setup status: " << Config_Status_Name(status); - aap_protobuf::service::media::sink::message::MediaSinkChannelSetupResponse response; - response.set_media_status(status); + aap_protobuf::service::media::shared::message::Config response; + response.set_status(status); response.set_max_unacked(1); response.add_configuration_indices(0); @@ -118,7 +126,7 @@ namespace f1x { channel_->receive(this->shared_from_this()); } - void VideoMediaSinkService::onChannelOpenRequest(const aap_protobuf::channel::ChannelOpenRequest &request) { + void VideoMediaSinkService::onChannelOpenRequest(const aap_protobuf::service::control::message::ChannelOpenRequest &request) { OPENAUTO_LOG(info) << "[VideoMediaSinkService] onChannelOpenRequest()"; OPENAUTO_LOG(info) << "[VideoMediaSinkService] Channel Id: " << request.service_id() << ", Priority: " << request.priority(); @@ -130,7 +138,7 @@ namespace f1x { OPENAUTO_LOG(info) << "[VideoMediaSinkService] Status determined: " << aap_protobuf::shared::MessageStatus_Name(status); - aap_protobuf::channel::ChannelOpenResponse response; + aap_protobuf::service::control::message::ChannelOpenResponse response; response.set_status(status); auto promise = aasdk::channel::SendPromise::defer(strand_); @@ -141,7 +149,7 @@ namespace f1x { } void VideoMediaSinkService::onMediaChannelStartIndication( - const aap_protobuf::channel::media::event::Start &indication) { + const aap_protobuf::service::media::shared::message::Start &indication) { OPENAUTO_LOG(info) << "[VideoMediaSinkService] onMediaChannelStartIndication()"; OPENAUTO_LOG(info) << "[VideoMediaSinkService] Channel Id: " << aasdk::messenger::channelIdToString(channel_->getId()) << ", session: " @@ -152,7 +160,7 @@ namespace f1x { } void VideoMediaSinkService::onMediaChannelStopIndication( - const aap_protobuf::channel::media::event::Stop &indication) { + const aap_protobuf::service::media::shared::message::Stop &indication) { OPENAUTO_LOG(info) << "[onMediaChannelStopIndication] onMediaChannelStopIndication()"; OPENAUTO_LOG(info) << "[onMediaChannelStopIndication] Channel Id: " << aasdk::messenger::channelIdToString(channel_->getId()) << ", session: " << session_; @@ -168,7 +176,7 @@ namespace f1x { videoOutput_->write(timestamp, buffer); - aap_protobuf::service::media::source::message::MediaSourceMediaAckIndication indication; + aap_protobuf::service::media::source::message::Ack indication; indication.set_session_id(session_); indication.set_ack(1); @@ -190,12 +198,12 @@ namespace f1x { } void VideoMediaSinkService::onVideoFocusRequest( - const aap_protobuf::channel::control::focus::video::event::VideoFocusRequestNotification &request) { + const aap_protobuf::service::media::video::message::VideoFocusRequestNotification &request) { OPENAUTO_LOG(info) << "[VideoMediaSinkService] onMediaIndication()"; OPENAUTO_LOG(info) << "[VideoMediaSinkService] Display index: " << request.disp_channel_id() << ", focus mode: " << VideoFocusMode_Name(request.mode()) << ", focus reason: " << VideoFocusReason_Name(request.reason()); if (request.mode() == - aap_protobuf::channel::control::focus::video::shared::VideoFocusMode::VIDEO_FOCUS_NATIVE) { + aap_protobuf::service::media::video::message::VideoFocusMode::VIDEO_FOCUS_NATIVE) { // Return to OS OPENAUTO_LOG(info) << "[VideoMediaSinkService] Returning to OS."; try { @@ -214,13 +222,13 @@ namespace f1x { void VideoMediaSinkService::sendVideoFocusIndication() { OPENAUTO_LOG(info) << "[VideoMediaSinkService] sendVideoFocusIndication()"; - aap_protobuf::channel::control::focus::video::notification::VideoFocusNotification videoFocusIndication; + aap_protobuf::service::media::video::message::VideoFocusNotification videoFocusIndication; videoFocusIndication.set_focus( - aap_protobuf::channel::control::focus::video::shared::VideoFocusMode::VIDEO_FOCUS_PROJECTED); + aap_protobuf::service::media::video::message::VideoFocusMode::VIDEO_FOCUS_PROJECTED); videoFocusIndication.set_unsolicited(false); auto promise = aasdk::channel::SendPromise::defer(strand_); - promise->then([]() {}, std::bind(&VideoMediaSinkService::onChannelError, this->shared_from_this(), + promise->then([]() {OPENAUTO_LOG(info) << "[VideoMediaSinkService] VideoFocus Request Sent";}, std::bind(&VideoMediaSinkService::onChannelError, this->shared_from_this(), std::placeholders::_1)); channel_->sendVideoFocusIndication(videoFocusIndication, std::move(promise)); } diff --git a/src/autoapp/Service/MediaSource/MediaSourceService.cpp b/src/autoapp/Service/MediaSource/MediaSourceService.cpp index a4f3eab..9d73fa7 100644 --- a/src/autoapp/Service/MediaSource/MediaSourceService.cpp +++ b/src/autoapp/Service/MediaSource/MediaSourceService.cpp @@ -19,7 +19,6 @@ #include #include #include -#include namespace f1x { namespace openauto { @@ -69,14 +68,14 @@ namespace f1x { * @param response */ void MediaSourceService::fillFeatures( - aap_protobuf::channel::control::servicediscovery::notification::ServiceDiscoveryResponse &response) { + aap_protobuf::service::control::message::ServiceDiscoveryResponse &response) { OPENAUTO_LOG(info) << "[MediaSourceService] fillFeatures()"; auto *service = response.add_channels(); service->set_id(static_cast(channel_->getId())); auto *avInputChannel = service->mutable_media_source_service(); - avInputChannel->set_stream_type( + avInputChannel->set_available_type( aap_protobuf::service::media::shared::message::MediaCodecType::MEDIA_CODEC_AUDIO_PCM); auto audioConfig = avInputChannel->mutable_audio_config(); @@ -93,7 +92,7 @@ namespace f1x { * Open Service Channel Request * @param request */ - void MediaSourceService::onChannelOpenRequest(const aap_protobuf::channel::ChannelOpenRequest &request) { + void MediaSourceService::onChannelOpenRequest(const aap_protobuf::service::control::message::ChannelOpenRequest &request) { OPENAUTO_LOG(info) << "[MediaSourceService] onChannelOpenRequest()"; OPENAUTO_LOG(info) << "[MediaSourceService] Channel Id: " << request.service_id() << ", Priority: " << request.priority(); @@ -103,7 +102,7 @@ namespace f1x { OPENAUTO_LOG(info) << "[MediaSourceService] Status determined: " << aap_protobuf::shared::MessageStatus_Name(status); - aap_protobuf::channel::ChannelOpenResponse response; + aap_protobuf::service::control::message::ChannelOpenResponse response; response.set_status(status); auto promise = aasdk::channel::SendPromise::defer(strand_); @@ -132,14 +131,14 @@ namespace f1x { * @param request */ void - MediaSourceService::onMediaChannelSetupRequest(const aap_protobuf::channel::media::event::Setup &request) { + MediaSourceService::onMediaChannelSetupRequest(const aap_protobuf::service::media::shared::message::Setup &request) { OPENAUTO_LOG(info) << "[MediaSourceService] onMediaChannelSetupRequest()"; OPENAUTO_LOG(info) << "[MediaSourceService] Channel Id: " << aasdk::messenger::channelIdToString(channel_->getId()) << ", Codec: " << MediaCodecType_Name(request.type()); - aap_protobuf::service::media::sink::message::MediaSinkChannelSetupResponse response; - auto status = aap_protobuf::service::media::sink::MediaSinkChannelSetupStatus::STATUS_READY; - response.set_media_status(status); + aap_protobuf::service::media::shared::message::Config response; + auto status = aap_protobuf::service::media::shared::message::Config::STATUS_READY; + response.set_status(status); response.set_max_unacked(1); response.add_configuration_indices(0); @@ -155,7 +154,7 @@ namespace f1x { * Generic Media Ack */ void MediaSourceService::onMediaChannelAckIndication( - const aap_protobuf::service::media::source::message::MediaSourceMediaAckIndication &) { + const aap_protobuf::service::media::source::message::Ack &) { OPENAUTO_LOG(info) << "[MediaSourceService] onMediaChannelAckIndication()"; channel_->receive(this->shared_from_this()); } diff --git a/src/autoapp/Service/NavigationStatus/NavigationStatusService.cpp b/src/autoapp/Service/NavigationStatus/NavigationStatusService.cpp index 44f2dc6..0e03ee4 100644 --- a/src/autoapp/Service/NavigationStatus/NavigationStatusService.cpp +++ b/src/autoapp/Service/NavigationStatus/NavigationStatusService.cpp @@ -60,7 +60,7 @@ namespace f1x { } void NavigationStatusService::fillFeatures( - aap_protobuf::channel::control::servicediscovery::notification::ServiceDiscoveryResponse &response) { + aap_protobuf::service::control::message::ServiceDiscoveryResponse &response) { OPENAUTO_LOG(info) << "[NavigationStatusService] fillFeatures()"; auto *service = response.add_channels(); @@ -69,11 +69,11 @@ namespace f1x { auto *navigationStatus = service->mutable_navigation_status_service(); } - void NavigationStatusService::onChannelOpenRequest(const aap_protobuf::channel::ChannelOpenRequest &request) { + void NavigationStatusService::onChannelOpenRequest(const aap_protobuf::service::control::message::ChannelOpenRequest &request) { OPENAUTO_LOG(info) << "[NavigationStatusService] onChannelOpenRequest()"; OPENAUTO_LOG(info) << "[NavigationStatusService] Channel Id: " << request.service_id() << ", Priority: " << request.priority(); - aap_protobuf::channel::ChannelOpenResponse response; + aap_protobuf::service::control::message::ChannelOpenResponse response; const aap_protobuf::shared::MessageStatus status = aap_protobuf::shared::MessageStatus::STATUS_SUCCESS; response.set_status(status); @@ -85,16 +85,16 @@ namespace f1x { channel_->receive(this->shared_from_this()); } - void NavigationStatusService::onStatusUpdate(const aap_protobuf::channel::navigation::event::NavigationStatus &navStatus) { + void NavigationStatusService::onStatusUpdate(const aap_protobuf::service::navigationstatus::message::NavigationStatus &navStatus) { channel_->receive(this->shared_from_this()); } - void NavigationStatusService::onTurnEvent(const aap_protobuf::channel::navigation::event::NavigationNextTurnEvent &turnEvent) { + void NavigationStatusService::onTurnEvent(const aap_protobuf::service::navigationstatus::message::NavigationNextTurnEvent &turnEvent) { channel_->receive(this->shared_from_this()); } - void NavigationStatusService::onDistanceEvent(const aap_protobuf::service::navigation::message::NavigationNextTurnDistanceEvent &distanceEvent) { + void NavigationStatusService::onDistanceEvent(const aap_protobuf::service::navigationstatus::message::NavigationNextTurnDistanceEvent &distanceEvent) { channel_->receive(this->shared_from_this()); } diff --git a/src/autoapp/Service/PhoneStatus/PhoneStatusService.cpp b/src/autoapp/Service/PhoneStatus/PhoneStatusService.cpp index 7a5510f..99b4786 100644 --- a/src/autoapp/Service/PhoneStatus/PhoneStatusService.cpp +++ b/src/autoapp/Service/PhoneStatus/PhoneStatusService.cpp @@ -60,7 +60,7 @@ namespace f1x { } void PhoneStatusService::fillFeatures( - aap_protobuf::channel::control::servicediscovery::notification::ServiceDiscoveryResponse &response) { + aap_protobuf::service::control::message::ServiceDiscoveryResponse &response) { OPENAUTO_LOG(info) << "[PhoneStatusService] fillFeatures()"; auto *service = response.add_channels(); @@ -69,11 +69,11 @@ namespace f1x { auto *phoneStatus = service->mutable_phone_status_service(); } - void PhoneStatusService::onChannelOpenRequest(const aap_protobuf::channel::ChannelOpenRequest &request) { + void PhoneStatusService::onChannelOpenRequest(const aap_protobuf::service::control::message::ChannelOpenRequest &request) { OPENAUTO_LOG(info) << "[PhoneStatusService] onChannelOpenRequest()"; OPENAUTO_LOG(info) << "[PhoneStatusService] Channel Id: " << request.service_id() << ", Priority: " << request.priority(); - aap_protobuf::channel::ChannelOpenResponse response; + aap_protobuf::service::control::message::ChannelOpenResponse response; const aap_protobuf::shared::MessageStatus status = aap_protobuf::shared::MessageStatus::STATUS_SUCCESS; response.set_status(status); diff --git a/src/autoapp/Service/Radio/RadioService.cpp b/src/autoapp/Service/Radio/RadioService.cpp index cf6c77a..6c8587f 100644 --- a/src/autoapp/Service/Radio/RadioService.cpp +++ b/src/autoapp/Service/Radio/RadioService.cpp @@ -60,7 +60,7 @@ namespace f1x { } void RadioService::fillFeatures( - aap_protobuf::channel::control::servicediscovery::notification::ServiceDiscoveryResponse &response) { + aap_protobuf::service::control::message::ServiceDiscoveryResponse &response) { OPENAUTO_LOG(info) << "[RadioService] fillFeatures()"; auto *service = response.add_channels(); @@ -69,12 +69,12 @@ namespace f1x { auto *radio = service->mutable_radio_service(); } - void RadioService::onChannelOpenRequest(const aap_protobuf::channel::ChannelOpenRequest &request) { + void RadioService::onChannelOpenRequest(const aap_protobuf::service::control::message::ChannelOpenRequest &request) { OPENAUTO_LOG(info) << "[RadioService] onChannelOpenRequest()"; OPENAUTO_LOG(info) << "[RadioService] Channel Id: " << request.service_id() << ", Priority: " << request.priority(); - aap_protobuf::channel::ChannelOpenResponse response; + aap_protobuf::service::control::message::ChannelOpenResponse response; const aap_protobuf::shared::MessageStatus status = aap_protobuf::shared::MessageStatus::STATUS_SUCCESS; response.set_status(status); diff --git a/src/autoapp/Service/Sensor/SensorService.cpp b/src/autoapp/Service/Sensor/SensorService.cpp index 7335931..f75e8aa 100644 --- a/src/autoapp/Service/Sensor/SensorService.cpp +++ b/src/autoapp/Service/Sensor/SensorService.cpp @@ -16,8 +16,8 @@ * along with openauto. If not, see . */ -#include -#include +#include +#include #include #include #include @@ -85,7 +85,7 @@ namespace f1x { } void SensorService::fillFeatures( - aap_protobuf::channel::control::servicediscovery::notification::ServiceDiscoveryResponse &response) { + aap_protobuf::service::control::message::ServiceDiscoveryResponse &response) { OPENAUTO_LOG(info) << "[SensorService] fillFeatures()"; auto *service = response.add_channels(); @@ -93,16 +93,16 @@ namespace f1x { // TODO: Add and Link other Sensors Here auto *sensorChannel = service->mutable_sensor_source_service(); - sensorChannel->add_sensors()->set_sensor_type(aap_protobuf::service::sensor::message::SensorType::SENSOR_DRIVING_STATUS_DATA); - sensorChannel->add_sensors()->set_sensor_type(aap_protobuf::service::sensor::message::SensorType::SENSOR_LOCATION); - sensorChannel->add_sensors()->set_sensor_type(aap_protobuf::service::sensor::message::SensorType::SENSOR_NIGHT_MODE); + sensorChannel->add_sensors()->set_sensor_type(aap_protobuf::service::sensorsource::message::SensorType::SENSOR_DRIVING_STATUS_DATA); + sensorChannel->add_sensors()->set_sensor_type(aap_protobuf::service::sensorsource::message::SensorType::SENSOR_LOCATION); + sensorChannel->add_sensors()->set_sensor_type(aap_protobuf::service::sensorsource::message::SensorType::SENSOR_NIGHT_MODE); } - void SensorService::onChannelOpenRequest(const aap_protobuf::channel::ChannelOpenRequest &request) { + void SensorService::onChannelOpenRequest(const aap_protobuf::service::control::message::ChannelOpenRequest &request) { OPENAUTO_LOG(info) << "[SensorService] onChannelOpenRequest()"; OPENAUTO_LOG(info) << "[SensorService] Channel Id: " << request.service_id() << ", Priority: " << request.priority(); - aap_protobuf::channel::ChannelOpenResponse response; + aap_protobuf::service::control::message::ChannelOpenResponse response; const aap_protobuf::shared::MessageStatus status = aap_protobuf::shared::MessageStatus::STATUS_SUCCESS; response.set_status(status); @@ -115,22 +115,22 @@ namespace f1x { } void SensorService::onSensorStartRequest( - const aap_protobuf::channel::sensor::event::SensorRequest &request) { + const aap_protobuf::service::sensorsource::message::SensorRequest &request) { OPENAUTO_LOG(info) << "[SensorService] onSensorStartRequest()"; OPENAUTO_LOG(info) << "[SensorService] Request Type: "<< request.type(); - aap_protobuf::service::sensor::message::SensorStartResponseMessage response; + aap_protobuf::service::sensorsource::message::SensorStartResponseMessage response; response.set_status(aap_protobuf::shared::MessageStatus::STATUS_SUCCESS); auto promise = aasdk::channel::SendPromise::defer(strand_); // TODO: Convert to Switch? - if (request.type() == aap_protobuf::service::sensor::message::SENSOR_DRIVING_STATUS_DATA) + if (request.type() == aap_protobuf::service::sensorsource::message::SENSOR_DRIVING_STATUS_DATA) { promise->then(std::bind(&SensorService::sendDrivingStatusUnrestricted, this->shared_from_this()), std::bind(&SensorService::onChannelError, this->shared_from_this(), std::placeholders::_1)); } - else if (request.type() == aap_protobuf::service::sensor::message::SensorType::SENSOR_NIGHT_MODE) + else if (request.type() == aap_protobuf::service::sensorsource::message::SensorType::SENSOR_NIGHT_MODE) { promise->then(std::bind(&SensorService::sendNightData, this->shared_from_this()), std::bind(&SensorService::onChannelError, this->shared_from_this(), std::placeholders::_1)); @@ -147,18 +147,18 @@ namespace f1x { void SensorService::sendDrivingStatusUnrestricted() { OPENAUTO_LOG(info) << "[SensorService] sendDrivingStatusUnrestricted()"; - aap_protobuf::service::sensor::message::SensorBatch indication; - indication.add_driving_status_data()->set_status(aap_protobuf::service::sensor::message::DrivingStatus::DRIVE_STATUS_UNRESTRICTED); + aap_protobuf::service::sensorsource::message::SensorBatch indication; + indication.add_driving_status_data()->set_status(aap_protobuf::service::sensorsource::message::DrivingStatus::DRIVE_STATUS_UNRESTRICTED); auto promise = aasdk::channel::SendPromise::defer(strand_); - promise->then([]() {}, + promise->then([]() { OPENAUTO_LOG(info) << "[SensorService] SendPromise resolved successfully()"; }, std::bind(&SensorService::onChannelError, this->shared_from_this(), std::placeholders::_1)); channel_->sendSensorEventIndication(indication, std::move(promise)); } void SensorService::sendNightData() { OPENAUTO_LOG(info) << "[SensorService] sendNightData()"; - aap_protobuf::service::sensor::message::SensorBatch indication; + aap_protobuf::service::sensorsource::message::SensorBatch indication; if (SensorService::isNight) { OPENAUTO_LOG(info) << "[SensorService] Night Mode Triggered"; @@ -180,29 +180,30 @@ namespace f1x { void SensorService::sendGPSLocationData() { OPENAUTO_LOG(info) << "[SensorService] sendGPSLocationData()"; - aap_protobuf::service::sensor::message::SensorBatch indication; + aap_protobuf::service::sensorsource::message::SensorBatch indication; + auto *locInd = indication.add_location_data(); // epoch seconds // locInd->set_timestamp(this->gpsData_.fix.time * 1e3); // degrees - locInd->set_latitude(this->gpsData_.fix.latitude * 1e7); - locInd->set_longitude(this->gpsData_.fix.longitude * 1e7); + locInd->set_latitude_e7(this->gpsData_.fix.latitude * 1e7); + locInd->set_longitude_e7(this->gpsData_.fix.longitude * 1e7); // meters auto accuracy = sqrt(pow(this->gpsData_.fix.epx, 2) + pow(this->gpsData_.fix.epy, 2)); - locInd->set_accuracy(accuracy * 1e3); + locInd->set_accuracy_e3(accuracy * 1e3); if (this->gpsData_.set & ALTITUDE_SET) { // meters above ellipsoid - locInd->set_altitude(this->gpsData_.fix.altitude * 1e2); + locInd->set_altitude_e2(this->gpsData_.fix.altitude * 1e2); } if (this->gpsData_.set & SPEED_SET) { // meters per second to knots - locInd->set_speed(this->gpsData_.fix.speed * 1.94384 * 1e3); + locInd->set_speed_e3(this->gpsData_.fix.speed * 1.94384 * 1e3); } if (this->gpsData_.set & TRACK_SET) { // degrees - locInd->set_bearing(this->gpsData_.fix.track * 1e6); + locInd->set_bearing_e6(this->gpsData_.fix.track * 1e6); } auto promise = aasdk::channel::SendPromise::defer(strand_); diff --git a/src/autoapp/Service/ServiceFactory.cpp b/src/autoapp/Service/ServiceFactory.cpp index 87c96e0..b397466 100644 --- a/src/autoapp/Service/ServiceFactory.cpp +++ b/src/autoapp/Service/ServiceFactory.cpp @@ -104,11 +104,11 @@ namespace f1x { OPENAUTO_LOG(info) << "[ServiceFactory] createInputService()"; QRect videoGeometry; switch (configuration_->getVideoResolution()) { - case aap_protobuf::service::media::shared::message::VideoCodecResolutionType::VIDEO_1280x720: + case aap_protobuf::service::media::sink::message::VideoCodecResolutionType::VIDEO_1280x720: OPENAUTO_LOG(info) << "[ServiceFactory] Resolution 1280x720"; videoGeometry = QRect(0, 0, 1280, 720); break; - case aap_protobuf::service::media::shared::message::VideoCodecResolutionType::VIDEO_1920x1080: + case aap_protobuf::service::media::sink::message::VideoCodecResolutionType::VIDEO_1920x1080: OPENAUTO_LOG(info) << "[ServiceFactory] Resolution 1920x1080"; videoGeometry = QRect(0, 0, 1920, 1080); break; @@ -162,8 +162,8 @@ namespace f1x { projection::IAudioOutput::Pointer(new projection::QtAudioOutput(1, 16, 16000), std::bind(&QObject::deleteLater, std::placeholders::_1)); - serviceList.emplace_back( - std::make_shared(ioService_, messenger, std::move(telephonyAudioOutput))); + // serviceList.emplace_back( + // std::make_shared(ioService_, messenger, std::move(telephonyAudioOutput))); } /* diff --git a/src/autoapp/Service/VendorExtension/VendorExtensionService.cpp b/src/autoapp/Service/VendorExtension/VendorExtensionService.cpp index 27d748a..a6b8ca9 100644 --- a/src/autoapp/Service/VendorExtension/VendorExtensionService.cpp +++ b/src/autoapp/Service/VendorExtension/VendorExtensionService.cpp @@ -60,7 +60,7 @@ namespace f1x { } void VendorExtensionService::fillFeatures( - aap_protobuf::channel::control::servicediscovery::notification::ServiceDiscoveryResponse &response) { + aap_protobuf::service::control::message::ServiceDiscoveryResponse &response) { OPENAUTO_LOG(info) << "[VendorExtensionService] fillFeatures()"; auto *service = response.add_channels(); @@ -73,11 +73,11 @@ namespace f1x { OPENAUTO_LOG(error) << "[VendorExtensionService] onChannelError(): " << e.what(); } - void VendorExtensionService::onChannelOpenRequest(const aap_protobuf::channel::ChannelOpenRequest &request) { + void VendorExtensionService::onChannelOpenRequest(const aap_protobuf::service::control::message::ChannelOpenRequest &request) { OPENAUTO_LOG(info) << "[VendorExtensionService] onChannelOpenRequest()"; OPENAUTO_LOG(info) << "[VendorExtensionService] Channel Id: " << request.service_id() << ", Priority: " << request.priority(); - aap_protobuf::channel::ChannelOpenResponse response; + aap_protobuf::service::control::message::ChannelOpenResponse response; const aap_protobuf::shared::MessageStatus status = aap_protobuf::shared::MessageStatus::STATUS_SUCCESS; response.set_status(status); diff --git a/src/autoapp/Service/WifiProjection/WifiProjectionStatus.cpp b/src/autoapp/Service/WifiProjection/WifiProjectionStatus.cpp index 4cca3f9..7b3f74b 100644 --- a/src/autoapp/Service/WifiProjection/WifiProjectionStatus.cpp +++ b/src/autoapp/Service/WifiProjection/WifiProjectionStatus.cpp @@ -59,7 +59,7 @@ namespace f1x { } void WifiProjectionService::fillFeatures( - aap_protobuf::channel::control::servicediscovery::notification::ServiceDiscoveryResponse &response) { + aap_protobuf::service::control::message::ServiceDiscoveryResponse &response) { OPENAUTO_LOG(info) << "[WifiProjectionService] fillFeatures()"; auto *service = response.add_channels(); @@ -89,12 +89,12 @@ namespace f1x { } - void WifiProjectionService::onChannelOpenRequest(const aap_protobuf::channel::ChannelOpenRequest &request) { + void WifiProjectionService::onChannelOpenRequest(const aap_protobuf::service::control::message::ChannelOpenRequest &request) { OPENAUTO_LOG(info) << "[WifiProjectionService] onChannelOpenRequest()"; OPENAUTO_LOG(info) << "[WifiProjectionService] Channel Id: " << request.service_id() << ", Priority: " << request.priority(); - aap_protobuf::channel::ChannelOpenResponse response; + aap_protobuf::service::control::message::ChannelOpenResponse response; const aap_protobuf::shared::MessageStatus status = aap_protobuf::shared::MessageStatus::STATUS_SUCCESS; response.set_status(status); diff --git a/src/autoapp/UI/SettingsWindow.cpp b/src/autoapp/UI/SettingsWindow.cpp index b1ca528..80f4e64 100644 --- a/src/autoapp/UI/SettingsWindow.cpp +++ b/src/autoapp/UI/SettingsWindow.cpp @@ -225,18 +225,18 @@ namespace f1x { configuration_->hideWarning(ui_->checkBoxDontShowAgain->isChecked()); configuration_->setVideoFPS(ui_->radioButton30FPS->isChecked() - ? aap_protobuf::service::media::shared::message::VideoFrameRateType::VIDEO_FPS_30 - : aap_protobuf::service::media::shared::message::VideoFrameRateType::VIDEO_FPS_60); + ? aap_protobuf::service::media::sink::message::VideoFrameRateType::VIDEO_FPS_30 + : aap_protobuf::service::media::sink::message::VideoFrameRateType::VIDEO_FPS_60); if (ui_->radioButton480p->isChecked()) { configuration_->setVideoResolution( - aap_protobuf::service::media::shared::message::VideoCodecResolutionType::VIDEO_800x480); + aap_protobuf::service::media::sink::message::VideoCodecResolutionType::VIDEO_800x480); } else if (ui_->radioButton720p->isChecked()) { configuration_->setVideoResolution( - aap_protobuf::service::media::shared::message::VideoCodecResolutionType::VIDEO_1280x720); + aap_protobuf::service::media::sink::message::VideoCodecResolutionType::VIDEO_1280x720); } else if (ui_->radioButton1080p->isChecked()) { configuration_->setVideoResolution( - aap_protobuf::service::media::shared::message::VideoCodecResolutionType::VIDEO_1920x1080); + aap_protobuf::service::media::sink::message::VideoCodecResolutionType::VIDEO_1920x1080); } configuration_->setScreenDPI(static_cast(ui_->horizontalSliderScreenDPI->value())); @@ -513,16 +513,16 @@ namespace f1x { ui_->checkBoxDontShowAgain->setChecked(configuration_->hideWarning()); ui_->radioButton30FPS->setChecked(configuration_->getVideoFPS() == - aap_protobuf::service::media::shared::message::VideoFrameRateType::VIDEO_FPS_30); + aap_protobuf::service::media::sink::message::VideoFrameRateType::VIDEO_FPS_30); ui_->radioButton60FPS->setChecked(configuration_->getVideoFPS() == - aap_protobuf::service::media::shared::message::VideoFrameRateType::VIDEO_FPS_60); + aap_protobuf::service::media::sink::message::VideoFrameRateType::VIDEO_FPS_60); ui_->radioButton480p->setChecked(configuration_->getVideoResolution() == - aap_protobuf::service::media::shared::message::VideoCodecResolutionType::VIDEO_800x480); + aap_protobuf::service::media::sink::message::VideoCodecResolutionType::VIDEO_800x480); ui_->radioButton720p->setChecked(configuration_->getVideoResolution() == - aap_protobuf::service::media::shared::message::VideoCodecResolutionType::VIDEO_1280x720); + aap_protobuf::service::media::sink::message::VideoCodecResolutionType::VIDEO_1280x720); ui_->radioButton1080p->setChecked(configuration_->getVideoResolution() == - aap_protobuf::service::media::shared::message::VideoCodecResolutionType::VIDEO_1920x1080); + aap_protobuf::service::media::sink::message::VideoCodecResolutionType::VIDEO_1920x1080); ui_->horizontalSliderScreenDPI->setValue(static_cast(configuration_->getScreenDPI())); ui_->spinBoxOmxLayerIndex->setValue(configuration_->getOMXLayerIndex()); @@ -573,55 +573,55 @@ namespace f1x { void SettingsWindow::loadButtonCheckBoxes() { const auto &buttonCodes = configuration_->getButtonCodes(); ui_->checkBoxPlayButton->setChecked(std::find(buttonCodes.begin(), buttonCodes.end(), - aap_protobuf::service::media::sink::KeyCode::KEYCODE_MEDIA_PLAY) != + aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_MEDIA_PLAY) != buttonCodes.end()); ui_->checkBoxPauseButton->setChecked(std::find(buttonCodes.begin(), buttonCodes.end(), - aap_protobuf::service::media::sink::KeyCode::KEYCODE_MEDIA_PAUSE) != + aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_MEDIA_PAUSE) != buttonCodes.end()); ui_->checkBoxTogglePlayButton->setChecked(std::find(buttonCodes.begin(), buttonCodes.end(), - aap_protobuf::service::media::sink::KeyCode::KEYCODE_MEDIA_PLAY_PAUSE) != + aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_MEDIA_PLAY_PAUSE) != buttonCodes.end()); ui_->checkBoxNextTrackButton->setChecked(std::find(buttonCodes.begin(), buttonCodes.end(), - aap_protobuf::service::media::sink::KeyCode::KEYCODE_MEDIA_NEXT) != + aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_MEDIA_NEXT) != buttonCodes.end()); ui_->checkBoxPreviousTrackButton->setChecked(std::find(buttonCodes.begin(), buttonCodes.end(), - aap_protobuf::service::media::sink::KeyCode::KEYCODE_MEDIA_PREVIOUS) != + aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_MEDIA_PREVIOUS) != buttonCodes.end()); ui_->checkBoxHomeButton->setChecked(std::find(buttonCodes.begin(), buttonCodes.end(), - aap_protobuf::service::media::sink::KeyCode::KEYCODE_HOME) != + aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_HOME) != buttonCodes.end()); ui_->checkBoxPhoneButton->setChecked(std::find(buttonCodes.begin(), buttonCodes.end(), - aap_protobuf::service::media::sink::KeyCode::KEYCODE_CALL) != + aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_CALL) != buttonCodes.end()); ui_->checkBoxCallEndButton->setChecked(std::find(buttonCodes.begin(), buttonCodes.end(), - aap_protobuf::service::media::sink::KeyCode::KEYCODE_ENDCALL) != + aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_ENDCALL) != buttonCodes.end()); ui_->checkBoxVoiceCommandButton->setChecked(std::find(buttonCodes.begin(), buttonCodes.end(), - aap_protobuf::service::media::sink::KeyCode::KEYCODE_SEARCH) != + aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_SEARCH) != buttonCodes.end()); ui_->checkBoxLeftButton->setChecked(std::find(buttonCodes.begin(), buttonCodes.end(), - aap_protobuf::service::media::sink::KeyCode::KEYCODE_DPAD_LEFT) != + aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_DPAD_LEFT) != buttonCodes.end()); ui_->checkBoxRightButton->setChecked(std::find(buttonCodes.begin(), buttonCodes.end(), - aap_protobuf::service::media::sink::KeyCode::KEYCODE_DPAD_RIGHT) != + aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_DPAD_RIGHT) != buttonCodes.end()); ui_->checkBoxUpButton->setChecked(std::find(buttonCodes.begin(), buttonCodes.end(), - aap_protobuf::service::media::sink::KeyCode::KEYCODE_DPAD_UP) != + aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_DPAD_UP) != buttonCodes.end()); ui_->checkBoxDownButton->setChecked(std::find(buttonCodes.begin(), buttonCodes.end(), - aap_protobuf::service::media::sink::KeyCode::KEYCODE_DPAD_DOWN) != + aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_DPAD_DOWN) != buttonCodes.end()); ui_->checkBoxScrollWheelButton->setChecked(std::find(buttonCodes.begin(), buttonCodes.end(), - aap_protobuf::service::media::sink::KeyCode::KEYCODE_ROTARY_CONTROLLER) != + aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_ROTARY_CONTROLLER) != buttonCodes.end()); ui_->checkBoxBackButton->setChecked(std::find(buttonCodes.begin(), buttonCodes.end(), - aap_protobuf::service::media::sink::KeyCode::KEYCODE_BACK) != + aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_BACK) != buttonCodes.end()); ui_->checkBoxEnterButton->setChecked(std::find(buttonCodes.begin(), buttonCodes.end(), - aap_protobuf::service::media::sink::KeyCode::KEYCODE_DPAD_CENTER) != + aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_DPAD_CENTER) != buttonCodes.end()); ui_->checkBoxNavButton->setChecked(std::find(buttonCodes.begin(), buttonCodes.end(), - aap_protobuf::service::media::sink::KeyCode::KEYCODE_NAVIGATION) != + aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_NAVIGATION) != buttonCodes.end()); } @@ -648,45 +648,45 @@ namespace f1x { void SettingsWindow::saveButtonCheckBoxes() { configuration::IConfiguration::ButtonCodes buttonCodes; this->saveButtonCheckBox(ui_->checkBoxPlayButton, buttonCodes, - aap_protobuf::service::media::sink::KeyCode::KEYCODE_MEDIA_PLAY); + aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_MEDIA_PLAY); this->saveButtonCheckBox(ui_->checkBoxPauseButton, buttonCodes, - aap_protobuf::service::media::sink::KeyCode::KEYCODE_MEDIA_PAUSE); + aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_MEDIA_PAUSE); this->saveButtonCheckBox(ui_->checkBoxTogglePlayButton, buttonCodes, - aap_protobuf::service::media::sink::KeyCode::KEYCODE_MEDIA_PLAY_PAUSE); + aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_MEDIA_PLAY_PAUSE); this->saveButtonCheckBox(ui_->checkBoxNextTrackButton, buttonCodes, - aap_protobuf::service::media::sink::KeyCode::KEYCODE_MEDIA_NEXT); + aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_MEDIA_NEXT); this->saveButtonCheckBox(ui_->checkBoxPreviousTrackButton, buttonCodes, - aap_protobuf::service::media::sink::KeyCode::KEYCODE_MEDIA_PREVIOUS); + aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_MEDIA_PREVIOUS); this->saveButtonCheckBox(ui_->checkBoxHomeButton, buttonCodes, - aap_protobuf::service::media::sink::KeyCode::KEYCODE_HOME); + aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_HOME); this->saveButtonCheckBox(ui_->checkBoxPhoneButton, buttonCodes, - aap_protobuf::service::media::sink::KeyCode::KEYCODE_CALL); + aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_CALL); this->saveButtonCheckBox(ui_->checkBoxCallEndButton, buttonCodes, - aap_protobuf::service::media::sink::KeyCode::KEYCODE_ENDCALL); + aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_ENDCALL); this->saveButtonCheckBox(ui_->checkBoxVoiceCommandButton, buttonCodes, - aap_protobuf::service::media::sink::KeyCode::KEYCODE_SEARCH); + aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_SEARCH); this->saveButtonCheckBox(ui_->checkBoxLeftButton, buttonCodes, - aap_protobuf::service::media::sink::KeyCode::KEYCODE_DPAD_LEFT); + aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_DPAD_LEFT); this->saveButtonCheckBox(ui_->checkBoxRightButton, buttonCodes, - aap_protobuf::service::media::sink::KeyCode::KEYCODE_DPAD_RIGHT); + aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_DPAD_RIGHT); this->saveButtonCheckBox(ui_->checkBoxUpButton, buttonCodes, - aap_protobuf::service::media::sink::KeyCode::KEYCODE_DPAD_UP); + aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_DPAD_UP); this->saveButtonCheckBox(ui_->checkBoxDownButton, buttonCodes, - aap_protobuf::service::media::sink::KeyCode::KEYCODE_DPAD_DOWN); + aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_DPAD_DOWN); this->saveButtonCheckBox(ui_->checkBoxScrollWheelButton, buttonCodes, - aap_protobuf::service::media::sink::KeyCode::KEYCODE_ROTARY_CONTROLLER); + aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_ROTARY_CONTROLLER); this->saveButtonCheckBox(ui_->checkBoxBackButton, buttonCodes, - aap_protobuf::service::media::sink::KeyCode::KEYCODE_BACK); + aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_BACK); this->saveButtonCheckBox(ui_->checkBoxEnterButton, buttonCodes, - aap_protobuf::service::media::sink::KeyCode::KEYCODE_DPAD_CENTER); + aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_DPAD_CENTER); this->saveButtonCheckBox(ui_->checkBoxNavButton, buttonCodes, - aap_protobuf::service::media::sink::KeyCode::KEYCODE_NAVIGATION); + aap_protobuf::service::media::sink::message::KeyCode::KEYCODE_NAVIGATION); configuration_->setButtonCodes(buttonCodes); } void SettingsWindow::saveButtonCheckBox(const QCheckBox *checkBox, configuration::IConfiguration::ButtonCodes &buttonCodes, - aap_protobuf::service::media::sink::KeyCode buttonCode) { + aap_protobuf::service::media::sink::message::KeyCode buttonCode) { if (checkBox->isChecked()) { buttonCodes.push_back(buttonCode); } diff --git a/src/autoapp/UI/assets/journey.jpg b/src/autoapp/UI/assets/journey.jpg new file mode 100644 index 0000000000000000000000000000000000000000..8051d95474684c3df7b71b8d62bacfa0311a1ae0 GIT binary patch literal 95089 zcmeFa2Ut`~lRrFU36itqoS7kKB!db_k|Yv_G~^s42}lMJkRTvYGKeB55=D}Lh~yjx zBuEs2A%AC3@AbX!-F1Y9*(*fU>PyrWn5D|#*9tczl63cK!yQlzKHU4O& z^1YSgKeqC8bCU4%gjq_MLj|A^QE?GoA#sQpuaJe6IIp>gxd^X?mAQ~0Sin+H6e<9W zMd0*<9Orj(=I;MAD4)5zyOo;<%-P8u=zyp5qk|x_!_^)98S zdDsFIaWaQF@If8SVUB!uE><=`R}iU%wWS3J=4ftX#s8xY58VQ0X>tB{!kGjqfJpHP zhzTx}5)%?rkdac-2{6*p(9lWq@UaM}UA=K#<*KsMO(S=Un|hA7l$0$atsK4mfSX5k6 zTJ^HJ=GE)kH+An?+uA!i-*@%rC$fmp(7Atgh{R-Tk(=e}FhVLe2|0 z&!5NN&Wi|`7b-eB8aftoUMQ&E$cYo7V=zK6iRHAg%w0*C1cEP-$|vN$Xu)O{)ZQku zaO=k*XAzob-9b+6VrKubiG}>Xn%N%{`*U6sAUre_VDZq1K(Zh>M_x4O|DW%B0xle& zylUQR~dxv^q=Fztt#!*7i8s?VXN;WHyL$yAlCOj$S-`|peR9<~@LY2zvenSjylt^?jB z=R6V}zNBK=>uNz{ox4TWk|H{JH9B&&T6LSM6-jTrs7glQ*9LuqFHgY{lR2d~13b7B z_C8fW^KP4{`*d7a^vlSjo}#Is^6=~WXWwkx&XkL_^gbL#w~q{(bbL``eq*XA3qA+k%d*Sh zW+t=ZQn{(jW#H&!$qmxJ4SzjsBHw2@ioMG9RVJcBl8t+;Bk#5BbIVLCvy|aR znsC#;3Y}Di=D5hOqVakR(KIY|xLML4j<|YYqfrMH1?Qk9cfDzvC;RIXf`C$x%}Q=StkpB%eAwM%2;d=QUXJ^wspKvqDBSd1n`OiR~kkMpxd z3ES8aDAW42N3!tNX~$GTbi>)g+kpx*s-`AI*=e~Xl_z;E2fWL*%=ID|mi>lr_##t< z`>za`2v;*%_A^E^_b+Ns-*wkJ2hB4!(66OjYMzSKJ2l+R&Dp=!RyDZkJQm~e{!V!( zjx6fR#0;SuI+0!dqd7a!Raq$LjCZphEzCc60R)9zblzA z>hcu}7s!q5`{2SwFTDO?GF6-0%RSYib0~8_cl1^tOj3bSyJuQMN!`1!4~DAFt*rME zq~CQ?>TAdQ_ra_GqnAKeTxms$_
  • YJIpWv97^{g?vbBd}V=*p%-c#+0!~& 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 CIj}zf literal 0 HcmV?d00001 diff --git a/src/autoapp/UI/journey.cpp b/src/autoapp/UI/journey.cpp deleted file mode 100644 index 9f52ef5..0000000 --- a/src/autoapp/UI/journey.cpp +++ /dev/null @@ -1,14 +0,0 @@ -#include "journey.h" -#include "ui_journey.h" - -journey::journey(QWidget *parent) - : QMainWindow(parent) - , ui(new Ui::journey) -{ - ui->setupUi(this); -} - -journey::~journey() -{ - delete ui; -} diff --git a/src/autoapp/UI/journey.h b/src/autoapp/UI/journey.h deleted file mode 100644 index d63b684..0000000 --- a/src/autoapp/UI/journey.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef JOURNEY_H -#define JOURNEY_H - -#include - -namespace Ui { -class journey; -} - -class journey : public QMainWindow -{ - Q_OBJECT - -public: - explicit journey(QWidget *parent = nullptr); - ~journey(); - -private: - Ui::journey *ui; -}; - -#endif // JOURNEY_H diff --git a/src/autoapp/UI/journey.ui b/src/autoapp/UI/journey.ui deleted file mode 100644 index 052073d..0000000 --- a/src/autoapp/UI/journey.ui +++ /dev/null @@ -1,31 +0,0 @@ - - - journey - - - - 0 - 0 - 800 - 600 - - - - MainWindow - - - - - - 0 - 0 - 800 - 24 - - - - - - - - diff --git a/src/btservice/AndroidBluetoothServer.cpp b/src/btservice/AndroidBluetoothServer.cpp index 0a8b702..96921dc 100644 --- a/src/btservice/AndroidBluetoothServer.cpp +++ b/src/btservice/AndroidBluetoothServer.cpp @@ -24,164 +24,158 @@ #include #include -namespace f1x { - namespace openauto { - namespace btservice { - AndroidBluetoothServer::AndroidBluetoothServer(autoapp::configuration::IConfiguration::Pointer configuration) - : rfcommServer_(std::make_unique(QBluetoothServiceInfo::RfcommProtocol, this)) - , configuration_(std::move(configuration)) - { - connect(rfcommServer_.get(), &QBluetoothServer::newConnection, this, - &AndroidBluetoothServer::onClientConnected); - } +namespace f1x::openauto::btservice { - uint16_t AndroidBluetoothServer::start(const QBluetoothAddress &address) { - if (rfcommServer_->listen(address)) { - return rfcommServer_->serverPort(); - } - return 0; - } + AndroidBluetoothServer::AndroidBluetoothServer(autoapp::configuration::IConfiguration::Pointer configuration) + : rfcommServer_(std::make_unique(QBluetoothServiceInfo::RfcommProtocol, this)), + configuration_(std::move(configuration)) { + connect(rfcommServer_.get(), &QBluetoothServer::newConnection, this, + &AndroidBluetoothServer::onClientConnected); + } - void AndroidBluetoothServer::onClientConnected() { - if (socket != nullptr) { - socket->deleteLater(); - } - - socket = rfcommServer_->nextPendingConnection(); - - if (socket != nullptr) { - OPENAUTO_LOG(info) << "[AndroidBluetoothServer] rfcomm client connected, peer name: " - << socket->peerName().toStdString(); - - connect(socket, &QBluetoothSocket::readyRead, this, &AndroidBluetoothServer::readSocket); -// connect(socket, &QBluetoothSocket::disconnected, this, -// QOverload<>::of(&ChatServer::clientDisconnected)); - - //aap_protobuf::messages::WifiInfoRequest request; - //request.set_ip_address(getIP4_("wlan0")); - //request.set_port(5000); - - //sendMessage(request, 1); - } else { - OPENAUTO_LOG(error) << "[AndroidBluetoothServer] received null socket during client connection."; - } - } - - void AndroidBluetoothServer::readSocket() { - buffer += socket->readAll(); - - OPENAUTO_LOG(info) << "Received message"; - - if (buffer.length() < 4) { - OPENAUTO_LOG(debug) << "Not enough data, waiting for more"; - return; - } - - QDataStream stream(buffer); - uint16_t length; - stream >> length; - - if (buffer.length() < length + 4) { - OPENAUTO_LOG(info) << "Not enough data, waiting for more: " << buffer.length(); - return; - } - - uint16_t messageId; - stream >> messageId; - - OPENAUTO_LOG(debug) << ""; - - switch (messageId) { - case 1: - handleWifiInfoRequest(buffer, length); - break; - case 2: - handleWifiSecurityRequest(buffer, length); - break; - case 7: - handleWifiInfoRequestResponse(buffer, length); - break; - default: { - std::stringstream ss; - ss << std::hex << std::setfill('0'); - for (auto &&val : buffer) { - ss << std::setw(2) << static_cast(val); - } - OPENAUTO_LOG(info) << "Unknown message: " << messageId; - OPENAUTO_LOG(info) << ss.str(); - break; - } - } - - buffer = buffer.mid(length + 4); - } - - void AndroidBluetoothServer::handleWifiInfoRequest(QByteArray &buffer, uint16_t length) { - //TODO: Restire - //aap_protobuf::messages::WifiInfoRequest msg; - //msg.ParseFromArray(buffer.data() + 4, length); - OPENAUTO_LOG(info) << "[AndroidBluetoothServer] WifiInfoRequest: "; //<< msg.DebugString(); - - //aap_protobuf::messages::WifiInfoResponse response; - //response.set_ip_address(getIP4_("wlan0")); - //response.set_port(5000); - //response.set_status(aap_protobuf::messages::WifiInfoResponse_Status_STATUS_SUCCESS); - - //sendMessage(response, 7); - } - - void AndroidBluetoothServer::handleWifiSecurityRequest(QByteArray &buffer, uint16_t length) { - OPENAUTO_LOG(info) << "[AndroidBluetoothServer] WifiSecurityRequest:"; - //aap_protobuf::messages::WifiSecurityReponse response; - - //response.set_ssid(configuration_->getParamFromFile("/etc/hostapd/hostapd.conf","ssid").toStdString()); - //response.set_bssid(QNetworkInterface::interfaceFromName("wlan0").hardwareAddress().toStdString()); - //response.set_key(configuration_->getParamFromFile("/etc/hostapd/hostapd.conf","wpa_passphrase").toStdString()); - //response.set_security_mode(aap_protobuf::messages::WifiSecurityReponse_SecurityMode_WPA2_PERSONAL); - //response.set_access_point_type(aap_protobuf::messages::WifiSecurityReponse_AccessPointType_STATIC); - - //sendMessage(response, 3); - } - - void AndroidBluetoothServer::sendMessage(const google::protobuf::Message& message, uint16_t type) { - int byteSize = message.ByteSize(); - QByteArray out(byteSize + 4, 0); - QDataStream ds(&out, QIODevice::ReadWrite); - ds << (uint16_t) byteSize; - ds << type; - message.SerializeToArray(out.data() + 4, byteSize); - - std::stringstream ss; - ss << std::hex << std::setfill('0'); - for (auto &&val : out) { - ss << std::setw(2) << static_cast(val); - } - //OPENAUTO_LOG(info) << "Writing message: " << ss.str(); - OPENAUTO_LOG(debug) << message.GetTypeName() << " - " + message.DebugString(); - - auto written = socket->write(out); - if (written > -1) { - OPENAUTO_LOG(info) << "Bytes written: " << written; - } else { - OPENAUTO_LOG(info) << "Could not write data"; - } - } - - void AndroidBluetoothServer::handleWifiInfoRequestResponse(QByteArray &buffer, uint16_t length) { - OPENAUTO_LOG(info) << "[AndroidBluetoothServer] WifiInfoRequestResponse"; - //aap_protobuf::messages::WifiInfoResponse msg; - //msg.ParseFromArray(buffer.data() + 4, length); - //OPENAUTO_LOG(info) << "WifiInfoResponse: " << msg.DebugString(); - } - - const ::std::string AndroidBluetoothServer::getIP4_(const QString intf) { - for (const QNetworkAddressEntry &address: QNetworkInterface::interfaceFromName(intf).addressEntries()) { - if (address.ip().protocol() == QAbstractSocket::IPv4Protocol) - return address.ip().toString().toStdString(); - } - return ""; - } - } + uint16_t AndroidBluetoothServer::start(const QBluetoothAddress &address) { + if (rfcommServer_->listen(address)) { + return rfcommServer_->serverPort(); } -} \ No newline at end of file + return 0; + } + + void AndroidBluetoothServer::onClientConnected() { + if (socket != nullptr) { + socket->deleteLater(); + } + + socket = rfcommServer_->nextPendingConnection(); + + if (socket != nullptr) { + OPENAUTO_LOG(info) << "[AndroidBluetoothServer] rfcomm client connected, peer name: " + << socket->peerName().toStdString(); + + connect(socket, &QBluetoothSocket::readyRead, this, &AndroidBluetoothServer::readSocket); + + aap_protobuf::service::wifiprojection::message::WifiCredentialsRequest request; + // TODO: How do we ping back the Wireless Port and IP? + //aap_protobuf::service::::WifiInfoRequest request; + //request.set_ip_address(getIP4_("wlan0")); + //request.set_port(5000); + + sendMessage(request, 1); + } else { + OPENAUTO_LOG(error) << "[AndroidBluetoothServer] received null socket during client connection."; + } + } + + void AndroidBluetoothServer::readSocket() { + buffer += socket->readAll(); + + OPENAUTO_LOG(info) << "Received message"; + + if (buffer.length() < 4) { + OPENAUTO_LOG(debug) << "Not enough data, waiting for more"; + return; + } + + QDataStream stream(buffer); + uint16_t length; + stream >> length; + + if (buffer.length() < length + 4) { + OPENAUTO_LOG(info) << "Not enough data, waiting for more: " << buffer.length(); + return; + } + + aap_protobuf::service::wifiprojection::WifiProjectionMessageId messageId; + //uint16_t messageId; + stream >> messageId; + + //OPENAUTO_LOG(info) << "[AndroidBluetoothServer] " << length << " " << messageId; + OPENAUTO_LOG(debug) << messageId; + + std::stringstream ss; + ss << std::hex << std::setfill('0'); + for (auto &&val: buffer) { + ss << std::setw(2) << static_cast(val); + } + OPENAUTO_LOG(info) << "Unknown message: " << messageId; + OPENAUTO_LOG(info) << ss.str(); + + buffer = buffer.mid(length + 4); + } + + void AndroidBluetoothServer::handleWifiInfoRequest(QByteArray &buffer, uint16_t length) { + aap_protobuf::service::wifiprojection::message::WifiCredentialsRequest msg; + msg.ParseFromArray(buffer.data() + 4, length); + OPENAUTO_LOG(info) << "WifiInfoRequest: " << msg.DebugString(); + + aap_protobuf::service::wifiprojection::message::WifiCredentialsResponse response; + + //response.set_ip_address(getIP4_("wlan0")); + //response.set_port(5000); + //response.set_status(aap_protobuf::service::control::WifiInfoResponse_Status_STATUS_SUCCESS); + + sendMessage(response, 7); + } + + void AndroidBluetoothServer::handleWifiSecurityRequest(QByteArray &buffer, uint16_t length) { + OPENAUTO_LOG(info) << "[AndroidBluetoothServer] WifiSecurityRequest:"; + aap_protobuf::service::wifiprojection::message::WifiCredentialsResponse response; + + response.set_car_wifi_security_mode( + aap_protobuf::service::wifiprojection::message::WifiSecurityMode::WPA2_PERSONAL); + response.set_car_wifi_ssid(configuration_->getParamFromFile("/etc/hostapd/hostapd.conf", "ssid").toStdString()); + response.set_car_wifi_password( + configuration_->getParamFromFile("/etc/hostapd/hostapd.conf", "wpa_passphrase").toStdString()); + response.set_access_point_type(aap_protobuf::service::wifiprojection::message::AccessPointType::STATIC); + response.add_supported_wifi_channels(1); + + + //response.set_ssid(configuration_->getParamFromFile("/etc/hostapd/hostapd.conf","ssid").toStdString()); + //response.set_bssid(QNetworkInterface::interfaceFromName("wlan0").hardwareAddress().toStdString()); + //response.set_key(configuration_->getParamFromFile("/etc/hostapd/hostapd.conf","wpa_passphrase").toStdString()); + //response.set_security_mode(aap_protobuf::messages::WifiSecurityReponse_SecurityMode_WPA2_PERSONAL); + //response.set_access_point_type(aap_protobuf::messages::WifiSecurityReponse_AccessPointType_STATIC); + + sendMessage(response, 3); + } + + void AndroidBluetoothServer::sendMessage(const google::protobuf::Message &message, uint16_t type) { + int byteSize = message.ByteSize(); + QByteArray out(byteSize + 4, 0); + QDataStream ds(&out, QIODevice::ReadWrite); + ds << (uint16_t) byteSize; + ds << type; + message.SerializeToArray(out.data() + 4, byteSize); + + std::stringstream ss; + ss << std::hex << std::setfill('0'); + for (auto &&val: out) { + ss << std::setw(2) << static_cast(val); + } + //OPENAUTO_LOG(info) << "Writing message: " << ss.str(); + OPENAUTO_LOG(debug) << message.GetTypeName() << " - " + message.DebugString(); + + auto written = socket->write(out); + if (written > -1) { + OPENAUTO_LOG(info) << "Bytes written: " << written; + } else { + OPENAUTO_LOG(info) << "Could not write data"; + } + } + + void AndroidBluetoothServer::handleWifiInfoRequestResponse(QByteArray &buffer, uint16_t length) { + OPENAUTO_LOG(info) << "[AndroidBluetoothServer] WifiInfoRequestResponse"; + aap_protobuf::service::wifiprojection::message::WifiCredentialsResponse msg; + msg.ParseFromArray(buffer.data() + 4, length); + OPENAUTO_LOG(info) << "WifiInfoResponse: " << msg.DebugString(); + } + + const ::std::string AndroidBluetoothServer::getIP4_(const QString intf) { + for (const QNetworkAddressEntry &address: QNetworkInterface::interfaceFromName(intf).addressEntries()) { + if (address.ip().protocol() == QAbstractSocket::IPv4Protocol) + return address.ip().toString().toStdString(); + } + return ""; + } +} + diff --git a/src/btservice/AndroidBluetoothService.cpp b/src/btservice/AndroidBluetoothService.cpp index f178662..01cc042 100644 --- a/src/btservice/AndroidBluetoothService.cpp +++ b/src/btservice/AndroidBluetoothService.cpp @@ -18,17 +18,9 @@ #include -namespace f1x -{ -namespace openauto -{ -namespace btservice -{ +namespace f1x::openauto::btservice { -AndroidBluetoothService::AndroidBluetoothService(uint16_t portNumber) -{ - //"4de17a00-52cb-11e6-bdf4-0800200c9a66"; - //"669a0c20-0008-f4bd-e611-cb52007ae14d"; + AndroidBluetoothService::AndroidBluetoothService(uint16_t portNumber) { const QBluetoothUuid serviceUuid(QLatin1String("4de17a00-52cb-11e6-bdf4-0800200c9a66")); QBluetoothServiceInfo::Sequence classId; @@ -38,7 +30,7 @@ AndroidBluetoothService::AndroidBluetoothService(uint16_t portNumber) serviceInfo_.setAttribute(QBluetoothServiceInfo::ServiceClassIds, classId); serviceInfo_.setAttribute(QBluetoothServiceInfo::ServiceName, "OpenAuto Bluetooth Service"); serviceInfo_.setAttribute(QBluetoothServiceInfo::ServiceDescription, "AndroidAuto WiFi projection automatic setup"); - serviceInfo_.setAttribute(QBluetoothServiceInfo::ServiceProvider, "f1xstudio.com"); + serviceInfo_.setAttribute(QBluetoothServiceInfo::ServiceProvider, "cubeone.co.uk"); serviceInfo_.setServiceUuid(serviceUuid); QBluetoothServiceInfo::Sequence publicBrowse; @@ -54,18 +46,16 @@ AndroidBluetoothService::AndroidBluetoothService(uint16_t portNumber) << QVariant::fromValue(quint16(portNumber)); protocolDescriptorList.append(QVariant::fromValue(protocol)); serviceInfo_.setAttribute(QBluetoothServiceInfo::ProtocolDescriptorList, protocolDescriptorList); -} + } -bool AndroidBluetoothService::registerService(const QBluetoothAddress& bluetoothAddress) -{ + bool AndroidBluetoothService::registerService(const QBluetoothAddress &bluetoothAddress) { return serviceInfo_.registerService(bluetoothAddress); -} + } -bool AndroidBluetoothService::unregisterService() -{ + bool AndroidBluetoothService::unregisterService() { return serviceInfo_.unregisterService(); -} + } } -} -} + + diff --git a/src/btservice/btservice.cpp b/src/btservice/btservice.cpp index 6fb042f..3b8b8ee 100644 --- a/src/btservice/btservice.cpp +++ b/src/btservice/btservice.cpp @@ -26,42 +26,42 @@ namespace btservice = f1x::openauto::btservice; int main(int argc, char *argv[]) { - QLoggingCategory::setFilterRules(QStringLiteral("qt.bluetooth*=true")); - QCoreApplication qApplication(argc, argv); + QLoggingCategory::setFilterRules(QStringLiteral("qt.bluetooth*=true")); + QCoreApplication qApplication(argc, argv); - QBluetoothLocalDevice localDevice; - const QBluetoothAddress address = localDevice.address(); + QBluetoothLocalDevice localDevice; + const QBluetoothAddress address = localDevice.address(); - auto configuration = std::make_shared(); + auto configuration = std::make_shared(); - // Turn Bluetooth on - localDevice.powerOn(); - // Make it visible to others - localDevice.setHostMode(QBluetoothLocalDevice::HostDiscoverable); + // Turn Bluetooth on + localDevice.powerOn(); + // Make it visible to others + localDevice.setHostMode(QBluetoothLocalDevice::HostDiscoverable); - btservice::AndroidBluetoothServer androidBluetoothServer(configuration); - uint16_t portNumber = androidBluetoothServer.start(address); + btservice::AndroidBluetoothServer androidBluetoothServer(configuration); + uint16_t portNumber = androidBluetoothServer.start(address); - if (portNumber == 0) { - OPENAUTO_LOG(error) << "[btservice] Server start failed."; - return 2; - } + if (portNumber == 0) { + OPENAUTO_LOG(error) << "[btservice] Server start failed."; + return 2; + } - OPENAUTO_LOG(info) << "[btservice] Listening for connections, address: " << address.toString().toStdString() - << ", port: " << portNumber; + OPENAUTO_LOG(info) << "[btservice] Listening for connections, address: " << address.toString().toStdString() + << ", port: " << portNumber; - btservice::AndroidBluetoothService androidBluetoothService(portNumber); - if (!androidBluetoothService.registerService(address)) { - OPENAUTO_LOG(error) << "[btservice] Service registration failed."; - return 1; - } else { - OPENAUTO_LOG(info) << "[btservice] Service registered, port: " << portNumber; - } + btservice::AndroidBluetoothService androidBluetoothService(portNumber); + if (!androidBluetoothService.registerService(address)) { + OPENAUTO_LOG(error) << "[btservice] Service registration failed."; + return 1; + } else { + OPENAUTO_LOG(info) << "[btservice] Service registered, port: " << portNumber; + } - QCoreApplication::exec(); + QCoreApplication::exec(); - OPENAUTO_LOG(info) << "stop"; - androidBluetoothService.unregisterService(); + OPENAUTO_LOG(info) << "stop"; + androidBluetoothService.unregisterService(); - return 0; + return 0; }