From e2b6985d87de76b6f8e55733f3283a5eccd16906 Mon Sep 17 00:00:00 2001 From: Cole Brinsfield Date: Thu, 20 Jan 2022 09:47:15 -0800 Subject: [PATCH] Navigation Status Service, Media Status Service, Touchscreen Multitouch Support, AAInterface (#26) * new services being added to openauto * cmake for new services * MediaStatusService, transitioning away from qt gstreamer * Reverting change to qmlglsink as it's not functional on raspbian as of this moment * Multitouch support within android auto * add night mode toggle to aainterface * Dot dump debug functionality * NavigationStatusService, MediaStatusService, AAInterface, Hotkey migration * Add a delay to dot dumping because caps aren't selected until data is streaming, so we can't rely on just a PLAYING status * PR cleanup --- .../openauto/Projection/GSTVideoOutput.hpp | 2 + .../Projection/IInputDeviceEventHandler.hpp | 6 +- include/openauto/Projection/InputDevice.hpp | 6 + .../Service/IAndroidAutoInterface.hpp | 88 +++++++++++++ include/openauto/Service/InputService.hpp | 5 +- .../openauto/Service/MediaStatusService.hpp | 52 ++++++++ .../Service/NavigationStatusService.hpp | 54 ++++++++ include/openauto/Service/ServiceFactory.hpp | 12 +- openauto/CMakeLists.txt | 7 +- openauto/Projection/GSTVideoOutput.cpp | 9 ++ openauto/Projection/InputDevice.cpp | 86 ++++++++++++- openauto/Service/InputService.cpp | 25 +++- openauto/Service/MediaStatusService.cpp | 97 ++++++++++++++ openauto/Service/NavigationStatusService.cpp | 119 ++++++++++++++++++ openauto/Service/SensorService.cpp | 1 - openauto/Service/ServiceFactory.cpp | 40 +++++- 16 files changed, 592 insertions(+), 17 deletions(-) create mode 100644 include/openauto/Service/IAndroidAutoInterface.hpp create mode 100644 include/openauto/Service/MediaStatusService.hpp create mode 100644 include/openauto/Service/NavigationStatusService.hpp create mode 100644 openauto/Service/MediaStatusService.cpp create mode 100644 openauto/Service/NavigationStatusService.cpp diff --git a/include/openauto/Projection/GSTVideoOutput.hpp b/include/openauto/Projection/GSTVideoOutput.hpp index 08ed16b..3b6df7c 100644 --- a/include/openauto/Projection/GSTVideoOutput.hpp +++ b/include/openauto/Projection/GSTVideoOutput.hpp @@ -72,6 +72,8 @@ protected slots: void onStartPlayback(); void onStopPlayback(); +public slots: + void dumpDot(); private: static GstPadProbeReturn convertProbe(GstPad* pad, GstPadProbeInfo* info, void*); static gboolean busCallback(GstBus*, GstMessage* message, gpointer*); diff --git a/include/openauto/Projection/IInputDeviceEventHandler.hpp b/include/openauto/Projection/IInputDeviceEventHandler.hpp index bfb1d09..e3e5c14 100644 --- a/include/openauto/Projection/IInputDeviceEventHandler.hpp +++ b/include/openauto/Projection/IInputDeviceEventHandler.hpp @@ -19,6 +19,8 @@ #pragma once #include "InputEvent.hpp" +#include "aasdk_proto/InputEventIndicationMessage.pb.h" + namespace openauto { @@ -31,7 +33,9 @@ public: virtual ~IInputDeviceEventHandler() = default; virtual void onButtonEvent(const ButtonEvent& event) = 0; - virtual void onTouchEvent(const TouchEvent& event) = 0; + virtual void onTouchEvent(aasdk::proto::messages::InputEventIndication inputEventIndication) = 0; + virtual void onMouseEvent(const projection::TouchEvent& event) = 0; + }; } diff --git a/include/openauto/Projection/InputDevice.hpp b/include/openauto/Projection/InputDevice.hpp index 4514d4c..9f6f691 100644 --- a/include/openauto/Projection/InputDevice.hpp +++ b/include/openauto/Projection/InputDevice.hpp @@ -22,6 +22,7 @@ #include #include "IInputDevice.hpp" #include "openauto/Configuration/IConfiguration.hpp" +#include namespace openauto { @@ -48,6 +49,7 @@ private: bool handleKeyEvent(QEvent* event, QKeyEvent* key); void dispatchKeyEvent(ButtonEvent event); bool handleTouchEvent(QEvent* event); + bool handleMouseEvent(QEvent* event); QObject& parent_; configuration::IConfiguration::Pointer configuration_; @@ -55,6 +57,10 @@ private: QRect displayGeometry_; IInputDeviceEventHandler* eventHandler_; std::mutex mutex_; + + std::priority_queue , std::greater > pointer_id_queue; + QMap pointer_map; + int max_pointers = 0; }; } diff --git a/include/openauto/Service/IAndroidAutoInterface.hpp b/include/openauto/Service/IAndroidAutoInterface.hpp new file mode 100644 index 0000000..13bcca5 --- /dev/null +++ b/include/openauto/Service/IAndroidAutoInterface.hpp @@ -0,0 +1,88 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#pragma once +#include "aasdk_proto/ButtonCodeEnum.pb.h" +#include "openauto/Projection/InputEvent.hpp" +#include "aasdk_proto/MediaInfoChannelMetadataData.pb.h" +#include "aasdk_proto/MediaInfoChannelPlaybackData.pb.h" +#include "aasdk_proto/NavigationStatusMessage.pb.h" +#include "aasdk_proto/NavigationDistanceEventMessage.pb.h" +#include "aasdk_proto/NavigationTurnEventMessage.pb.h" +#include "openauto/Service/ServiceFactory.hpp" + + +namespace openauto +{ +namespace service +{ + +class IAndroidAutoInterface: public std::enable_shared_from_this +{ +public: + std::shared_ptr getPtr() + { + return shared_from_this(); + } + typedef std::shared_ptr Pointer; + + virtual ~IAndroidAutoInterface() = default; + + virtual void mediaPlaybackUpdate(const aasdk::proto::messages::MediaInfoChannelPlaybackData& playback) = 0; + virtual void mediaMetadataUpdate(const aasdk::proto::messages::MediaInfoChannelMetadataData& metadata) = 0; + virtual void navigationStatusUpdate(const aasdk::proto::messages::NavigationStatus& navStatus) = 0; + virtual void navigationTurnEvent(const aasdk::proto::messages::NavigationTurnEvent& turnEvent) = 0; + virtual void navigationDistanceEvent(const aasdk::proto::messages::NavigationDistanceEvent& distanceEvent) = 0; + void setServiceFactory(ServiceFactory* serviceFactory) + { + this->m_serviceFactory = serviceFactory; + + } + void injectButtonPress(aasdk::proto::enums::ButtonCode::Enum buttonCode, projection::WheelDirection wheelDirection=openauto::projection::WheelDirection::NONE, projection::ButtonEventType buttonEventType = projection::ButtonEventType::NONE) + { + if(m_serviceFactory != NULL) + { + + m_serviceFactory->sendButtonPress(buttonCode, wheelDirection, buttonEventType); + } + } + void injectButtonPress(aasdk::proto::enums::ButtonCode::Enum buttonCode, projection::ButtonEventType buttonEventType) + { + this->injectButtonPress(buttonCode, projection::WheelDirection::NONE, buttonEventType); + } + void setNightMode(bool mode) + { + if(m_serviceFactory != NULL) + { + + m_serviceFactory->setNightMode(mode); + } + } + + + + +private: + using std::enable_shared_from_this::shared_from_this; + ServiceFactory* m_serviceFactory; +}; + + + +} +} diff --git a/include/openauto/Service/InputService.hpp b/include/openauto/Service/InputService.hpp index 893d2fb..6898985 100644 --- a/include/openauto/Service/InputService.hpp +++ b/include/openauto/Service/InputService.hpp @@ -38,7 +38,7 @@ class InputService: public: InputService(boost::asio::io_service& ioService, aasdk::messenger::IMessenger::Pointer messenger, projection::IInputDevice::Pointer inputDevice); - void sendButtonPress(aasdk::proto::enums::ButtonCode::Enum buttonCode, projection::WheelDirection wheelDirection = projection::WheelDirection::NONE); + void sendButtonPress(aasdk::proto::enums::ButtonCode::Enum buttonCode, projection::WheelDirection wheelDirection = projection::WheelDirection::NONE, projection::ButtonEventType buttonEventType = projection::ButtonEventType::NONE); void start() override; void stop() override; void fillFeatures(aasdk::proto::messages::ServiceDiscoveryResponse& response) override; @@ -46,7 +46,8 @@ public: void onBindingRequest(const aasdk::proto::messages::BindingRequest& request) override; void onChannelError(const aasdk::error::Error& e) override; void onButtonEvent(const projection::ButtonEvent& event) override; - void onTouchEvent(const projection::TouchEvent& event) override; + void onTouchEvent(aasdk::proto::messages::InputEventIndication inputEventIndication) override; + void onMouseEvent(const projection::TouchEvent& event) override; private: using std::enable_shared_from_this::shared_from_this; diff --git a/include/openauto/Service/MediaStatusService.hpp b/include/openauto/Service/MediaStatusService.hpp new file mode 100644 index 0000000..210fec0 --- /dev/null +++ b/include/openauto/Service/MediaStatusService.hpp @@ -0,0 +1,52 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#pragma once + +#include "aasdk/Channel/AV/MediaStatusServiceChannel.hpp" +#include "IService.hpp" + +namespace openauto +{ +namespace service +{ +class IAndroidAutoInterface; +class MediaStatusService: public aasdk::channel::av::IMediaStatusServiceChannelEventHandler, public IService, public std::enable_shared_from_this +{ +public: + MediaStatusService(boost::asio::io_service& ioService, aasdk::messenger::IMessenger::Pointer messenger, IAndroidAutoInterface* aa_interface); + void start() override; + void stop() override; + void fillFeatures(aasdk::proto::messages::ServiceDiscoveryResponse& response) override; + void onChannelOpenRequest(const aasdk::proto::messages::ChannelOpenRequest& request) override; + void onChannelError(const aasdk::error::Error& e) override; + void onMetadataUpdate(const aasdk::proto::messages::MediaInfoChannelMetadataData& metadata) override; + void onPlaybackUpdate(const aasdk::proto::messages::MediaInfoChannelPlaybackData& playback) override; + void setAndroidAutoInterface(IAndroidAutoInterface* aa_interface); + + +private: + using std::enable_shared_from_this::shared_from_this; + + boost::asio::io_service::strand strand_; + aasdk::channel::av::MediaStatusServiceChannel::Pointer channel_; + IAndroidAutoInterface* aa_interface_ = nullptr; +}; + +} +} diff --git a/include/openauto/Service/NavigationStatusService.hpp b/include/openauto/Service/NavigationStatusService.hpp new file mode 100644 index 0000000..d87b82e --- /dev/null +++ b/include/openauto/Service/NavigationStatusService.hpp @@ -0,0 +1,54 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. + +* openauto is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with openauto. If not, see . +*/ + +#pragma once + +#include "aasdk/Channel/Navigation/NavigationStatusServiceChannel.hpp" +#include "IService.hpp" + +namespace openauto +{ +namespace service +{ +class IAndroidAutoInterface; +class NavigationStatusService: public aasdk::channel::navigation::INavigationStatusServiceChannelEventHandler, public IService, public std::enable_shared_from_this +{ +public: + NavigationStatusService(boost::asio::io_service& ioService, aasdk::messenger::IMessenger::Pointer messenger, IAndroidAutoInterface* aa_interface); + void start() override; + void stop() override; + void fillFeatures(aasdk::proto::messages::ServiceDiscoveryResponse& response) override; + void onChannelOpenRequest(const aasdk::proto::messages::ChannelOpenRequest& request) override; + void onChannelError(const aasdk::error::Error& e) override; + void onTurnEvent(const aasdk::proto::messages::NavigationTurnEvent& turnEvent) override; + void onDistanceEvent(const aasdk::proto::messages::NavigationDistanceEvent& distanceEvent) override; + void onStatusUpdate(const aasdk::proto::messages::NavigationStatus& navStatus) override; + void setAndroidAutoInterface(IAndroidAutoInterface* aa_interface); + + +private: + using std::enable_shared_from_this::shared_from_this; + + boost::asio::io_service::strand strand_; + aasdk::channel::navigation::NavigationStatusServiceChannel::Pointer channel_; + IAndroidAutoInterface* aa_interface_ = nullptr; + +}; + +} +} diff --git a/include/openauto/Service/ServiceFactory.hpp b/include/openauto/Service/ServiceFactory.hpp index 8eef8e8..aaede04 100644 --- a/include/openauto/Service/ServiceFactory.hpp +++ b/include/openauto/Service/ServiceFactory.hpp @@ -24,6 +24,8 @@ #include "openauto/Projection/OMXVideoOutput.hpp" #include "openauto/Projection/GSTVideoOutput.hpp" #include "openauto/Projection/QtVideoOutput.hpp" +#include "openauto/Service/MediaStatusService.hpp" +#include "openauto/Service/NavigationStatusService.hpp" #include "openauto/Service/SensorService.hpp" #include "openauto/Service/InputService.hpp" #include "btservice/btservice.hpp" @@ -32,7 +34,7 @@ namespace openauto { namespace service { - +class IAndroidAutoInterface; class ServiceFactory : public IServiceFactory { public: @@ -41,8 +43,9 @@ public: void setOpacity(unsigned int alpha); void resize(); void setNightMode(bool nightMode); - void sendButtonPress(aasdk::proto::enums::ButtonCode::Enum buttonCode, projection::WheelDirection wheelDirection = projection::WheelDirection::NONE); + void sendButtonPress(aasdk::proto::enums::ButtonCode::Enum buttonCode, projection::WheelDirection wheelDirection = projection::WheelDirection::NONE, projection::ButtonEventType buttonEventType = projection::ButtonEventType::NONE); void sendKeyEvent(QKeyEvent* event); + void setAndroidAutoInterface(IAndroidAutoInterface* aa_interface); static QRect mapActiveAreaToGlobal(QWidget* activeArea); #ifdef USE_OMX static projection::DestRect QRectToDestRect(QRect rect); @@ -51,6 +54,8 @@ public: private: IService::Pointer createVideoService(aasdk::messenger::IMessenger::Pointer messenger); IService::Pointer createBluetoothService(aasdk::messenger::IMessenger::Pointer messenger); + std::shared_ptr createNavigationStatusService(aasdk::messenger::IMessenger::Pointer messenger); + std::shared_ptr createMediaStatusService(aasdk::messenger::IMessenger::Pointer messenger); std::shared_ptr createInputService(aasdk::messenger::IMessenger::Pointer messenger); void createAudioServices(ServiceList& serviceList, aasdk::messenger::IMessenger::Pointer messenger); @@ -71,6 +76,9 @@ private: bool nightMode_; std::weak_ptr sensorService_; std::weak_ptr inputService_; + std::weak_ptr mediaStatusService_; + std::weak_ptr navStatusService_; + IAndroidAutoInterface* aa_interface_ = nullptr; }; } diff --git a/openauto/CMakeLists.txt b/openauto/CMakeLists.txt index f648044..e201c6c 100644 --- a/openauto/CMakeLists.txt +++ b/openauto/CMakeLists.txt @@ -13,6 +13,8 @@ add_library(openauto SHARED Service/Pinger.cpp Service/AndroidAutoEntity.cpp Service/VideoService.cpp + Service/NavigationStatusService.cpp + Service/MediaStatusService.cpp Configuration/RecentAddressesList.cpp Configuration/Configuration.cpp Projection/RemoteBluetoothDevice.cpp @@ -28,6 +30,7 @@ add_library(openauto SHARED Projection/RtAudioOutput.cpp Projection/QtAudioOutput.cpp ${CMAKE_SOURCE_DIR}/btservice/AndroidBluetoothServer.cpp + ${CMAKE_SOURCE_DIR}/btservice/AndroidBluetoothServer.cpp ${CMAKE_SOURCE_DIR}/btservice/AndroidBluetoothService.cpp ${CMAKE_SOURCE_DIR}/btservice/btservice.cpp ${CMAKE_SOURCE_DIR}/include/btservice/AndroidBluetoothServer.hpp @@ -42,7 +45,9 @@ add_library(openauto SHARED ${CMAKE_SOURCE_DIR}/include/openauto/Configuration/IRecentAddressesList.hpp ${CMAKE_SOURCE_DIR}/include/openauto/Configuration/HandednessOfTrafficType.hpp ${CMAKE_SOURCE_DIR}/include/openauto/Configuration/BluetootAdapterType.hpp - ${CMAKE_SOURCE_DIR}/include/openauto/Service/MediaAudioService.hpp + ${CMAKE_SOURCE_DIR}/include/openauto/Service/NavigationStatusService.hpp + ${CMAKE_SOURCE_DIR}/include/openauto/Service/MediaStatusService.hpp + ${CMAKE_SOURCE_DIR}/include/openauto/Service/MediaAudioService.hpp ${CMAKE_SOURCE_DIR}/include/openauto/Service/SensorService.hpp ${CMAKE_SOURCE_DIR}/include/openauto/Service/IPinger.hpp ${CMAKE_SOURCE_DIR}/include/openauto/Service/IAndroidAutoEntity.hpp diff --git a/openauto/Projection/GSTVideoOutput.cpp b/openauto/Projection/GSTVideoOutput.cpp index 5d55b02..4513d32 100644 --- a/openauto/Projection/GSTVideoOutput.cpp +++ b/openauto/Projection/GSTVideoOutput.cpp @@ -20,6 +20,7 @@ #include "aasdk/Common/Data.hpp" #include "openauto/Projection/GSTVideoOutput.hpp" #include "OpenautoLog.hpp" +#include namespace openauto { @@ -92,6 +93,13 @@ GSTVideoOutput::~GSTVideoOutput() gst_object_unref(vidSrc_); } +void GSTVideoOutput::dumpDot(){ + + gst_debug_bin_to_dot_file(GST_BIN(vidPipeline_), GST_DEBUG_GRAPH_SHOW_VERBOSE, "pipeline"); + OPENAUTO_LOG(info) << "[GSTVideoOutput] Dumped dot debug info"; + +} + gboolean GSTVideoOutput::busCallback(GstBus*, GstMessage* message, gpointer*) { gchar* debug; @@ -197,6 +205,7 @@ void GSTVideoOutput::onStartPlayback() videoWidget_->resize(videoContainer_->size()); } videoWidget_->show(); + QTimer::singleShot(10000, this, SLOT(dumpDot())); } void GSTVideoOutput::stop() diff --git a/openauto/Projection/InputDevice.cpp b/openauto/Projection/InputDevice.cpp index 503a0a4..411e6c5 100644 --- a/openauto/Projection/InputDevice.cpp +++ b/openauto/Projection/InputDevice.cpp @@ -19,6 +19,7 @@ #include "OpenautoLog.hpp" #include "openauto/Projection/IInputDeviceEventHandler.hpp" #include "openauto/Projection/InputDevice.hpp" +#include namespace openauto { @@ -33,6 +34,7 @@ InputDevice::InputDevice(QObject& parent, configuration::IConfiguration::Pointer , eventHandler_(nullptr) { this->moveToThread(parent.thread()); + pointer_id_queue.push(INT_MAX); } void InputDevice::start(IInputDeviceEventHandler& eventHandler) @@ -67,10 +69,14 @@ bool InputDevice::eventFilter(QObject* obj, QEvent* event) return this->handleKeyEvent(event, key); } } - else if(event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonRelease || event->type() == QEvent::MouseMove) + else if(event->type() == QEvent::TouchBegin || event->type() == QEvent::TouchUpdate || event->type() == QEvent::TouchEnd || event->type() == QEvent::TouchCancel) { return this->handleTouchEvent(event); } + else if(event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonRelease || event->type() == QEvent::MouseMove) + { + return this->handleMouseEvent(event); + } } return QObject::eventFilter(obj, event); @@ -175,7 +181,6 @@ bool InputDevice::handleKeyEvent(QEvent* event, QKeyEvent* key) return true; } - bool InputDevice::handleTouchEvent(QEvent* event) { if(!configuration_->getTouchscreenEnabled()) @@ -183,6 +188,81 @@ bool InputDevice::handleTouchEvent(QEvent* event) return true; } + + QTouchEvent* qtTouchEvent = static_cast(event); + aasdk::proto::enums::TouchAction::Enum type; + auto timestamp = std::chrono::duration_cast(std::chrono::high_resolution_clock::now().time_since_epoch()); + aasdk::proto::messages::InputEventIndication inputEventIndication; + inputEventIndication.set_timestamp(timestamp.count()); + auto touchEvent = inputEventIndication.mutable_touch_event(); + switch(event->type()){ + case QEvent::TouchBegin: + type = aasdk::proto::enums::TouchAction::PRESS; + break; + case QEvent::TouchUpdate: + if(qtTouchEvent->touchPointStates().testFlag(Qt::TouchPointPressed)) type = aasdk::proto::enums::TouchAction::POINTER_DOWN; + else if(qtTouchEvent->touchPointStates().testFlag(Qt::TouchPointReleased)) type = aasdk::proto::enums::TouchAction::POINTER_UP; + else{ + type = aasdk::proto::enums::TouchAction::DRAG; + touchEvent->set_action_index(0); + } + break; + case QEvent::TouchEnd: + type = aasdk::proto::enums::TouchAction::RELEASE; + break; + case QEvent::TouchCancel: + type = aasdk::proto::enums::TouchAction::RELEASE; + default: + return true; + } + + touchEvent->set_touch_action(type); + + auto pointers = qtTouchEvent->touchPoints(); + + // What's with this pointer map and pointer id queue? + // Pointers get a unique id during their lifespan, and android auto gets pissy when you try and just use the unique id qt assigns + // but it's happier with smaller valued ids + // and since there are no garuntees about id range, or similar (because of drivers and whatnot) + // pointer id queue is a min heap, with the first item being the next availible "smaller id" + // and pointer maps stores the qt id: small id relation + // the pointer id queue will expand as needed + + // I kinda hate this, but it works + + for(int i=0; iset_action_index(i); + if(pointer_id_queue.top() == INT_MAX){ + pointer_id_queue.push(max_pointers++); + } + pointer_map.insert(pointers[i].id(), pointer_id_queue.top()); + pointer_id_queue.pop(); + } + else if(pointers[i].state() == Qt::TouchPointReleased){ + touchEvent->set_action_index(i); + pointer_id_queue.push(pointer_map.take(pointers[i].id())); + } + + auto touchLocation = touchEvent->add_touch_location(); + touchLocation->set_x((static_cast(pointers[i].pos().x()) / touchscreenGeometry_.width()) * displayGeometry_.width()); + touchLocation->set_y((static_cast(pointers[i].pos().y()) / touchscreenGeometry_.height()) * displayGeometry_.height()); + touchLocation->set_pointer_id(pointer_map[pointers[i].id()]); + } + + eventHandler_->onTouchEvent(inputEventIndication); + + return true; + +} +bool InputDevice::handleMouseEvent(QEvent* event) +{ + if(!configuration_->getTouchscreenEnabled()) + { + return true; + } + aasdk::proto::enums::TouchAction::Enum type; switch(event->type()) @@ -205,7 +285,7 @@ bool InputDevice::handleTouchEvent(QEvent* event) { const uint32_t x = (static_cast(mouse->pos().x()) / touchscreenGeometry_.width()) * displayGeometry_.width(); const uint32_t y = (static_cast(mouse->pos().y()) / touchscreenGeometry_.height()) * displayGeometry_.height(); - eventHandler_->onTouchEvent({type, x, y, 0}); + eventHandler_->onMouseEvent({type, x, y, 0}); } return true; diff --git a/openauto/Service/InputService.cpp b/openauto/Service/InputService.cpp index db2982f..9a0a502 100644 --- a/openauto/Service/InputService.cpp +++ b/openauto/Service/InputService.cpp @@ -163,7 +163,7 @@ void InputService::onButtonEvent(const projection::ButtonEvent& event) }); } -void InputService::sendButtonPress(aasdk::proto::enums::ButtonCode::Enum buttonCode, projection::WheelDirection wheelDirection) +void InputService::sendButtonPress(aasdk::proto::enums::ButtonCode::Enum buttonCode, projection::WheelDirection wheelDirection, projection::ButtonEventType buttonEventType) { OPENAUTO_LOG(info) << "[InputService] injecting button press"; if(buttonCode == aasdk::proto::enums::ButtonCode::SCROLL_WHEEL) @@ -173,12 +173,29 @@ void InputService::sendButtonPress(aasdk::proto::enums::ButtonCode::Enum buttonC } else { - onButtonEvent({projection::ButtonEventType::PRESS, projection::WheelDirection::NONE, buttonCode}); - onButtonEvent({projection::ButtonEventType::RELEASE, projection::WheelDirection::NONE, buttonCode}); + if(buttonEventType == projection::ButtonEventType::NONE){ + onButtonEvent({projection::ButtonEventType::PRESS, projection::WheelDirection::NONE, buttonCode}); + onButtonEvent({projection::ButtonEventType::RELEASE, projection::WheelDirection::NONE, buttonCode}); + } + else + { + onButtonEvent({buttonEventType, projection::WheelDirection::NONE, buttonCode}); + } } } -void InputService::onTouchEvent(const projection::TouchEvent& event) +void InputService::onTouchEvent(aasdk::proto::messages::InputEventIndication inputEventIndication) +{ + + strand_.dispatch([this, self = this->shared_from_this(), inputEventIndication = std::move(inputEventIndication)]() { + + auto promise = aasdk::channel::SendPromise::defer(strand_); + promise->then([]() {}, std::bind(&InputService::onChannelError, this->shared_from_this(), std::placeholders::_1)); + channel_->sendInputEventIndication(inputEventIndication, std::move(promise)); + }); +} + +void InputService::onMouseEvent(const projection::TouchEvent& event) { auto timestamp = std::chrono::duration_cast(std::chrono::high_resolution_clock::now().time_since_epoch()); diff --git a/openauto/Service/MediaStatusService.cpp b/openauto/Service/MediaStatusService.cpp new file mode 100644 index 0000000..7a280b4 --- /dev/null +++ b/openauto/Service/MediaStatusService.cpp @@ -0,0 +1,97 @@ +#include "OpenautoLog.hpp" +#include "openauto/Service/MediaStatusService.hpp" +#include "openauto/Service/IAndroidAutoInterface.hpp" + +namespace openauto +{ +namespace service +{ + +MediaStatusService::MediaStatusService(boost::asio::io_service& ioService, aasdk::messenger::IMessenger::Pointer messenger, IAndroidAutoInterface* aa_interface) + : strand_(ioService) + , channel_(std::make_shared(strand_, std::move(messenger))) +{ + aa_interface_ = aa_interface; +} + +void MediaStatusService::start() +{ + strand_.dispatch([this, self = this->shared_from_this()]() { + OPENAUTO_LOG(info) << "[MediaStatusService] start."; + channel_->receive(this->shared_from_this()); + }); +} + +void MediaStatusService::stop() +{ + strand_.dispatch([this, self = this->shared_from_this()]() { + OPENAUTO_LOG(info) << "[MediaStatusService] stop."; + }); +} + +void MediaStatusService::fillFeatures(aasdk::proto::messages::ServiceDiscoveryResponse& response) +{ + OPENAUTO_LOG(info) << "[MediaStatusService] fill features"; + + auto* channelDescriptor = response.add_channels(); + auto mediaStatusChannel = channelDescriptor->mutable_media_infochannel(); + channelDescriptor->set_channel_id(static_cast(channel_->getId())); +} + +void MediaStatusService::onChannelOpenRequest(const aasdk::proto::messages::ChannelOpenRequest& request) +{ + OPENAUTO_LOG(info) << "[MediaStatusService] open request, priority: " << request.priority(); + const aasdk::proto::enums::Status::Enum status = aasdk::proto::enums::Status::OK; + OPENAUTO_LOG(info) << "[MediaStatusService] open status: " << status; + + aasdk::proto::messages::ChannelOpenResponse response; + response.set_status(status); + + auto promise = aasdk::channel::SendPromise::defer(strand_); + promise->then([]() {}, std::bind(&MediaStatusService::onChannelError, this->shared_from_this(), std::placeholders::_1)); + channel_->sendChannelOpenResponse(response, std::move(promise)); + + channel_->receive(this->shared_from_this()); +} + + +void MediaStatusService::onChannelError(const aasdk::error::Error& e) +{ + OPENAUTO_LOG(error) << "[MediaStatusService] channel error: " << e.what(); +} + +void MediaStatusService::onMetadataUpdate(const aasdk::proto::messages::MediaInfoChannelMetadataData& metadata) +{ + OPENAUTO_LOG(info) << "[MediaStatusService] Metadata update" + << ", track: " << metadata.track_name() + << (metadata.has_artist_name()?", artist: ":"") << (metadata.has_artist_name()?metadata.artist_name():"") + << (metadata.has_album_name()?", album: ":"") << (metadata.has_album_name()?metadata.album_name():"") + << ", length: " << metadata.track_length(); + if(aa_interface_ != NULL) + { + aa_interface_->mediaMetadataUpdate(metadata); + } + channel_->receive(this->shared_from_this()); +} + +void MediaStatusService::onPlaybackUpdate(const aasdk::proto::messages::MediaInfoChannelPlaybackData& playback) +{ + OPENAUTO_LOG(info) << "[MediaStatusService] Playback update" + << ", source: " << playback.media_source() + << ", state: " << playback.playback_state() + << ", progress: " << playback.track_progress(); + if(aa_interface_ != NULL) + { + aa_interface_->mediaPlaybackUpdate(playback); + } + channel_->receive(this->shared_from_this()); +} + +void MediaStatusService::setAndroidAutoInterface(IAndroidAutoInterface* aa_interface) +{ + this->aa_interface_ = aa_interface; +} + + +} +} diff --git a/openauto/Service/NavigationStatusService.cpp b/openauto/Service/NavigationStatusService.cpp new file mode 100644 index 0000000..8c45930 --- /dev/null +++ b/openauto/Service/NavigationStatusService.cpp @@ -0,0 +1,119 @@ +#include "OpenautoLog.hpp" +#include "openauto/Service/NavigationStatusService.hpp" +#include "aasdk_proto/ManeuverTypeEnum.pb.h" +#include "aasdk_proto/ManeuverDirectionEnum.pb.h" +#include "aasdk_proto/DistanceUnitEnum.pb.h" +#include "openauto/Service/IAndroidAutoInterface.hpp" + +namespace openauto +{ +namespace service +{ + +NavigationStatusService::NavigationStatusService(boost::asio::io_service& ioService, aasdk::messenger::IMessenger::Pointer messenger, IAndroidAutoInterface* aa_interface) + : strand_(ioService) + , channel_(std::make_shared(strand_, std::move(messenger))) +{ + this->aa_interface_ = aa_interface; +} + +void NavigationStatusService::start() +{ + strand_.dispatch([this, self = this->shared_from_this()]() { + OPENAUTO_LOG(info) << "[NavigationStatusService] start."; + channel_->receive(this->shared_from_this()); + }); +} + +void NavigationStatusService::stop() +{ + strand_.dispatch([this, self = this->shared_from_this()]() { + OPENAUTO_LOG(info) << "[NavigationStatusService] stop."; + }); +} + +void NavigationStatusService::fillFeatures(aasdk::proto::messages::ServiceDiscoveryResponse& response) +{ + OPENAUTO_LOG(info) << "[NavigationStatusService] fill features"; + + auto* channelDescriptor = response.add_channels(); + channelDescriptor->set_channel_id(static_cast(channel_->getId())); + auto navStatusChannel = channelDescriptor->mutable_navigation_channel(); + navStatusChannel->set_minimum_interval_ms(1000); + navStatusChannel->set_type(aasdk::proto::enums::NavigationTurnType::IMAGE); + auto* imageOptions = new aasdk::proto::data::NavigationImageOptions(); + imageOptions->set_colour_depth_bits(16); + imageOptions->set_height(256); + imageOptions->set_width(256); + imageOptions->set_dunno(255); + navStatusChannel->set_allocated_image_options(imageOptions); +} + +void NavigationStatusService::onChannelOpenRequest(const aasdk::proto::messages::ChannelOpenRequest& request) +{ + OPENAUTO_LOG(info) << "[NavigationStatusService] open request, priority: " << request.priority(); + const aasdk::proto::enums::Status::Enum status = aasdk::proto::enums::Status::OK; + OPENAUTO_LOG(info) << "[NavigationStatusService] open status: " << status; + + aasdk::proto::messages::ChannelOpenResponse response; + response.set_status(status); + + auto promise = aasdk::channel::SendPromise::defer(strand_); + promise->then([]() {}, std::bind(&NavigationStatusService::onChannelError, this->shared_from_this(), std::placeholders::_1)); + channel_->sendChannelOpenResponse(response, std::move(promise)); + + channel_->receive(this->shared_from_this()); +} + + +void NavigationStatusService::onChannelError(const aasdk::error::Error& e) +{ + OPENAUTO_LOG(error) << "[NavigationStatusService] channel error: " << e.what(); +} + +void NavigationStatusService::onStatusUpdate(const aasdk::proto::messages::NavigationStatus& navStatus) +{ + OPENAUTO_LOG(info) << "[NavigationStatusService] Navigation Status Update" + << ", Status: " << aasdk::proto::messages::NavigationStatus_Enum_Name(navStatus.status()); + if(aa_interface_ != NULL) + { + aa_interface_->navigationStatusUpdate(navStatus); + } + channel_->receive(this->shared_from_this()); +} + +void NavigationStatusService::onTurnEvent(const aasdk::proto::messages::NavigationTurnEvent& turnEvent) +{ + OPENAUTO_LOG(info) << "[NavigationStatusService] Turn Event" + << ", Street: " << turnEvent.street_name() + << ", Maneuver: " << aasdk::proto::enums::ManeuverDirection_Enum_Name(turnEvent.maneuverdirection()) << " " << aasdk::proto::enums::ManeuverType_Enum_Name(turnEvent.maneuvertype()); + if(aa_interface_ != NULL) + { + aa_interface_->navigationTurnEvent(turnEvent); + } + channel_->receive(this->shared_from_this()); +} + +void NavigationStatusService::onDistanceEvent(const aasdk::proto::messages::NavigationDistanceEvent& distanceEvent) +{ + OPENAUTO_LOG(info) << "[NavigationStatusService] Distance Event" + << ", Distance (meters): " << distanceEvent.meters() + << ", Time To Turn (seconds): " << distanceEvent.timetostepseconds() + << ", Distance: " << distanceEvent.distancetostepmillis()/1000.0 + << " ("<navigationDistanceEvent(distanceEvent); + } + channel_->receive(this->shared_from_this()); +} + + +void NavigationStatusService::setAndroidAutoInterface(IAndroidAutoInterface* aa_interface) +{ + this->aa_interface_ = aa_interface; +} + + +} +} diff --git a/openauto/Service/SensorService.cpp b/openauto/Service/SensorService.cpp index 8638413..1e2f5ec 100644 --- a/openauto/Service/SensorService.cpp +++ b/openauto/Service/SensorService.cpp @@ -54,7 +54,6 @@ void SensorService::fillFeatures(aasdk::proto::messages::ServiceDiscoveryRespons auto* channelDescriptor = response.add_channels(); channelDescriptor->set_channel_id(static_cast(channel_->getId())); - auto* sensorChannel = channelDescriptor->mutable_sensor_channel(); sensorChannel->add_sensors()->set_type(aasdk::proto::enums::SensorType::DRIVING_STATUS); //sensorChannel->add_sensors()->set_type(aasdk::proto::enums::SensorType::LOCATION); diff --git a/openauto/Service/ServiceFactory.cpp b/openauto/Service/ServiceFactory.cpp index afad991..71e811a 100644 --- a/openauto/Service/ServiceFactory.cpp +++ b/openauto/Service/ServiceFactory.cpp @@ -30,6 +30,7 @@ #include "openauto/Service/SensorService.hpp" #include "openauto/Service/BluetoothService.hpp" #include "openauto/Service/InputService.hpp" +#include "openauto/Service/NavigationStatusService.hpp" #include "openauto/Projection/QtVideoOutput.hpp" #include "openauto/Projection/GSTVideoOutput.hpp" #include "openauto/Projection/OMXVideoOutput.hpp" @@ -40,12 +41,13 @@ #include "openauto/Projection/LocalBluetoothDevice.hpp" #include "openauto/Projection/RemoteBluetoothDevice.hpp" #include "openauto/Projection/DummyBluetoothDevice.hpp" +#include "openauto/Service/IAndroidAutoInterface.hpp" + namespace openauto { namespace service { - ServiceFactory::ServiceFactory(boost::asio::io_service& ioService, configuration::IConfiguration::Pointer configuration, QWidget *activeArea, std::function activeCallback, bool nightMode) : ioService_(ioService) , configuration_(std::move(configuration)) @@ -62,6 +64,7 @@ ServiceFactory::ServiceFactory(boost::asio::io_service& ioService, configuration , btservice_(configuration_) , nightMode_(nightMode) { + OPENAUTO_LOG(info) << "SERVICE FACTORY INITED"; } @@ -79,6 +82,13 @@ ServiceList ServiceFactory::create(aasdk::messenger::IMessenger::Pointer messeng serviceList.emplace_back(this->createVideoService(messenger)); serviceList.emplace_back(this->createBluetoothService(messenger)); + std::shared_ptr navStatusService = this->createNavigationStatusService(messenger); + navStatusService_ = navStatusService; + serviceList.emplace_back(navStatusService); + std::shared_ptr mediaStatusService = this->createMediaStatusService(messenger); + mediaStatusService_ = mediaStatusService; + serviceList.emplace_back(mediaStatusService); + std::shared_ptr inputService = this->createInputService(messenger); inputService_ = inputService; serviceList.emplace_back(inputService); @@ -128,6 +138,16 @@ IService::Pointer ServiceFactory::createBluetoothService(aasdk::messenger::IMess return std::make_shared(ioService_, messenger, std::move(bluetoothDevice)); } +std::shared_ptr ServiceFactory::createNavigationStatusService(aasdk::messenger::IMessenger::Pointer messenger) +{ + return std::make_shared(ioService_, messenger, aa_interface_); +} + +std::shared_ptr ServiceFactory::createMediaStatusService(aasdk::messenger::IMessenger::Pointer messenger) +{ + return std::make_shared(ioService_, messenger, aa_interface_); +} + std::shared_ptr ServiceFactory::createInputService(aasdk::messenger::IMessenger::Pointer messenger) { QRect videoGeometry; @@ -218,6 +238,20 @@ void ServiceFactory::resize() } #endif } +void ServiceFactory::setAndroidAutoInterface(IAndroidAutoInterface* aa_interface){ + if(aa_interface==NULL) return; + this->aa_interface_ = aa_interface; + + if(std::shared_ptr mediaStatusService = mediaStatusService_.lock()) + { + mediaStatusService->setAndroidAutoInterface(aa_interface); + } + if(std::shared_ptr navStatusService = navStatusService_.lock()) + { + navStatusService->setAndroidAutoInterface(aa_interface); + } + +} void ServiceFactory::setNightMode(bool nightMode) { @@ -228,12 +262,12 @@ void ServiceFactory::setNightMode(bool nightMode) } } -void ServiceFactory::sendButtonPress(aasdk::proto::enums::ButtonCode::Enum buttonCode, projection::WheelDirection wheelDirection) +void ServiceFactory::sendButtonPress(aasdk::proto::enums::ButtonCode::Enum buttonCode, projection::WheelDirection wheelDirection, projection::ButtonEventType buttonEventType) { if(std::shared_ptr inputService = inputService_.lock()) { - inputService->sendButtonPress(buttonCode, wheelDirection); + inputService->sendButtonPress(buttonCode, wheelDirection, buttonEventType); } }